FreeBSD 15.0+ and newer support VLAN filtering for bridges. It is controlled by the IFBRF_VLANFILTER flag. Implement virNetDevBridgeGetVlanFiltering() and virNetDevBridgeSetVlanFiltering() for systems that have this flag defined. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/util/virnetdevbridge.c | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c index 20c7a25585..c8da3f11ee 100644 --- a/src/util/virnetdevbridge.c +++ b/src/util/virnetdevbridge.c @@ -53,7 +53,8 @@ VIR_LOG_INIT("util.netdevbridge"); static int virNetDevBridgeCmd(const char *brname, u_long op, void *arg, - size_t argsize) + size_t argsize, + bool set) { struct ifdrv ifd = { 0 }; VIR_AUTOCLOSE s = -1; @@ -75,7 +76,7 @@ static int virNetDevBridgeCmd(const char *brname, ifd.ifd_len = argsize; ifd.ifd_data = arg; - return ioctl(s, SIOCSDRVSPEC, &ifd); + return ioctl(s, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd); } #endif @@ -693,7 +694,7 @@ int virNetDevBridgeAddPort(const char *brname, return -1; } - if (virNetDevBridgeCmd(brname, BRDGADD, &req, sizeof(req)) < 0) { + if (virNetDevBridgeCmd(brname, BRDGADD, &req, sizeof(req), true) < 0) { virReportSystemError(errno, _("Unable to add bridge %1$s port %2$s"), brname, ifname); return -1; @@ -759,7 +760,7 @@ int virNetDevBridgeRemovePort(const char *brname, return -1; } - if (virNetDevBridgeCmd(brname, BRDGDEL, &req, sizeof(req)) < 0) { + if (virNetDevBridgeCmd(brname, BRDGDEL, &req, sizeof(req), true) < 0) { virReportSystemError(errno, _("Unable to remove bridge %1$s port %2$s"), brname, ifname); return -1; @@ -883,7 +884,7 @@ int virNetDevBridgeSetSTPDelay(const char *brname, delay_seconds = delay_seconds < 4 ? 4 : delay_seconds; param.ifbrp_fwddelay = delay_seconds & 0xff; - if (virNetDevBridgeCmd(brname, BRDGSFD, ¶m, sizeof(param)) < 0) { + if (virNetDevBridgeCmd(brname, BRDGSFD, ¶m, sizeof(param), true) < 0) { virReportSystemError(errno, _("Unable to set STP delay on %1$s"), brname); return -1; @@ -996,6 +997,51 @@ virNetDevBridgeSetVlanFiltering(const char *brname, } +#elif defined(WITH_BSD_BRIDGE_MGMT) && defined(IFBRF_VLANFILTER) +int +virNetDevBridgeGetVlanFiltering(const char *brname, + bool *enable) +{ + struct ifbrparam req; + + if (virNetDevBridgeCmd(brname, BRDGGFLAGS, &req, sizeof(req), false) < 0) { + virReportSystemError(errno, + _("Unable to get bridge %1$s flags"), brname); + return -1; + } + + *enable = !!(req.ifbrp_flags & IFBRF_VLANFILTER); + return 0; +} + + +int +virNetDevBridgeSetVlanFiltering(const char *brname, + bool enable) +{ + struct ifbrparam req; + + if (virNetDevBridgeCmd(brname, BRDGGFLAGS, &req, sizeof(req), false) < 0) { + virReportSystemError(errno, + _("Unable to get bridge %1$s flag"), brname); + return -1; + } + + if (enable) + req.ifbrp_flags |= IFBRF_VLANFILTER; + else + req.ifbrp_flags &= ~IFBRF_VLANFILTER; + + if (virNetDevBridgeCmd(brname, BRDGSFLAGS, &req, sizeof(req), true) < 0) { + virReportSystemError(errno, + _("Unable to set bridge %1$s flag"), brname); + return -1; + } + + return 0; +} + + #else int virNetDevBridgeGetVlanFiltering(const char *brname G_GNUC_UNUSED, -- 2.55.0