[libvirt] [PATCH 2/3] support new forward mode of vlan for virtual network

Shi Lei shilei.massclouds at gmx.com
Wed Jul 18 11:32:27 UTC 2018



> Sent: Wednesday, July 18, 2018 at 12:38 AM
> From: "John Ferlan" <jferlan at redhat.com>
> To: "Shi Lei" <shilei.massclouds at gmx.com>, libvir-list at redhat.com
> Subject: Re: [libvirt] [PATCH 2/3] support new forward mode of vlan for virtual network
>
> 
> 
> On 07/05/2018 11:36 PM, Shi Lei wrote:
> > Signed-off-by: Shi Lei <shilei.massclouds at gmx.com>
> > ---
> >  src/conf/network_conf.c     | 12 ++++---
> >  src/conf/network_conf.h     |  1 +
> >  src/network/bridge_driver.c | 80 +++++++++++++++++++++++++++++++++++++++++----
> >  3 files changed, 82 insertions(+), 11 deletions(-)
> > 
> 
> This would be missing RNG changes in docs/schemas/network.rng,
> documentation changes in docs/formatnetwork.html.in in order to describe
> things, and networkxml2* tests.  Usually if you look at the last person
> to add a new element to something it'll give you a good hint. In this
> case, see commit id 25e8112d7 when "open" was added. I use gitk to chase
> changes, but others use straight git - whatever works for you.

OK. Thank you! I will add these in patch v2.

