Author: freqlabs
Date: Wed Jul  1 02:32:41 2020
New Revision: 362824
URL: https://svnweb.freebsd.org/changeset/base/362824

Log:
  libifconfig: Add function to get bridge status
  
  The new function operates similarly to ifconfig_lagg_get_lagg_status and
  likewise is accompanied by a function to free the bridge status data 
structure.
  
  I have included in this patch the relocation of some strings describing STP
  parameters and the PV2ID macro from ifconfig into net/if_bridgevar.h as they
  are useful for consumers of libifconfig.
  
  Reviewed by:  kp, melifaro, mmacy
  Approved by:  mmacy (mentor)
  MFC after:    1 week
  Relnotes:     yes
  Differential Revision:        https://reviews.freebsd.org/D25460

Added:
  head/lib/libifconfig/libifconfig_bridge.c   (contents, props changed)
Modified:
  head/lib/libifconfig/Makefile
  head/lib/libifconfig/libifconfig.h
  head/sbin/ifconfig/ifbridge.c
  head/sys/net/if_bridgevar.h

Modified: head/lib/libifconfig/Makefile
==============================================================================
--- head/lib/libifconfig/Makefile       Wed Jul  1 02:16:36 2020        
(r362823)
+++ head/lib/libifconfig/Makefile       Wed Jul  1 02:32:41 2020        
(r362824)
@@ -6,9 +6,14 @@ INTERNALLIB=   true
 
 SHLIBDIR?=     /lib
 SHLIB_MAJOR=   1
-SRCS=          libifconfig.c libifconfig_carp.c libifconfig_inet.c
-SRCS+=         libifconfig_inet6.c libifconfig_internal.c libifconfig_lagg.c
-SRCS+=         libifconfig_media.c
+SRCS=          libifconfig.c \
+               libifconfig_bridge.c \
+               libifconfig_carp.c \
+               libifconfig_inet.c \
+               libifconfig_inet6.c \
+               libifconfig_internal.c \
+               libifconfig_lagg.c \
+               libifconfig_media.c
 
 # If libifconfig become public uncomment those two lines
 #INCSDIR=      ${INCLUDEDIR}

Modified: head/lib/libifconfig/libifconfig.h
==============================================================================
--- head/lib/libifconfig/libifconfig.h  Wed Jul  1 02:16:36 2020        
(r362823)
+++ head/lib/libifconfig/libifconfig.h  Wed Jul  1 02:32:41 2020        
(r362824)
@@ -49,12 +49,23 @@ typedef struct ifconfig_handle ifconfig_handle_t;
 
 struct carpreq;
 struct ifaddrs;
+struct ifbropreq;
+struct ifbreq;
 struct in6_ndireq;
 struct lagg_reqall;
 struct lagg_reqflags;
 struct lagg_reqopts;
 struct lagg_reqport;
 
