The snmpd parts are OK with me but I don't think I'm qualified to OK
adding the new ioctl myself.
On 2018/05/18 11:08, Jan Klemkow wrote:
> On Mon, May 14, 2018 at 09:21:13PM +0200, Jan Klemkow wrote:
> > On Mon, May 14, 2018 at 06:53:20PM +0100, Stuart Henderson wrote:
> > > On 2018/05/14 17:59, Jan Klemkow wrote:
> > > > The following diff adds an interface group table to the OpenBSD MIBs and
> > > > the OpenSNMPd. The new snmp table helps to keep track of the demote
> > > > values of more complex carp setups. To iterate directly through all
> > > > interface groups, the diff has to extent ioctl interface by a new
> > > > command SIOCGIFGLIST.
> > > >
> > > > This new interface could also be used to extent ifconfig(8), in a later
> > > > diff, to list all interface groups with there demote counter.
> > > >
> > > > I tested this diff with snmpctl(8) from base and snmpwalk from
> > > > net/net-snmp under current amd64.
> >
> > > This seems a reasonable thing to report on and I didn't spot any code
> > > problems yet, one thing with the MIB file though:
> >
> > > > Index: share/snmp/OPENBSD-CARP-MIB.txt
> > > > ===================================================================
> > > > RCS file: /cvs//src/share/snmp/OPENBSD-CARP-MIB.txt,v
> > > > retrieving revision 1.3
> > > > diff -u -p -r1.3 OPENBSD-CARP-MIB.txt
> > > > --- share/snmp/OPENBSD-CARP-MIB.txt 28 Sep 2012 09:21:48 -0000
> > > > 1.3
> > > > +++ share/snmp/OPENBSD-CARP-MIB.txt 14 May 2018 14:53:02 -0000
> > > > @@ -41,7 +41,7 @@ carpMIBObjects MODULE-IDENTITY
> > > > "
> > > > DESCRIPTION "The MIB module for gathering information about
> > > > Common Address Redundancy Protocol (CARP) interfaces."
> > > > - REVISION "201201310000Z"
> > > > + REVISION "201805140000Z"
> > > > DESCRIPTION "Add the OPENBSD-CARP-MIB to snmpd."
> > > > ::= { openBSD 6 }
> > >
> > > This section is meant to be a sort of changelog; please add a new
> > > REVISION/DESCRIPTION rather than changing the existing one. (Also check
> > > that smilint is happy).
> >
> > Thanks for the hint. I fixed the changelog and some other issues
> > pointed by smilint.
>
> This is the merged version of the diff:
>
> Thanks,
> Jan
>
> Index: share/snmp/OPENBSD-CARP-MIB.txt
> ===================================================================
> RCS file: /cvs//src/share/snmp/OPENBSD-CARP-MIB.txt,v
> retrieving revision 1.3
> diff -u -p -r1.3 OPENBSD-CARP-MIB.txt
> --- share/snmp/OPENBSD-CARP-MIB.txt 28 Sep 2012 09:21:48 -0000 1.3
> +++ share/snmp/OPENBSD-CARP-MIB.txt 14 May 2018 18:58:59 -0000
> @@ -32,7 +32,7 @@ IMPORTS
> FROM SNMPv2-CONF;
>
> carpMIBObjects MODULE-IDENTITY
> - LAST-UPDATED "201201310000Z"
> + LAST-UPDATED "201805140000Z"
> ORGANIZATION "OpenBSD"
> CONTACT-INFO "
> Author: Joel Knight
> @@ -41,6 +41,8 @@ carpMIBObjects MODULE-IDENTITY
> "
> DESCRIPTION "The MIB module for gathering information about
> Common Address Redundancy Protocol (CARP) interfaces."
> + REVISION "201805140000Z"
> + DESCRIPTION "Add the carpGroupTable to OPENBSD-CARP-MIB."
> REVISION "201201310000Z"
> DESCRIPTION "Add the OPENBSD-CARP-MIB to snmpd."
> ::= { openBSD 6 }
> @@ -174,6 +176,58 @@ carpIfState OBJECT-TYPE
> DESCRIPTION
> "Indicates the operational state of the CARP interface."
> ::= { carpIfEntry 7 }
> +
> +
> +-- carpGroup
> +
> +carpGroupTable OBJECT-TYPE
> + SYNTAX SEQUENCE OF CarpGroupEntry
> + MAX-ACCESS not-accessible
> + STATUS current
> + DESCRIPTION
> + "A list of interface groups."
> + ::= { carpMIBObjects 4 }
> +
> +carpGroupEntry OBJECT-TYPE
> + SYNTAX CarpGroupEntry
> + MAX-ACCESS not-accessible
> + STATUS current
> + DESCRIPTION
> + "An entry containing management information applicable to a
> + particular interface group."
> + INDEX { carpGroupIndex }
> + ::= { carpGroupTable 1 }
> +
> +CarpGroupEntry ::=
> + SEQUENCE {
> + carpGroupIndex Integer32,
> + carpGroupName OCTET STRING,
> + carpGroupDemote Integer32
> + }
> +
> +carpGroupIndex OBJECT-TYPE
> + SYNTAX Integer32 (1..2147483647)
> + MAX-ACCESS not-accessible
> + STATUS current
> + DESCRIPTION
> + "The demote value of the interface group."
> + ::= { carpGroupEntry 1 }
> +
> +carpGroupName OBJECT-TYPE
> + SYNTAX OCTET STRING
> + MAX-ACCESS read-only
> + STATUS current
> + DESCRIPTION
> + "The name of the interface group."
> + ::= { carpGroupEntry 2 }
> +
> +carpGroupDemote OBJECT-TYPE
> + SYNTAX Integer32 (1..2147483647)
> + MAX-ACCESS read-only
> + STATUS current
> + DESCRIPTION
> + "The demote value of the interface group."
> + ::= { carpGroupEntry 3 }
>
>
> -- carpStats
> Index: sys/net/if.c
> ===================================================================
> RCS file: /cvs//src/sys/net/if.c,v
> retrieving revision 1.552
> diff -u -p -r1.552 if.c
> --- sys/net/if.c 17 May 2018 11:04:14 -0000 1.552
> +++ sys/net/if.c 18 May 2018 08:53:39 -0000
> @@ -145,6 +145,7 @@ int if_getgroup(caddr_t, struct ifnet *)
> int if_getgroupmembers(caddr_t);
> int if_getgroupattribs(caddr_t);
> int if_setgroupattribs(caddr_t);
> +int if_getgrouplist(caddr_t);
>
> void if_linkstate(struct ifnet *);
> void if_linkstate_task(void *);
> @@ -1851,6 +1852,7 @@ ifioctl(struct socket *so, u_long cmd, c
> case SIOCIFGCLONERS:
> case SIOCGIFGMEMB:
> case SIOCGIFGATTR:
> + case SIOCGIFGLIST:
> case SIOCGIFFLAGS:
> case SIOCGIFXFLAGS:
> case SIOCGIFMETRIC:
> @@ -2189,6 +2191,11 @@ ifioctl_get(u_long cmd, caddr_t data)
> error = if_getgroupattribs(data);
> NET_RUNLOCK();
> return (error);
> + case SIOCGIFGLIST:
> + NET_RLOCK();
> + error = if_getgrouplist(data);
> + NET_RUNLOCK();
> + return (error);
> }
>
> ifp = ifunit(ifr->ifr_name);
> @@ -2620,6 +2627,41 @@ if_setgroupattribs(caddr_t data)
>
> TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
> ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp, SIOCSIFGATTR, data);
> +
> + return (0);
> +}
> +
> +/*
> + * Stores all groups in memory pointed to by data
> + */
> +int
> +if_getgrouplist(caddr_t data)
> +{
> + struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
> + struct ifg_group *ifg;
> + struct ifg_req ifgrq, *ifgp;
> + int len, error;
> +
> + if (ifgr->ifgr_len == 0) {
> + TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
> + ifgr->ifgr_len += sizeof(ifgrq);
> + return (0);
> + }
> +
> + len = ifgr->ifgr_len;
> + ifgp = ifgr->ifgr_groups;
> + TAILQ_FOREACH(ifg, &ifg_head, ifg_next) {
> + if (len < sizeof(ifgrq))
> + return (EINVAL);
> + bzero(&ifgrq, sizeof ifgrq);
> + strlcpy(ifgrq.ifgrq_group, ifg->ifg_group,
> + sizeof(ifgrq.ifgrq_group));
> + if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
> + sizeof(struct ifg_req))))
> + return (error);
> + ifgr->ifgr_len += sizeof(ifgrq);
> + ifgp++;
> + }
>
> return (0);
> }
> Index: sys/sys/sockio.h
> ===================================================================
> RCS file: /cvs//src/sys/sys/sockio.h,v
> retrieving revision 1.75
> diff -u -p -r1.75 sockio.h
> --- sys/sys/sockio.h 20 Feb 2018 03:43:07 -0000 1.75
> +++ sys/sys/sockio.h 9 May 2018 12:56:46 -0000
> @@ -129,6 +129,7 @@
> #define SIOCGIFGMEMB _IOWR('i', 138, struct ifgroupreq) /* get
> members */
> #define SIOCGIFGATTR _IOWR('i', 139, struct ifgroupreq) /* get
> ifgroup attribs */
> #define SIOCSIFGATTR _IOW('i', 140, struct ifgroupreq) /* set ifgroup
> attribs */
> +#define SIOCGIFGLIST _IOWR('i', 141, struct ifgroupreq) /* get
> ifgroup list */
>
> #define SIOCSIFDESCR _IOW('i', 128, struct ifreq) /* set ifnet
> descr */
> #define SIOCGIFDESCR _IOWR('i', 129, struct ifreq) /* get ifnet
> descr */
> Index: usr.sbin/snmpd/mib.c
> ===================================================================
> RCS file: /cvs//src/usr.sbin/snmpd/mib.c,v
> retrieving revision 1.86
> diff -u -p -r1.86 mib.c
> --- usr.sbin/snmpd/mib.c 9 May 2018 13:56:46 -0000 1.86
> +++ usr.sbin/snmpd/mib.c 14 May 2018 18:51:24 -0000
> @@ -1422,6 +1422,7 @@ char *mib_sensorvalue(struct sensor *);
> int mib_carpsysctl(struct oid *, struct ber_oid *, struct ber_element **);
> int mib_carpstats(struct oid *, struct ber_oid *, struct ber_element **);
> int mib_carpiftable(struct oid *, struct ber_oid *, struct ber_element **);
> +int mib_carpgrouptable(struct oid *, struct ber_oid *, struct ber_element
> **);
> int mib_carpifnum(struct oid *, struct ber_oid *, struct ber_element **);
> struct carpif
> *mib_carpifget(u_int);
> @@ -1637,6 +1638,8 @@ static struct oid openbsd_mib[] = {
> { MIB(carpIfAdvbase), OID_TRD, mib_carpiftable },
> { MIB(carpIfAdvskew), OID_TRD, mib_carpiftable },
> { MIB(carpIfState), OID_TRD, mib_carpiftable },
> + { MIB(carpGroupName), OID_TRD, mib_carpgrouptable },
> + { MIB(carpGroupDemote), OID_TRD, mib_carpgrouptable },
> { MIB(memMIBObjects), OID_MIB },
> { MIB(memMIBVersion), OID_RD, mps_getint, NULL, NULL,
> OIDVER_OPENBSD_MEM },
> @@ -2871,6 +2874,105 @@ mib_carpiftable(struct oid *oid, struct
> }
>
> free(cif);
> + return (0);
> +}
> +
> +static struct ifg_req *
> +mib_carpgroupget(u_int idx)
> +{
> + struct ifgroupreq ifgr;
> + struct ifg_req *ifg = NULL;
> + u_int len;
> + int s = -1;
> +
> + bzero(&ifgr, sizeof(ifgr));
> +
> + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
> + log_warn("socket");
> + return (NULL);
> + }
> +
> + if (ioctl(s, SIOCGIFGLIST, (caddr_t)&ifgr) == -1) {
> + log_warn("SIOCGIFGLIST");
> + goto err;
> + }
> + len = ifgr.ifgr_len;
> +
> + if (len / sizeof(*ifgr.ifgr_groups) <= idx-1)
> + goto err;
> +
> + if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) {
> + log_warn("alloc");
> + return (NULL);
> + }
> + if (ioctl(s, SIOCGIFGLIST, (caddr_t)&ifgr) == -1) {
> + log_warn("SIOCGIFGLIST");
> + free(ifgr.ifgr_groups);
> + goto err;
> + }
> + close(s);
> +
> + if ((ifg = calloc(1, sizeof *ifg)) == NULL) {
> + log_warn("alloc");
> + goto err;
> + }
> +
> + memcpy(ifg, &ifgr.ifgr_groups[idx-1], sizeof *ifg);
> + free(ifgr.ifgr_groups);
> + return ifg;
> + err:
> + free(ifgr.ifgr_groups);
> + close(s);
> + return (NULL);
> +}
> +
> +int
> +mib_carpgrouptable(struct oid *oid, struct ber_oid *o, struct ber_element
> **elm)
> +{
> + struct ifgroupreq ifgr;
> + struct ifg_req *ifg;
> + uint32_t idx;
> + int s;
> +
> + /* Get and verify the current row index */
> + idx = o->bo_id[OIDIDX_carpGroupIndex];
> +
> + if ((ifg = mib_carpgroupget(idx)) == NULL)
> + return (1);
> +
> + /* Tables need to prepend the OID on their own */
> + o->bo_id[OIDIDX_carpGroupIndex] = idx;
> + *elm = ber_add_oid(*elm, o);
> +
> + switch (o->bo_id[OIDIDX_carpGroupEntry]) {
> + case 2:
> + *elm = ber_add_string(*elm, ifg->ifgrq_group);
> + break;
> + case 3:
> + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
> + log_warn("socket");
> + free(ifg);
> + return (1);
> + }
> +
> + bzero(&ifgr, sizeof(ifgr));
> + strlcpy(ifgr.ifgr_name, ifg->ifgrq_group,
> sizeof(ifgr.ifgr_name));
> + if (ioctl(s, SIOCGIFGATTR, (caddr_t)&ifgr) == -1) {
> + log_warn("SIOCGIFGATTR");
> + close(s);
> + free(ifg);
> + return (1);
> + }
> +
> + close(s);
> + *elm = ber_add_integer(*elm, ifgr.ifgr_attrib.ifg_carp_demoted);
> + break;
> + default:
> + free(ifg);
> + return (1);
> + }
> +
> + free(ifg);
> return (0);
> }
>
> Index: usr.sbin/snmpd/mib.h
> ===================================================================
> RCS file: /cvs//src/usr.sbin/snmpd/mib.h,v
> retrieving revision 1.38
> diff -u -p -r1.38 mib.h
> --- usr.sbin/snmpd/mib.h 7 Mar 2016 19:33:26 -0000 1.38
> +++ usr.sbin/snmpd/mib.h 14 May 2018 18:51:01 -0000
> @@ -722,6 +722,12 @@
> #define MIB_carpIp6PktsSent MIB_carpStats, 13
> #define MIB_carpNoMemory MIB_carpStats, 14
> #define MIB_carpTransitionsToMaster MIB_carpStats, 15
> +#define MIB_carpGroupTable MIB_carpMIBObjects, 4
> +#define MIB_carpGroupEntry MIB_carpGroupTable, 1
> +#define OIDIDX_carpGroupEntry 10
> +#define OIDIDX_carpGroupIndex 11
> +#define MIB_carpGroupName MIB_carpGroupEntry, 2
> +#define MIB_carpGroupDemote MIB_carpGroupEntry, 3
> #define MIB_localSystem MIB_openBSD, 23
> #define MIB_SYSOID_DEFAULT MIB_openBSD, 23, 1
> #define MIB_localTest MIB_openBSD, 42
> @@ -1272,6 +1278,10 @@
> { MIBDECL(carpIp6PktsSent) }, \
> { MIBDECL(carpNoMemory) }, \
> { MIBDECL(carpTransitionsToMaster) }, \
> + { MIBDECL(carpGroupTable) }, \
> + { MIBDECL(carpGroupEntry) }, \
> + { MIBDECL(carpGroupName) }, \
> + { MIBDECL(carpGroupDemote) }, \
> { MIBDECL(localSystem) }, \
> { MIBDECL(localTest) }, \
> \