diff --git a/plugins/main/macvlan/README.md b/plugins/main/macvlan/README.md index 7e8239b1..6653d901 100644 --- a/plugins/main/macvlan/README.md +++ b/plugins/main/macvlan/README.md @@ -23,9 +23,9 @@ Since each macvlan interface has its own MAC address, it makes it easy to use wi * `name` (string, required): the name of the network * `type` (string, required): "macvlan" -* `master` (string, optional): name of the host interface to enslave. Defaults to default route interace. +* `master` (string, optional): name of the host interface to enslave. Defaults to default route interface. * `mode` (string, optional): one of "bridge", "private", "vepa", "passthru". Defaults to "bridge". -* `mtu` (integer, optional): explicitly set MTU to the specified value. Defaults to the value chosen by the kernel. +* `mtu` (integer, optional): explicitly set MTU to the specified value. Defaults to the value chosen by the kernel. The value must be \[0, master's MTU\]. * `ipam` (dictionary, required): IPAM configuration to be used for this network. For interface only without ip address, create empty dictionary. ## Notes diff --git a/plugins/main/macvlan/macvlan.go b/plugins/main/macvlan/macvlan.go index 7ffba21d..d290e709 100644 --- a/plugins/main/macvlan/macvlan.go +++ b/plugins/main/macvlan/macvlan.go @@ -85,9 +85,27 @@ func loadConf(bytes []byte) (*NetConf, string, error) { } n.Master = defaultRouteInterface } + + // check existing and MTU of master interface + masterMTU, err := getMTUByName(n.Master) + if err != nil { + return nil, "", err + } + if n.MTU < 0 || n.MTU > masterMTU { + return nil, "", fmt.Errorf("invalid MTU %d, must be [0, master MTU(%d)]", n.MTU, masterMTU) + } + return n, n.CNIVersion, nil } +func getMTUByName(ifName string) (int, error) { + link, err := netlink.LinkByName(ifName) + if err != nil { + return 0, err + } + return link.Attrs().MTU, nil +} + func modeFromString(s string) (netlink.MacvlanMode, error) { switch s { case "", "bridge":