Skip to content

Commit 77a0cc6

Browse files
committed
macvlan: support chaining for master interface
If "master" is omitted from the macvlan configuration, then macvlan can get master from previous Result which contain a single interface name. Signed-off-by: firemiles <[email protected]>
1 parent 2b097c5 commit 77a0cc6

File tree

2 files changed

+119
-4
lines changed

2 files changed

+119
-4
lines changed

Diff for: plugins/main/macvlan/macvlan.go

+27-4
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,35 @@ func loadConf(args *skel.CmdArgs, envArgs string) (*NetConf, string, error) {
107107
if err := json.Unmarshal(args.StdinData, n); err != nil {
108108
return nil, "", fmt.Errorf("failed to load netconf: %v", err)
109109
}
110-
if n.Master == "" {
111-
defaultRouteInterface, err := getNamespacedDefaultRouteInterfaceName(args.Netns, n.LinkContNs)
110+
111+
var result *current.Result
112+
var err error
113+
// Parse previous result
114+
if n.NetConf.RawPrevResult != nil {
115+
if err = version.ParsePrevResult(&n.NetConf); err != nil {
116+
return nil, "", fmt.Errorf("could not parse prevResult: %v", err)
117+
}
118+
119+
result, err = current.NewResultFromResult(n.PrevResult)
112120
if err != nil {
113-
return nil, "", err
121+
return nil, "", fmt.Errorf("could not convert result to current version: %v", err)
122+
}
123+
}
124+
if n.Master == "" {
125+
if result == nil {
126+
var defaultRouteInterface string
127+
defaultRouteInterface, err = getNamespacedDefaultRouteInterfaceName(args.Netns, n.LinkContNs)
128+
if err != nil {
129+
return nil, "", err
130+
}
131+
n.Master = defaultRouteInterface
132+
} else {
133+
if len(result.Interfaces) == 1 && result.Interfaces[0].Name != "" {
134+
n.Master = result.Interfaces[0].Name
135+
} else {
136+
return nil, "", fmt.Errorf("chained master failure. PrevResult lacks a single named interface")
137+
}
114138
}
115-
n.Master = defaultRouteInterface
116139
}
117140

118141
// check existing and MTU of master interface

Diff for: plugins/main/macvlan/macvlan_test.go

+92
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,98 @@ var _ = Describe("macvlan Operations", func() {
880880
})
881881
Expect(err).NotTo(HaveOccurred())
882882
})
883+
if testutils.SpecVersionHasChaining(ver) {
884+
It(fmt.Sprintf("[%s] configures and deconfigures an l2 macvlan link with ADD/DEL when chained", ver), func() {
885+
const IFNAME = "macvl0"
886+
conf := fmt.Sprintf(`{
887+
"cniVersion": "%s",
888+
"name": "mynet",
889+
"type": "macvlan",
890+
%s
891+
"prevResult": {
892+
"interfaces": [
893+
{
894+
"name": "%s"
895+
}
896+
],
897+
"ips": [
898+
{
899+
"version": "4",
900+
"address": "10.1.2.2/24",
901+
"gateway": "10.1.2.1",
902+
"interface": 0
903+
}
904+
],
905+
"routes": []
906+
}
907+
}`, ver, linkInContainer, masterInterface)
908+
args := &skel.CmdArgs{
909+
ContainerID: "dummy",
910+
Netns: targetNS.Path(),
911+
IfName: IFNAME,
912+
StdinData: []byte(conf),
913+
}
914+
915+
var macAddress string
916+
err := originalNS.Do(func(ns.NetNS) error {
917+
defer GinkgoRecover()
918+
919+
result, _, err := testutils.CmdAddWithArgs(args, func() error {
920+
return cmdAdd(args)
921+
})
922+
923+
t := newTesterByVersion(ver)
924+
macAddress = t.verifyResult(result, err, IFNAME, 0)
925+
return nil
926+
})
927+
Expect(err).NotTo(HaveOccurred())
928+
929+
// Make sure macvlan link exists in the target namespace
930+
err = targetNS.Do(func(ns.NetNS) error {
931+
defer GinkgoRecover()
932+
933+
link, err := netlink.LinkByName(IFNAME)
934+
Expect(err).NotTo(HaveOccurred())
935+
Expect(link.Attrs().Name).To(Equal(IFNAME))
936+
937+
if macAddress != "" {
938+
hwaddr, err := net.ParseMAC(macAddress)
939+
Expect(err).NotTo(HaveOccurred())
940+
Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))
941+
}
942+
943+
addrs, err := netlink.AddrList(link, syscall.AF_INET)
944+
Expect(err).NotTo(HaveOccurred())
945+
Expect(addrs).To(BeEmpty())
946+
return nil
947+
})
948+
Expect(err).NotTo(HaveOccurred())
949+
950+
err = originalNS.Do(func(ns.NetNS) error {
951+
defer GinkgoRecover()
952+
953+
err := testutils.CmdDelWithArgs(args, func() error {
954+
return cmdDel(args)
955+
})
956+
Expect(err).NotTo(HaveOccurred())
957+
return nil
958+
})
959+
Expect(err).NotTo(HaveOccurred())
960+
961+
// Make sure macvlan link has been deleted
962+
err = targetNS.Do(func(ns.NetNS) error {
963+
defer GinkgoRecover()
964+
965+
link, err := netlink.LinkByName(IFNAME)
966+
Expect(err).To(HaveOccurred())
967+
Expect(link).To(BeNil())
968+
return nil
969+
})
970+
Expect(err).NotTo(HaveOccurred())
971+
972+
})
973+
}
974+
883975
}
884976
}
885977
})

0 commit comments

Comments
 (0)