Skip to content

Commit e4dde28

Browse files
committed
Support chaining of VLAN plugin
1 parent 1fb5bf6 commit e4dde28

File tree

2 files changed

+106
-1
lines changed

2 files changed

+106
-1
lines changed

plugins/main/vlan/vlan.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,31 @@ func loadConf(args *skel.CmdArgs) (*NetConf, string, error) {
5252
if err := json.Unmarshal(args.StdinData, n); err != nil {
5353
return nil, "", fmt.Errorf("failed to load netconf: %v", err)
5454
}
55+
56+
// Parse previous result
57+
var result *current.Result
58+
var err error
59+
if n.NetConf.RawPrevResult != nil {
60+
if err = version.ParsePrevResult(&n.NetConf); err != nil {
61+
return nil, "", fmt.Errorf("could not parse prevResult: %v", err)
62+
}
63+
64+
result, err = current.NewResultFromResult(n.PrevResult)
65+
if err != nil {
66+
return nil, "", fmt.Errorf("could not convert result to current version: %v", err)
67+
}
68+
}
69+
5570
if n.Master == "" {
56-
return nil, "", fmt.Errorf("\"master\" field is required. It specifies the host interface name to create the VLAN for")
71+
if result != nil && n.LinkContNs {
72+
// Chaining scenario: CNI_IFNAME used as a master and new IfName is named <Master>.<VlanID>
73+
n.Master = args.IfName
74+
args.IfName = fmt.Sprintf("%s.%d", n.Master, n.VlanID)
75+
} else {
76+
return nil, "", fmt.Errorf("\"master\" field is required. It specifies the host interface name to create the VLAN for")
77+
}
5778
}
79+
5880
if n.VlanID < 0 || n.VlanID > 4094 {
5981
return nil, "", fmt.Errorf("invalid VLAN ID %d (must be between 0 and 4095 inclusive)", n.VlanID)
6082
}

plugins/main/vlan/vlan_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strings"
2323
"syscall"
2424

25+
"github.com/onsi/ginkgo/v2"
2526
. "github.com/onsi/ginkgo/v2"
2627
. "github.com/onsi/gomega"
2728
"github.com/vishvananda/netlink"
@@ -454,6 +455,88 @@ var _ = Describe("vlan Operations", func() {
454455
Expect(err).NotTo(HaveOccurred())
455456
})
456457

458+
Context("When master is not provided", func() {
459+
masterInterface := ""
460+
461+
Context("When used as a chained plugin", func() {
462+
Context("When linkInContainer is true", func() {
463+
It(fmt.Sprintf("[%s] Use IFNAME as a master interface", ver), func() {
464+
if !isInContainer {
465+
ginkgo.Skip("Skipping because linkInContainer is false")
466+
}
467+
468+
var err error
469+
const IFNAME = MASTER_NAME_INCONTAINER
470+
vlanId := 1234
471+
NEWIFNAME := fmt.Sprintf("%s.%d", IFNAME, vlanId)
472+
473+
conf := fmt.Sprintf(`{
474+
"cniVersion": "%s",
475+
"name": "vlanTestv4",
476+
"type": "vlan",
477+
"master": "%s",
478+
"vlanId": %d,
479+
"linkInContainer": %t,
480+
"ipam": {
481+
"type": "host-local",
482+
"subnet": "10.1.2.0/24",
483+
"dataDir": "%s"
484+
},
485+
"prevResult": {
486+
"cniVersion": "%s"
487+
}
488+
}`, ver, masterInterface, vlanId, isInContainer, dataDir, ver)
489+
490+
args := &skel.CmdArgs{
491+
ContainerID: "dummy",
492+
Netns: targetNS.Path(),
493+
IfName: IFNAME,
494+
StdinData: []byte(conf),
495+
}
496+
497+
t := newTesterByVersion(ver)
498+
499+
var result types.Result
500+
var macAddress string
501+
err = originalNS.Do(func(ns.NetNS) error {
502+
defer GinkgoRecover()
503+
504+
var err error
505+
result, _, err = testutils.CmdAddWithArgs(args, func() error {
506+
return cmdAdd(args)
507+
})
508+
Expect(err).NotTo(HaveOccurred())
509+
510+
macAddress = t.verifyResult(result, NEWIFNAME)
511+
return nil
512+
})
513+
Expect(err).NotTo(HaveOccurred())
514+
515+
// Make sure vlan link exists in the target namespace
516+
err = targetNS.Do(func(ns.NetNS) error {
517+
defer GinkgoRecover()
518+
519+
link, err := netlink.LinkByName(NEWIFNAME)
520+
Expect(err).NotTo(HaveOccurred())
521+
Expect(link.Attrs().Name).To(Equal(NEWIFNAME))
522+
523+
if macAddress != "" {
524+
hwaddr, err := net.ParseMAC(macAddress)
525+
Expect(err).NotTo(HaveOccurred())
526+
Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))
527+
}
528+
529+
addrs, err := netlink.AddrList(link, syscall.AF_INET)
530+
Expect(err).NotTo(HaveOccurred())
531+
Expect(addrs).To(HaveLen(1))
532+
return nil
533+
})
534+
Expect(err).NotTo(HaveOccurred())
535+
})
536+
})
537+
})
538+
})
539+
457540
Describe("fails to create vlan link with invalid MTU", func() {
458541
const confFmt = `{
459542
"cniVersion": "%s",

0 commit comments

Comments
 (0)