Merge pull request #480 from clinta/macvlan-mac
macvlan: set mac address from args
This commit is contained in:
commit
67175607ad
@ -45,6 +45,17 @@ type NetConf struct {
|
|||||||
Master string `json:"master"`
|
Master string `json:"master"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
MTU int `json:"mtu"`
|
MTU int `json:"mtu"`
|
||||||
|
Mac string `json:"mac,omitempty"`
|
||||||
|
|
||||||
|
RuntimeConfig struct {
|
||||||
|
Mac string `json:"mac,omitempty"`
|
||||||
|
} `json:"runtimeConfig,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MacEnvArgs represents CNI_ARG
|
||||||
|
type MacEnvArgs struct {
|
||||||
|
types.CommonArgs
|
||||||
|
MAC types.UnmarshallableString `json:"mac,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -73,7 +84,7 @@ func getDefaultRouteInterfaceName() (string, error) {
|
|||||||
return "", fmt.Errorf("no default route interface found")
|
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{}
|
n := &NetConf{}
|
||||||
if err := json.Unmarshal(bytes, n); err != nil {
|
if err := json.Unmarshal(bytes, n); err != nil {
|
||||||
return nil, "", fmt.Errorf("failed to load netconf: %v", err)
|
return nil, "", fmt.Errorf("failed to load netconf: %v", err)
|
||||||
@ -95,6 +106,22 @@ func loadConf(bytes []byte) (*NetConf, string, error) {
|
|||||||
return nil, "", fmt.Errorf("invalid MTU %d, must be [0, master MTU(%d)]", n.MTU, masterMTU)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.RuntimeConfig.Mac != "" {
|
||||||
|
n.Mac = n.RuntimeConfig.Mac
|
||||||
|
}
|
||||||
|
|
||||||
return n, n.CNIVersion, nil
|
return n, n.CNIVersion, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,14 +183,24 @@ func createMacvlan(conf *NetConf, ifName string, netns ns.NetNS) (*current.Inter
|
|||||||
return nil, err
|
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{
|
mv := &netlink.Macvlan{
|
||||||
LinkAttrs: netlink.LinkAttrs{
|
LinkAttrs: linkAttrs,
|
||||||
MTU: conf.MTU,
|
Mode: mode,
|
||||||
Name: tmpName,
|
|
||||||
ParentIndex: m.Attrs().Index,
|
|
||||||
Namespace: netlink.NsFd(int(netns.Fd())),
|
|
||||||
},
|
|
||||||
Mode: mode,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := netlink.LinkAdd(mv); err != nil {
|
if err := netlink.LinkAdd(mv); err != nil {
|
||||||
@ -204,7 +241,7 @@ func createMacvlan(conf *NetConf, ifName string, netns ns.NetNS) (*current.Inter
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cmdAdd(args *skel.CmdArgs) error {
|
func cmdAdd(args *skel.CmdArgs) error {
|
||||||
n, cniVersion, err := loadConf(args.StdinData)
|
n, cniVersion, err := loadConf(args.StdinData, args.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -311,7 +348,7 @@ func cmdAdd(args *skel.CmdArgs) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cmdDel(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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -349,7 +386,7 @@ func main() {
|
|||||||
|
|
||||||
func cmdCheck(args *skel.CmdArgs) error {
|
func cmdCheck(args *skel.CmdArgs) error {
|
||||||
|
|
||||||
n, _, err := loadConf(args.StdinData)
|
n, _, err := loadConf(args.StdinData, args.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -594,4 +594,176 @@ var _ = Describe("macvlan Operations", func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("configures and deconfigures l2 macvlan link with mac address (from CNI_ARGS) with CNI v4 ADD/DEL", func() {
|
||||||
|
const IFNAME = "macvl0"
|
||||||
|
|
||||||
|
conf := fmt.Sprintf(`{
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"name": "mynet",
|
||||||
|
"type": "macvlan",
|
||||||
|
"master": "%s",
|
||||||
|
"ipam": {}
|
||||||
|
}`, MASTER_NAME)
|
||||||
|
|
||||||
|
targetNs, err := testutils.NewNS()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
defer targetNs.Close()
|
||||||
|
|
||||||
|
args := &skel.CmdArgs{
|
||||||
|
ContainerID: "dummy",
|
||||||
|
Netns: targetNs.Path(),
|
||||||
|
IfName: IFNAME,
|
||||||
|
StdinData: []byte(conf),
|
||||||
|
Args: "IgnoreUnknown=true;MAC=c2:11:22:33:44:55",
|
||||||
|
}
|
||||||
|
|
||||||
|
var result *current.Result
|
||||||
|
err = originalNS.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
r, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||||
|
return cmdAdd(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
result, err = current.GetResult(r)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(len(result.Interfaces)).To(Equal(1))
|
||||||
|
Expect(result.Interfaces[0].Name).To(Equal(IFNAME))
|
||||||
|
Expect(len(result.IPs)).To(Equal(0))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Make sure macvlan link exists in the target namespace
|
||||||
|
err = targetNs.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
link, err := netlink.LinkByName(IFNAME)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(link.Attrs().Name).To(Equal(IFNAME))
|
||||||
|
|
||||||
|
hwaddr, err := net.ParseMAC("c2:11:22:33:44:55")
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))
|
||||||
|
|
||||||
|
addrs, err := netlink.AddrList(link, syscall.AF_INET)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(len(addrs)).To(Equal(0))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = originalNS.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
err := testutils.CmdDelWithArgs(args, func() error {
|
||||||
|
return cmdDel(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Make sure macvlan link has been deleted
|
||||||
|
err = targetNs.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
link, err := netlink.LinkByName(IFNAME)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(link).To(BeNil())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("configures and deconfigures l2 macvlan link with mac address (from RuntimeConfig) with ADD/DEL", func() {
|
||||||
|
const IFNAME = "macvl0"
|
||||||
|
|
||||||
|
conf := fmt.Sprintf(`{
|
||||||
|
"cniVersion": "0.3.1",
|
||||||
|
"capabilities": {"mac": true},
|
||||||
|
"RuntimeConfig": {
|
||||||
|
"mac": "c2:11:22:33:44:55"
|
||||||
|
},
|
||||||
|
"name": "mynet",
|
||||||
|
"type": "macvlan",
|
||||||
|
"master": "%s",
|
||||||
|
"ipam": {}
|
||||||
|
}`, MASTER_NAME)
|
||||||
|
|
||||||
|
targetNs, err := testutils.NewNS()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
defer targetNs.Close()
|
||||||
|
|
||||||
|
args := &skel.CmdArgs{
|
||||||
|
ContainerID: "dummy",
|
||||||
|
Netns: targetNs.Path(),
|
||||||
|
IfName: IFNAME,
|
||||||
|
StdinData: []byte(conf),
|
||||||
|
}
|
||||||
|
|
||||||
|
var result *current.Result
|
||||||
|
err = originalNS.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
r, _, err := testutils.CmdAddWithArgs(args, func() error {
|
||||||
|
return cmdAdd(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
result, err = current.GetResult(r)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(len(result.Interfaces)).To(Equal(1))
|
||||||
|
Expect(result.Interfaces[0].Name).To(Equal(IFNAME))
|
||||||
|
Expect(len(result.IPs)).To(Equal(0))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Make sure macvlan link exists in the target namespace
|
||||||
|
err = targetNs.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
link, err := netlink.LinkByName(IFNAME)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(link.Attrs().Name).To(Equal(IFNAME))
|
||||||
|
|
||||||
|
hwaddr, err := net.ParseMAC("c2:11:22:33:44:55")
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))
|
||||||
|
|
||||||
|
addrs, err := netlink.AddrList(link, syscall.AF_INET)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(len(addrs)).To(Equal(0))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = originalNS.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
err := testutils.CmdDelWithArgs(args, func() error {
|
||||||
|
return cmdDel(args)
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
// Make sure macvlan link has been deleted
|
||||||
|
err = targetNs.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
link, err := netlink.LinkByName(IFNAME)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(link).To(BeNil())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user