From 05baa566c61b435538d890680d87b09b924cc973 Mon Sep 17 00:00:00 2001 From: Martynas Pumputis Date: Thu, 30 Jun 2016 17:06:29 +0100 Subject: [PATCH] Refactor common.GetBridgeNetDev - Optimize. Use LinkByName instead of iterating over list of available links. Linux does not support interfaces with the same names. - Remove unnecessary indirection in utility functions which return common.NetDev. --- common/utils.go | 25 +++++++++++++++++-------- net/netns.go | 10 ++++++++++ plugin/net/cni.go | 11 ++++------- prog/weaveutil/addrs.go | 6 +++++- prog/weaveutil/main.go | 1 + proxy/proxy.go | 6 +++--- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/common/utils.go b/common/utils.go index 7086cd9f54..4189271452 100644 --- a/common/utils.go +++ b/common/utils.go @@ -55,7 +55,7 @@ func FindNetDevs(processID int, match func(link netlink.Link) bool) ([]NetDev, e if err != nil { return err } - netDevs = append(netDevs, *netDev) + netDevs = append(netDevs, netDev) } return nil }) @@ -77,13 +77,13 @@ func forEachLink(f func(netlink.Link) error) error { return nil } -func linkToNetDev(link netlink.Link) (*NetDev, error) { +func linkToNetDev(link netlink.Link) (NetDev, error) { addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { - return nil, err + return NetDev{}, err } - netDev := &NetDev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr} + netDev := NetDev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr} for _, addr := range addrs { netDev.CIDRs = append(netDev.CIDRs, addr.IPNet) } @@ -133,11 +133,20 @@ func GetWeaveNetDevs(processID int) ([]NetDev, error) { }) } -// Get the weave bridge interface -func GetBridgeNetDev(bridgeName string) ([]NetDev, error) { - return FindNetDevs(1, func(link netlink.Link) bool { - return link.Attrs().Name == bridgeName +// Get the weave bridge interface. +func GetBridgeNetDev(bridgeName string) (NetDev, error) { + var netdev NetDev + + err := weavenet.WithNetNSLinkByPid(1, bridgeName, func(link netlink.Link) error { + var err error + netdev, err = linkToNetDev(link) + if err != nil { + return err + } + return nil }) + + return netdev, err } // Do post-attach configuration of all veths we have created diff --git a/net/netns.go b/net/netns.go index aeb8214c79..ac2cea4a50 100644 --- a/net/netns.go +++ b/net/netns.go @@ -35,3 +35,13 @@ func WithNetNSLink(ns netns.NsHandle, ifName string, work func(link netlink.Link return work(link) }) } + +func WithNetNSLinkByPid(pid int, ifName string, work func(link netlink.Link) error) error { + ns, err := netns.GetFromPid(pid) + if err != nil { + return err + } + defer ns.Close() + + return WithNetNSLink(ns, ifName, work) +} diff --git a/plugin/net/cni.go b/plugin/net/cni.go index ec73b5f0af..ac8c1d2c0b 100644 --- a/plugin/net/cni.go +++ b/plugin/net/cni.go @@ -131,23 +131,20 @@ func setupRoutes(link netlink.Link, name string, ipnet net.IPNet, gw net.IP, rou } func findBridgeIP(bridgeName string, subnet net.IPNet) (net.IP, error) { - netdevs, err := common.GetBridgeNetDev(bridgeName) + netdev, err := common.GetBridgeNetDev(bridgeName) if err != nil { return nil, fmt.Errorf("Failed to get netdev for %q bridge: %s", bridgeName, err) } - if len(netdevs) == 0 { - return nil, fmt.Errorf("Could not find %q bridge", bridgeName) - } - if len(netdevs[0].CIDRs) == 0 { + if len(netdev.CIDRs) == 0 { return nil, fmt.Errorf("Bridge %q has no IP addresses; did you forget to run 'weave expose'?", bridgeName) } - for _, cidr := range netdevs[0].CIDRs { + for _, cidr := range netdev.CIDRs { if subnet.Contains(cidr.IP) { return cidr.IP, nil } } // None in the required subnet; just return the first one - return netdevs[0].CIDRs[0].IP, nil + return netdev.CIDRs[0].IP, nil } func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error { diff --git a/prog/weaveutil/addrs.go b/prog/weaveutil/addrs.go index 9c0d45f5b1..3708fc327e 100644 --- a/prog/weaveutil/addrs.go +++ b/prog/weaveutil/addrs.go @@ -41,7 +41,11 @@ func containerAddrs(args []string) error { func getNetDevs(bridgeName string, c *docker.Client, containerID string) ([]common.NetDev, error) { if containerID == "weave:expose" { - return common.GetBridgeNetDev(bridgeName) + if netDev, err := common.GetBridgeNetDev(bridgeName); err != nil { + return nil, err + } else { + return []common.NetDev{netDev}, nil + } } container, err := c.InspectContainer(containerID) diff --git a/prog/weaveutil/main.go b/prog/weaveutil/main.go index 2550d56d6d..da338994ef 100644 --- a/prog/weaveutil/main.go +++ b/prog/weaveutil/main.go @@ -30,6 +30,7 @@ func main() { usage() os.Exit(1) } + cmd, found := commands[os.Args[1]] if !found { usage() diff --git a/proxy/proxy.go b/proxy/proxy.go index 83c4ce10c4..53985ffcc9 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -149,14 +149,14 @@ func NewProxy(c Config) (*Proxy, error) { p.client = client.Client if !p.WithoutDNS { - netDevs, err := common.GetBridgeNetDev(c.DockerBridge) + netDev, err := common.GetBridgeNetDev(c.DockerBridge) if err != nil { return nil, err } - if len(netDevs) != 1 || len(netDevs[0].CIDRs) != 1 { + if len(netDev.CIDRs) != 1 { return nil, fmt.Errorf("Could not obtain address of %s", c.DockerBridge) } - p.dockerBridgeIP = netDevs[0].CIDRs[0].IP.String() + p.dockerBridgeIP = netDev.CIDRs[0].IP.String() } p.hostnameMatchRegexp, err = regexp.Compile(c.HostnameMatch)