Skip to content

Commit a714098

Browse files
authored
Merge pull request #35 from dnardo/bridge-plugin
bridge: add support for promiscuous mode
2 parents 409be3d + 9d08b04 commit a714098

3 files changed

Lines changed: 52 additions & 2 deletions

File tree

plugins/main/bridge/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ If the bridge is missing, the plugin will create one on first use and, if gatewa
4040
* `mtu` (integer, optional): explicitly set MTU to the specified value. Defaults to the value chosen by the kernel.
4141
* `hairpinMode` (boolean, optional): set hairpin mode for interfaces on the bridge. Defaults to false.
4242
* `ipam` (dictionary, required): IPAM configuration to be used for this network.
43+
* `promiscMode` (boolean, optional): set promiscuous mode on the bridge. Defaults to false.

plugins/main/bridge/bridge.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type NetConf struct {
4646
IPMasq bool `json:"ipMasq"`
4747
MTU int `json:"mtu"`
4848
HairpinMode bool `json:"hairpinMode"`
49+
PromiscMode bool `json:"promiscMode"`
4950
}
5051

5152
type gwInfo struct {
@@ -196,7 +197,7 @@ func bridgeByName(name string) (*netlink.Bridge, error) {
196197
return br, nil
197198
}
198199

199-
func ensureBridge(brName string, mtu int) (*netlink.Bridge, error) {
200+
func ensureBridge(brName string, mtu int, promiscMode bool) (*netlink.Bridge, error) {
200201
br := &netlink.Bridge{
201202
LinkAttrs: netlink.LinkAttrs{
202203
Name: brName,
@@ -214,6 +215,12 @@ func ensureBridge(brName string, mtu int) (*netlink.Bridge, error) {
214215
return nil, fmt.Errorf("could not add %q: %v", brName, err)
215216
}
216217

218+
if promiscMode {
219+
if err := netlink.SetPromiscOn(br); err != nil {
220+
return nil, fmt.Errorf("could not set promiscuous mode on %q: %v", brName, err)
221+
}
222+
}
223+
217224
// Re-fetch link to read all attributes and if it already existed,
218225
// ensure it's really a bridge with similar configuration
219226
br, err = bridgeByName(brName)
@@ -275,7 +282,7 @@ func calcGatewayIP(ipn *net.IPNet) net.IP {
275282

276283
func setupBridge(n *NetConf) (*netlink.Bridge, *current.Interface, error) {
277284
// create bridge if necessary
278-
br, err := ensureBridge(n.BrName, n.MTU)
285+
br, err := ensureBridge(n.BrName, n.MTU, n.PromiscMode)
279286
if err != nil {
280287
return nil, nil, fmt.Errorf("failed to create bridge %q: %v", n.BrName, err)
281288
}
@@ -310,6 +317,10 @@ func cmdAdd(args *skel.CmdArgs) error {
310317
n.IsGW = true
311318
}
312319

320+
if n.HairpinMode && n.PromiscMode {
321+
return fmt.Errorf("cannot set hairpin mode and promiscous mode at the same time.")
322+
}
323+
313324
br, brInterface, err := setupBridge(n)
314325
if err != nil {
315326
return err

plugins/main/bridge/bridge_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ var _ = Describe("bridge Operations", func() {
583583
link, err := netlink.LinkByName(BRNAME)
584584
Expect(err).NotTo(HaveOccurred())
585585
Expect(link.Attrs().Name).To(Equal(BRNAME))
586+
Expect(link.Attrs().Promisc).To(Equal(0))
586587
return nil
587588
})
588589
Expect(err).NotTo(HaveOccurred())
@@ -854,4 +855,41 @@ var _ = Describe("bridge Operations", func() {
854855
delBridgeAddrs(originalNS)
855856
}
856857
})
858+
It("ensure promiscuous mode on bridge", func() {
859+
const IFNAME = "bridge0"
860+
const EXPECTED_IP = "10.0.0.0/8"
861+
const CHANGED_EXPECTED_IP = "10.1.2.3/16"
862+
863+
conf := &NetConf{
864+
NetConf: types.NetConf{
865+
CNIVersion: "0.3.1",
866+
Name: "testConfig",
867+
Type: "bridge",
868+
},
869+
BrName: IFNAME,
870+
IsGW: true,
871+
IPMasq: false,
872+
HairpinMode: false,
873+
PromiscMode: true,
874+
MTU: 5000,
875+
}
876+
877+
err := originalNS.Do(func(ns.NetNS) error {
878+
defer GinkgoRecover()
879+
880+
_, _, err := setupBridge(conf)
881+
Expect(err).NotTo(HaveOccurred())
882+
// Check if ForceAddress has default value
883+
Expect(conf.ForceAddress).To(Equal(false))
884+
885+
//Check if promiscuous mode is set correctly
886+
link, err := netlink.LinkByName("bridge0")
887+
Expect(err).NotTo(HaveOccurred())
888+
889+
Expect(link.Attrs().Promisc).To(Equal(1))
890+
891+
return nil
892+
})
893+
Expect(err).NotTo(HaveOccurred())
894+
})
857895
})

0 commit comments

Comments
 (0)