Skip to content

Commit 14bdce5

Browse files
authored
Merge pull request #997 from ormergi/bridge-cont-iface-state
bridge: Enable disabling bridge interface
2 parents b6a0e0b + 7e131a0 commit 14bdce5

File tree

2 files changed

+104
-34
lines changed

2 files changed

+104
-34
lines changed

plugins/main/bridge/bridge.go

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,20 @@ const defaultBrName = "cni0"
4747

4848
type NetConf struct {
4949
types.NetConf
50-
BrName string `json:"bridge"`
51-
IsGW bool `json:"isGateway"`
52-
IsDefaultGW bool `json:"isDefaultGateway"`
53-
ForceAddress bool `json:"forceAddress"`
54-
IPMasq bool `json:"ipMasq"`
55-
MTU int `json:"mtu"`
56-
HairpinMode bool `json:"hairpinMode"`
57-
PromiscMode bool `json:"promiscMode"`
58-
Vlan int `json:"vlan"`
59-
VlanTrunk []*VlanTrunk `json:"vlanTrunk,omitempty"`
60-
PreserveDefaultVlan bool `json:"preserveDefaultVlan"`
61-
MacSpoofChk bool `json:"macspoofchk,omitempty"`
62-
EnableDad bool `json:"enabledad,omitempty"`
50+
BrName string `json:"bridge"`
51+
IsGW bool `json:"isGateway"`
52+
IsDefaultGW bool `json:"isDefaultGateway"`
53+
ForceAddress bool `json:"forceAddress"`
54+
IPMasq bool `json:"ipMasq"`
55+
MTU int `json:"mtu"`
56+
HairpinMode bool `json:"hairpinMode"`
57+
PromiscMode bool `json:"promiscMode"`
58+
Vlan int `json:"vlan"`
59+
VlanTrunk []*VlanTrunk `json:"vlanTrunk,omitempty"`
60+
PreserveDefaultVlan bool `json:"preserveDefaultVlan"`
61+
MacSpoofChk bool `json:"macspoofchk,omitempty"`
62+
EnableDad bool `json:"enabledad,omitempty"`
63+
DisableContainerInterface bool `json:"disableContainerInterface,omitempty"`
6364

6465
Args struct {
6566
Cni BridgeArgs `json:"cni,omitempty"`
@@ -530,6 +531,10 @@ func cmdAdd(args *skel.CmdArgs) error {
530531

531532
isLayer3 := n.IPAM.Type != ""
532533

534+
if isLayer3 && n.DisableContainerInterface {
535+
return fmt.Errorf("cannot use IPAM when DisableContainerInterface flag is set")
536+
}
537+
533538
if n.IsDefaultGW {
534539
n.IsGW = true
535540
}
@@ -676,12 +681,13 @@ func cmdAdd(args *skel.CmdArgs) error {
676681
}
677682
}
678683
}
679-
} else {
684+
} else if !n.DisableContainerInterface {
680685
if err := netns.Do(func(_ ns.NetNS) error {
681686
link, err := netlink.LinkByName(args.IfName)
682687
if err != nil {
683688
return fmt.Errorf("failed to retrieve link: %v", err)
684689
}
690+
685691
// If layer 2 we still need to set the container veth to up
686692
if err = netlink.LinkSetUp(link); err != nil {
687693
return fmt.Errorf("failed to set %q up: %v", args.IfName, err)
@@ -692,23 +698,28 @@ func cmdAdd(args *skel.CmdArgs) error {
692698
}
693699
}
694700

695-
var hostVeth netlink.Link
701+
hostVeth, err := netlink.LinkByName(hostInterface.Name)
702+
if err != nil {
703+
return err
704+
}
696705

697-
// check bridge port state
698-
retries := []int{0, 50, 500, 1000, 1000}
699-
for idx, sleep := range retries {
700-
time.Sleep(time.Duration(sleep) * time.Millisecond)
706+
if !n.DisableContainerInterface {
707+
// check bridge port state
708+
retries := []int{0, 50, 500, 1000, 1000}
709+
for idx, sleep := range retries {
710+
time.Sleep(time.Duration(sleep) * time.Millisecond)
701711

702-
hostVeth, err = netlink.LinkByName(hostInterface.Name)
703-
if err != nil {
704-
return err
705-
}
706-
if hostVeth.Attrs().OperState == netlink.OperUp {
707-
break
708-
}
712+
hostVeth, err = netlink.LinkByName(hostInterface.Name)
713+
if err != nil {
714+
return err
715+
}
716+
if hostVeth.Attrs().OperState == netlink.OperUp {
717+
break
718+
}
709719

710-
if idx == len(retries)-1 {
711-
return fmt.Errorf("bridge port in error state: %s", hostVeth.Attrs().OperState)
720+
if idx == len(retries)-1 {
721+
return fmt.Errorf("bridge port in error state: %s", hostVeth.Attrs().OperState)
722+
}
712723
}
713724
}
714725

plugins/main/bridge/bridge_test.go

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,12 @@ type testCase struct {
7878
removeDefaultVlan bool
7979
ipMasq bool
8080
macspoofchk bool
81-
AddErr020 string
82-
DelErr020 string
83-
AddErr010 string
84-
DelErr010 string
81+
disableContIface bool
82+
83+
AddErr020 string
84+
DelErr020 string
85+
AddErr010 string
86+
DelErr010 string
8587

8688
envArgs string // CNI_ARGS
8789
runtimeConfig struct {
@@ -154,6 +156,9 @@ const (
154156
netDefault = `,
155157
"isDefaultGateway": true`
156158

159+
disableContainerInterface = `,
160+
"disableContainerInterface": true`
161+
157162
ipamStartStr = `,
158163
"ipam": {
159164
"type": "host-local"`
@@ -248,6 +253,10 @@ func (tc testCase) netConfJSON(dataDir string) string {
248253
conf += fmt.Sprintf(macspoofchkFormat, tc.macspoofchk)
249254
}
250255

256+
if tc.disableContIface {
257+
conf += disableContainerInterface
258+
}
259+
251260
if !tc.isLayer2 {
252261
conf += netDefault
253262
if tc.subnet != "" || tc.ranges != nil {
@@ -677,14 +686,16 @@ func (tester *testerV10x) cmdAddTest(tc testCase, dataDir string) (types.Result,
677686
Expect(err).NotTo(HaveOccurred())
678687
Expect(link.Attrs().Name).To(Equal(IFNAME))
679688
Expect(link).To(BeAssignableToTypeOf(&netlink.Veth{}))
689+
assertContainerInterfaceLinkState(&tc, link)
680690

681691
expCIDRsV4, expCIDRsV6 := tc.expectedCIDRs()
682692
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
683693
Expect(err).NotTo(HaveOccurred())
684694
Expect(addrs).To(HaveLen(len(expCIDRsV4)))
685695
addrs, err = netlink.AddrList(link, netlink.FAMILY_V6)
686-
Expect(addrs).To(HaveLen(len(expCIDRsV6) + 1)) // add one for the link-local
687696
Expect(err).NotTo(HaveOccurred())
697+
assertIPv6Addresses(&tc, addrs, expCIDRsV6)
698+
688699
// Ignore link local address which may or may not be
689700
// ready when we read addresses.
690701
var foundAddrs int
@@ -728,6 +739,15 @@ func (tester *testerV10x) cmdAddTest(tc testCase, dataDir string) (types.Result,
728739
return result, nil
729740
}
730741

742+
func assertContainerInterfaceLinkState(tc *testCase, link netlink.Link) {
743+
linkState := int(link.Attrs().OperState)
744+
if tc.disableContIface {
745+
Expect(linkState).ToNot(Equal(netlink.OperUp))
746+
} else {
747+
Expect(linkState).To(Equal(netlink.OperUp))
748+
}
749+
}
750+
731751
func (tester *testerV10x) cmdCheckTest(tc testCase, conf *Net, _ string) {
732752
// Generate network config and command arguments
733753
tester.args = tc.createCheckCmdArgs(tester.targetNS, conf)
@@ -1008,8 +1028,9 @@ func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (types.Result,
10081028
Expect(err).NotTo(HaveOccurred())
10091029
Expect(addrs).To(HaveLen(len(expCIDRsV4)))
10101030
addrs, err = netlink.AddrList(link, netlink.FAMILY_V6)
1011-
Expect(addrs).To(HaveLen(len(expCIDRsV6) + 1)) // add one for the link-local
10121031
Expect(err).NotTo(HaveOccurred())
1032+
assertIPv6Addresses(&tc, addrs, expCIDRsV6)
1033+
10131034
// Ignore link local address which may or may not be
10141035
// ready when we read addresses.
10151036
var foundAddrs int
@@ -1053,6 +1074,14 @@ func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (types.Result,
10531074
return result, nil
10541075
}
10551076

1077+
func assertIPv6Addresses(tc *testCase, addrs []netlink.Addr, expCIDRsV6 []*net.IPNet) {
1078+
if tc.disableContIface {
1079+
Expect(addrs).To(BeEmpty())
1080+
} else {
1081+
Expect(addrs).To(HaveLen(len(expCIDRsV6) + 1)) // add one for the link-local
1082+
}
1083+
}
1084+
10561085
func (tester *testerV04x) cmdCheckTest(tc testCase, conf *Net, _ string) {
10571086
// Generate network config and command arguments
10581087
tester.args = tc.createCheckCmdArgs(tester.targetNS, conf)
@@ -2461,6 +2490,36 @@ var _ = Describe("bridge Operations", func() {
24612490
return nil
24622491
})).To(Succeed())
24632492
})
2493+
2494+
It(fmt.Sprintf("[%s] should fail when both IPAM and DisableContainerInterface are set", ver), func() {
2495+
Expect(originalNS.Do(func(ns.NetNS) error {
2496+
defer GinkgoRecover()
2497+
tc := testCase{
2498+
cniVersion: ver,
2499+
subnet: "10.1.2.0/24",
2500+
disableContIface: true,
2501+
}
2502+
args := tc.createCmdArgs(targetNS, dataDir)
2503+
Expect(cmdAdd(args)).To(HaveOccurred())
2504+
2505+
return nil
2506+
})).To(Succeed())
2507+
})
2508+
2509+
It(fmt.Sprintf("[%s] should set the container veth peer state down", ver), func() {
2510+
Expect(originalNS.Do(func(ns.NetNS) error {
2511+
defer GinkgoRecover()
2512+
tc := testCase{
2513+
cniVersion: ver,
2514+
disableContIface: true,
2515+
isLayer2: true,
2516+
AddErr020: "cannot convert: no valid IP addresses",
2517+
AddErr010: "cannot convert: no valid IP addresses",
2518+
}
2519+
cmdAddDelTest(originalNS, targetNS, tc, dataDir)
2520+
return nil
2521+
})).To(Succeed())
2522+
})
24642523
}
24652524

24662525
It("check vlan id when loading net conf", func() {

0 commit comments

Comments
 (0)