Skip to content

Commit 9f1f9a5

Browse files
authored
Merge pull request containernetworking#875 from mlguerrero12/adddefaultvlanparam
Add parameter to disable default vlan
2 parents 71aa710 + 821982d commit 9f1f9a5

File tree

2 files changed

+109
-31
lines changed

2 files changed

+109
-31
lines changed

plugins/main/bridge/bridge.go

+45-16
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,18 @@ const defaultBrName = "cni0"
4646

4747
type NetConf struct {
4848
types.NetConf
49-
BrName string `json:"bridge"`
50-
IsGW bool `json:"isGateway"`
51-
IsDefaultGW bool `json:"isDefaultGateway"`
52-
ForceAddress bool `json:"forceAddress"`
53-
IPMasq bool `json:"ipMasq"`
54-
MTU int `json:"mtu"`
55-
HairpinMode bool `json:"hairpinMode"`
56-
PromiscMode bool `json:"promiscMode"`
57-
Vlan int `json:"vlan"`
58-
MacSpoofChk bool `json:"macspoofchk,omitempty"`
59-
EnableDad bool `json:"enabledad,omitempty"`
49+
BrName string `json:"bridge"`
50+
IsGW bool `json:"isGateway"`
51+
IsDefaultGW bool `json:"isDefaultGateway"`
52+
ForceAddress bool `json:"forceAddress"`
53+
IPMasq bool `json:"ipMasq"`
54+
MTU int `json:"mtu"`
55+
HairpinMode bool `json:"hairpinMode"`
56+
PromiscMode bool `json:"promiscMode"`
57+
Vlan int `json:"vlan"`
58+
PreserveDefaultVlan bool `json:"preserveDefaultVlan"`
59+
MacSpoofChk bool `json:"macspoofchk,omitempty"`
60+
EnableDad bool `json:"enabledad,omitempty"`
6061

6162
Args struct {
6263
Cni BridgeArgs `json:"cni,omitempty"`
@@ -94,6 +95,8 @@ func init() {
9495
func loadNetConf(bytes []byte, envArgs string) (*NetConf, string, error) {
9596
n := &NetConf{
9697
BrName: defaultBrName,
98+
// Set default value equal to true to maintain existing behavior.
99+
PreserveDefaultVlan: true,
97100
}
98101
if err := json.Unmarshal(bytes, n); err != nil {
99102
return nil, "", fmt.Errorf("failed to load netconf: %v", err)
@@ -299,7 +302,7 @@ func ensureBridge(brName string, mtu int, promiscMode, vlanFiltering bool) (*net
299302
return br, nil
300303
}
301304

302-
func ensureVlanInterface(br *netlink.Bridge, vlanID int) (netlink.Link, error) {
305+
func ensureVlanInterface(br *netlink.Bridge, vlanID int, preserveDefaultVlan bool) (netlink.Link, error) {
303306
name := fmt.Sprintf("%s.%d", br.Name, vlanID)
304307

305308
brGatewayVeth, err := netlink.LinkByName(name)
@@ -313,7 +316,7 @@ func ensureVlanInterface(br *netlink.Bridge, vlanID int) (netlink.Link, error) {
313316
return nil, fmt.Errorf("faild to find host namespace: %v", err)
314317
}
315318

316-
_, brGatewayIface, err := setupVeth(hostNS, br, name, br.MTU, false, vlanID, "")
319+
_, brGatewayIface, err := setupVeth(hostNS, br, name, br.MTU, false, vlanID, preserveDefaultVlan, "")
317320
if err != nil {
318321
return nil, fmt.Errorf("faild to create vlan gateway %q: %v", name, err)
319322
}
@@ -332,7 +335,7 @@ func ensureVlanInterface(br *netlink.Bridge, vlanID int) (netlink.Link, error) {
332335
return brGatewayVeth, nil
333336
}
334337

335-
func setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairpinMode bool, vlanID int, mac string) (*current.Interface, *current.Interface, error) {
338+
func setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairpinMode bool, vlanID int, preserveDefaultVlan bool, mac string) (*current.Interface, *current.Interface, error) {
336339
contIface := &current.Interface{}
337340
hostIface := &current.Interface{}
338341

@@ -370,6 +373,13 @@ func setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairp
370373
}
371374

372375
if vlanID != 0 {
376+
if !preserveDefaultVlan {
377+
err = removeDefaultVlan(hostVeth)
378+
if err != nil {
379+
return nil, nil, fmt.Errorf("failed to remove default vlan on interface %q: %v", hostIface.Name, err)
380+
}
381+
}
382+
373383
err = netlink.BridgeVlanAdd(hostVeth, uint16(vlanID), true, true, false, true)
374384
if err != nil {
375385
return nil, nil, fmt.Errorf("failed to setup vlan tag on interface %q: %v", hostIface.Name, err)
@@ -379,6 +389,25 @@ func setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairp
379389
return hostIface, contIface, nil
380390
}
381391

392+
func removeDefaultVlan(hostVeth netlink.Link) error {
393+
vlanInfo, err := netlink.BridgeVlanList()
394+
if err != nil {
395+
return err
396+
}
397+
398+
brVlanInfo, ok := vlanInfo[int32(hostVeth.Attrs().Index)]
399+
if ok {
400+
for _, info := range brVlanInfo {
401+
err = netlink.BridgeVlanDel(hostVeth, info.Vid, false, false, false, true)
402+
if err != nil {
403+
return err
404+
}
405+
}
406+
}
407+
408+
return nil
409+
}
410+
382411
func calcGatewayIP(ipn *net.IPNet) net.IP {
383412
nid := ipn.IP.Mask(ipn.Mask)
384413
return ip.NextIP(nid)
@@ -434,7 +463,7 @@ func cmdAdd(args *skel.CmdArgs) error {
434463
}
435464
defer netns.Close()
436465

437-
hostInterface, containerInterface, err := setupVeth(netns, br, args.IfName, n.MTU, n.HairpinMode, n.Vlan, n.mac)
466+
hostInterface, containerInterface, err := setupVeth(netns, br, args.IfName, n.MTU, n.HairpinMode, n.Vlan, n.PreserveDefaultVlan, n.mac)
438467
if err != nil {
439468
return err
440469
}
@@ -523,7 +552,7 @@ func cmdAdd(args *skel.CmdArgs) error {
523552
firstV4Addr = gw.IP
524553
}
525554
if n.Vlan != 0 {
526-
vlanIface, err := ensureVlanInterface(br, n.Vlan)
555+
vlanIface, err := ensureVlanInterface(br, n.Vlan, n.PreserveDefaultVlan)
527556
if err != nil {
528557
return fmt.Errorf("failed to create vlan interface: %v", err)
529558
}

plugins/main/bridge/bridge_test.go

+64-15
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,22 @@ type Net struct {
6565
// testCase defines the CNI network configuration and the expected
6666
// bridge addresses for a test case.
6767
type testCase struct {
68-
cniVersion string // CNI Version
69-
subnet string // Single subnet config: Subnet CIDR
70-
gateway string // Single subnet config: Gateway
71-
ranges []rangeInfo // Ranges list (multiple subnets config)
72-
resolvConf string // host-local resolvConf file path
73-
isGW bool
74-
isLayer2 bool
75-
expGWCIDRs []string // Expected gateway addresses in CIDR form
76-
vlan int
77-
ipMasq bool
78-
macspoofchk bool
79-
AddErr020 string
80-
DelErr020 string
81-
AddErr010 string
82-
DelErr010 string
68+
cniVersion string // CNI Version
69+
subnet string // Single subnet config: Subnet CIDR
70+
gateway string // Single subnet config: Gateway
71+
ranges []rangeInfo // Ranges list (multiple subnets config)
72+
resolvConf string // host-local resolvConf file path
73+
isGW bool
74+
isLayer2 bool
75+
expGWCIDRs []string // Expected gateway addresses in CIDR form
76+
vlan int
77+
removeDefaultVlan bool
78+
ipMasq bool
79+
macspoofchk bool
80+
AddErr020 string
81+
DelErr020 string
82+
AddErr010 string
83+
DelErr010 string
8384

8485
envArgs string // CNI_ARGS
8586
runtimeConfig struct {
@@ -129,6 +130,9 @@ const (
129130
vlan = `,
130131
"vlan": %d`
131132

133+
preserveDefaultVlan = `,
134+
"preserveDefaultVlan": false`
135+
132136
netDefault = `,
133137
"isDefaultGateway": true`
134138

@@ -191,6 +195,10 @@ func (tc testCase) netConfJSON(dataDir string) string {
191195
conf := fmt.Sprintf(netConfStr, tc.cniVersion, BRNAME)
192196
if tc.vlan != 0 {
193197
conf += fmt.Sprintf(vlan, tc.vlan)
198+
199+
if tc.removeDefaultVlan {
200+
conf += preserveDefaultVlan
201+
}
194202
}
195203
if tc.ipMasq {
196204
conf += tc.ipMasqConfig()
@@ -527,6 +535,9 @@ func (tester *testerV10x) cmdAddTest(tc testCase, dataDir string) (types.Result,
527535
vlans, isExist := interfaceMap[int32(peerLink.Attrs().Index)]
528536
Expect(isExist).To(BeTrue())
529537
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
538+
if tc.removeDefaultVlan {
539+
Expect(vlans).To(HaveLen(1))
540+
}
530541
}
531542

532543
// Check the bridge vlan filtering equals true
@@ -582,6 +593,9 @@ func (tester *testerV10x) cmdAddTest(tc testCase, dataDir string) (types.Result,
582593
vlans, isExist := interfaceMap[int32(link.Attrs().Index)]
583594
Expect(isExist).To(BeTrue())
584595
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
596+
if tc.removeDefaultVlan {
597+
Expect(vlans).To(HaveLen(1))
598+
}
585599
}
586600

587601
// Check that the bridge has a different mac from the veth
@@ -832,6 +846,9 @@ func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (types.Result,
832846
vlans, isExist := interfaceMap[int32(peerLink.Attrs().Index)]
833847
Expect(isExist).To(BeTrue())
834848
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
849+
if tc.removeDefaultVlan {
850+
Expect(vlans).To(HaveLen(1))
851+
}
835852
}
836853

837854
// Check the bridge vlan filtering equals true
@@ -887,6 +904,9 @@ func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (types.Result,
887904
vlans, isExist := interfaceMap[int32(link.Attrs().Index)]
888905
Expect(isExist).To(BeTrue())
889906
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
907+
if tc.removeDefaultVlan {
908+
Expect(vlans).To(HaveLen(1))
909+
}
890910
}
891911

892912
// Check that the bridge has a different mac from the veth
@@ -1132,6 +1152,9 @@ func (tester *testerV03x) cmdAddTest(tc testCase, dataDir string) (types.Result,
11321152
vlans, isExist := interfaceMap[int32(peerLink.Attrs().Index)]
11331153
Expect(isExist).To(BeTrue())
11341154
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
1155+
if tc.removeDefaultVlan {
1156+
Expect(vlans).To(HaveLen(1))
1157+
}
11351158
}
11361159

11371160
// Check the bridge vlan filtering equals true
@@ -1187,6 +1210,9 @@ func (tester *testerV03x) cmdAddTest(tc testCase, dataDir string) (types.Result,
11871210
vlans, isExist := interfaceMap[int32(link.Attrs().Index)]
11881211
Expect(isExist).To(BeTrue())
11891212
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
1213+
if tc.removeDefaultVlan {
1214+
Expect(vlans).To(HaveLen(1))
1215+
}
11901216
}
11911217

11921218
// Check that the bridge has a different mac from the veth
@@ -1358,6 +1384,9 @@ func (tester *testerV01xOr02x) cmdAddTest(tc testCase, dataDir string) (types.Re
13581384
vlans, isExist := interfaceMap[int32(peerLink.Attrs().Index)]
13591385
Expect(isExist).To(BeTrue())
13601386
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
1387+
if tc.removeDefaultVlan {
1388+
Expect(vlans).To(HaveLen(1))
1389+
}
13611390
}
13621391

13631392
// Check the bridge vlan filtering equals true
@@ -1480,6 +1509,9 @@ func (tester *testerV01xOr02x) cmdAddTest(tc testCase, dataDir string) (types.Re
14801509
vlans, isExist := hostNSVlanMap[int32(peerIndex)]
14811510
Expect(isExist).To(BeTrue())
14821511
Expect(checkVlan(tc.vlan, vlans)).To(BeTrue())
1512+
if tc.removeDefaultVlan {
1513+
Expect(vlans).To(HaveLen(1))
1514+
}
14831515
}
14841516

14851517
return nil
@@ -1772,6 +1804,18 @@ var _ = Describe("bridge Operations", func() {
17721804
cmdAddDelTest(originalNS, targetNS, tc, dataDir)
17731805
})
17741806

1807+
It(fmt.Sprintf("[%s] configures and deconfigures a l2 bridge with vlan id 100 and no default vlan using ADD/DEL", ver), func() {
1808+
tc := testCase{
1809+
cniVersion: ver,
1810+
isLayer2: true,
1811+
vlan: 100,
1812+
removeDefaultVlan: true,
1813+
AddErr020: "cannot convert: no valid IP addresses",
1814+
AddErr010: "cannot convert: no valid IP addresses",
1815+
}
1816+
cmdAddDelTest(originalNS, targetNS, tc, dataDir)
1817+
})
1818+
17751819
for i, tc := range []testCase{
17761820
{
17771821
// IPv4 only
@@ -1822,6 +1866,11 @@ var _ = Describe("bridge Operations", func() {
18221866
tc.cniVersion = ver
18231867
cmdAddDelTest(originalNS, targetNS, tc, dataDir)
18241868
})
1869+
It(fmt.Sprintf("[%s] (%d) configures and deconfigures a bridge, veth with default route and vlanID 100 and no default vlan with ADD/DEL", ver, i), func() {
1870+
tc.cniVersion = ver
1871+
tc.removeDefaultVlan = true
1872+
cmdAddDelTest(originalNS, targetNS, tc, dataDir)
1873+
})
18251874
}
18261875

18271876
for i, tc := range []testCase{

0 commit comments

Comments
 (0)