src/util/virnetdevbridge.c | 122 ++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 61 deletions(-)
virNetDevBridgeSetupVlans() calls virNetlinkBridgeVlanFilterSet(),
which requires libnl. Use the function only when libnl is available
to avoid breaking builds.
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
src/util/virnetdevbridge.c | 122 ++++++++++++++++++++++-----------------------
1 file changed, 61 insertions(+), 61 deletions(-)
diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c
index c79d0c79b7b16a0a070b5013ed7df9d0a63b1c38..70e82a0029634ddf44c2b933577bf783c89f035c 100644
--- a/src/util/virnetdevbridge.c
+++ b/src/util/virnetdevbridge.c
@@ -313,66 +313,6 @@ virNetDevBridgePortSetIsolated(const char *brname,
return virNetDevBridgePortSet(brname, ifname, "isolated", enable ? 1 : 0);
}
-static int
-virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan *virtVlan)
-{
- int error = 0;
- unsigned short flags;
-
- if (!virtVlan || !virtVlan->nTags)
- return 0;
-
- // The interface will have been automatically added to vlan 1, so remove it
- if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, &error) < 0) {
- if (error != 0) {
- virReportSystemError(-error,
- _("error removing vlan filter from interface %1$s"),
- ifname);
- }
- return -1;
- }
-
- // If trunk mode, add the native VLAN then add the others, if any
- if (virtVlan->trunk) {
- size_t i;
-
- if (virtVlan->nativeTag) {
- flags = BRIDGE_VLAN_INFO_PVID;
- if (virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_UNTAGGED ||
- virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) {
- flags |= BRIDGE_VLAN_INFO_UNTAGGED;
- }
-
- if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags,
- virtVlan->nativeTag, &error) < 0) {
- goto error;
- }
- }
-
- for (i = 0; i < virtVlan->nTags; i++) {
- if (virtVlan->tag[i] != virtVlan->nativeTag)
- if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, 0,
- virtVlan->tag[i], &error) < 0) {
- goto error;
- }
- }
- } else {
- // In native mode, add the single VLAN as pvid untagged
- flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED;
- if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags,
- virtVlan->tag[0], &error) < 0) {
- goto error;
- }
- }
-
- return 0;
-
- error:
- if (error != 0)
- virReportSystemError(-error, _("error adding vlan filter to interface %1$s"), ifname);
- return -1;
-}
-
#else
int
@@ -651,7 +591,67 @@ int virNetDevBridgeDelete(const char *brname G_GNUC_UNUSED)
*
* Returns 0 in case of success or an errno code in case of failure.
*/
-#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF)
+#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) && defined(WITH_LIBNL)
+static int
+virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan *virtVlan)
+{
+ int error = 0;
+ unsigned short flags;
+
+ if (!virtVlan || !virtVlan->nTags)
+ return 0;
+
+ // The interface will have been automatically added to vlan 1, so remove it
+ if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, &error) < 0) {
+ if (error != 0) {
+ virReportSystemError(-error,
+ _("error removing vlan filter from interface %1$s"),
+ ifname);
+ }
+ return -1;
+ }
+
+ // If trunk mode, add the native VLAN then add the others, if any
+ if (virtVlan->trunk) {
+ size_t i;
+
+ if (virtVlan->nativeTag) {
+ flags = BRIDGE_VLAN_INFO_PVID;
+ if (virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_UNTAGGED ||
+ virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) {
+ flags |= BRIDGE_VLAN_INFO_UNTAGGED;
+ }
+
+ if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags,
+ virtVlan->nativeTag, &error) < 0) {
+ goto error;
+ }
+ }
+
+ for (i = 0; i < virtVlan->nTags; i++) {
+ if (virtVlan->tag[i] != virtVlan->nativeTag)
+ if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, 0,
+ virtVlan->tag[i], &error) < 0) {
+ goto error;
+ }
+ }
+ } else {
+ // In native mode, add the single VLAN as pvid untagged
+ flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED;
+ if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags,
+ virtVlan->tag[0], &error) < 0) {
+ goto error;
+ }
+ }
+
+ return 0;
+
+ error:
+ if (error != 0)
+ virReportSystemError(-error, _("error adding vlan filter to interface %1$s"), ifname);
+ return -1;
+}
+
int virNetDevBridgeAddPort(const char *brname,
const char *ifname,
const virNetDevVlan *virtVlan)
---
base-commit: e5299ddf86121d3c792ca271ffcb54900eb19dc3
change-id: 20250304-nl-605e05b8c5f2
Best regards,
--
Akihiko Odaki <akihiko.odaki@daynix.com>
On 3/7/25 6:48 AM, Akihiko Odaki wrote: > virNetDevBridgeSetupVlans() calls virNetlinkBridgeVlanFilterSet(), > which requires libnl. Use the function only when libnl is available > to avoid breaking builds. > > Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> I'm curious what is the Linux platform where we don't have libnl available? Also, in this case you've removed the ability to add ports to a bridge, even if the request has no vlan info. If there really are Linux distros that don't have libnl then we don't want to completely disable the ability to add a tap to a bridge - instead we should move the check for vlan == NULL from the top of virNetDevBridgeSetupVlans() to the place where virNetDevBridgeSetupVlans() is called (in virNetDevBridgeAddPort()). Then virNetDeBridgeSetupVlans should be placed inside an #if defined(WITH_LIBNL) that has an #else alternative implementation just reporting that vlans can't be set on host bridge ports on this platform - this entire set of 2 virNetDevBridgeeSetupVlan() functions should be defined immediately preceding the definition of virNetDebBridgeAddPort(), inside the same #if as that function. So in short, you should have: #if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) # if defined(WITH_LIBNL) static int virNetDevBridgeSetupVlans() { /* existing virNetDevBridgeSetupVlans() body except NULL check */ } # else static int virNetDevBridgeSetupVlans() { virReportSystemError(ENOSYS, "%s", _("Cannot configure vlans on host bridge ports on this platform")); /* *un*break previous two lines!! */ return -1;} } # fi int virNetDevBridgeAddPort(...) { /* existing body of this function, except at the end do this: */ if (virtVlan && virtVlan->nTags) return virNetDevBridgeSetupVlans(ifname, virtVlan); else return 0; } #elif defined(WITH_BSD_BRIDGE_MGMT) ... This way you'll stil have the ability to add ports to a bridge when libnl isn't available, but will get a runtime error if someone tries to configure vlan stuff for a port. > --- > src/util/virnetdevbridge.c | 122 ++++++++++++++++++++++----------------------- > 1 file changed, 61 insertions(+), 61 deletions(-) > > diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c > index c79d0c79b7b16a0a070b5013ed7df9d0a63b1c38..70e82a0029634ddf44c2b933577bf783c89f035c 100644 > --- a/src/util/virnetdevbridge.c > +++ b/src/util/virnetdevbridge.c > @@ -313,66 +313,6 @@ virNetDevBridgePortSetIsolated(const char *brname, > return virNetDevBridgePortSet(brname, ifname, "isolated", enable ? 1 : 0); > } > > -static int > -virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan *virtVlan) > -{ > - int error = 0; > - unsigned short flags; > - > - if (!virtVlan || !virtVlan->nTags) > - return 0; > - > - // The interface will have been automatically added to vlan 1, so remove it > - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, &error) < 0) { > - if (error != 0) { > - virReportSystemError(-error, > - _("error removing vlan filter from interface %1$s"), > - ifname); > - } > - return -1; > - } > - > - // If trunk mode, add the native VLAN then add the others, if any > - if (virtVlan->trunk) { > - size_t i; > - > - if (virtVlan->nativeTag) { > - flags = BRIDGE_VLAN_INFO_PVID; > - if (virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_UNTAGGED || > - virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) { > - flags |= BRIDGE_VLAN_INFO_UNTAGGED; > - } > - > - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, > - virtVlan->nativeTag, &error) < 0) { > - goto error; > - } > - } > - > - for (i = 0; i < virtVlan->nTags; i++) { > - if (virtVlan->tag[i] != virtVlan->nativeTag) > - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, 0, > - virtVlan->tag[i], &error) < 0) { > - goto error; > - } > - } > - } else { > - // In native mode, add the single VLAN as pvid untagged > - flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; > - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, > - virtVlan->tag[0], &error) < 0) { > - goto error; > - } > - } > - > - return 0; > - > - error: > - if (error != 0) > - virReportSystemError(-error, _("error adding vlan filter to interface %1$s"), ifname); > - return -1; > -} > - > > #else > int > @@ -651,7 +591,67 @@ int virNetDevBridgeDelete(const char *brname G_GNUC_UNUSED) > * > * Returns 0 in case of success or an errno code in case of failure. > */ > -#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) > +#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) && defined(WITH_LIBNL) > +static int > +virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan *virtVlan) > +{ > + int error = 0; > + unsigned short flags; > + > + if (!virtVlan || !virtVlan->nTags) > + return 0; > + > + // The interface will have been automatically added to vlan 1, so remove it > + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, &error) < 0) { > + if (error != 0) { > + virReportSystemError(-error, > + _("error removing vlan filter from interface %1$s"), > + ifname); > + } > + return -1; > + } > + > + // If trunk mode, add the native VLAN then add the others, if any > + if (virtVlan->trunk) { > + size_t i; > + > + if (virtVlan->nativeTag) { > + flags = BRIDGE_VLAN_INFO_PVID; > + if (virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_UNTAGGED || > + virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) { > + flags |= BRIDGE_VLAN_INFO_UNTAGGED; > + } > + > + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, > + virtVlan->nativeTag, &error) < 0) { > + goto error; > + } > + } > + > + for (i = 0; i < virtVlan->nTags; i++) { > + if (virtVlan->tag[i] != virtVlan->nativeTag) > + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, 0, > + virtVlan->tag[i], &error) < 0) { > + goto error; > + } > + } > + } else { > + // In native mode, add the single VLAN as pvid untagged > + flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; > + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, > + virtVlan->tag[0], &error) < 0) { > + goto error; > + } > + } > + > + return 0; > + > + error: > + if (error != 0) > + virReportSystemError(-error, _("error adding vlan filter to interface %1$s"), ifname); > + return -1; > +} > + > int virNetDevBridgeAddPort(const char *brname, > const char *ifname, > const virNetDevVlan *virtVlan) > > --- > base-commit: e5299ddf86121d3c792ca271ffcb54900eb19dc3 > change-id: 20250304-nl-605e05b8c5f2 > > Best regards,
On 2025/03/07 22:11, Laine Stump wrote: > On 3/7/25 6:48 AM, Akihiko Odaki wrote: >> virNetDevBridgeSetupVlans() calls virNetlinkBridgeVlanFilterSet(), >> which requires libnl. Use the function only when libnl is available >> to avoid breaking builds. >> >> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> > > I'm curious what is the Linux platform where we don't have libnl available? I didn't have libnl3-devel installed. Another option is to require libnl3-devel in Mesa; it will give nicer error messages to anyone trying to build libvirt without libnl and allows us to drop WITH_LIBNL checks. > > Also, in this case you've removed the ability to add ports to a bridge, > even if the request has no vlan info. If there really are Linux distros > that don't have libnl then we don't want to completely disable the > ability to add a tap to a bridge - instead we should move the check for > vlan == NULL from the top of virNetDevBridgeSetupVlans() to the place > where virNetDevBridgeSetupVlans() is called (in > virNetDevBridgeAddPort()). Then virNetDeBridgeSetupVlans should be > placed inside an #if defined(WITH_LIBNL) that has an #else alternative > implementation just reporting that vlans can't be set on host bridge > ports on this platform - this entire set of 2 > virNetDevBridgeeSetupVlan() functions should be defined immediately > preceding the definition of virNetDebBridgeAddPort(), inside the same > #if as that function. > > So in short, you should have: > > #if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) > # if defined(WITH_LIBNL) > static int > virNetDevBridgeSetupVlans() > { > /* existing virNetDevBridgeSetupVlans() body except NULL check */ > } > # else > static int > virNetDevBridgeSetupVlans() > { > virReportSystemError(ENOSYS, "%s", > _("Cannot configure vlans on host bridge ports > on this platform")); > /* *un*break previous two lines!! */ > return -1;} > } > # fi > > > int > virNetDevBridgeAddPort(...) > { > /* existing body of this function, except at the end do this: */ > if (virtVlan && virtVlan->nTags) > return virNetDevBridgeSetupVlans(ifname, virtVlan); > else > return 0; > } > #elif defined(WITH_BSD_BRIDGE_MGMT) > ... > > > This way you'll stil have the ability to add ports to a bridge when > libnl isn't available, but will get a runtime error if someone tries to > configure vlan stuff for a port. > >> --- >> src/util/virnetdevbridge.c | 122 +++++++++++++++++++++ >> +----------------------- >> 1 file changed, 61 insertions(+), 61 deletions(-) >> >> diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c >> index >> c79d0c79b7b16a0a070b5013ed7df9d0a63b1c38..70e82a0029634ddf44c2b933577bf783c89f035c 100644 >> --- a/src/util/virnetdevbridge.c >> +++ b/src/util/virnetdevbridge.c >> @@ -313,66 +313,6 @@ virNetDevBridgePortSetIsolated(const char *brname, >> return virNetDevBridgePortSet(brname, ifname, "isolated", >> enable ? 1 : 0); >> } >> -static int >> -virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan >> *virtVlan) >> -{ >> - int error = 0; >> - unsigned short flags; >> - >> - if (!virtVlan || !virtVlan->nTags) >> - return 0; >> - >> - // The interface will have been automatically added to vlan 1, so >> remove it >> - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, >> &error) < 0) { >> - if (error != 0) { >> - virReportSystemError(-error, >> - _("error removing vlan filter from >> interface %1$s"), >> - ifname); >> - } >> - return -1; >> - } >> - >> - // If trunk mode, add the native VLAN then add the others, if any >> - if (virtVlan->trunk) { >> - size_t i; >> - >> - if (virtVlan->nativeTag) { >> - flags = BRIDGE_VLAN_INFO_PVID; >> - if (virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_UNTAGGED || >> - virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) { >> - flags |= BRIDGE_VLAN_INFO_UNTAGGED; >> - } >> - >> - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, >> flags, >> - virtVlan->nativeTag, >> &error) < 0) { >> - goto error; >> - } >> - } >> - >> - for (i = 0; i < virtVlan->nTags; i++) { >> - if (virtVlan->tag[i] != virtVlan->nativeTag) >> - if (virNetlinkBridgeVlanFilterSet(ifname, >> RTM_SETLINK, 0, >> - virtVlan->tag[i], >> &error) < 0) { >> - goto error; >> - } >> - } >> - } else { >> - // In native mode, add the single VLAN as pvid untagged >> - flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; >> - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, >> - virtVlan->tag[0], &error) < >> 0) { >> - goto error; >> - } >> - } >> - >> - return 0; >> - >> - error: >> - if (error != 0) >> - virReportSystemError(-error, _("error adding vlan filter to >> interface %1$s"), ifname); >> - return -1; >> -} >> - >> #else >> int >> @@ -651,7 +591,67 @@ int virNetDevBridgeDelete(const char *brname >> G_GNUC_UNUSED) >> * >> * Returns 0 in case of success or an errno code in case of failure. >> */ >> -#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) >> +#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) && >> defined(WITH_LIBNL) >> +static int >> +virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan >> *virtVlan) >> +{ >> + int error = 0; >> + unsigned short flags; >> + >> + if (!virtVlan || !virtVlan->nTags) >> + return 0; >> + >> + // The interface will have been automatically added to vlan 1, so >> remove it >> + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, >> &error) < 0) { >> + if (error != 0) { >> + virReportSystemError(-error, >> + _("error removing vlan filter from >> interface %1$s"), >> + ifname); >> + } >> + return -1; >> + } >> + >> + // If trunk mode, add the native VLAN then add the others, if any >> + if (virtVlan->trunk) { >> + size_t i; >> + >> + if (virtVlan->nativeTag) { >> + flags = BRIDGE_VLAN_INFO_PVID; >> + if (virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_UNTAGGED || >> + virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) { >> + flags |= BRIDGE_VLAN_INFO_UNTAGGED; >> + } >> + >> + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, >> flags, >> + virtVlan->nativeTag, >> &error) < 0) { >> + goto error; >> + } >> + } >> + >> + for (i = 0; i < virtVlan->nTags; i++) { >> + if (virtVlan->tag[i] != virtVlan->nativeTag) >> + if (virNetlinkBridgeVlanFilterSet(ifname, >> RTM_SETLINK, 0, >> + virtVlan->tag[i], >> &error) < 0) { >> + goto error; >> + } >> + } >> + } else { >> + // In native mode, add the single VLAN as pvid untagged >> + flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; >> + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, >> + virtVlan->tag[0], &error) < >> 0) { >> + goto error; >> + } >> + } >> + >> + return 0; >> + >> + error: >> + if (error != 0) >> + virReportSystemError(-error, _("error adding vlan filter to >> interface %1$s"), ifname); >> + return -1; >> +} >> + >> int virNetDevBridgeAddPort(const char *brname, >> const char *ifname, >> const virNetDevVlan *virtVlan) >> >> --- >> base-commit: e5299ddf86121d3c792ca271ffcb54900eb19dc3 >> change-id: 20250304-nl-605e05b8c5f2 >> >> Best regards, >
On 3/7/25 8:21 AM, Akihiko Odaki wrote: > On 2025/03/07 22:11, Laine Stump wrote: >> On 3/7/25 6:48 AM, Akihiko Odaki wrote: >>> virNetDevBridgeSetupVlans() calls virNetlinkBridgeVlanFilterSet(), >>> which requires libnl. Use the function only when libnl is available >>> to avoid breaking builds. >>> >>> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> >> >> I'm curious what is the Linux platform where we don't have libnl >> available? > > I didn't have libnl3-devel installed. > > Another option is to require libnl3-devel in Mesa; it will give nicer > error messages to anyone trying to build libvirt without libnl and > allows us to drop WITH_LIBNL checks. Ah, so it's not that your distro doesn't have libnl available, you just didn't happen to have it installed. I'm actually surprised that it compiles to something usable (wrt. networking) if you do that. (I guess you just don't use any of the features that require libnl). The "WITH_LIBNL" stuff has been in there so long (since around 2011, maybe earlier) that I hadn't even considered removing the #ifdefs (and don't have the brain cells to think about it right now, since I have to leave town in about an hour :-); it's an interesting idea though, since so much functionality wouldn't work without it. I suppose we should enumerate that and then decide if it's worthwhile to allow building something thats missing all those things.) > >> >> Also, in this case you've removed the ability to add ports to a >> bridge, even if the request has no vlan info. If there really are >> Linux distros that don't have libnl then we don't want to completely >> disable the ability to add a tap to a bridge - instead we should move >> the check for vlan == NULL from the top of virNetDevBridgeSetupVlans() >> to the place where virNetDevBridgeSetupVlans() is called (in >> virNetDevBridgeAddPort()). Then virNetDeBridgeSetupVlans should be >> placed inside an #if defined(WITH_LIBNL) that has an #else >> alternative implementation just reporting that vlans can't be set on >> host bridge ports on this platform - this entire set of 2 >> virNetDevBridgeeSetupVlan() functions should be defined immediately >> preceding the definition of virNetDebBridgeAddPort(), inside the same >> #if as that function. >> >> So in short, you should have: >> >> #if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) >> # if defined(WITH_LIBNL) >> static int >> virNetDevBridgeSetupVlans() >> { >> /* existing virNetDevBridgeSetupVlans() body except NULL check */ >> } >> # else >> static int >> virNetDevBridgeSetupVlans() >> { >> virReportSystemError(ENOSYS, "%s", >> _("Cannot configure vlans on host bridge ports >> on this platform")); >> /* *un*break previous two lines!! */ >> return -1;} >> } >> # fi >> >> >> int >> virNetDevBridgeAddPort(...) >> { >> /* existing body of this function, except at the end do this: */ >> if (virtVlan && virtVlan->nTags) >> return virNetDevBridgeSetupVlans(ifname, virtVlan); >> else >> return 0; >> } >> #elif defined(WITH_BSD_BRIDGE_MGMT) >> ... >> >> >> This way you'll stil have the ability to add ports to a bridge when >> libnl isn't available, but will get a runtime error if someone tries >> to configure vlan stuff for a port. >> >>> --- >>> src/util/virnetdevbridge.c | 122 +++++++++++++++++++++ >>> +----------------------- >>> 1 file changed, 61 insertions(+), 61 deletions(-) >>> >>> diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c >>> index >>> c79d0c79b7b16a0a070b5013ed7df9d0a63b1c38..70e82a0029634ddf44c2b933577bf783c89f035c 100644 >>> --- a/src/util/virnetdevbridge.c >>> +++ b/src/util/virnetdevbridge.c >>> @@ -313,66 +313,6 @@ virNetDevBridgePortSetIsolated(const char *brname, >>> return virNetDevBridgePortSet(brname, ifname, "isolated", >>> enable ? 1 : 0); >>> } >>> -static int >>> -virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan >>> *virtVlan) >>> -{ >>> - int error = 0; >>> - unsigned short flags; >>> - >>> - if (!virtVlan || !virtVlan->nTags) >>> - return 0; >>> - >>> - // The interface will have been automatically added to vlan 1, >>> so remove it >>> - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, >>> &error) < 0) { >>> - if (error != 0) { >>> - virReportSystemError(-error, >>> - _("error removing vlan filter from >>> interface %1$s"), >>> - ifname); >>> - } >>> - return -1; >>> - } >>> - >>> - // If trunk mode, add the native VLAN then add the others, if any >>> - if (virtVlan->trunk) { >>> - size_t i; >>> - >>> - if (virtVlan->nativeTag) { >>> - flags = BRIDGE_VLAN_INFO_PVID; >>> - if (virtVlan->nativeMode == >>> VIR_NATIVE_VLAN_MODE_UNTAGGED || >>> - virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) { >>> - flags |= BRIDGE_VLAN_INFO_UNTAGGED; >>> - } >>> - >>> - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, >>> flags, >>> - virtVlan->nativeTag, >>> &error) < 0) { >>> - goto error; >>> - } >>> - } >>> - >>> - for (i = 0; i < virtVlan->nTags; i++) { >>> - if (virtVlan->tag[i] != virtVlan->nativeTag) >>> - if (virNetlinkBridgeVlanFilterSet(ifname, >>> RTM_SETLINK, 0, >>> - virtVlan->tag[i], >>> &error) < 0) { >>> - goto error; >>> - } >>> - } >>> - } else { >>> - // In native mode, add the single VLAN as pvid untagged >>> - flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; >>> - if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, >>> - virtVlan->tag[0], &error) >>> < 0) { >>> - goto error; >>> - } >>> - } >>> - >>> - return 0; >>> - >>> - error: >>> - if (error != 0) >>> - virReportSystemError(-error, _("error adding vlan filter to >>> interface %1$s"), ifname); >>> - return -1; >>> -} >>> - >>> #else >>> int >>> @@ -651,7 +591,67 @@ int virNetDevBridgeDelete(const char *brname >>> G_GNUC_UNUSED) >>> * >>> * Returns 0 in case of success or an errno code in case of failure. >>> */ >>> -#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) >>> +#if defined(WITH_STRUCT_IFREQ) && defined(SIOCBRADDIF) && >>> defined(WITH_LIBNL) >>> +static int >>> +virNetDevBridgeSetupVlans(const char *ifname, const virNetDevVlan >>> *virtVlan) >>> +{ >>> + int error = 0; >>> + unsigned short flags; >>> + >>> + if (!virtVlan || !virtVlan->nTags) >>> + return 0; >>> + >>> + // The interface will have been automatically added to vlan 1, >>> so remove it >>> + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_DELLINK, 0, 1, >>> &error) < 0) { >>> + if (error != 0) { >>> + virReportSystemError(-error, >>> + _("error removing vlan filter from >>> interface %1$s"), >>> + ifname); >>> + } >>> + return -1; >>> + } >>> + >>> + // If trunk mode, add the native VLAN then add the others, if any >>> + if (virtVlan->trunk) { >>> + size_t i; >>> + >>> + if (virtVlan->nativeTag) { >>> + flags = BRIDGE_VLAN_INFO_PVID; >>> + if (virtVlan->nativeMode == >>> VIR_NATIVE_VLAN_MODE_UNTAGGED || >>> + virtVlan->nativeMode == VIR_NATIVE_VLAN_MODE_DEFAULT) { >>> + flags |= BRIDGE_VLAN_INFO_UNTAGGED; >>> + } >>> + >>> + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, >>> flags, >>> + virtVlan->nativeTag, >>> &error) < 0) { >>> + goto error; >>> + } >>> + } >>> + >>> + for (i = 0; i < virtVlan->nTags; i++) { >>> + if (virtVlan->tag[i] != virtVlan->nativeTag) >>> + if (virNetlinkBridgeVlanFilterSet(ifname, >>> RTM_SETLINK, 0, >>> + virtVlan->tag[i], >>> &error) < 0) { >>> + goto error; >>> + } >>> + } >>> + } else { >>> + // In native mode, add the single VLAN as pvid untagged >>> + flags = BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED; >>> + if (virNetlinkBridgeVlanFilterSet(ifname, RTM_SETLINK, flags, >>> + virtVlan->tag[0], &error) >>> < 0) { >>> + goto error; >>> + } >>> + } >>> + >>> + return 0; >>> + >>> + error: >>> + if (error != 0) >>> + virReportSystemError(-error, _("error adding vlan filter to >>> interface %1$s"), ifname); >>> + return -1; >>> +} >>> + >>> int virNetDevBridgeAddPort(const char *brname, >>> const char *ifname, >>> const virNetDevVlan *virtVlan) >>> >>> --- >>> base-commit: e5299ddf86121d3c792ca271ffcb54900eb19dc3 >>> change-id: 20250304-nl-605e05b8c5f2 >>> >>> Best regards, >> >
© 2016 - 2025 Red Hat, Inc.