svn commit: r362824 - in head: lib/libifconfig sbin/ifconfig sys/net

Ryan Moeller freqlabs at FreeBSD.org
Wed Jul 1 02:32:43 UTC 2020


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 <freqlabs at 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 {			\


More information about the svn-src-all mailing list