[libvirt] [PATCH 5/9] network: store network promiscLinks setting in NetDef actual object

John Ferlan jferlan at redhat.com
Mon Nov 24 23:00:01 UTC 2014



On 11/24/2014 12:48 PM, Laine Stump wrote:
> At the time that the network driver allocates a connection to a
> network, the tap device that will be used hasn't yet been created -
> that will be done later by qemu (or lxc or whoever) - but if the
> network has promiscLinks='no', then when we do get around to creating
> the tap device, we will need to add an entry for it to the network
> bridge's fdb (forwarding database) *and* turn off learning and
> unicast_flood for that tap device in the bridge's sysfs settings. This
> means that qemu needs to know both the bridge name as well as the
> setting of promiscLinks, so we either need to create a new API to
> retrieve that info, or just pass it back in the ActualNetDef that is
> created during networkAllocateActualDevice. We choose the latter
> method, since it's already done for the bridge device, and it has the
> side effect of making the information available in domain status.
> 
> (NB: in the future, I think that the tap device should actually be
> created by networkAllocateActualDevice(), as that will solve several
> other problems, but that is a battle for another day, and this
> information will still be useful outside the network driver)
> ---
>  src/conf/domain_conf.c      | 29 +++++++++++++++++++++++++++++
>  src/conf/domain_conf.h      |  2 ++
>  src/libvirt_private.syms    |  1 +
>  src/network/bridge_driver.c |  6 +++++-
>  4 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 932bb1c..1317df4 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -6971,6 +6971,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
>      char *mode = NULL;
>      char *addrtype = NULL;
>      char *trustGuestRxFilters = NULL;
> +    char *promiscLinks = NULL;
>  
>      if (VIR_ALLOC(actual) < 0)
>          return -1;
> @@ -7087,6 +7088,16 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
>              goto error;
>          }
>          actual->data.bridge.brname = brname;
> +        promiscLinks = virXPathString("string(./source/@promiscLinks)", ctxt);
> +        if (promiscLinks &&
> +            (actual->data.bridge.promiscLinks
> +             = virTristateBoolTypeFromString(promiscLinks)) <= 0) {
> +            virReportError(VIR_ERR_XML_ERROR,
> +                           _("Invalid promiscLinks setting '%s' "
> +                             "in domain interface's <actual> element"),
> +                           promiscLinks);
> +            goto error;
> +        }
>      }
>  
>      bandwidth_node = virXPathNode("./bandwidth", ctxt);
> @@ -7107,6 +7118,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
>      VIR_FREE(mode);
>      VIR_FREE(addrtype);
>      VIR_FREE(trustGuestRxFilters);
> +    VIR_FREE(promiscLinks);
>      virDomainActualNetDefFree(actual);
>  
>      ctxt->node = save_ctxt;
> @@ -17045,12 +17057,18 @@ virDomainActualNetDefContentsFormat(virBufferPtr buf,
>          }
>          if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
>              actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
> +            int promiscLinks = virDomainNetGetActualPromiscLinks(def);
> +
>              /* actualType == NETWORK includes the name of the bridge
>               * that is used by the network, whether we are
>               * "inSubElement" or not.
>               */
>              virBufferEscapeString(buf, " bridge='%s'",
>                                    virDomainNetGetActualBridgeName(def));
> +            if (promiscLinks) {
> +                virBufferAsprintf(buf, " promiscLinks='%s'",
> +                                  virTristateSwitchTypeToString(promiscLinks));
> +            }
>          } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
>              const char *mode;
>  
> @@ -20647,6 +20665,17 @@ virDomainNetGetActualBridgeName(virDomainNetDefPtr iface)
>      return NULL;
>  }
>  
> +int
> +virDomainNetGetActualPromiscLinks(virDomainNetDefPtr iface)
> +{
> +    if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
> +        iface->data.network.actual &&
> +        (iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
> +         iface->data.network.actual->type == VIR_DOMAIN_NET_TYPE_NETWORK))
> +        return iface->data.network.actual->data.bridge.promiscLinks;
> +    return 0;

return VIR_TRISTATE_BOOL_YES;  ??

of course that could change to _NO if you followed my comment in patch 3...

> +}
> +
>  const char *
>  virDomainNetGetActualDirectDev(virDomainNetDefPtr iface)
>  {
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 0a609df..3b8ac54 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -880,6 +880,7 @@ struct _virDomainActualNetDef {
>      union {
>          struct {
>              char *brname;
> +            int promiscLinks;

                                 /* enum virTristateBool */


Rest looks reasonable, ACK

John
>          } bridge;
>          struct {
>              char *linkdev;
> @@ -2533,6 +2534,7 @@ int virDomainGraphicsListenSetNetwork(virDomainGraphicsDefPtr def,
>  
>  int virDomainNetGetActualType(virDomainNetDefPtr iface);
>  const char *virDomainNetGetActualBridgeName(virDomainNetDefPtr iface);
> +int virDomainNetGetActualPromiscLinks(virDomainNetDefPtr iface);
>  const char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface);
>  int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface);
>  virDomainHostdevDefPtr virDomainNetGetActualHostdev(virDomainNetDefPtr iface);
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 6b6c51b..4730781 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -332,6 +332,7 @@ virDomainNetGetActualBridgeName;
>  virDomainNetGetActualDirectDev;
>  virDomainNetGetActualDirectMode;
>  virDomainNetGetActualHostdev;
> +virDomainNetGetActualPromiscLinks;
>  virDomainNetGetActualTrustGuestRxFilters;
>  virDomainNetGetActualType;
>  virDomainNetGetActualVirtPortProfile;
> diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
> index 92efd7e..bc8da79 100644
> --- a/src/network/bridge_driver.c
> +++ b/src/network/bridge_driver.c
> @@ -3771,7 +3771,7 @@ networkAllocateActualDevice(virDomainDefPtr dom,
>           */
>          iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_NETWORK;
>  
> -        /* we also store the bridge device
> +        /* we also store the bridge device and promiscLinks settings
>           * in iface->data.network.actual->data.bridge for later use
>           * after the domain's tap device is created (to attach to the
>           * bridge and set flood/learning mode on the tap device)
> @@ -3779,6 +3779,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
>          if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
>                         netdef->bridge) < 0)
>              goto error;
> +        iface->data.network.actual->data.bridge.promiscLinks
> +            = netdef->promiscLinks;
>  
>          if (networkPlugBandwidth(network, iface) < 0)
>              goto error;
> @@ -3794,6 +3796,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
>          if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
>                         netdef->bridge) < 0)
>              goto error;
> +        iface->data.network.actual->data.bridge.promiscLinks
> +            = netdef->promiscLinks;
>  
>          /* merge virtualports from interface, network, and portgroup to
>           * arrive at actual virtualport to use
> 




More information about the libvir-list mailing list