From a1d81c03f30f6d594b8695819a19e6635095f862 Mon Sep 17 00:00:00 2001 From: Clint Armstrong Date: Wed, 29 Apr 2020 23:05:37 -0400 Subject: [PATCH] macvlan: set mac address from CNI_ARGS This change sets the mac address if specified during the creation of the macvlan interface. This is superior to setting it via the tuning plugin because this ensures the mac address is set before an IP is set, allowing a container to get a reserved IP address from DHCP. Related #450 --- plugins/main/macvlan/macvlan.go | 51 ++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/plugins/main/macvlan/macvlan.go b/plugins/main/macvlan/macvlan.go index d290e709c..8388271ba 100644 --- a/plugins/main/macvlan/macvlan.go +++ b/plugins/main/macvlan/macvlan.go @@ -45,6 +45,13 @@ type NetConf struct { Master string `json:"master"` Mode string `json:"mode"` MTU int `json:"mtu"` + Mac string `json:"mac,omitempty"` +} + +// MacEnvArgs represents CNI_ARG +type MacEnvArgs struct { + types.CommonArgs + MAC types.UnmarshallableString `json:"mac,omitempty"` } func init() { @@ -73,7 +80,7 @@ func getDefaultRouteInterfaceName() (string, error) { return "", fmt.Errorf("no default route interface found") } -func loadConf(bytes []byte) (*NetConf, string, error) { +func loadConf(bytes []byte, envArgs string) (*NetConf, string, error) { n := &NetConf{} if err := json.Unmarshal(bytes, n); err != nil { return nil, "", fmt.Errorf("failed to load netconf: %v", err) @@ -95,6 +102,18 @@ func loadConf(bytes []byte) (*NetConf, string, error) { return nil, "", fmt.Errorf("invalid MTU %d, must be [0, master MTU(%d)]", n.MTU, masterMTU) } + if envArgs != "" { + e := MacEnvArgs{} + err := types.LoadArgs(envArgs, &e) + if err != nil { + return nil, "", err + } + + if e.MAC != "" { + n.Mac = string(e.MAC) + } + } + return n, n.CNIVersion, nil } @@ -156,14 +175,24 @@ func createMacvlan(conf *NetConf, ifName string, netns ns.NetNS) (*current.Inter return nil, err } + linkAttrs := netlink.LinkAttrs{ + MTU: conf.MTU, + Name: tmpName, + ParentIndex: m.Attrs().Index, + Namespace: netlink.NsFd(int(netns.Fd())), + } + + if conf.Mac != "" { + addr, err := net.ParseMAC(conf.Mac) + if err != nil { + return nil, fmt.Errorf("invalid args %v for MAC addr: %v", conf.Mac, err) + } + linkAttrs.HardwareAddr = addr + } + mv := &netlink.Macvlan{ - LinkAttrs: netlink.LinkAttrs{ - MTU: conf.MTU, - Name: tmpName, - ParentIndex: m.Attrs().Index, - Namespace: netlink.NsFd(int(netns.Fd())), - }, - Mode: mode, + LinkAttrs: linkAttrs, + Mode: mode, } if err := netlink.LinkAdd(mv); err != nil { @@ -204,7 +233,7 @@ func createMacvlan(conf *NetConf, ifName string, netns ns.NetNS) (*current.Inter } func cmdAdd(args *skel.CmdArgs) error { - n, cniVersion, err := loadConf(args.StdinData) + n, cniVersion, err := loadConf(args.StdinData, args.Args) if err != nil { return err } @@ -311,7 +340,7 @@ func cmdAdd(args *skel.CmdArgs) error { } func cmdDel(args *skel.CmdArgs) error { - n, _, err := loadConf(args.StdinData) + n, _, err := loadConf(args.StdinData, args.Args) if err != nil { return err } @@ -349,7 +378,7 @@ func main() { func cmdCheck(args *skel.CmdArgs) error { - n, _, err := loadConf(args.StdinData) + n, _, err := loadConf(args.StdinData, args.Args) if err != nil { return err }