The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7988
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === And various smaller fixes.
From 27fbdd30a059a98051180ac7cee574548a05125b Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:30:54 +0100 Subject: [PATCH 01/13] lxd/networks: Log error in doNetworksCreate after failed create if cleanup fails too Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/networks.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lxd/networks.go b/lxd/networks.go index ae67d059a8..09ea358629 100644 --- a/lxd/networks.go +++ b/lxd/networks.go @@ -456,7 +456,11 @@ func doNetworksCreate(d *Daemon, projectName string, req api.NetworksPost, clien if clientType != cluster.ClientTypeJoiner { err = n.Start() if err != nil { - n.Delete(clientType) + delErr := n.Delete(clientType) + if delErr != nil { + logger.Errorf("Failed clearing up network %q after failed create: %v", n.Name(), delErr) + } + return err } } From 4a50691e278f8bf9219669072ce27f83fc677bcd Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:51:40 +0100 Subject: [PATCH 02/13] lxd/network/driver: Improve missing parent network error message Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_macvlan.go | 2 +- lxd/network/driver_sriov.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/network/driver_macvlan.go b/lxd/network/driver_macvlan.go index 8f82680e35..2b4903670b 100644 --- a/lxd/network/driver_macvlan.go +++ b/lxd/network/driver_macvlan.go @@ -29,7 +29,7 @@ func (n *macvlan) DBType() db.NetworkType { // Validate network config. func (n *macvlan) Validate(config map[string]string) error { rules := map[string]func(value string) error{ - "parent": validInterfaceName, + "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), "mtu": validate.Optional(validate.IsNetworkMTU), "vlan": validate.Optional(validate.IsNetworkVLAN), "maas.subnet.ipv4": validate.IsAny, diff --git a/lxd/network/driver_sriov.go b/lxd/network/driver_sriov.go index 698242778f..54ead8c60c 100644 --- a/lxd/network/driver_sriov.go +++ b/lxd/network/driver_sriov.go @@ -29,7 +29,7 @@ func (n *sriov) DBType() db.NetworkType { // Validate network config. func (n *sriov) Validate(config map[string]string) error { rules := map[string]func(value string) error{ - "parent": validInterfaceName, + "parent": validate.Required(validate.IsNotEmpty, validInterfaceName), "mtu": validate.Optional(validate.IsNetworkMTU), "vlan": validate.Optional(validate.IsNetworkVLAN), "maas.subnet.ipv4": validate.IsAny, From 36c2637c3259268e62dcec5c66dacb2630d31f08 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 14:52:56 +0100 Subject: [PATCH 03/13] lxd/network/driver/ovn: Moves uplink type agnostic parent port allocation logic into allocateParentPortIPs() Ready to accomodate other types of uplink network types. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index c05910891f..f4ab603101 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -371,8 +371,6 @@ func (n *ovn) setupParentPort(routerMAC net.HardwareAddr) (*ovnParentVars, error // setupParentPortBridge allocates external IPs on the parent bridge. // Returns the derived ovnParentVars settings. func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAddr) (*ovnParentVars, error) { - v := &ovnParentVars{} - bridgeNet, ok := parentNet.(*bridge) if !ok { return nil, fmt.Errorf("Network is not bridge type") @@ -383,19 +381,32 @@ func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAdd return nil, errors.Wrapf(err, "Network %q is not suitable for use as OVN parent", bridgeNet.name) } + v, err := n.allocateParentPortIPs(parentNet, "ipv4.address", "ipv6.address", routerMAC) + if err != nil { + return nil, errors.Wrapf(err, "Failed allocating parent port IPs on network", parentNet.Name()) + } + + return v, nil +} + +// allocateParentPortIPs attempts to find a free IP in the parent network's OVN ranges and then stores it in +// ovnVolatileParentIPv4 and ovnVolatileParentIPv6 config keys on this network. Returns ovnParentVars settings. +func (n *ovn) allocateParentPortIPs(parentNet Network, v4CIDRKey string, v6CIDRKey string, routerMAC net.HardwareAddr) (*ovnParentVars, error) { + v := &ovnParentVars{} + parentNetConf := parentNet.Config() // Parent derived settings. v.extSwitchProviderName = parentNet.Name() // Optional parent values. - parentIPv4, parentIPv4Net, err := net.ParseCIDR(parentNetConf["ipv4.address"]) + parentIPv4, parentIPv4Net, err := net.ParseCIDR(parentNetConf[v4CIDRKey]) if err == nil { v.dnsIPv4 = parentIPv4 v.routerExtGwIPv4 = parentIPv4 } - parentIPv6, parentIPv6Net, err := net.ParseCIDR(parentNetConf["ipv6.address"]) + parentIPv6, parentIPv6Net, err := net.ParseCIDR(parentNetConf[v6CIDRKey]) if err == nil { v.dnsIPv6 = parentIPv6 v.routerExtGwIPv6 = parentIPv6 From b30f975a6838367a1e117b27583666781d8903f1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:33:29 +0100 Subject: [PATCH 04/13] lxd/network/driver/ovn: Better error messages Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index f4ab603101..ff185854a5 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -365,7 +365,7 @@ func (n *ovn) setupParentPort(routerMAC net.HardwareAddr) (*ovnParentVars, error return n.setupParentPortBridge(parentNet, routerMAC) } - return nil, fmt.Errorf("Network type %q unsupported as OVN parent", parentNet.Type()) + return nil, fmt.Errorf("Failed setting up parent port, network type %q unsupported as OVN parent", parentNet.Type()) } // setupParentPortBridge allocates external IPs on the parent bridge. @@ -597,7 +597,7 @@ func (n *ovn) startParentPort() error { return n.startParentPortBridge(parentNet) } - return fmt.Errorf("Network type %q unsupported as OVN parent", parentNet.Type()) + return fmt.Errorf("Failed starting parent port, network type %q unsupported as OVN parent", parentNet.Type()) } // parentOperationLockName returns the lock name to use for operations on the parent network. @@ -727,7 +727,7 @@ func (n *ovn) deleteParentPort() error { return n.deleteParentPortBridge(parentNet) } - return fmt.Errorf("Network type %q unsupported as OVN parent", parentNet.Type()) + return fmt.Errorf("Failed deleting parent port, network type %q unsupported as OVN parent", parentNet.Type()) } return nil From fdc703d3e3e83fea3c89da0c849b018ca7976da9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:33:46 +0100 Subject: [PATCH 05/13] lxd/network/driver/ovn: Moves parent port lock into deleteParentPort So it applies to all uplink parent network types. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index ff185854a5..d73e02f4d7 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -722,6 +722,10 @@ func (n *ovn) deleteParentPort() error { return errors.Wrapf(err, "Failed loading parent network") } + // Lock parent network so we don't race each other networks using the OVS uplink bridge. + unlock := locking.Lock(n.parentOperationLockName(parentNet)) + defer unlock() + switch parentNet.Type() { case "bridge": return n.deleteParentPortBridge(parentNet) @@ -735,10 +739,6 @@ func (n *ovn) deleteParentPort() error { // deleteParentPortBridge deletes the dnsmasq static lease and removes parent uplink OVS bridge if not in use. func (n *ovn) deleteParentPortBridge(parentNet Network) error { - // Lock parent network so we don't race each other networks using the OVS uplink bridge. - unlock := locking.Lock(n.parentOperationLockName(parentNet)) - defer unlock() - // Check OVS uplink bridge exists, if it does, check how many ports it has. removeVeths := false vars := n.parentPortBridgeVars(parentNet) From 2d4c4be6b06d519a89f09ef1fd88405da094c412 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 16:28:54 +0100 Subject: [PATCH 06/13] lxd/network/driver/ovn: Moves parent port lock into startParentPort So it applies to all uplink parent network types. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index d73e02f4d7..c4981aa68f 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -592,6 +592,11 @@ func (n *ovn) startParentPort() error { return errors.Wrapf(err, "Failed loading parent network") } + // Lock parent network so that if multiple OVN networks are trying to connect to the same parent we don't + // race each other setting up the connection. + unlock := locking.Lock(n.parentOperationLockName(parentNet)) + defer unlock() + switch parentNet.Type() { case "bridge": return n.startParentPortBridge(parentNet) @@ -621,11 +626,6 @@ func (n *ovn) parentPortBridgeVars(parentNet Network) *ovnParentPortBridgeVars { func (n *ovn) startParentPortBridge(parentNet Network) error { vars := n.parentPortBridgeVars(parentNet) - // Lock parent network so that if multiple OVN networks are trying to connect to the same parent we don't - // race each other setting up the connection. - unlock := locking.Lock(n.parentOperationLockName(parentNet)) - defer unlock() - // Do this after gaining lock so that on failure we revert before release locking. revert := revert.New() defer revert.Fail() From 8e821a1af8fdd708cd353b11d4daeb2933be836c Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:34:41 +0100 Subject: [PATCH 07/13] lxd/network/driver/ovn: deleteParentPortBridge comments Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index c4981aa68f..3e3c29c4bc 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -737,7 +737,7 @@ func (n *ovn) deleteParentPort() error { return nil } -// deleteParentPortBridge deletes the dnsmasq static lease and removes parent uplink OVS bridge if not in use. +// deleteParentPortBridge deletes parent uplink OVS bridge, OVN bridge mappings and veth interfaces if not in use. func (n *ovn) deleteParentPortBridge(parentNet Network) error { // Check OVS uplink bridge exists, if it does, check how many ports it has. removeVeths := false From e8f50946eeed770926ef7648d730943bf23b8406 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:35:35 +0100 Subject: [PATCH 08/13] lxd/network/driver/ovn: Don't setup SNAT if no external uplink IPs Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 3e3c29c4bc..7d6909abab 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1052,14 +1052,14 @@ func (n *ovn) setup(update bool) error { } // Add SNAT rules. - if routerIntPortIPv4Net != nil { + if routerIntPortIPv4Net != nil && routerExtPortIPv4 != nil { err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv4Net, routerExtPortIPv4) if err != nil { return err } } - if routerIntPortIPv6Net != nil { + if routerIntPortIPv6Net != nil && routerExtPortIPv6 != nil { err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv6Net, routerExtPortIPv6) if err != nil { return err From 02cb55fc11e0d597d67a094858ccf9e478bb1988 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:58:24 +0100 Subject: [PATCH 09/13] lxd/network/driver/ovn: Makes setting up external router port and switch conditional on having external IPs Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 84 ++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 7d6909abab..2c0a5ae001 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1066,17 +1066,6 @@ func (n *ovn) setup(update bool) error { } } - // Create external logical switch. - if update { - client.LogicalSwitchDelete(n.getExtSwitchName()) - } - - err = client.LogicalSwitchAdd(n.getExtSwitchName(), false) - if err != nil { - return errors.Wrapf(err, "Failed adding external switch") - } - revert.Add(func() { client.LogicalSwitchDelete(n.getExtSwitchName()) }) - // Generate external router port IPs (in CIDR format). extRouterIPs := []*net.IPNet{} if routerExtPortIPv4Net != nil { @@ -1093,41 +1082,54 @@ func (n *ovn) setup(update bool) error { }) } - // Create external router port. - err = client.LogicalRouterPortAdd(n.getRouterName(), n.getRouterExtPortName(), routerMAC, extRouterIPs...) - if err != nil { - return errors.Wrapf(err, "Failed adding external router port") - } - revert.Add(func() { client.LogicalRouterPortDelete(n.getRouterExtPortName()) }) + if len(extRouterIPs) > 0 { + // Create external logical switch. + if update { + client.LogicalSwitchDelete(n.getExtSwitchName()) + } - // Associate external router port to chassis group. - err = client.LogicalRouterPortLinkChassisGroup(n.getRouterExtPortName(), n.getChassisGroupName()) - if err != nil { - return errors.Wrapf(err, "Failed linking external router port to chassis group") - } + err = client.LogicalSwitchAdd(n.getExtSwitchName(), false) + if err != nil { + return errors.Wrapf(err, "Failed adding external switch") + } + revert.Add(func() { client.LogicalSwitchDelete(n.getExtSwitchName()) }) - // Create external switch port and link to router port. - err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchRouterPortName(), false) - if err != nil { - return errors.Wrapf(err, "Failed adding external switch router port") - } - revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchRouterPortName()) }) + // Create external router port. + err = client.LogicalRouterPortAdd(n.getRouterName(), n.getRouterExtPortName(), routerMAC, extRouterIPs...) + if err != nil { + return errors.Wrapf(err, "Failed adding external router port") + } + revert.Add(func() { client.LogicalRouterPortDelete(n.getRouterExtPortName()) }) - err = client.LogicalSwitchPortLinkRouter(n.getExtSwitchRouterPortName(), n.getRouterExtPortName()) - if err != nil { - return errors.Wrapf(err, "Failed linking external router port to external switch port") - } + // Associate external router port to chassis group. + err = client.LogicalRouterPortLinkChassisGroup(n.getRouterExtPortName(), n.getChassisGroupName()) + if err != nil { + return errors.Wrapf(err, "Failed linking external router port to chassis group") + } - // Create external switch port and link to external provider network. - err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchProviderPortName(), false) - if err != nil { - return errors.Wrapf(err, "Failed adding external switch provider port") - } - revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchProviderPortName()) }) + // Create external switch port and link to router port. + err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchRouterPortName(), false) + if err != nil { + return errors.Wrapf(err, "Failed adding external switch router port") + } + revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchRouterPortName()) }) - err = client.LogicalSwitchPortLinkProviderNetwork(n.getExtSwitchProviderPortName(), parent.extSwitchProviderName) - if err != nil { - return errors.Wrapf(err, "Failed linking external switch provider port to external provider network") + err = client.LogicalSwitchPortLinkRouter(n.getExtSwitchRouterPortName(), n.getRouterExtPortName()) + if err != nil { + return errors.Wrapf(err, "Failed linking external router port to external switch port") + } + + // Create external switch port and link to external provider network. + err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchProviderPortName(), false) + if err != nil { + return errors.Wrapf(err, "Failed adding external switch provider port") + } + revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchProviderPortName()) }) + + err = client.LogicalSwitchPortLinkProviderNetwork(n.getExtSwitchProviderPortName(), parent.extSwitchProviderName) + if err != nil { + return errors.Wrapf(err, "Failed linking external switch provider port to external provider network") + } } // Create internal logical switch if not updating. From 3099041494bec4a42bb53e75c5a85f30e50718f6 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 2 Oct 2020 15:58:44 +0100 Subject: [PATCH 10/13] lxd/network/driver/ovn: Removes old comment Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 2c0a5ae001..bc0404218e 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -1149,8 +1149,6 @@ func (n *ovn) setup(update bool) error { return errors.Wrapf(err, "Failed setting IP allocation settings on internal switch") } - // Find MAC address for internal router port. - var dhcpv4UUID, dhcpv6UUID string if update { From e9fc96df5e28540c5a213e5895134d7589c26c9a Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Mon, 5 Oct 2020 16:20:45 +0100 Subject: [PATCH 11/13] lxd/network/driver/ovn: Fix sentence in startParentPortBridge error Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index bc0404218e..6b98923523 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -648,7 +648,7 @@ func (n *ovn) startParentPortBridge(parentNet Network) error { fmt.Sprintf("net.ipv6.conf.%s.forwarding=0", vars.ovsEnd), ) if err != nil { - return errors.Wrapf(err, "Failed to set configure uplink veth interfaces %q and %q", vars.parentEnd, vars.ovsEnd) + return errors.Wrapf(err, "Failed to configure uplink veth interfaces %q and %q", vars.parentEnd, vars.ovsEnd) } // Connect parent end of veth pair to parent bridge and bring up. From 137fcbb8b0813eba045c8f2972b2df465a9b9735 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 6 Oct 2020 09:58:58 +0100 Subject: [PATCH 12/13] lxd/network/driver/ovn: Fixes error message in setupParentPortBridge Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/driver_ovn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go index 6b98923523..99423d4b3c 100644 --- a/lxd/network/driver_ovn.go +++ b/lxd/network/driver_ovn.go @@ -383,7 +383,7 @@ func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAdd v, err := n.allocateParentPortIPs(parentNet, "ipv4.address", "ipv6.address", routerMAC) if err != nil { - return nil, errors.Wrapf(err, "Failed allocating parent port IPs on network", parentNet.Name()) + return nil, errors.Wrapf(err, "Failed allocating parent port IPs on network %q", parentNet.Name()) } return v, nil From df0a848f3d9c889b7bd72e1401c850a1584a711a Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Tue, 6 Oct 2020 10:27:37 +0100 Subject: [PATCH 13/13] lxd/network/network/utils: Moves bridge related functions into own file Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/network/network_utils.go | 82 ------------------------- lxd/network/network_utils_bridge.go | 93 +++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 82 deletions(-) create mode 100644 lxd/network/network_utils_bridge.go diff --git a/lxd/network/network_utils.go b/lxd/network/network_utils.go index 4723340161..010a00978c 100644 --- a/lxd/network/network_utils.go +++ b/lxd/network/network_utils.go @@ -24,7 +24,6 @@ import ( "github.com/lxc/lxd/lxd/dnsmasq/dhcpalloc" "github.com/lxc/lxd/lxd/instance" "github.com/lxc/lxd/lxd/instance/instancetype" - "github.com/lxc/lxd/lxd/network/openvswitch" "github.com/lxc/lxd/lxd/project" "github.com/lxc/lxd/lxd/state" "github.com/lxc/lxd/shared" @@ -250,47 +249,6 @@ func isInUseByDevices(s *state.State, networkProjectName string, networkName str return false, nil } -// IsNativeBridge returns whether the bridge name specified is a Linux native bridge. -func IsNativeBridge(bridgeName string) bool { - return shared.PathExists(fmt.Sprintf("/sys/class/net/%s/bridge", bridgeName)) -} - -// AttachInterface attaches an interface to a bridge. -func AttachInterface(bridgeName string, devName string) error { - if IsNativeBridge(bridgeName) { - _, err := shared.RunCommand("ip", "link", "set", "dev", devName, "master", bridgeName) - if err != nil { - return err - } - } else { - ovs := openvswitch.NewOVS() - err := ovs.BridgePortAdd(bridgeName, devName, true) - if err != nil { - return err - } - } - - return nil -} - -// DetachInterface detaches an interface from a bridge. -func DetachInterface(bridgeName string, devName string) error { - if IsNativeBridge(bridgeName) { - _, err := shared.RunCommand("ip", "link", "set", "dev", devName, "nomaster") - if err != nil { - return err - } - } else { - ovs := openvswitch.NewOVS() - err := ovs.BridgePortDelete(bridgeName, devName) - if err != nil { - return err - } - } - - return nil -} - // GetDevMTU retrieves the current MTU setting for a named network device. func GetDevMTU(devName string) (uint32, error) { content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/mtu", devName)) @@ -932,46 +890,6 @@ func usesIPv6Firewall(netConfig map[string]string) bool { return false } -// BridgeVLANFilteringStatus returns whether VLAN filtering is enabled on a bridge interface. -func BridgeVLANFilteringStatus(interfaceName string) (string, error) { - content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName)) - if err != nil { - return "", errors.Wrapf(err, "Failed getting bridge VLAN status for %q", interfaceName) - } - - return strings.TrimSpace(fmt.Sprintf("%s", content)), nil -} - -// BridgeVLANFilterSetStatus sets the status of VLAN filtering on a bridge interface. -func BridgeVLANFilterSetStatus(interfaceName string, status string) error { - err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName), []byte(status), 0) - if err != nil { - return errors.Wrapf(err, "Failed enabling VLAN filtering on bridge %q", interfaceName) - } - - return nil -} - -// BridgeVLANDefaultPVID returns the VLAN default port VLAN ID (PVID). -func BridgeVLANDefaultPVID(interfaceName string) (string, error) { - content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName)) - if err != nil { - return "", errors.Wrapf(err, "Failed getting bridge VLAN default PVID for %q", interfaceName) - } - - return strings.TrimSpace(fmt.Sprintf("%s", content)), nil -} - -// BridgeVLANSetDefaultPVID sets the VLAN default port VLAN ID (PVID). -func BridgeVLANSetDefaultPVID(interfaceName string, vlanID string) error { - err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName), []byte(vlanID), 0) - if err != nil { - return errors.Wrapf(err, "Failed setting bridge VLAN default PVID for %q", interfaceName) - } - - return nil -} - // RandomHwaddr generates a random MAC address from the provided random source. func randomHwaddr(r *rand.Rand) string { // Generate a new random MAC address using the usual prefix. diff --git a/lxd/network/network_utils_bridge.go b/lxd/network/network_utils_bridge.go new file mode 100644 index 0000000000..f19b313e8d --- /dev/null +++ b/lxd/network/network_utils_bridge.go @@ -0,0 +1,93 @@ +package network + +import ( + "fmt" + "io/ioutil" + "strings" + + "github.com/pkg/errors" + + "github.com/lxc/lxd/lxd/network/openvswitch" + "github.com/lxc/lxd/shared" +) + +// BridgeVLANFilteringStatus returns whether VLAN filtering is enabled on a bridge interface. +func BridgeVLANFilteringStatus(interfaceName string) (string, error) { + content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName)) + if err != nil { + return "", errors.Wrapf(err, "Failed getting bridge VLAN status for %q", interfaceName) + } + + return strings.TrimSpace(fmt.Sprintf("%s", content)), nil +} + +// BridgeVLANFilterSetStatus sets the status of VLAN filtering on a bridge interface. +func BridgeVLANFilterSetStatus(interfaceName string, status string) error { + err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName), []byte(status), 0) + if err != nil { + return errors.Wrapf(err, "Failed enabling VLAN filtering on bridge %q", interfaceName) + } + + return nil +} + +// BridgeVLANDefaultPVID returns the VLAN default port VLAN ID (PVID). +func BridgeVLANDefaultPVID(interfaceName string) (string, error) { + content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName)) + if err != nil { + return "", errors.Wrapf(err, "Failed getting bridge VLAN default PVID for %q", interfaceName) + } + + return strings.TrimSpace(fmt.Sprintf("%s", content)), nil +} + +// BridgeVLANSetDefaultPVID sets the VLAN default port VLAN ID (PVID). +func BridgeVLANSetDefaultPVID(interfaceName string, vlanID string) error { + err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName), []byte(vlanID), 0) + if err != nil { + return errors.Wrapf(err, "Failed setting bridge VLAN default PVID for %q", interfaceName) + } + + return nil +} + +// IsNativeBridge returns whether the bridge name specified is a Linux native bridge. +func IsNativeBridge(bridgeName string) bool { + return shared.PathExists(fmt.Sprintf("/sys/class/net/%s/bridge", bridgeName)) +} + +// AttachInterface attaches an interface to a bridge. +func AttachInterface(bridgeName string, devName string) error { + if IsNativeBridge(bridgeName) { + _, err := shared.RunCommand("ip", "link", "set", "dev", devName, "master", bridgeName) + if err != nil { + return err + } + } else { + ovs := openvswitch.NewOVS() + err := ovs.BridgePortAdd(bridgeName, devName, true) + if err != nil { + return err + } + } + + return nil +} + +// DetachInterface detaches an interface from a bridge. +func DetachInterface(bridgeName string, devName string) error { + if IsNativeBridge(bridgeName) { + _, err := shared.RunCommand("ip", "link", "set", "dev", devName, "nomaster") + if err != nil { + return err + } + } else { + ovs := openvswitch.NewOVS() + err := ovs.BridgePortDelete(bridgeName, devName) + if err != nil { + return err + } + } + + return nil +}
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel