From 344d343431c014727dcb3abe9eba02e3d7f3e6a9 Mon Sep 17 00:00:00 2001 From: Bruce Ma Date: Sat, 18 May 2019 13:58:33 +0800 Subject: [PATCH] bandwidth: get bandwidth interface in host ns through container interface Signed-off-by: Bruce Ma --- plugins/meta/bandwidth/main.go | 49 ++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/plugins/meta/bandwidth/main.go b/plugins/meta/bandwidth/main.go index 6d800589..d967c932 100644 --- a/plugins/meta/bandwidth/main.go +++ b/plugins/meta/bandwidth/main.go @@ -17,7 +17,6 @@ package main import ( "crypto/sha1" "encoding/json" - "errors" "fmt" "github.com/vishvananda/netlink" @@ -28,6 +27,7 @@ import ( "github.com/containernetworking/cni/pkg/version" "github.com/containernetworking/plugins/pkg/ip" + "github.com/containernetworking/plugins/pkg/ns" bv "github.com/containernetworking/plugins/pkg/utils/buildversion" ) @@ -130,21 +130,35 @@ func getMTU(deviceName string) (int, error) { return link.Attrs().MTU, nil } -func getHostInterface(interfaces []*current.Interface) (*current.Interface, error) { +// get the veth peer of container interface in host namespace +func getHostInterface(interfaces []*current.Interface, containerIfName string, netns ns.NetNS) (*current.Interface, error) { if len(interfaces) == 0 { - return nil, errors.New("no interfaces provided") + return nil, fmt.Errorf("no interfaces provided") } + // get veth peer index of container interface + var peerIndex int var err error + _ = netns.Do(func(_ ns.NetNS) error { + _, peerIndex, err = ip.GetVethPeerIfindex(containerIfName) + return nil + }) + if peerIndex <= 0 { + return nil, fmt.Errorf("container interface %s has no veth peer: %v", containerIfName, err) + } + + // find host interface by index + link, err := netlink.LinkByIndex(peerIndex) + if err != nil { + return nil, fmt.Errorf("veth peer with index %d is not in host ns", peerIndex) + } for _, iface := range interfaces { - if iface.Sandbox == "" { // host interface - _, _, err = ip.GetVethPeerIfindex(iface.Name) - if err == nil { - return iface, err - } + if iface.Sandbox == "" && iface.Name == link.Attrs().Name { + return iface, nil } } - return nil, errors.New(fmt.Sprintf("no host interface found. last error: %s", err)) + + return nil, fmt.Errorf("no veth peer of container interface found in host ns") } func cmdAdd(args *skel.CmdArgs) error { @@ -166,7 +180,14 @@ func cmdAdd(args *skel.CmdArgs) error { if err != nil { return fmt.Errorf("could not convert result to current version: %v", err) } - hostInterface, err := getHostInterface(result.Interfaces) + + netns, err := ns.GetNS(args.Netns) + if err != nil { + return fmt.Errorf("failed to open netns %q: %v", netns, err) + } + defer netns.Close() + + hostInterface, err := getHostInterface(result.Interfaces, args.IfName, netns) if err != nil { return err } @@ -266,7 +287,13 @@ func cmdCheck(args *skel.CmdArgs) error { return fmt.Errorf("could not convert result to current version: %v", err) } - hostInterface, err := getHostInterface(result.Interfaces) + netns, err := ns.GetNS(args.Netns) + if err != nil { + return fmt.Errorf("failed to open netns %q: %v", netns, err) + } + defer netns.Close() + + hostInterface, err := getHostInterface(result.Interfaces, args.IfName, netns) if err != nil { return err }