From owner-svn-src-head@freebsd.org Wed Jul 1 02:32:42 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id E637435B45F; Wed, 1 Jul 2020 02:32:42 +0000 (UTC) (envelope-from freqlabs@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49xQHZ5rQTz4FYs; Wed, 1 Jul 2020 02:32:42 +0000 (UTC) (envelope-from freqlabs@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id AC9172230C; Wed, 1 Jul 2020 02:32:42 +0000 (UTC) (envelope-from freqlabs@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0612Wg6L012325; Wed, 1 Jul 2020 02:32:42 GMT (envelope-from freqlabs@FreeBSD.org) Received: (from freqlabs@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0612WfAp012320; Wed, 1 Jul 2020 02:32:41 GMT (envelope-from freqlabs@FreeBSD.org) Message-Id: <202007010232.0612WfAp012320@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: freqlabs set sender to freqlabs@FreeBSD.org using -f From: Ryan Moeller Date: Wed, 1 Jul 2020 02:32:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362824 - in head: lib/libifconfig sbin/ifconfig sys/net X-SVN-Group: head X-SVN-Commit-Author: freqlabs X-SVN-Commit-Paths: in head: lib/libifconfig sbin/ifconfig sys/net X-SVN-Commit-Revision: 362824 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Jul 2020 02:32:43 -0000 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 + * + * 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 +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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 { \