[lxc-devel] [lxd/master] Export bridge/bond details

stgraber on Github lxc-bot at linuxcontainers.org
Thu Jun 4 20:59:11 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200604/04ad5c1d/attachment.bin>
-------------- next part --------------
From 1b2d095d5ae153e254e58db0c0918bd638dcc00c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 4 Jun 2020 16:58:13 -0400
Subject: [PATCH 1/3] api: Add network_state_bond_bridge
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/api-extensions.md | 25 ++++++++++++++++++++++++-
 shared/version/api.go |  1 +
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 2c4410be99..ffe908dc68 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -1046,7 +1046,30 @@ This introduces the `dns.search` config option on networks.
 This introduces `limits.ingress`, `limits.egress` and `limits.max` for routed NICs.
 
 ## instance\_nic\_bridged\_vlan
-
 This introduces the `vlan` and `vlan.tagged` settings for `bridged` NICs.
 
 `vlan` specifies the untagged VLAN to join, and `vlan.tagged` is a comma delimited list of tagged VLANs to join.
+
+## network\_state\_bond\_bridge
+This adds a "bridge" and "bond" section to the /1.0/networks/NAME/state API.
+
+Those contain additional state information relevant to those particular types.
+
+Bond:
+
+ - Mode
+ - Transmit hash
+ - Up delay
+ - Down delay
+ - MII frequency
+ - MII state
+ - Lower devices
+
+Bridge:
+
+ - ID
+ - Forward delay
+ - STP mode
+ - Default VLAN
+ - VLAN filtering
+ - Upper devices
diff --git a/shared/version/api.go b/shared/version/api.go
index 532db6ab0c..f5b80fe004 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -213,6 +213,7 @@ var APIExtensions = []string{
 	"network_dns_search",
 	"container_nic_routed_limits",
 	"instance_nic_bridged_vlan",
+	"network_state_bond_bridge",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From 41e0175810f354e0ebc80b7421115db58406063e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 4 Jun 2020 16:58:27 -0400
Subject: [PATCH 2/3] shared/api: Extend NetworkState for bridge/bond
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/api/network.go | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/shared/api/network.go b/shared/api/network.go
index bb6cdf6862..ab23150e8e 100644
--- a/shared/api/network.go
+++ b/shared/api/network.go
@@ -69,6 +69,10 @@ type NetworkState struct {
 	Mtu       int                   `json:"mtu" yaml:"mtu"`
 	State     string                `json:"state" yaml:"state"`
 	Type      string                `json:"type" yaml:"type"`
+
+	// API extension: network_state_bond_bridge
+	Bond   *NetworkStateBond   `json:"bond" yaml:"bond"`
+	Bridge *NetworkStateBridge `json:"bridge" yaml:"bridge"`
 }
 
 // NetworkStateAddress represents a network address
@@ -86,3 +90,30 @@ type NetworkStateCounters struct {
 	PacketsReceived int64 `json:"packets_received" yaml:"packets_received"`
 	PacketsSent     int64 `json:"packets_sent" yaml:"packets_sent"`
 }
+
+// NetworkStateBond represents bond specific state
+// API extension: network_state_bond_bridge
+type NetworkStateBond struct {
+	Mode           string `json:"mode" yaml:"mode"`
+	TransmitPolicy string `json:"transmit_policy" yaml:"transmit_policy"`
+	UpDelay        uint64 `json:"up_delay" yaml:"up_delay"`
+	DownDelay      uint64 `json:"down_delay" yaml:"down_delay"`
+
+	MIIFrequency uint64 `json:"mii_frequency" yaml:"mii_frequency"`
+	MIIState     string `json:"mii_state" yaml:"mii_state"`
+
+	LowerDevices []string `json:"lower_devices" yaml:"lower_devices"`
+}
+
+// NetworkStateBridge represents bond specific state
+// API extension: network_state_bond_bridge
+type NetworkStateBridge struct {
+	ID           string `json:"id" yaml:"id"`
+	STP          bool   `json:"stp" yaml:"stp"`
+	ForwardDelay uint64 `json:"forward_delay" yaml:"forward_delay"`
+
+	VLANDefault   uint64 `json:"vlan_default", yaml:"vlan_default"`
+	VLANFiltering bool   `json:"vlan_filtering", yaml:"vlan_filtering"`
+
+	UpperDevices []string `json:"upper_devices" yaml:"upper_devices"`
+}

From 272358dc785cb847d6d36ecc2b1eca18563a6615 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 4 Jun 2020 16:58:34 -0400
Subject: [PATCH 3/3] lxd/networks: Add bridge/bond details
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #7324

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/networks_utils.go | 120 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 118 insertions(+), 2 deletions(-)

diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index d8e5bf214d..5f6a52820f 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -2,7 +2,9 @@ package main
 
 import (
 	"fmt"
+	"io/ioutil"
 	"net"
+	"path/filepath"
 	"regexp"
 	"strconv"
 	"strings"
@@ -15,6 +17,20 @@ import (
 	"github.com/lxc/lxd/shared/api"
 )
 
+func readUint(path string) (uint64, error) {
+	content, err := ioutil.ReadFile(path)
+	if err != nil {
+		return 0, err
+	}
+
+	value, err := strconv.ParseUint(strings.TrimSpace(string(content)), 10, 64)
+	if err != nil {
+		return 0, err
+	}
+
+	return value, nil
+}
+
 func networkAutoAttach(cluster *db.Cluster, devName string) error {
 	_, dbInfo, err := cluster.GetNetworkWithInterface(devName)
 	if err != nil {
@@ -188,7 +204,7 @@ func networkGetState(netIf net.Interface) api.NetworkState {
 		Type:      netType,
 	}
 
-	// Get address information
+	// Populate address information.
 	addrs, err := netIf.Addrs()
 	if err == nil {
 		for _, addr := range addrs {
@@ -229,7 +245,107 @@ func networkGetState(netIf net.Interface) api.NetworkState {
 		}
 	}
 
-	// Get counters
+	// Populate bond details.
+	bondPath := fmt.Sprintf("/sys/class/net/%s/bonding", netIf.Name)
+	if shared.PathExists(bondPath) {
+		bonding := api.NetworkStateBond{}
+
+		// Bond mode.
+		strValue, err := ioutil.ReadFile(filepath.Join(bondPath, "mode"))
+		if err == nil {
+			bonding.Mode = strings.Split(strings.TrimSpace(string(strValue)), " ")[0]
+		}
+
+		// Bond transmit policy.
+		strValue, err = ioutil.ReadFile(filepath.Join(bondPath, "xmit_hash_policy"))
+		if err == nil {
+			bonding.TransmitPolicy = strings.Split(strings.TrimSpace(string(strValue)), " ")[0]
+		}
+
+		// Up delay.
+		uintValue, err := readUint(filepath.Join(bondPath, "updelay"))
+		if err == nil {
+			bonding.UpDelay = uintValue
+		}
+
+		// Down delay.
+		uintValue, err = readUint(filepath.Join(bondPath, "downdelay"))
+		if err == nil {
+			bonding.DownDelay = uintValue
+		}
+
+		// MII frequency.
+		uintValue, err = readUint(filepath.Join(bondPath, "miimon"))
+		if err == nil {
+			bonding.MIIFrequency = uintValue
+		}
+
+		// MII state.
+		strValue, err = ioutil.ReadFile(filepath.Join(bondPath, "mii_status"))
+		if err == nil {
+			bonding.MIIState = strings.TrimSpace(string(strValue))
+		}
+
+		// Lower devices.
+		strValue, err = ioutil.ReadFile(filepath.Join(bondPath, "slaves"))
+		if err == nil {
+			bonding.LowerDevices = strings.Split(strings.TrimSpace(string(strValue)), " ")
+		}
+
+		network.Bond = &bonding
+	}
+
+	// Populate bridge details.
+	bridgePath := fmt.Sprintf("/sys/class/net/%s/bridge", netIf.Name)
+	if shared.PathExists(bridgePath) {
+		bridge := api.NetworkStateBridge{}
+
+		// Bridge ID.
+		strValue, err := ioutil.ReadFile(filepath.Join(bridgePath, "bridge_id"))
+		if err == nil {
+			bridge.ID = strings.TrimSpace(string(strValue))
+		}
+
+		// Bridge STP.
+		uintValue, err := readUint(filepath.Join(bridgePath, "stp_state"))
+		if err == nil {
+			bridge.STP = uintValue == 1
+		}
+
+		// Bridge forward delay.
+		uintValue, err = readUint(filepath.Join(bridgePath, "forward_delay"))
+		if err == nil {
+			bridge.ForwardDelay = uintValue
+		}
+
+		// Bridge default VLAN.
+		uintValue, err = readUint(filepath.Join(bridgePath, "default_pvid"))
+		if err == nil {
+			bridge.VLANDefault = uintValue
+		}
+
+		// Bridge VLAN filtering.
+		uintValue, err = readUint(filepath.Join(bridgePath, "vlan_filtering"))
+		if err == nil {
+			bridge.VLANFiltering = uintValue == 1
+		}
+
+		// Upper devices.
+		bridgeIfPath := fmt.Sprintf("/sys/class/net/%s/brif", netIf.Name)
+		if shared.PathExists(bridgeIfPath) {
+			entries, err := ioutil.ReadDir(bridgeIfPath)
+			if err == nil {
+				bridge.UpperDevices = []string{}
+				for _, entry := range entries {
+					bridge.UpperDevices = append(bridge.UpperDevices, entry.Name())
+				}
+			}
+		}
+
+		network.Bridge = &bridge
+	}
+
+	// Get counters.
 	network.Counters = shared.NetworkGetCounters(netIf.Name)
 	return network
 }


More information about the lxc-devel mailing list