[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