Skip to content

Commit

Permalink
network: Added GetBridgePorts() and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimiter Naydenov committed Sep 5, 2016
1 parent df3f84c commit 71794f9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
29 changes: 29 additions & 0 deletions network/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,32 @@ func ParseInterfaceType(sysPath, interfaceName string) InterfaceType {

return UnknownInterface
}

// GetBridgePorts extracts and returns the names of all interfaces configured as
// ports of the given bridgeName from the Linux kernel userspace SYSFS location
// "<sysPath/<bridgeName>/brif/*". SysClassNetPath should be passed as sysPath.
// Returns an empty result if the ports cannot be determined reliably for any
// reason, or if there are no configured ports for the bridge.
//
// Example call: network.GetBridgePorts(network.SysClassNetPath, "br-eth1")
func GetBridgePorts(sysPath, bridgeName string) []string {
portsGlobPath := filepath.Join(sysPath, bridgeName, "brif", "*")
// Glob ignores I/O errors and can only return ErrBadPattern, which we treat
// as no results, but for debugging we're still logging the error.
paths, err := filepath.Glob(portsGlobPath)
if err != nil {
logger.Debugf("ignoring error traversing path %q: %v", portsGlobPath, err)
}

if len(paths) == 0 {
return nil
}

// We need to convert full paths like /sys/class/net/br-eth0/brif/eth0 to
// just names.
names := make([]string, len(paths))
for i := range paths {
names[i] = filepath.Base(paths[i])
}
return names
}
33 changes: 33 additions & 0 deletions network/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,39 @@ func (*UtilsSuite) TestParseInterfaceType(c *gc.C) {
c.Check(result, gc.Equals, network.UnknownInterface)
}

func (*UtilsSuite) TestGetBridgePorts(c *gc.C) {
fakeSysPath := filepath.Join(c.MkDir(), network.SysClassNetPath)
err := os.MkdirAll(fakeSysPath, 0700)
c.Check(err, jc.ErrorIsNil)

writeFakePorts := func(bridgeName string, portNames ...string) {
fakePortsPath := filepath.Join(fakeSysPath, bridgeName, "brif")
err := os.MkdirAll(fakePortsPath, 0700)
c.Check(err, jc.ErrorIsNil)

for _, portName := range portNames {
portPath := filepath.Join(fakePortsPath, portName)
err = ioutil.WriteFile(portPath, []byte(""), 0644)
c.Check(err, jc.ErrorIsNil)
}
}

result := network.GetBridgePorts(fakeSysPath, "missing")
c.Check(result, gc.IsNil)

writeFakePorts("br-eth0")
result = network.GetBridgePorts(fakeSysPath, "br-eth0")
c.Check(result, gc.IsNil)

writeFakePorts("br-eth0", "eth0")
result = network.GetBridgePorts(fakeSysPath, "br-eth0")
c.Check(result, jc.DeepEquals, []string{"eth0"})

writeFakePorts("br-ovs", "eth0", "eth1", "eth2")
result = network.GetBridgePorts(fakeSysPath, "br-ovs")
c.Check(result, jc.DeepEquals, []string{"eth0", "eth1", "eth2"})
}

type mockListener struct {
net.Listener
}
Expand Down

0 comments on commit 71794f9

Please sign in to comment.