+/** Stores extra info associated with a bridge(4) interface */
+struct ifconfig_bridge_status {
+       struct ifbropreq *params;       /**< current operational parameters */
+       struct ifbreq *members;         /**< list of bridge members */
+       size_t members_count;           /**< how many member interfaces */
+       uint32_t cache_size;            /**< size of address cache */
+       uint32_t cache_lifetime;        /**< address cache entry lifetime */
+};
+
 struct ifconfig_capabilities {
        /** Current capabilities (ifconfig prints this as 'options')*/
        int curcap;
@@ -217,6 +228,16 @@ int ifconfig_inet_get_addrinfo(ifconfig_handle_t *h,
 int ifconfig_inet6_get_addrinfo(ifconfig_handle_t *h,
     const char *name, struct ifaddrs *ifa, struct ifconfig_inet6_addr *addr);
 
+/** Retrieve additional information about a bridge(4) interface */
+int ifconfig_bridge_get_bridge_status(ifconfig_handle_t *h,
+    const char *name, struct ifconfig_bridge_status **bridge);
+
+/** Frees the structure returned by ifconfig_bridge_get_bridge_status.  Does
+ * nothing if the argument is NULL
+ * @param bridge       Pointer to the structure to free
+ */
+void ifconfig_bridge_free_bridge_status(struct ifconfig_bridge_status *bridge);
+
 /** Retrieve additional information about a lagg(4) interface */
 int ifconfig_lagg_get_lagg_status(ifconfig_handle_t *h,
     const char *name, struct ifconfig_lagg_status **lagg_status);
@@ -225,8 +246,8 @@ int ifconfig_lagg_get_lagg_status(ifconfig_handle_t *h
 int ifconfig_lagg_get_laggport_status(ifconfig_handle_t *h,
     const char *name, struct lagg_reqport *rp);
 
-/** Frees the structure returned by ifconfig_lagg_get_status.  Does nothing if
- * the argument is NULL
+/** Frees the structure returned by ifconfig_lagg_get_lagg_status.  Does
+ * nothing if the argument is NULL
  * @param laggstat     Pointer to the structure to free
  */
 void ifconfig_lagg_free_lagg_status(struct ifconfig_lagg_status *laggstat);

Added: head/lib/libifconfig/libifconfig_bridge.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/lib/libifconfig/libifconfig_bridge.c   Wed Jul  1 02:32:41 2020        
(r362824)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2020, Ryan Moeller <freql...@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/ioctl.h>
+
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_bridgevar.h>
+#include <net/route.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libifconfig.h"
+#include "libifconfig_internal.h"
+
+/* Internal structure used for allocations and frees */
+struct _ifconfig_bridge_status {
+       struct ifconfig_bridge_status inner;    /* wrapped bridge status */
+       struct ifbropreq params;                /* operational parameters */
+};
+
+static int
+ifconfig_bridge_ioctlwrap(ifconfig_handle_t *h, const char *name,
+    unsigned long cmd, void *arg, size_t arglen, bool set)
+{
+       struct ifdrv ifd = { 0 };
+       unsigned long req = set ? SIOCSDRVSPEC : SIOCGDRVSPEC;
+
+       strlcpy(ifd.ifd_name, name, sizeof(ifd.ifd_name));
+       ifd.ifd_cmd = cmd;
+       ifd.ifd_data = arg;
+       ifd.ifd_len = arglen;
+
+       return (ifconfig_ioctlwrap(h, AF_LOCAL, req, &ifd));
+}
+
+int
+ifconfig_bridge_get_bridge_status(ifconfig_handle_t *h,
+    const char *name, struct ifconfig_bridge_status **bridgep)
+{
+       struct ifbifconf members;
+       struct ifbrparam cache_param;
+       struct _ifconfig_bridge_status *bridge;
+       char *buf;
+
+       *bridgep = NULL;
+
+       bridge = calloc(1, sizeof(struct _ifconfig_bridge_status));
+       if (bridge == NULL) {
+               h->error.errtype = OTHER;
+               h->error.errcode = ENOMEM;
+               return (-1);
+       }
+       bridge->inner.params = &bridge->params;
+
+       if (ifconfig_bridge_ioctlwrap(h, name, BRDGGCACHE,
+           &cache_param, sizeof(cache_param), false) != 0) {
+               free(bridge);
+               return (-1);
+       }
+       bridge->inner.cache_size = cache_param.ifbrp_csize;
+
+       if (ifconfig_bridge_ioctlwrap(h, name, BRDGGTO,
+           &cache_param, sizeof(cache_param), false) != 0) {
+               free(bridge);
+               return (-1);
+       }
+       bridge->inner.cache_lifetime = cache_param.ifbrp_ctime;
+
+       if (ifconfig_bridge_ioctlwrap(h, name, BRDGPARAM,
+           &bridge->params, sizeof(bridge->params), false) != 0) {
+               free(bridge);
+               return (-1);
+       }
+
+       members.ifbic_buf = NULL;
+       for (size_t len = 8192;
+           (buf = realloc(members.ifbic_buf, len)) != NULL;
+           len *= 2) {
+               members.ifbic_buf = buf;
+               members.ifbic_len = len;
+               if (ifconfig_bridge_ioctlwrap(h, name, BRDGGIFS,
+                   &members, sizeof(members), false) != 0) {
+                       free(buf);
+                       free(bridge);
+                       return (-1);
+               }
+               if (members.ifbic_len <= len)
+                       break;
+       }
+       if (buf == NULL) {
+               free(members.ifbic_buf);
+               free(bridge);
+               h->error.errtype = OTHER;
+               h->error.errcode = ENOMEM;
+               return (-1);
+       }
+       bridge->inner.members = members.ifbic_req;
+       bridge->inner.members_count =
+           members.ifbic_len / sizeof(*members.ifbic_req);
+
+       *bridgep = &bridge->inner;
+
+       return (0);
+}
+
+void
+ifconfig_bridge_free_bridge_status(struct ifconfig_bridge_status *bridge)
+{
+       if (bridge != NULL) {
+               free(bridge->members);
+               free(bridge);
+       }
+}

Modified: head/sbin/ifconfig/ifbridge.c
==============================================================================
--- head/sbin/ifconfig/ifbridge.c       Wed Jul  1 02:16:36 2020        
(r362823)
+++ head/sbin/ifconfig/ifbridge.c       Wed Jul  1 02:32:41 2020        
(r362824)
@@ -63,36 +63,9 @@ static const char rcsid[] =
 
 #include "ifconfig.h"
 
-#define PV2ID(pv, epri, eaddr)  do {           \
-               epri     = pv >> 48;            \
-               eaddr[0] = pv >> 40;            \
-               eaddr[1] = pv >> 32;            \
-               eaddr[2] = pv >> 24;            \
-               eaddr[3] = pv >> 16;            \
-               eaddr[4] = pv >> 8;             \
-               eaddr[5] = pv >> 0;             \
-} while (0)
-
-static const char *stpstates[] = {
-       "disabled",
-       "listening",
-       "learning",
-       "forwarding",
-       "blocking",
-       "discarding"
-};
-static const char *stpproto[] = {
-       "stp",
-       "-",
-       "rstp"
-};
-static const char *stproles[] = {
-       "disabled",
-       "root",
-       "designated",
-       "alternate",
-       "backup"
-};
+static const char *stpstates[] = { STP_STATES };
+static const char *stpproto[] = { STP_PROTOS };
+static const char *stproles[] = { STP_ROLES };
 
 static int
 get_val(const char *cp, u_long *valp)

Modified: head/sys/net/if_bridgevar.h
==============================================================================
--- head/sys/net/if_bridgevar.h Wed Jul  1 02:16:36 2020        (r362823)
+++ head/sys/net/if_bridgevar.h Wed Jul  1 02:32:41 2020        (r362824)
@@ -269,6 +269,36 @@ struct ifbpstpconf {
 #define        ifbpstp_req     ifbpstp_ifbpstpu.ifbpstpu_req
 };
 
+#define STP_STATES \
+    "disabled",    \
+    "listening",   \
+    "learning",    \
+    "forwarding",  \
+    "blocking",    \
+    "discarding"
+
+#define STP_PROTOS \
+    "stp"          \
+    "-"            \
+    "rstp"
+
+#define STP_ROLES \
+    "disabled"    \
+    "root"        \
+    "designated"  \
+    "alternate"   \
+    "backup"
+
+#define PV2ID(pv, epri, eaddr) do { \
+       epri     = pv >> 48;         \
+       eaddr[0] = pv >> 40;         \
+       eaddr[1] = pv >> 32;         \
+       eaddr[2] = pv >> 24;         \
+       eaddr[3] = pv >> 16;         \
+       eaddr[4] = pv >> 8;          \
+       eaddr[5] = pv >> 0;          \
+} while (0)
+
 #ifdef _KERNEL
 
 #define BRIDGE_INPUT(_ifp, _m)         do {                    \
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to