Hi, 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. Bye, 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 14:53:02 -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,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 } @@ -51,6 +51,7 @@ carpMIBObjects MODULE-IDENTITY carpSysctl OBJECT IDENTIFIER ::= { carpMIBObjects 1 } carpIf OBJECT IDENTIFIER ::= { carpMIBObjects 2 } carpStats OBJECT IDENTIFIER ::= { carpMIBObjects 3 } +carpGroupTable OBJECT IDENTIFIER ::= { carpMIBObjects 4 } -- carpSysctl @@ -174,6 +175,49 @@ 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 { + carpGroupName OCTET STRING, + carpGroupDemote Integer32 + } + +carpGroupName OBJECT-TYPE + SYNTAX OCTET STRING + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the interface group." + ::= { carpIfEntry 1 } + +carpGroupDemote OBJECT-TYPE + SYNTAX Integer32 (1..2147483647) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The demote value of the interface group." + ::= { carpIfEntry 2 } -- carpStats Index: sys/net/if.c =================================================================== RCS file: /cvs//src/sys/net/if.c,v retrieving revision 1.551 diff -u -p -r1.551 if.c --- sys/net/if.c 28 Apr 2018 15:44:59 -0000 1.551 +++ sys/net/if.c 9 May 2018 08:16:33 -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 *); @@ -1838,6 +1839,7 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCIFGCLONERS: case SIOCGIFGMEMB: case SIOCGIFGATTR: + case SIOCGIFGLIST: case SIOCGIFFLAGS: case SIOCGIFXFLAGS: case SIOCGIFMETRIC: @@ -2178,6 +2180,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); @@ -2609,6 +2616,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 15:18:07 -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 1: + *elm = ber_add_string(*elm, ifg->ifgrq_group); + break; + case 2: + 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 13:30:28 -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, 1 +#define MIB_carpGroupDemote MIB_carpGroupEntry, 2 #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) }, \ \
signature.asc
Description: PGP signature