diff options
| author | Lexi Winter <ivy@FreeBSD.org> | 2025-05-28 07:57:33 +0000 |
|---|---|---|
| committer | Lexi Winter <ivy@FreeBSD.org> | 2025-07-05 07:04:31 +0000 |
| commit | 032d32c2c276983ce680ffaa6e7d6c12a9584fab (patch) | |
| tree | 935f2bd3a3539fd500288da26737a0fbb5229139 /lib/libifconfig | |
| parent | 877a7a325b9824995e920d070a0bfb0c6a1cc7e2 (diff) | |
Diffstat (limited to 'lib/libifconfig')
| -rw-r--r-- | lib/libifconfig/libifconfig.h | 2 | ||||
| -rw-r--r-- | lib/libifconfig/libifconfig_bridge.c | 54 |
2 files changed, 40 insertions, 16 deletions
diff --git a/lib/libifconfig/libifconfig.h b/lib/libifconfig/libifconfig.h index 8d5ca01b0ce6..fc835485a51e 100644 --- a/lib/libifconfig/libifconfig.h +++ b/lib/libifconfig/libifconfig.h @@ -29,6 +29,7 @@ #include <sys/types.h> #include <net/if.h> +#include <net/if_bridgevar.h> /* for ifbvlan_set_t */ #include <netinet/in.h> #include <netinet/ip_carp.h> @@ -64,6 +65,7 @@ struct lagg_reqport; struct ifconfig_bridge_status { struct ifbropreq *params; /**< current operational parameters */ struct ifbreq *members; /**< list of bridge members */ + ifbvlan_set_t *member_vlans; /**< bridge member vlan sets */ size_t members_count; /**< how many member interfaces */ uint32_t cache_size; /**< size of address cache */ uint32_t cache_lifetime; /**< address cache entry lifetime */ diff --git a/lib/libifconfig/libifconfig_bridge.c b/lib/libifconfig/libifconfig_bridge.c index 2a9bbc35858b..b4a920f488c5 100644 --- a/lib/libifconfig/libifconfig_bridge.c +++ b/lib/libifconfig/libifconfig_bridge.c @@ -66,40 +66,37 @@ ifconfig_bridge_get_bridge_status(ifconfig_handle_t *h, { struct ifbifconf members; struct ifbrparam cache_param; - struct _ifconfig_bridge_status *bridge; - char *buf; + struct _ifconfig_bridge_status *bridge = NULL; + char *buf = NULL; + members.ifbic_buf = NULL; *bridgep = NULL; bridge = calloc(1, sizeof(struct _ifconfig_bridge_status)); if (bridge == NULL) { h->error.errtype = OTHER; h->error.errcode = ENOMEM; - return (-1); + goto err; } bridge->inner.params = &bridge->params; if (ifconfig_bridge_ioctlwrap(h, name, BRDGGCACHE, &cache_param, sizeof(cache_param), false) != 0) { - free(bridge); - return (-1); + goto err; } 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); + goto err; } 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); + goto err; } - members.ifbic_buf = NULL; for (size_t len = 8192; (buf = realloc(members.ifbic_buf, len)) != NULL; len *= 2) { @@ -107,27 +104,52 @@ ifconfig_bridge_get_bridge_status(ifconfig_handle_t *h, members.ifbic_len = len; if (ifconfig_bridge_ioctlwrap(h, name, BRDGGIFS, &members, sizeof(members), false) != 0) { - free(buf); - free(bridge); - return (-1); + goto err; } if ((members.ifbic_len + sizeof(*members.ifbic_req)) < len) break; } if (buf == NULL) { - free(members.ifbic_buf); - free(bridge); h->error.errtype = OTHER; h->error.errcode = ENOMEM; - return (-1); + goto err; } bridge->inner.members = members.ifbic_req; bridge->inner.members_count = members.ifbic_len / sizeof(*members.ifbic_req); + bridge->inner.member_vlans = calloc(bridge->inner.members_count, + sizeof(ifbvlan_set_t)); + if (bridge->inner.member_vlans == NULL) { + h->error.errtype = OTHER; + h->error.errcode = ENOMEM; + goto err; + } + for (size_t i = 0; i < bridge->inner.members_count; ++i) { + struct ifbif_vlan_req vreq; + memset(&vreq, 0, sizeof(vreq)); + strlcpy(vreq.bv_ifname, bridge->inner.members[i].ifbr_ifsname, + sizeof(vreq.bv_ifname)); + + if (ifconfig_bridge_ioctlwrap(h, name, BRDGGIFVLANSET, &vreq, + sizeof(vreq), false) != 0) { + goto err; + } + + __BIT_COPY(BRVLAN_SETSIZE, &vreq.bv_set, + &bridge->inner.member_vlans[i]); + } + *bridgep = &bridge->inner; return (0); + +err: + free(members.ifbic_buf); + if (bridge) + free(bridge->inner.member_vlans); + free(bridge); + return (-1); } void |
