add support for bridge port neighbor suppression

this PR adds support for setting neigh_suppress attribute to a member port of a bridge
This commit is contained in:
Bernardo Soares 2023-07-14 16:00:46 +01:00 committed by Alessandro Boch
parent 229a10237c
commit a4fcbb7aeb
4 changed files with 44 additions and 9 deletions

View File

@ -2461,6 +2461,14 @@ func (h *Handle) LinkSetBrProxyArpWiFi(link Link, mode bool) error {
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP_WIFI) return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP_WIFI)
} }
func LinkSetBrNeighSuppress(link Link, mode bool) error {
return pkgHandle.LinkSetBrNeighSuppress(link, mode)
}
func (h *Handle) LinkSetBrNeighSuppress(link Link, mode bool) error {
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_NEIGH_SUPPRESS)
}
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error { func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
base := link.Attrs() base := link.Attrs()
h.ensureIndex(base) h.ensureIndex(base)

View File

@ -6,15 +6,16 @@ import (
// Protinfo represents bridge flags from netlink. // Protinfo represents bridge flags from netlink.
type Protinfo struct { type Protinfo struct {
Hairpin bool Hairpin bool
Guard bool Guard bool
FastLeave bool FastLeave bool
RootBlock bool RootBlock bool
Learning bool Learning bool
Flood bool Flood bool
ProxyArp bool ProxyArp bool
ProxyArpWiFi bool ProxyArpWiFi bool
Isolated bool Isolated bool
NeighSuppress bool
} }
// String returns a list of enabled flags // String returns a list of enabled flags
@ -51,6 +52,9 @@ func (prot *Protinfo) String() string {
if prot.Isolated { if prot.Isolated {
boolStrings = append(boolStrings, "Isolated") boolStrings = append(boolStrings, "Isolated")
} }
if prot.NeighSuppress {
boolStrings = append(boolStrings, "NeighSuppress")
}
return strings.Join(boolStrings, " ") return strings.Join(boolStrings, " ")
} }

View File

@ -70,6 +70,8 @@ func parseProtinfo(infos []syscall.NetlinkRouteAttr) (pi Protinfo) {
pi.ProxyArpWiFi = byteToBool(info.Value[0]) pi.ProxyArpWiFi = byteToBool(info.Value[0])
case nl.IFLA_BRPORT_ISOLATED: case nl.IFLA_BRPORT_ISOLATED:
pi.Isolated = byteToBool(info.Value[0]) pi.Isolated = byteToBool(info.Value[0])
case nl.IFLA_BRPORT_NEIGH_SUPPRESS:
pi.NeighSuppress = byteToBool(info.Value[0])
} }
} }
return return

View File

@ -1,3 +1,4 @@
//go:build linux
// +build linux // +build linux
package netlink package netlink
@ -83,6 +84,9 @@ func TestProtinfo(t *testing.T) {
if pi1.Flood != oldpi1.Flood { if pi1.Flood != oldpi1.Flood {
t.Fatalf("Flood field was changed for %s but shouldn't", iface1.Name) t.Fatalf("Flood field was changed for %s but shouldn't", iface1.Name)
} }
if pi1.NeighSuppress != oldpi1.NeighSuppress {
t.Fatalf("NeighSuppress field was changed for %s but shouldn't", iface1.Name)
}
if err := LinkSetGuard(iface2, true); err != nil { if err := LinkSetGuard(iface2, true); err != nil {
t.Fatal(err) t.Fatal(err)
@ -118,6 +122,9 @@ func TestProtinfo(t *testing.T) {
if pi2.Flood != oldpi2.Flood { if pi2.Flood != oldpi2.Flood {
t.Fatalf("Flood field was changed for %s but shouldn't", iface2.Name) t.Fatalf("Flood field was changed for %s but shouldn't", iface2.Name)
} }
if pi2.NeighSuppress != oldpi2.NeighSuppress {
t.Fatalf("NeighSuppress field was changed for %s but shouldn't", iface2.Name)
}
if err := LinkSetHairpin(iface3, true); err == nil || err.Error() != "operation not supported" { 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) t.Fatalf("Set protinfo attrs for link without master is not supported, but err: %s", err)
@ -162,6 +169,20 @@ func TestProtinfo(t *testing.T) {
t.Fatalf("Flood field was changed for %s but shouldn't", iface4.Name) t.Fatalf("Flood field was changed for %s but shouldn't", iface4.Name)
} }
// BR_NEIGH_SUPPRESS added on 4.15
minKernelRequired(t, 4, 15)
if err := LinkSetBrNeighSuppress(iface1, true); err != nil {
t.Fatal(err)
}
pi1, err = LinkGetProtinfo(iface1)
if err != nil {
t.Fatal(err)
}
if !pi1.NeighSuppress {
t.Fatalf("NeighSuppress is not enabled for %s but should", iface1.Name)
}
// Setting kernel requirement for next tests which require BRPORT_ISOLATED // Setting kernel requirement for next tests which require BRPORT_ISOLATED
minKernelRequired(t, 4, 18) minKernelRequired(t, 4, 18)