Signed-off-by: Shi Lei <shilei.massclo...@gmx.com> --- src/conf/domain_conf.c | 1 + src/conf/network_conf.c | 24 +++++++++++++++++-- src/conf/network_conf.h | 1 + src/conf/virnetworkobj.c | 1 + src/esx/esx_network_driver.c | 1 + src/network/bridge_driver.c | 55 ++++++++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_process.c | 1 + 7 files changed, 80 insertions(+), 4 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 77cc737..0b6d247 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -30369,6 +30369,7 @@ virDomainNetResolveActualType(virDomainNetDefPtr iface) case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case 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 diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index c08456b..cb51c7b 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, @@ -1914,6 +1914,24 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) } break; + case VIR_NETWORK_FORWARD_VLAN: + if (def->forward.nifs != 1 || + strlen(def->forward.ifs[0].device.dev) == 0) { + virReportError(VIR_ERR_XML_ERROR, + _("network '%s' in forward mode 'vlan' requests " + "one and only one interface"), + def->name); + goto error; + } + if (def->vlan.nTags != 1 || def->vlan.tag[0] >= 4096) { + virReportError(VIR_ERR_XML_ERROR, + _("network '%s' in forward mode 'vlan' requests " + "one and only one VLan-Tag"), + def->name); + goto error; + } + break; + case VIR_NETWORK_FORWARD_PRIVATE: case VIR_NETWORK_FORWARD_VEPA: case VIR_NETWORK_FORWARD_PASSTHROUGH: @@ -1970,6 +1988,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case VIR_NETWORK_FORWARD_VLAN: break; case VIR_NETWORK_FORWARD_BRIDGE: @@ -1978,7 +1997,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) case VIR_NETWORK_FORWARD_PASSTHROUGH: case VIR_NETWORK_FORWARD_HOSTDEV: 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); @@ -2494,6 +2513,7 @@ virNetworkDefFormatBuf(virBufferPtr buf, case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case VIR_NETWORK_FORWARD_VLAN: hasbridge = true; break; 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/conf/virnetworkobj.c b/src/conf/virnetworkobj.c index b13e5a7..fd5c268 100644 --- a/src/conf/virnetworkobj.c +++ b/src/conf/virnetworkobj.c @@ -1014,6 +1014,7 @@ virNetworkLoadConfig(virNetworkObjListPtr nets, case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case VIR_NETWORK_FORWARD_VLAN: if (!def->mac_specified) { virNetworkSetBridgeMacAddr(def); virNetworkSaveConfig(configDir, def); diff --git a/src/esx/esx_network_driver.c b/src/esx/esx_network_driver.c index 31bceb7..8f91ae9 100644 --- a/src/esx/esx_network_driver.c +++ b/src/esx/esx_network_driver.c @@ -334,6 +334,7 @@ esxNetworkDefineXML(virConnectPtr conn, const char *xml) case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case VIR_NETWORK_FORWARD_VLAN: case VIR_NETWORK_FORWARD_PRIVATE: case VIR_NETWORK_FORWARD_VEPA: case VIR_NETWORK_FORWARD_PASSTHROUGH: diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 588b0d1..2e203f5 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); @@ -2099,6 +2100,7 @@ networkRefreshDaemonsHelper(virNetworkObjPtr obj, case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case 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 @@ -2155,6 +2157,7 @@ networkReloadFirewallRulesHelper(virNetworkObjPtr obj, case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: + case 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 @@ -2552,6 +2555,29 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver, if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0) goto err5; + if (def->forward.type == VIR_NETWORK_FORWARD_VLAN) { + /* ifs[0].device.dev and vlan.tag[0] have been validated + * in virNetworkDefParseXML + */ + VIR_AUTOFREE(char *) vlanDevName = NULL; + if (virNetDevCreateVLanDev(def->forward.ifs[0].device.dev, def->vlan.tag[0], + &vlanDevName) < 0) + goto err5; + + if (virNetDevBridgeAddPort(def->bridge, vlanDevName) < 0) { + virNetDevDestroyVLanDev(def->forward.ifs[0].device.dev, + def->vlan.tag[0], vlanDevName); + goto err5; + } + + if (virNetDevSetOnline(vlanDevName, true) < 0) { + ignore_value(virNetDevBridgeRemovePort(def->bridge, vlanDevName)); + virNetDevDestroyVLanDev(def->forward.ifs[0].device.dev, + def->vlan.tag[0], vlanDevName); + goto err5; + } + } + VIR_FREE(macTapIfName); VIR_FREE(macMapFile); @@ -2616,6 +2642,17 @@ networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver, pid_t radvdPid; pid_t dnsmasqPid; + if (def->forward.type == VIR_NETWORK_FORWARD_VLAN) { + VIR_AUTOFREE(char *) vlanDevName = NULL; + if (!virNetDevGetVLanDevName(def->forward.ifs[0].device.dev, + def->vlan.tag[0], &vlanDevName)) { + ignore_value(virNetDevSetOnline(vlanDevName, false)); + ignore_value(virNetDevBridgeRemovePort(def->bridge, vlanDevName)); + virNetDevDestroyVLanDev(def->forward.ifs[0].device.dev, + def->vlan.tag[0], vlanDevName); + } + } + if (def->bandwidth) virNetDevBandwidthClear(def->bridge); @@ -2759,6 +2796,7 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case VIR_NETWORK_FORWARD_VLAN: /* by definition these will never be encountered here */ break; @@ -2861,6 +2899,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; @@ -2948,6 +2987,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; @@ -3332,6 +3372,7 @@ networkValidate(virNetworkDriverStatePtr driver, case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case 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. */ @@ -3510,11 +3551,12 @@ networkValidate(virNetworkDriverStatePtr driver, /* The only type of networks that currently support transparent * vlan configuration are those using hostdev sr-iov devices from - * a pool, and those using an Open vSwitch bridge. + * a pool, and those using an Open vSwitch bridge or based on 8021q. */ vlanAllowed = (def->forward.type == VIR_NETWORK_FORWARD_HOSTDEV || def->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH || + def->forward.type == VIR_NETWORK_FORWARD_VLAN || (def->forward.type == VIR_NETWORK_FORWARD_BRIDGE && def->virtPortProfile && def->virtPortProfile->virtPortType @@ -3596,6 +3638,11 @@ networkValidate(virNetworkDriverStatePtr driver, } } } + + if (def->forward.type == VIR_NETWORK_FORWARD_VLAN) { + if (virNetDevLoad8021Q() < 0) + return -1; + } return 0; } @@ -3825,6 +3872,7 @@ networkUpdate(virNetworkPtr net, case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: + case VIR_NETWORK_FORWARD_VLAN: switch (section) { case VIR_NETWORK_SECTION_FORWARD: case VIR_NETWORK_SECTION_FORWARD_INTERFACE: @@ -4531,6 +4579,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case 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 @@ -4792,7 +4841,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) || @@ -5133,6 +5183,7 @@ networkReleaseActualDevice(virDomainDefPtr dom, case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case VIR_NETWORK_FORWARD_VLAN: if (iface->data.network.actual && networkUnplugBandwidth(obj, iface) < 0) goto error; break; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 02fdc55..ae725a8 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4550,6 +4550,7 @@ qemuProcessGetNetworkAddress(const char *netname, case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: + case VIR_NETWORK_FORWARD_VLAN: ipdef = virNetworkDefGetIPByIndex(netdef, AF_UNSPEC, 0); if (!ipdef) { virReportError(VIR_ERR_INTERNAL_ERROR, -- 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list