[lxc-devel] [lxd/master] Network: Splits host veth helper functions
tomponline on Github
lxc-bot at linuxcontainers.org
Wed Jul 29 14:12:29 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 543 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200729/f036d4c1/attachment.bin>
-------------- next part --------------
From 0cd7e953d6bb9d3e8003befd18326ca7099634fe Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 27 Jul 2020 17:08:37 +0100
Subject: [PATCH 1/9] lxd/network/driver/common: Adds Create function no-op
Most network types don't need this.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/network/driver_common.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lxd/network/driver_common.go b/lxd/network/driver_common.go
index bc26dcaed3..584d90ec7f 100644
--- a/lxd/network/driver_common.go
+++ b/lxd/network/driver_common.go
@@ -362,6 +362,11 @@ func (n *common) delete(clusterNotification bool) error {
return nil
}
+// Create is a no-op.
+func (n *common) Create(clusterNotification bool) error {
+ return nil
+}
+
// HandleHeartbeat is a no-op.
func (n *common) HandleHeartbeat(heartbeatData *cluster.APIHeartbeat) error {
return nil
From 3972cf6937e9e57568d9b49e838cf0f210792520 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 27 Jul 2020 17:09:00 +0100
Subject: [PATCH 2/9] lxd/network/network/interface: Adds Create function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/network/network_interface.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/lxd/network/network_interface.go b/lxd/network/network_interface.go
index cedb68ef31..0bba1fd637 100644
--- a/lxd/network/network_interface.go
+++ b/lxd/network/network_interface.go
@@ -25,6 +25,7 @@ type Network interface {
DHCPv6Ranges() []DHCPRange
// Actions.
+ Create(clusterNotification bool) error
Start() error
Stop() error
Rename(name string) error
From 0a784e9bbbd4ce6686c8ec356b18ff63d14866b6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 27 Jul 2020 17:09:52 +0100
Subject: [PATCH 3/9] lxd/networks: Adds call to network Create in
doNetworksCreate
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/networks.go | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lxd/networks.go b/lxd/networks.go
index c5c25ce106..7f7913e4ec 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -355,6 +355,12 @@ func doNetworksCreate(d *Daemon, req api.NetworksPost, clusterNotification bool)
return err
}
+ // Run initial creation setup for the network driver.
+ err = n.Create(clusterNotification)
+ if err != nil {
+ return err
+ }
+
err = n.Start()
if err != nil {
n.Delete(clusterNotification)
From ebdd0ae69448260a35e26c45ec70ed92bdcd1519 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 29 Jul 2020 12:36:23 +0100
Subject: [PATCH 4/9] lxd/device/device/utils/network: Adds networkDHCPValidIP
For use with multiple NIC types (bridged and ovn).
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/device_utils_network.go | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/lxd/device/device_utils_network.go b/lxd/device/device_utils_network.go
index 01306bd716..c88341c5fe 100644
--- a/lxd/device/device_utils_network.go
+++ b/lxd/device/device_utils_network.go
@@ -1,10 +1,12 @@
package device
import (
+ "bytes"
"crypto/rand"
"encoding/hex"
"fmt"
"io/ioutil"
+ "net"
"strconv"
"strings"
"sync"
@@ -603,3 +605,23 @@ func networkInterfaceBindWait(ifName string) error {
return fmt.Errorf("Bind of interface %q took too long", ifName)
}
+
+// networkDHCPValidIP returns whether an IP fits inside one of the supplied DHCP ranges and subnet.
+func networkDHCPValidIP(subnet *net.IPNet, ranges []network.DHCPRange, IP net.IP) bool {
+ inSubnet := subnet.Contains(IP)
+ if !inSubnet {
+ return false
+ }
+
+ if len(ranges) > 0 {
+ for _, IPRange := range ranges {
+ if bytes.Compare(IP, IPRange.Start) >= 0 && bytes.Compare(IP, IPRange.End) <= 0 {
+ return true
+ }
+ }
+ } else if inSubnet {
+ return true
+ }
+
+ return false
+}
From 04495ec8f82b939be9a8e1f0becc5517d6f2bd46 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 29 Jul 2020 12:36:59 +0100
Subject: [PATCH 5/9] lxd/device/nic/bridged: Removes networkDHCPValidIP
Updates usage to package level networkDHCPValidIP.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/nic_bridged.go | 34 +++++++---------------------------
1 file changed, 7 insertions(+), 27 deletions(-)
diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go
index aaa375f3af..c509126c75 100644
--- a/lxd/device/nic_bridged.go
+++ b/lxd/device/nic_bridged.go
@@ -109,7 +109,7 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
// Check the static IP supplied is valid for the linked network. It should be part of the
// network's subnet, but not necessarily part of the dynamic allocation ranges.
- if !d.networkDHCPValidIP(subnet, nil, net.ParseIP(d.config["ipv4.address"])) {
+ if !networkDHCPValidIP(subnet, nil, net.ParseIP(d.config["ipv4.address"])) {
return fmt.Errorf("Device IP address %q not within network %q subnet", d.config["ipv4.address"], d.config["network"])
}
}
@@ -127,7 +127,7 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
// Check the static IP supplied is valid for the linked network. It should be part of the
// network's subnet, but not necessarily part of the dynamic allocation ranges.
- if !d.networkDHCPValidIP(subnet, nil, net.ParseIP(d.config["ipv6.address"])) {
+ if !networkDHCPValidIP(subnet, nil, net.ParseIP(d.config["ipv6.address"])) {
return fmt.Errorf("Device IP address %q not within network %q subnet", d.config["ipv6.address"], d.config["network"])
}
}
@@ -208,7 +208,7 @@ func (d *nicBridged) validateEnvironment() error {
}
if !shared.PathExists(fmt.Sprintf("/sys/class/net/%s", d.config["parent"])) {
- return fmt.Errorf("Parent device '%s' doesn't exist", d.config["parent"])
+ return fmt.Errorf("Parent device %q doesn't exist", d.config["parent"])
}
return nil
@@ -715,7 +715,7 @@ func (d *nicBridged) allocateFilterIPs(n network.Network) (net.IP, net.IP, error
// Check the existing static DHCP IP is still valid in the subnet & ranges, if not
// then we'll need to generate a new one.
ranges := n.DHCPv4Ranges()
- if d.networkDHCPValidIP(subnet, ranges, curIPv4.IP.To4()) {
+ if networkDHCPValidIP(subnet, ranges, curIPv4.IP.To4()) {
IPv4 = curIPv4.IP.To4()
}
}
@@ -730,7 +730,7 @@ func (d *nicBridged) allocateFilterIPs(n network.Network) (net.IP, net.IP, error
// Check the existing static DHCP IP is still valid in the subnet & ranges, if not
// then we'll need to generate a new one.
ranges := n.DHCPv6Ranges()
- if d.networkDHCPValidIP(subnet, ranges, curIPv6.IP.To16()) {
+ if networkDHCPValidIP(subnet, ranges, curIPv6.IP.To16()) {
IPv6 = curIPv6.IP.To16()
}
}
@@ -787,26 +787,6 @@ func (d *nicBridged) allocateFilterIPs(n network.Network) (net.IP, net.IP, error
return IPv4, IPv6, nil
}
-// networkDHCPValidIP returns whether an IP fits inside one of the supplied DHCP ranges and subnet.
-func (d *nicBridged) networkDHCPValidIP(subnet *net.IPNet, ranges []network.DHCPRange, IP net.IP) bool {
- inSubnet := subnet.Contains(IP)
- if !inSubnet {
- return false
- }
-
- if len(ranges) > 0 {
- for _, IPRange := range ranges {
- if bytes.Compare(IP, IPRange.Start) >= 0 && bytes.Compare(IP, IPRange.End) <= 0 {
- return true
- }
- }
- } else if inSubnet {
- return true
- }
-
- return false
-}
-
// getDHCPFreeIPv4 attempts to find a free IPv4 address for the device.
// It first checks whether there is an existing allocation for the instance.
// If no previous allocation, then a free IP is picked from the ranges configured.
@@ -826,7 +806,7 @@ func (d *nicBridged) getDHCPFreeIPv4(usedIPs map[[4]byte]dnsmasq.DHCPAllocation,
// Lets see if there is already an allocation for our device and that it sits within subnet.
// If there are custom DHCP ranges defined, check also that the IP falls within one of the ranges.
for _, DHCP := range usedIPs {
- if (ctName == DHCP.Name || bytes.Compare(MAC, DHCP.MAC) == 0) && d.networkDHCPValidIP(subnet, dhcpRanges, DHCP.IP) {
+ if (ctName == DHCP.Name || bytes.Compare(MAC, DHCP.MAC) == 0) && networkDHCPValidIP(subnet, dhcpRanges, DHCP.IP) {
return DHCP.IP, nil
}
}
@@ -898,7 +878,7 @@ func (d *nicBridged) getDHCPFreeIPv6(usedIPs map[[16]byte]dnsmasq.DHCPAllocation
// allocations using instance name. If there are custom DHCP ranges defined, check also
// that the IP falls within one of the ranges.
for _, DHCP := range usedIPs {
- if ctName == DHCP.Name && d.networkDHCPValidIP(subnet, dhcpRanges, DHCP.IP) {
+ if ctName == DHCP.Name && networkDHCPValidIP(subnet, dhcpRanges, DHCP.IP) {
return DHCP.IP, nil
}
}
From 92729611c7cbb827a60489d827233871b499f6d9 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 29 Jul 2020 14:32:47 +0100
Subject: [PATCH 6/9] lxd/device/device/utils/networks: Splits
networkSetupHostVethDevice into multiple functions
So that each specific host-side veth feature can be used in isolation without having to use all of them.
This supports applying host-veth limits for OVN NICs without needing the static routes functionality (that will be in OVN itself).
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/device_utils_network.go | 59 +++++++++++++-----------------
1 file changed, 25 insertions(+), 34 deletions(-)
diff --git a/lxd/device/device_utils_network.go b/lxd/device/device_utils_network.go
index c88341c5fe..71295a098d 100644
--- a/lxd/device/device_utils_network.go
+++ b/lxd/device/device_utils_network.go
@@ -337,46 +337,23 @@ func networkCreateTap(hostName string, m deviceConfig.Device) error {
return nil
}
-// networkSetupHostVethDevice configures a nic device's host side veth settings.
-func networkSetupHostVethDevice(s *state.State, device deviceConfig.Device, oldDevice deviceConfig.Device, v map[string]string) error {
- // If not configured, check if volatile data contains the most recently added host_name.
- if device["host_name"] == "" {
- device["host_name"] = v["host_name"]
- }
-
- // If not configured, check if volatile data contains the most recently added hwaddr.
- if device["hwaddr"] == "" {
- device["hwaddr"] = v["hwaddr"]
- }
-
+// networkSetupHostVethRoutes configures a nic device's host side veth routes.
+// Accepts an optional oldDevice that will have its old host routes removed before adding the new device routes.
+// This allows live update of a veth device.
+func networkSetupHostVethRoutes(s *state.State, device deviceConfig.Device, oldDevice deviceConfig.Device, v map[string]string) error {
// Check whether host device resolution succeeded.
if device["host_name"] == "" {
- return fmt.Errorf("Failed to find host side veth name for device \"%s\"", device["name"])
- }
-
- // Refresh tc limits.
- err := networkSetVethLimits(device)
- if err != nil {
- return err
+ return fmt.Errorf("Failed to find host side veth name for device %q", device["name"])
}
// If oldDevice provided, remove old routes if any remain.
if oldDevice != nil {
- // If not configured, copy the volatile host_name into old device to support live updates.
- if oldDevice["host_name"] == "" {
- oldDevice["host_name"] = v["host_name"]
- }
-
- // If not configured, copy the volatile hwaddr into old device to support live updates.
- if oldDevice["hwaddr"] == "" {
- oldDevice["hwaddr"] = v["hwaddr"]
- }
-
+ networkVethFillFromVolatile(oldDevice, v)
networkRemoveVethRoutes(s, oldDevice)
}
// Setup static routes to container.
- err = networkSetVethRoutes(s, device)
+ err := networkSetVethRoutes(s, device)
if err != nil {
return err
}
@@ -384,6 +361,19 @@ func networkSetupHostVethDevice(s *state.State, device deviceConfig.Device, oldD
return nil
}
+// networkVethFillFromVolatile fills veth host_name and hwaddr fields from volatile if not set in device config.
+func networkVethFillFromVolatile(device deviceConfig.Device, volatile map[string]string) {
+ // If not configured, check if volatile data contains the most recently added host_name.
+ if device["host_name"] == "" {
+ device["host_name"] = volatile["host_name"]
+ }
+
+ // If not configured, check if volatile data contains the most recently added hwaddr.
+ if device["hwaddr"] == "" {
+ device["hwaddr"] = volatile["hwaddr"]
+ }
+}
+
// networkSetVethRoutes applies any static routes configured from the host to the container nic.
func networkSetVethRoutes(s *state.State, m deviceConfig.Device) error {
// Decide whether the route should point to the veth parent or the bridge parent.
@@ -476,13 +466,14 @@ func networkRemoveVethRoutes(s *state.State, m deviceConfig.Device) {
}
}
-// networkSetVethLimits applies any network rate limits to the veth device specified in the config.
-func networkSetVethLimits(m deviceConfig.Device) error {
+// networkSetupHostVethLimits applies any network rate limits to the veth device specified in the config.
+func networkSetupHostVethLimits(m deviceConfig.Device) error {
var err error
veth := m["host_name"]
- if !shared.PathExists(fmt.Sprintf("/sys/class/net/%s", veth)) {
- return fmt.Errorf("Unknown or missing host side veth: %s", veth)
+
+ if veth == "" || !shared.PathExists(fmt.Sprintf("/sys/class/net/%s", veth)) {
+ return fmt.Errorf("Unknown or missing host side veth device %q", veth)
}
// Apply max limit
From 292c6df3d7d958f47dcdf9f3d8cbd4c672c9b889 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 29 Jul 2020 14:35:42 +0100
Subject: [PATCH 7/9] lxd/device/nic/bridged: networkVethFillFromVolatile usage
and other host-veth functions
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/nic_bridged.go | 40 +++++++++++++++++++++++++--------------
1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go
index c509126c75..1f77dd13b9 100644
--- a/lxd/device/nic_bridged.go
+++ b/lxd/device/nic_bridged.go
@@ -266,8 +266,17 @@ func (d *nicBridged) Start() (*deviceConfig.RunConfig, error) {
revert.Add(func() { NetworkRemoveInterface(saveData["host_name"]) })
- // Apply and host-side limits and routes.
- err = networkSetupHostVethDevice(d.state, d.config, nil, saveData)
+ // Populate device config with volatile fields if needed.
+ networkVethFillFromVolatile(d.config, saveData)
+
+ // Apply host-side routes.
+ err = networkSetupHostVethRoutes(d.state, d.config, nil, saveData)
+ if err != nil {
+ return nil, err
+ }
+
+ // Apply host-side limits.
+ err = networkSetupHostVethLimits(d.config)
if err != nil {
return nil, err
}
@@ -351,6 +360,9 @@ func (d *nicBridged) Update(oldDevices deviceConfig.Devices, isRunning bool) err
v := d.volatileGet()
+ // Populate device config with volatile fields if needed.
+ networkVethFillFromVolatile(d.config, v)
+
// If instance is running, apply host side limits and filters first before rebuilding
// dnsmasq config below so that existing config can be used as part of the filter removal.
if isRunning {
@@ -359,8 +371,14 @@ func (d *nicBridged) Update(oldDevices deviceConfig.Devices, isRunning bool) err
return err
}
- // Apply and host-side limits and routes.
- err = networkSetupHostVethDevice(d.state, d.config, oldConfig, v)
+ // Apply host-side routes.
+ err = networkSetupHostVethRoutes(d.state, d.config, oldConfig, v)
+ if err != nil {
+ return err
+ }
+
+ // Apply host-side limits.
+ err = networkSetupHostVethLimits(d.config)
if err != nil {
return err
}
@@ -381,12 +399,12 @@ func (d *nicBridged) Update(oldDevices deviceConfig.Devices, isRunning bool) err
// If an IPv6 address has changed, if the instance is running we should bounce the host-side
// veth interface to give the instance a chance to detect the change and re-apply for an
// updated lease with new IP address.
- if d.config["ipv6.address"] != oldConfig["ipv6.address"] && v["host_name"] != "" && shared.PathExists(fmt.Sprintf("/sys/class/net/%s", v["host_name"])) {
- _, err := shared.RunCommand("ip", "link", "set", v["host_name"], "down")
+ if d.config["ipv6.address"] != oldConfig["ipv6.address"] && d.config["host_name"] != "" && shared.PathExists(fmt.Sprintf("/sys/class/net/%s", d.config["host_name"])) {
+ _, err := shared.RunCommand("ip", "link", "set", d.config["host_name"], "down")
if err != nil {
return err
}
- _, err = shared.RunCommand("ip", "link", "set", v["host_name"], "up")
+ _, err = shared.RunCommand("ip", "link", "set", d.config["host_name"], "up")
if err != nil {
return err
}
@@ -412,13 +430,7 @@ func (d *nicBridged) postStop() error {
v := d.volatileGet()
- if d.config["host_name"] == "" {
- d.config["host_name"] = v["host_name"]
- }
-
- if d.config["hwaddr"] == "" {
- d.config["hwaddr"] = v["hwaddr"]
- }
+ networkVethFillFromVolatile(d.config, v)
if d.config["host_name"] != "" && shared.PathExists(fmt.Sprintf("/sys/class/net/%s", d.config["host_name"])) {
// Detach host-side end of veth pair from bridge (required for openvswitch particularly).
From 90d08afc0fd96355dd30425388caf8be2584705b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 29 Jul 2020 14:36:54 +0100
Subject: [PATCH 8/9] lxd/device/nic/p2p: networkVethFillFromVolatile usage and
other host-veth helper functions
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/nic_p2p.go | 38 ++++++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/lxd/device/nic_p2p.go b/lxd/device/nic_p2p.go
index 341ae1ea13..5f5b7ef089 100644
--- a/lxd/device/nic_p2p.go
+++ b/lxd/device/nic_p2p.go
@@ -6,6 +6,7 @@ import (
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
+ "github.com/lxc/lxd/lxd/revert"
"github.com/lxc/lxd/shared"
)
@@ -61,6 +62,9 @@ func (d *nicP2P) Start() (*deviceConfig.RunConfig, error) {
return nil, err
}
+ revert := revert.New()
+ defer revert.Fail()
+
saveData := make(map[string]string)
saveData["host_name"] = d.config["host_name"]
@@ -84,10 +88,20 @@ func (d *nicP2P) Start() (*deviceConfig.RunConfig, error) {
return nil, err
}
- // Apply and host-side limits and routes.
- err = networkSetupHostVethDevice(d.state, d.config, nil, saveData)
+ revert.Add(func() { NetworkRemoveInterface(saveData["host_name"]) })
+
+ // Populate device config with volatile fields if needed.
+ networkVethFillFromVolatile(d.config, saveData)
+
+ // Apply host-side routes.
+ err = networkSetupHostVethRoutes(d.state, d.config, nil, saveData)
+ if err != nil {
+ return nil, err
+ }
+
+ // Apply host-side limits.
+ err = networkSetupHostVethLimits(d.config)
if err != nil {
- NetworkRemoveInterface(saveData["host_name"])
return nil, err
}
@@ -112,6 +126,7 @@ func (d *nicP2P) Start() (*deviceConfig.RunConfig, error) {
}...)
}
+ revert.Success()
return &runConf, nil
}
@@ -130,8 +145,17 @@ func (d *nicP2P) Update(oldDevices deviceConfig.Devices, isRunning bool) error {
v := d.volatileGet()
- // Apply and host-side limits and routes.
- err = networkSetupHostVethDevice(d.state, d.config, oldConfig, v)
+ // Populate device config with volatile fields if needed.
+ networkVethFillFromVolatile(d.config, v)
+
+ // Apply host-side routes.
+ err = networkSetupHostVethRoutes(d.state, d.config, oldConfig, v)
+ if err != nil {
+ return err
+ }
+
+ // Apply host-side limits.
+ err = networkSetupHostVethLimits(d.config)
if err != nil {
return err
}
@@ -156,9 +180,7 @@ func (d *nicP2P) postStop() error {
v := d.volatileGet()
- if d.config["host_name"] == "" {
- d.config["host_name"] = v["host_name"]
- }
+ networkVethFillFromVolatile(d.config, v)
if d.config["host_name"] != "" && shared.PathExists(fmt.Sprintf("/sys/class/net/%s", d.config["host_name"])) {
// Removing host-side end of veth pair will delete the peer end too.
From 1ea421ead29df66024cb45f52d33a9f3a49ca822 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 29 Jul 2020 14:37:56 +0100
Subject: [PATCH 9/9] lxd/device/nic/routed: networkVethFillFromVolatile usage
and other host-veth helper functions
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/nic_routed.go | 125 ++++++++++++++++++++-------------------
1 file changed, 63 insertions(+), 62 deletions(-)
diff --git a/lxd/device/nic_routed.go b/lxd/device/nic_routed.go
index 9eaa638eb3..9a7f963e4c 100644
--- a/lxd/device/nic_routed.go
+++ b/lxd/device/nic_routed.go
@@ -307,9 +307,11 @@ func (d *nicRouted) Update(oldDevices deviceConfig.Devices, isRunning bool) erro
return err
}
+ // Populate device config with volatile fields if needed.
+ networkVethFillFromVolatile(d.config, v)
+
// Apply host-side limits.
- d.config["host_name"] = v["host_name"]
- err = networkSetVethLimits(d.config)
+ err = networkSetupHostVethLimits(d.config)
if err != nil {
return err
}
@@ -322,77 +324,76 @@ func (d *nicRouted) Update(oldDevices deviceConfig.Devices, isRunning bool) erro
func (d *nicRouted) postStart() error {
v := d.volatileGet()
- // If volatile host_name is defined (and it should be), then configure the host-side interface.
- if v["host_name"] != "" {
- // Apply host-side limits.
- d.config["host_name"] = v["host_name"]
- err := networkSetVethLimits(d.config)
- if err != nil {
- return err
- }
+ // Populate device config with volatile fields if needed.
+ networkVethFillFromVolatile(d.config, v)
- // Attempt to disable IPv6 router advertisement acceptance.
- err = util.SysctlSet(fmt.Sprintf("net/ipv6/conf/%s/accept_ra", v["host_name"]), "0")
- if err != nil && !os.IsNotExist(err) {
- return err
- }
+ // Apply host-side limits.
+ err := networkSetupHostVethLimits(d.config)
+ if err != nil {
+ return err
+ }
- // Prevent source address spoofing by requiring a return path.
- err = util.SysctlSet(fmt.Sprintf("net/ipv4/conf/%s/rp_filter", v["host_name"]), "1")
- if err != nil && !os.IsNotExist(err) {
- return err
- }
+ // Attempt to disable IPv6 router advertisement acceptance.
+ err = util.SysctlSet(fmt.Sprintf("net/ipv6/conf/%s/accept_ra", d.config["host_name"]), "0")
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ // Prevent source address spoofing by requiring a return path.
+ err = util.SysctlSet(fmt.Sprintf("net/ipv4/conf/%s/rp_filter", d.config["host_name"]), "1")
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ // Apply firewall rules for reverse path filtering of IPv4 and IPv6.
+ err = d.state.Firewall.InstanceSetupRPFilter(d.inst.Project(), d.inst.Name(), d.name, d.config["host_name"])
+ if err != nil {
+ return errors.Wrapf(err, "Error setting up reverse path filter")
+ }
- // Apply firewall rules for reverse path filtering of IPv4 and IPv6.
- err = d.state.Firewall.InstanceSetupRPFilter(d.inst.Project(), d.inst.Name(), d.name, v["host_name"])
+ if d.config["ipv4.address"] != "" {
+ // Add dummy link-local gateway IPs to the host end of the veth pair. This ensures that
+ // liveness detection of the gateways inside the instance work and ensure that traffic
+ // doesn't periodically halt whilst ARP is re-detected.
+ _, err := shared.RunCommand("ip", "-4", "addr", "add", fmt.Sprintf("%s/32", d.ipv4HostAddress()), "dev", d.config["host_name"])
if err != nil {
- return errors.Wrapf(err, "Error setting up reverse path filter")
+ return err
}
- if d.config["ipv4.address"] != "" {
- // Add dummy link-local gateway IPs to the host end of the veth pair. This ensures that
- // liveness detection of the gateways inside the instance work and ensure that traffic
- // doesn't periodically halt whilst ARP is re-detected.
- _, err := shared.RunCommand("ip", "-4", "addr", "add", fmt.Sprintf("%s/32", d.ipv4HostAddress()), "dev", v["host_name"])
- if err != nil {
- return err
- }
-
- // Add static routes to instance IPs to custom routing tables if specified.
- // This is in addition to the static route added by liblxc to the main routing table, which
- // is still critical to ensure that reverse path filtering doesn't kick in blocking traffic
- // from the instance.
- if d.config["ipv4.host_table"] != "" {
- for _, addr := range strings.Split(d.config["ipv4.address"], ",") {
- addr = strings.TrimSpace(addr)
- _, err := shared.RunCommand("ip", "-4", "route", "add", "table", d.config["ipv4.host_table"], fmt.Sprintf("%s/32", addr), "dev", v["host_name"])
- if err != nil {
- return err
- }
+ // Add static routes to instance IPs to custom routing tables if specified.
+ // This is in addition to the static route added by liblxc to the main routing table, which
+ // is still critical to ensure that reverse path filtering doesn't kick in blocking traffic
+ // from the instance.
+ if d.config["ipv4.host_table"] != "" {
+ for _, addr := range strings.Split(d.config["ipv4.address"], ",") {
+ addr = strings.TrimSpace(addr)
+ _, err := shared.RunCommand("ip", "-4", "route", "add", "table", d.config["ipv4.host_table"], fmt.Sprintf("%s/32", addr), "dev", d.config["host_name"])
+ if err != nil {
+ return err
}
}
}
+ }
- if d.config["ipv6.address"] != "" {
- // Add dummy link-local gateway IPs to the host end of the veth pair. This ensures that
- // liveness detection of the gateways inside the instance work and ensure that traffic
- // doesn't periodically halt whilst NDP is re-detected.
- _, err := shared.RunCommand("ip", "-6", "addr", "add", fmt.Sprintf("%s/128", d.ipv6HostAddress()), "dev", v["host_name"])
- if err != nil {
- return err
- }
+ if d.config["ipv6.address"] != "" {
+ // Add dummy link-local gateway IPs to the host end of the veth pair. This ensures that
+ // liveness detection of the gateways inside the instance work and ensure that traffic
+ // doesn't periodically halt whilst NDP is re-detected.
+ _, err := shared.RunCommand("ip", "-6", "addr", "add", fmt.Sprintf("%s/128", d.ipv6HostAddress()), "dev", d.config["host_name"])
+ if err != nil {
+ return err
+ }
- // Add static routes to instance IPs to custom routing tables if specified.
- // This is in addition to the static route added by liblxc to the main routing table, which
- // is still critical to ensure that reverse path filtering doesn't kick in blocking traffic
- // from the instance.
- if d.config["ipv6.host_table"] != "" {
- for _, addr := range strings.Split(d.config["ipv6.address"], ",") {
- addr = strings.TrimSpace(addr)
- _, err := shared.RunCommand("ip", "-6", "route", "add", "table", d.config["ipv6.host_table"], fmt.Sprintf("%s/128", addr), "dev", v["host_name"])
- if err != nil {
- return err
- }
+ // Add static routes to instance IPs to custom routing tables if specified.
+ // This is in addition to the static route added by liblxc to the main routing table, which
+ // is still critical to ensure that reverse path filtering doesn't kick in blocking traffic
+ // from the instance.
+ if d.config["ipv6.host_table"] != "" {
+ for _, addr := range strings.Split(d.config["ipv6.address"], ",") {
+ addr = strings.TrimSpace(addr)
+ _, err := shared.RunCommand("ip", "-6", "route", "add", "table", d.config["ipv6.host_table"], fmt.Sprintf("%s/128", addr), "dev", d.config["host_name"])
+ if err != nil {
+ return err
}
}
}
More information about the lxc-devel
mailing list