> 
> > diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
> > index 630a87f..6e1de6c 100644
> > --- a/src/conf/network_conf.c
> > +++ b/src/conf/network_conf.c
> > @@ -50,7 +50,7 @@ VIR_ENUM_IMPL(virNetworkForward,
> >                VIR_NETWORK_FORWARD_LAST,
> >                "none", "nat", "route", "open",
> >                "bridge", "private", "vepa", "passthrough",
> > -              "hostdev")
> > +              "hostdev", "vlan")
> >  
> >  VIR_ENUM_IMPL(virNetworkBridgeMACTableManager,
> >                VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LAST,
> > @@ -1876,6 +1876,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
> >       */
> >      switch (def->forward.type) {
> >      case VIR_NETWORK_FORWARD_NONE:
> > +    case VIR_NETWORK_FORWARD_VLAN:
> >          break;
> >  
> >      case VIR_NETWORK_FORWARD_ROUTE:
> > @@ -1963,9 +1964,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
> >          (def->forward.type != VIR_NETWORK_FORWARD_NONE &&
> >           def->forward.type != VIR_NETWORK_FORWARD_NAT &&
> >           def->forward.type != VIR_NETWORK_FORWARD_ROUTE &&
> > -         def->forward.type != VIR_NETWORK_FORWARD_OPEN)) {
> > +         def->forward.type != VIR_NETWORK_FORWARD_OPEN &&
> > +         def->forward.type != VIR_NETWORK_FORWARD_VLAN)) {
> >          virReportError(VIR_ERR_XML_ERROR,
> > -                       _("mtu size only allowed in open, route, nat, "
> > +                       _("mtu size only allowed in open, route, nat, vlan "
> >                           "and isolated mode, not in %s (network '%s')"),
> >                         virNetworkForwardTypeToString(def->forward.type),
> >                         def->name);
> > @@ -2474,6 +2476,7 @@ virNetworkDefFormatBuf(virBufferPtr buf,
> >          def->forward.type == VIR_NETWORK_FORWARD_NAT ||
> >          def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
> >          def->forward.type == VIR_NETWORK_FORWARD_OPEN ||
> > +        def->forward.type == VIR_NETWORK_FORWARD_VLAN ||
> >          def->bridge || def->macTableManager) {
> >  
> >          virBufferAddLit(buf, "<bridge");
> > @@ -2481,7 +2484,8 @@ virNetworkDefFormatBuf(virBufferPtr buf,
> >          if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
> >              def->forward.type == VIR_NETWORK_FORWARD_NAT ||
> >              def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
> > -            def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
> > +            def->forward.type == VIR_NETWORK_FORWARD_OPEN ||
> > +            def->forward.type == VIR_NETWORK_FORWARD_VLAN) {
> >              virBufferAsprintf(buf, " stp='%s' delay='%ld'",
> >                                def->stp ? "on" : "off", def->delay);
> >          }
> > diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
> > index 54c8ed1..47bb83e 100644
> > --- a/src/conf/network_conf.h
> > +++ b/src/conf/network_conf.h
> > @@ -53,6 +53,7 @@ typedef enum {
> >      VIR_NETWORK_FORWARD_VEPA,
> >      VIR_NETWORK_FORWARD_PASSTHROUGH,
> >      VIR_NETWORK_FORWARD_HOSTDEV,
> > +    VIR_NETWORK_FORWARD_VLAN,
> >  
> >      VIR_NETWORK_FORWARD_LAST,
> >  } virNetworkForwardType;
> > diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
> > index da3c32e..314f78c 100644
> > --- a/src/network/bridge_driver.c
> > +++ b/src/network/bridge_driver.c
> > @@ -451,6 +451,7 @@ networkUpdateState(virNetworkObjPtr obj,
> >      case VIR_NETWORK_FORWARD_NAT:
> >      case VIR_NETWORK_FORWARD_ROUTE:
> >      case VIR_NETWORK_FORWARD_OPEN:
> > +    case VIR_NETWORK_FORWARD_VLAN:
> >          /* If bridge doesn't exist, then mark it inactive */
> >          if (!(def->bridge && virNetDevExists(def->bridge) == 1))
> >              virNetworkObjSetActive(obj, false);
> > @@ -2092,7 +2093,8 @@ networkRefreshDaemonsHelper(virNetworkObjPtr obj,
> >          ((def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
> >           (def->forward.type == VIR_NETWORK_FORWARD_NAT) ||
> >           (def->forward.type == VIR_NETWORK_FORWARD_ROUTE) ||
> > -         (def->forward.type == VIR_NETWORK_FORWARD_OPEN))) {
> > +         (def->forward.type == VIR_NETWORK_FORWARD_OPEN) ||
> > +         (def->forward.type == VIR_NETWORK_FORWARD_VLAN))) {
> >          /* Only the three L3 network types that are configured by
> >           * libvirt will have a dnsmasq or radvd daemon associated
> >           * with them.  Here we send a SIGHUP to an existing
> > @@ -2131,7 +2133,8 @@ networkReloadFirewallRulesHelper(virNetworkObjPtr obj,
> >      if (virNetworkObjIsActive(obj) &&
> >          ((def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
> >           (def->forward.type == VIR_NETWORK_FORWARD_NAT) ||
> > -         (def->forward.type == VIR_NETWORK_FORWARD_ROUTE))) {
> > +         (def->forward.type == VIR_NETWORK_FORWARD_ROUTE) ||
> > +         (def->forward.type == VIR_NETWORK_FORWARD_VLAN))) {
> >          /* Only three of the L3 network types that are configured by
> >           * libvirt need to have iptables rules reloaded. The 4th L3
> >           * network type, forward='open', doesn't need this because it
> > @@ -2513,6 +2516,27 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
> >      if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0)
> >          goto err5;
> >  
> > +    if (def->forward.type == VIR_NETWORK_FORWARD_VLAN) {
> > +        char vlanDevName[IFNAMSIZ];
> 
>     char *vlanDevName = NULL;  (needs to be at the top)

OK.

> 
> > +        /* ifs[0].device.dev and vlan.tag[0] have been validated in networkValidate() */
> > +        if (virNetDevCreateVLanDev(def->forward.ifs[0].device.dev, def->vlan.tag[0],
> > +                          vlanDevName, sizeof(vlanDevName)) < 0)
> 
> Make sure the vlanDevName aligns under the def->forward...

OK.

> 
> > +            goto err5;
> 
> err5 is for bandwidth failure, maybe there needs to be a err6 for VLAN
> and within that there will need to be a VIR_FREE(vlanDevName);

OK.

> 
> > +
> > +        if (virNetDevBridgeAddPort(def->bridge, vlanDevName) < 0) {
> > +            ignore_value(virNetDevDestroyVLanDev(def->forward.ifs[0].device.dev,
> > +                                                 def->vlan.tag[0]));
> > +            goto err5;
> > +        }
> > +
> > +        if (virNetDevSetOnline(vlanDevName, true) < 0) {
> > +            ignore_value(virNetDevBridgeRemovePort(def->bridge, vlanDevName));
> > +            ignore_value(virNetDevDestroyVLanDev(def->forward.ifs[0].device.dev,
> > +                                                 def->vlan.tag[0]));
> 
> BTW: If all callers to virNetDevDestroyVLanDev are just going to be
> wrapped in ignore_value(), then let's just make it a void and be done
> with it.

OK. I think about it.

> 
> > +            goto err5;
> > +        }
> 
>     VIR_FREE(vlanDevName);
> 
> > +    }
> > +
> >      VIR_FREE(macTapIfName);
> >      VIR_FREE(macMapFile);
> >  
> > @@ -2576,6 +2600,18 @@ networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver,
> >      pid_t radvdPid;
> >      pid_t dnsmasqPid;
> >  
> > +    if (def->forward.type == VIR_NETWORK_FORWARD_VLAN) {
> > +        char vlanDevName[IFNAMSIZ];
> 
>     char *vlanDevName = NULL;
> 
> > +        ignore_value(virNetDevGetVLanDevName(def->forward.ifs[0].device.dev,
> > +                                             def->vlan.tag[0],
> > +                                             vlanDevName, sizeof(vlanDevName)));
> 
> don't think this can be ignored since it's used as input for other
> functions that follow that may not expect a NULL vlanDevName

Yes. I'll fix it!

> 
> > +
> > +        ignore_value(virNetDevSetOnline(vlanDevName, false));
> > +        ignore_value(virNetDevBridgeRemovePort(def->bridge, vlanDevName));
> > +        ignore_value(virNetDevDestroyVLanDev(def->forward.ifs[0].device.dev,
> 
> I'm now having more thoughts related to whether virNetDevDestroyVLanDev
> should take an ifname.  Above you do the virNetDevGetVLanDevName call
> and then again when calling virNetDevDestroyVLanDev, so why not just
> have it take the vdname instead.
> 
> 
> 
> > +                                             def->vlan.tag[0]));
> 
> 
>    VIR_FREE(vlanDevName);
> 
> John

Yes. It's better to take the vdname. Thanks!

Shi Lei

> 
> > +    }
> > +
> >      if (def->bandwidth)
> >          virNetDevBandwidthClear(def->bridge);
> >  
> > @@ -2719,6 +2755,7 @@ networkCreateInterfacePool(virNetworkDefPtr netdef)
> >          case VIR_NETWORK_FORWARD_NAT:
> >          case VIR_NETWORK_FORWARD_ROUTE:
> >          case VIR_NETWORK_FORWARD_OPEN:
> > +        case VIR_NETWORK_FORWARD_VLAN:
> >          case VIR_NETWORK_FORWARD_LAST:
> >              /* by definition these will never be encountered here */
> >              break;
> > @@ -2817,6 +2854,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
> >      case VIR_NETWORK_FORWARD_NAT:
> >      case VIR_NETWORK_FORWARD_ROUTE:
> >      case VIR_NETWORK_FORWARD_OPEN:
> > +    case VIR_NETWORK_FORWARD_VLAN:
> >          if (networkStartNetworkVirtual(driver, obj) < 0)
> >              goto cleanup;
> >          break;
> > @@ -2899,6 +2937,7 @@ networkShutdownNetwork(virNetworkDriverStatePtr driver,
> >      case VIR_NETWORK_FORWARD_NAT:
> >      case VIR_NETWORK_FORWARD_ROUTE:
> >      case VIR_NETWORK_FORWARD_OPEN:
> > +    case VIR_NETWORK_FORWARD_VLAN:
> >          ret = networkShutdownNetworkVirtual(driver, obj);
> >          break;
> >  
> > @@ -3276,7 +3315,8 @@ networkValidate(virNetworkDriverStatePtr driver,
> >      if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
> >          def->forward.type == VIR_NETWORK_FORWARD_NAT ||
> >          def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
> > -        def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
> > +        def->forward.type == VIR_NETWORK_FORWARD_OPEN ||
> > +        def->forward.type == VIR_NETWORK_FORWARD_VLAN) {
> >  
> >          /* if no bridge name was given in the config, find a name
> >           * unused by any other libvirt networks and assign it.
> > @@ -3447,7 +3487,8 @@ networkValidate(virNetworkDriverStatePtr driver,
> >       * a pool, and those using an Open vSwitch bridge.
> >       */
> >  
> > -    vlanAllowed = (def->forward.type == VIR_NETWORK_FORWARD_HOSTDEV ||
> > +    vlanAllowed = (def->forward.type == VIR_NETWORK_FORWARD_VLAN ||
> > +                   def->forward.type == VIR_NETWORK_FORWARD_HOSTDEV ||
> >                     def->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH ||
> >                     (def->forward.type == VIR_NETWORK_FORWARD_BRIDGE &&
> >                      def->virtPortProfile &&
> > @@ -3530,6 +3571,28 @@ networkValidate(virNetworkDriverStatePtr driver,
> >              }
> >          }
> >      }
> > +
> > +    if (def->forward.type == VIR_NETWORK_FORWARD_VLAN) {
> > +        if (virNetDevLoad8021Q() < 0)
> > +            return -1;
> > +
> > +        if (def->forward.nifs != 1 ||
> > +            strlen(def->forward.ifs[0].device.dev) == 0) {
> > +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > +                           _("invalid dev in <forward mode='vlan' dev='xxx'> "
> > +                             "of network '%s' with forward mode='%s'"),
> > +                           def->name, virNetworkForwardTypeToString(def->forward.type));
> > +            return -1;
> > +        }
> > +        if (def->vlan.nTags != 1 || def->vlan.tag[0] >= 4096) {
> > +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > +                           _("unsupported vlan config. check <vlan><tag id='xxx'> "
> > +                             "of network '%s' with forward mode='%s'"),
> > +                           def->name, virNetworkForwardTypeToString(def->forward.type));
> > +            return -1;
> > +        }
> > +    }
> > +
> >      return 0;
> >  }
> >  
> > @@ -3757,7 +3820,8 @@ networkUpdate(virNetworkPtr net,
> >           */
> >          if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
> >              def->forward.type == VIR_NETWORK_FORWARD_NAT ||
> > -            def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
> > +            def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
> > +            def->forward.type == VIR_NETWORK_FORWARD_VLAN) {
> >              switch (section) {
> >              case VIR_NETWORK_SECTION_FORWARD:
> >              case VIR_NETWORK_SECTION_FORWARD_INTERFACE:
> > @@ -4443,7 +4507,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
> >      if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) ||
> >          (netdef->forward.type == VIR_NETWORK_FORWARD_NAT) ||
> >          (netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE) ||
> > -        (netdef->forward.type == VIR_NETWORK_FORWARD_OPEN)) {
> > +        (netdef->forward.type == VIR_NETWORK_FORWARD_OPEN) ||
> > +        (netdef->forward.type == VIR_NETWORK_FORWARD_VLAN)) {
> >          /* for these forward types, the actual net type really *is*
> >           * NETWORK; we just keep the info from the portgroup in
> >           * iface->data.network.actual
> > @@ -4701,7 +4766,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
> >           * mode) and openvswitch bridges. Otherwise log an error and
> >           * fail
> >           */
> > -        if (!(actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
> > +        if (!(netdef->forward.type == VIR_NETWORK_FORWARD_VLAN ||
> > +              actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
> >                (actualType == VIR_DOMAIN_NET_TYPE_DIRECT &&
> >                 virDomainNetGetActualDirectMode(iface)
> >                 == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) ||
> > 
> 




More information about the libvir-list mailing list