The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7487
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) ===
From 1b2d095d5ae153e254e58db0c0918bd638dcc00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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 }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel