mirror of
https://github.com/vishvananda/netlink
synced 2025-02-15 03:26:55 +00:00
Add support for BR_PROXYARP and BR_PROXYARP_WIFI.
Bridge ports can be set to use the proxy arp features by calling either LinkSetBrProxyArp() or LinkSetBrProxyArpWiFi(). Signed-off-by: David Wilder <wilder@us.ibm.com>
This commit is contained in:
parent
838b9b5fcb
commit
b71e0bb214
@ -1288,6 +1288,22 @@ func (h *Handle) LinkSetFlood(link Link, mode bool) error {
|
||||
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_UNICAST_FLOOD)
|
||||
}
|
||||
|
||||
func LinkSetBrProxyArp(link Link, mode bool) error {
|
||||
return pkgHandle.LinkSetBrProxyArp(link, mode)
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetBrProxyArp(link Link, mode bool) error {
|
||||
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP)
|
||||
}
|
||||
|
||||
func LinkSetBrProxyArpWiFi(link Link, mode bool) error {
|
||||
return pkgHandle.LinkSetBrProxyArpWiFi(link, mode)
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetBrProxyArpWiFi(link Link, mode bool) error {
|
||||
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP_WIFI)
|
||||
}
|
||||
|
||||
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
|
@ -102,7 +102,10 @@ const (
|
||||
IFLA_BRPORT_FAST_LEAVE
|
||||
IFLA_BRPORT_LEARNING
|
||||
IFLA_BRPORT_UNICAST_FLOOD
|
||||
IFLA_BRPORT_MAX = IFLA_BRPORT_UNICAST_FLOOD
|
||||
IFLA_BRPORT_PROXYARP
|
||||
IFLA_BRPORT_LEARNING_SYNC
|
||||
IFLA_BRPORT_PROXYARP_WIFI
|
||||
IFLA_BRPORT_MAX = IFLA_BRPORT_PROXYARP_WIFI
|
||||
)
|
||||
|
||||
const (
|
||||
|
20
protinfo.go
20
protinfo.go
@ -6,12 +6,14 @@ import (
|
||||
|
||||
// Protinfo represents bridge flags from netlink.
|
||||
type Protinfo struct {
|
||||
Hairpin bool
|
||||
Guard bool
|
||||
FastLeave bool
|
||||
RootBlock bool
|
||||
Learning bool
|
||||
Flood bool
|
||||
Hairpin bool
|
||||
Guard bool
|
||||
FastLeave bool
|
||||
RootBlock bool
|
||||
Learning bool
|
||||
Flood bool
|
||||
ProxyArp bool
|
||||
ProxyArpWiFi bool
|
||||
}
|
||||
|
||||
// String returns a list of enabled flags
|
||||
@ -35,6 +37,12 @@ func (prot *Protinfo) String() string {
|
||||
if prot.Flood {
|
||||
boolStrings = append(boolStrings, "Flood")
|
||||
}
|
||||
if prot.ProxyArp {
|
||||
boolStrings = append(boolStrings, "ProxyArp")
|
||||
}
|
||||
if prot.ProxyArpWiFi {
|
||||
boolStrings = append(boolStrings, "ProxyArpWiFi")
|
||||
}
|
||||
return strings.Join(boolStrings, " ")
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,10 @@ func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
|
||||
pi.Learning = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_UNICAST_FLOOD:
|
||||
pi.Flood = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_PROXYARP:
|
||||
pi.ProxyArp = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_PROXYARP_WIFI:
|
||||
pi.ProxyArpWiFi = byteToBool(info.Value[0])
|
||||
}
|
||||
}
|
||||
return &pi
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
package netlink
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProtinfo(t *testing.T) {
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
@ -14,6 +17,7 @@ func TestProtinfo(t *testing.T) {
|
||||
iface1 := &Dummy{LinkAttrs{Name: "bar1", MasterIndex: master.Index}}
|
||||
iface2 := &Dummy{LinkAttrs{Name: "bar2", MasterIndex: master.Index}}
|
||||
iface3 := &Dummy{LinkAttrs{Name: "bar3"}}
|
||||
iface4 := &Dummy{LinkAttrs{Name: "bar4", MasterIndex: master.Index}}
|
||||
|
||||
if err := LinkAdd(iface1); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -24,6 +28,9 @@ func TestProtinfo(t *testing.T) {
|
||||
if err := LinkAdd(iface3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := LinkAdd(iface4); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
oldpi1, err := LinkGetProtinfo(iface1)
|
||||
if err != nil {
|
||||
@ -33,6 +40,10 @@ func TestProtinfo(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
oldpi4, err := LinkGetProtinfo(iface4)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkSetHairpin(iface1, true); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -52,6 +63,12 @@ func TestProtinfo(t *testing.T) {
|
||||
if !pi1.RootBlock {
|
||||
t.Fatalf("RootBlock is not enabled for %s, but should", iface1.Name)
|
||||
}
|
||||
if pi1.ProxyArp != oldpi1.ProxyArp {
|
||||
t.Fatalf("ProxyArp field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.ProxyArpWiFi != oldpi1.ProxyArp {
|
||||
t.Fatalf("ProxyArpWiFi ProxyArp field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.Guard != oldpi1.Guard {
|
||||
t.Fatalf("Guard field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
@ -81,6 +98,12 @@ func TestProtinfo(t *testing.T) {
|
||||
if !pi2.Guard {
|
||||
t.Fatalf("Guard is not enabled for %s, but should", iface2.Name)
|
||||
}
|
||||
if pi2.ProxyArp != oldpi2.ProxyArp {
|
||||
t.Fatalf("ProxyArp field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.ProxyArpWiFi != oldpi2.ProxyArpWiFi {
|
||||
t.Fatalf("ProxyArpWiFi field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.Learning {
|
||||
t.Fatalf("Learning is enabled for %s, but shouldn't", iface2.Name)
|
||||
}
|
||||
@ -97,4 +120,44 @@ func TestProtinfo(t *testing.T) {
|
||||
if err := LinkSetHairpin(iface3, true); err == nil || err.Error() != "operation not supported" {
|
||||
t.Fatalf("Set protinfo attrs for link without master is not supported, but err: %s", err)
|
||||
}
|
||||
|
||||
if os.Getenv("TRAVIS_BUILD_DIR") != "" {
|
||||
t.Skipf("Skipped some tests because travis kernel is to old to support BR_PROXYARP.")
|
||||
}
|
||||
|
||||
if err := LinkSetBrProxyArp(iface4, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkSetBrProxyArpWiFi(iface4, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pi4, err := LinkGetProtinfo(iface4)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if pi4.Hairpin != oldpi4.Hairpin {
|
||||
t.Fatalf("Hairpin field was changed for %s but shouldn't", iface4.Name)
|
||||
}
|
||||
if pi4.Guard != oldpi4.Guard {
|
||||
t.Fatalf("Guard field was changed for %s but shouldn't", iface4.Name)
|
||||
}
|
||||
if pi4.Learning != oldpi4.Learning {
|
||||
t.Fatalf("Learning field was changed for %s but shouldn't", iface4.Name)
|
||||
}
|
||||
if !pi4.ProxyArp {
|
||||
t.Fatalf("ProxyArp is not enabled for %s, but should", iface4.Name)
|
||||
}
|
||||
if !pi4.ProxyArpWiFi {
|
||||
t.Fatalf("ProxyArpWiFi is not enabled for %s, but should", iface4.Name)
|
||||
}
|
||||
if pi4.RootBlock != oldpi4.RootBlock {
|
||||
t.Fatalf("RootBlock field was changed for %s but shouldn't", iface4.Name)
|
||||
}
|
||||
if pi4.FastLeave != oldpi4.FastLeave {
|
||||
t.Fatalf("FastLeave field was changed for %s but shouldn't", iface4.Name)
|
||||
}
|
||||
if pi4.Flood != oldpi4.Flood {
|
||||
t.Fatalf("Flood field was changed for %s but shouldn't", iface4.Name)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user