Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cni: add promiscous mode knob #98

Merged
merged 1 commit into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ The CNI config json allows the following parameters:
* `deviceID` (string, required): name of an existing macvtap host interface, which
will be moved to the correct net namespace and configured. Optional when used within a
NetworkAttachmentDefinition, as Multus provides the deviceID in that case.
* `promiscMode` (bool, optional): enable promiscous mode on the pod side of the
veth. Defaults to false.

A pod can be attached to that network which would result in the pod having the corresponding
macvtap interface:
Expand Down
7 changes: 4 additions & 3 deletions pkg/cni/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ import (
// A NetConf structure represents a Multus network attachment definition configuration
type NetConf struct {
types.NetConf
DeviceID string `json:"deviceID"`
MTU int `json:"mtu,omitempty"`
DeviceID string `json:"deviceID"`
MTU int `json:"mtu,omitempty"`
IsPromiscuous bool `json:"promiscMode,omitempty"`
}

// EnvArgs structure represents inputs sent from each VMI via environment variables
Expand Down Expand Up @@ -103,7 +104,7 @@ func CmdAdd(args *skel.CmdArgs) error {
}
}()

macvtapInterface, err := util.ConfigureInterface(netConf.DeviceID, args.IfName, mac, netConf.MTU, netns)
macvtapInterface, err := util.ConfigureInterface(netConf.DeviceID, args.IfName, mac, netConf.MTU, netConf.IsPromiscuous, netns)
if err != nil {
return err
}
Expand Down
41 changes: 41 additions & 0 deletions pkg/cni/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,46 @@ var _ = Describe("Macvtap CNI", func() {
})
})
})

When("importing a macvtap interface into the target netns with promiscous mode enabled", func() {
BeforeEach(func() {
promiscousModeArgs := fmt.Sprintf(`{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "macvtap",
"deviceID": "%s",
"promiscMode": true
}`, deviceID)
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNs.Path(),
IfName: deviceID,
StdinData: []byte(promiscousModeArgs),
}

originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, _, err := testutils.CmdAdd(args.Netns, args.ContainerID, args.IfName, args.StdinData, func() error { return cni.CmdAdd(args) })
Expect(err).NotTo(HaveOccurred())

return nil
})
})

It("SHOULD successfully import the macvtap interface into the target netns, having the link promisc mode enabled", func() {
// confirm macvtap is available on target namespace, and the correct configurations were applied
targetNs.Do(func(ns.NetNS) error {
const enabled = 1
defer GinkgoRecover()

link, err := netlink.LinkByName(deviceID)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().Promisc).To(Equal(enabled))

return nil
})
})
})
})
})
8 changes: 7 additions & 1 deletion pkg/util/netlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func onLinkEvent(match func(netlink.Link) bool, nsPath string, do func(), stop <

// Move an existing macvtap interface from the current netns to the target netns, and rename it..
// Optionally configure the MAC address of the interface and the link's MTU.
func ConfigureInterface(currentIfaceName string, newIfaceName string, macAddr *net.HardwareAddr, mtu int, netns ns.NetNS) (*current.Interface, error) {
func ConfigureInterface(currentIfaceName string, newIfaceName string, macAddr *net.HardwareAddr, mtu int, promisc bool, netns ns.NetNS) (*current.Interface, error) {
var err error

macvtapIface, err := netlink.LinkByName(currentIfaceName)
Expand Down Expand Up @@ -263,6 +263,12 @@ func ConfigureInterface(currentIfaceName string, newIfaceName string, macAddr *n
}
}

if promisc {
if err := netlink.SetPromiscOn(macvtapIface); err != nil {
return fmt.Errorf("failed to enable promiscous mode on %q: %v", currentIfaceName, err)
}
}

renamedMacvtapIface, err := renameInterface(macvtapIface, newIfaceName)
if err != nil {
return err
Expand Down