Merge pull request #35 from dnardo/bridge-plugin
bridge: add support for promiscuous mode
This commit is contained in:
commit
a714098daf
@ -40,3 +40,4 @@ If the bridge is missing, the plugin will create one on first use and, if gatewa
|
|||||||
* `mtu` (integer, optional): explicitly set MTU to the specified value. Defaults to the value chosen by the kernel.
|
* `mtu` (integer, optional): explicitly set MTU to the specified value. Defaults to the value chosen by the kernel.
|
||||||
* `hairpinMode` (boolean, optional): set hairpin mode for interfaces on the bridge. Defaults to false.
|
* `hairpinMode` (boolean, optional): set hairpin mode for interfaces on the bridge. Defaults to false.
|
||||||
* `ipam` (dictionary, required): IPAM configuration to be used for this network.
|
* `ipam` (dictionary, required): IPAM configuration to be used for this network.
|
||||||
|
* `promiscMode` (boolean, optional): set promiscuous mode on the bridge. Defaults to false.
|
||||||
|
@ -46,6 +46,7 @@ type NetConf struct {
|
|||||||
IPMasq bool `json:"ipMasq"`
|
IPMasq bool `json:"ipMasq"`
|
||||||
MTU int `json:"mtu"`
|
MTU int `json:"mtu"`
|
||||||
HairpinMode bool `json:"hairpinMode"`
|
HairpinMode bool `json:"hairpinMode"`
|
||||||
|
PromiscMode bool `json:"promiscMode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type gwInfo struct {
|
type gwInfo struct {
|
||||||
@ -196,7 +197,7 @@ func bridgeByName(name string) (*netlink.Bridge, error) {
|
|||||||
return br, nil
|
return br, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureBridge(brName string, mtu int) (*netlink.Bridge, error) {
|
func ensureBridge(brName string, mtu int, promiscMode bool) (*netlink.Bridge, error) {
|
||||||
br := &netlink.Bridge{
|
br := &netlink.Bridge{
|
||||||
LinkAttrs: netlink.LinkAttrs{
|
LinkAttrs: netlink.LinkAttrs{
|
||||||
Name: brName,
|
Name: brName,
|
||||||
@ -214,6 +215,12 @@ func ensureBridge(brName string, mtu int) (*netlink.Bridge, error) {
|
|||||||
return nil, fmt.Errorf("could not add %q: %v", brName, err)
|
return nil, fmt.Errorf("could not add %q: %v", brName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if promiscMode {
|
||||||
|
if err := netlink.SetPromiscOn(br); err != nil {
|
||||||
|
return nil, fmt.Errorf("could not set promiscuous mode on %q: %v", brName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Re-fetch link to read all attributes and if it already existed,
|
// Re-fetch link to read all attributes and if it already existed,
|
||||||
// ensure it's really a bridge with similar configuration
|
// ensure it's really a bridge with similar configuration
|
||||||
br, err = bridgeByName(brName)
|
br, err = bridgeByName(brName)
|
||||||
@ -275,7 +282,7 @@ func calcGatewayIP(ipn *net.IPNet) net.IP {
|
|||||||
|
|
||||||
func setupBridge(n *NetConf) (*netlink.Bridge, *current.Interface, error) {
|
func setupBridge(n *NetConf) (*netlink.Bridge, *current.Interface, error) {
|
||||||
// create bridge if necessary
|
// create bridge if necessary
|
||||||
br, err := ensureBridge(n.BrName, n.MTU)
|
br, err := ensureBridge(n.BrName, n.MTU, n.PromiscMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to create bridge %q: %v", n.BrName, err)
|
return nil, nil, fmt.Errorf("failed to create bridge %q: %v", n.BrName, err)
|
||||||
}
|
}
|
||||||
@ -310,6 +317,10 @@ func cmdAdd(args *skel.CmdArgs) error {
|
|||||||
n.IsGW = true
|
n.IsGW = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if n.HairpinMode && n.PromiscMode {
|
||||||
|
return fmt.Errorf("cannot set hairpin mode and promiscous mode at the same time.")
|
||||||
|
}
|
||||||
|
|
||||||
br, brInterface, err := setupBridge(n)
|
br, brInterface, err := setupBridge(n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -583,6 +583,7 @@ var _ = Describe("bridge Operations", func() {
|
|||||||
link, err := netlink.LinkByName(BRNAME)
|
link, err := netlink.LinkByName(BRNAME)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(link.Attrs().Name).To(Equal(BRNAME))
|
Expect(link.Attrs().Name).To(Equal(BRNAME))
|
||||||
|
Expect(link.Attrs().Promisc).To(Equal(0))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
@ -854,4 +855,41 @@ var _ = Describe("bridge Operations", func() {
|
|||||||
delBridgeAddrs(originalNS)
|
delBridgeAddrs(originalNS)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
It("ensure promiscuous mode on bridge", func() {
|
||||||
|
const IFNAME = "bridge0"
|
||||||
|
const EXPECTED_IP = "10.0.0.0/8"
|
||||||
|
const CHANGED_EXPECTED_IP = "10.1.2.3/16"
|
||||||
|
|
||||||
|
conf := &NetConf{
|
||||||
|
NetConf: types.NetConf{
|
||||||
|
CNIVersion: "0.3.1",
|
||||||
|
Name: "testConfig",
|
||||||
|
Type: "bridge",
|
||||||
|
},
|
||||||
|
BrName: IFNAME,
|
||||||
|
IsGW: true,
|
||||||
|
IPMasq: false,
|
||||||
|
HairpinMode: false,
|
||||||
|
PromiscMode: true,
|
||||||
|
MTU: 5000,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := originalNS.Do(func(ns.NetNS) error {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
|
||||||
|
_, _, err := setupBridge(conf)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
// Check if ForceAddress has default value
|
||||||
|
Expect(conf.ForceAddress).To(Equal(false))
|
||||||
|
|
||||||
|
//Check if promiscuous mode is set correctly
|
||||||
|
link, err := netlink.LinkByName("bridge0")
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(link.Attrs().Promisc).To(Equal(1))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user