Add LinkSetMacvlanMode

This commit is contained in:
Jaime Caamaño Ruiz 2020-03-04 23:14:25 +01:00 committed by Vish (Ishaya) Abrams
parent e499154279
commit 02121dbd7e
2 changed files with 102 additions and 0 deletions

View File

@ -237,6 +237,37 @@ func (h *Handle) macvlanMACAddrChange(link Link, addrs []net.HardwareAddr, mode
return err
}
// LinkSetMacvlanMode sets the mode of a macvlan or macvtap link device.
// Note that passthrough mode cannot be set to and from and will fail.
// Equivalent to: `ip link set $link type (macvlan|macvtap) mode $mode
func LinkSetMacvlanMode(link Link, mode MacvlanMode) error {
return pkgHandle.LinkSetMacvlanMode(link, mode)
}
// LinkSetMacvlanMode sets the mode of the macvlan or macvtap link device.
// Note that passthrough mode cannot be set to and from and will fail.
// Equivalent to: `ip link set $link type (macvlan|macvtap) mode $mode
func (h *Handle) LinkSetMacvlanMode(link Link, mode MacvlanMode) error {
base := link.Attrs()
h.ensureIndex(base)
req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
msg.Index = int32(base.Index)
req.AddData(msg)
linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type()))
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[mode]))
req.AddData(linkInfo)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
func BridgeSetMcastSnoop(link Link, on bool) error {
return pkgHandle.BridgeSetMcastSnoop(link, on)
}

View File

@ -2576,3 +2576,74 @@ func TestLinkSetAllmulticast(t *testing.T) {
t.Fatalf("RawFlags start value:%d differs from end value:%d", rawFlagsStart, rawFlagsEnd)
}
}
func TestLinkSetMacvlanMode(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()
const (
parentName = "foo"
macvlanName = "fooFoo"
macvtapName = "fooBar"
)
parent := &Dummy{LinkAttrs{Name: parentName}}
if err := LinkAdd(parent); err != nil {
t.Fatal(err)
}
defer LinkDel(parent)
testMacvlanMode := func(link Link, mode MacvlanMode) {
if err := LinkSetMacvlanMode(link, mode); err != nil {
t.Fatal(err)
}
name := link.Attrs().Name
result, err := LinkByName(name)
if err != nil {
t.Fatal(err)
}
var actual MacvlanMode
switch l := result.(type) {
case *Macvlan:
actual = l.Mode
case *Macvtap:
actual = l.Macvlan.Mode
}
if actual != mode {
t.Fatalf("expected %v got %v for %+v", mode, actual, link)
}
}
macvlan := &Macvlan{
LinkAttrs: LinkAttrs{Name: macvlanName, ParentIndex: parent.Attrs().Index},
Mode: MACVLAN_MODE_BRIDGE,
}
if err := LinkAdd(macvlan); err != nil {
t.Fatal(err)
}
defer LinkDel(macvlan)
testMacvlanMode(macvlan, MACVLAN_MODE_VEPA)
testMacvlanMode(macvlan, MACVLAN_MODE_PRIVATE)
testMacvlanMode(macvlan, MACVLAN_MODE_SOURCE)
testMacvlanMode(macvlan, MACVLAN_MODE_BRIDGE)
macvtap := &Macvtap{
Macvlan: Macvlan{
LinkAttrs: LinkAttrs{Name: macvtapName, ParentIndex: parent.Attrs().Index},
Mode: MACVLAN_MODE_BRIDGE,
},
}
if err := LinkAdd(macvtap); err != nil {
t.Fatal(err)
}
defer LinkDel(macvtap)
testMacvlanMode(macvtap, MACVLAN_MODE_VEPA)
testMacvlanMode(macvtap, MACVLAN_MODE_PRIVATE)
testMacvlanMode(macvtap, MACVLAN_MODE_SOURCE)
testMacvlanMode(macvtap, MACVLAN_MODE_BRIDGE)
}