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) },                         \
                                                        \

Attachment: signature.asc
Description: PGP signature

Reply via email to