mirror of https://github.com/vishvananda/netlink
Change logic of setting protinfo attrs
Now interface is supposing that you setting protinfo attrs for link one by one. But you can get all protinfo attrs with one call. Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
parent
8bde0c8190
commit
2e9d285a71
|
@ -560,6 +560,52 @@ func LinkList() ([]Link, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
func LinkSetHairpin(link Link, mode bool) error {
|
||||
return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_MODE)
|
||||
}
|
||||
|
||||
func LinkSetGuard(link Link, mode bool) error {
|
||||
return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_GUARD)
|
||||
}
|
||||
|
||||
func LinkSetFastLeave(link Link, mode bool) error {
|
||||
return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_FAST_LEAVE)
|
||||
}
|
||||
|
||||
func LinkSetLearning(link Link, mode bool) error {
|
||||
return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_LEARNING)
|
||||
}
|
||||
|
||||
func LinkSetRootBlock(link Link, mode bool) error {
|
||||
return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROTECT)
|
||||
}
|
||||
|
||||
func LinkSetFlood(link Link, mode bool) error {
|
||||
return setProtinfoAttr(link, mode, nl.IFLA_BRPORT_UNICAST_FLOOD)
|
||||
}
|
||||
|
||||
func setProtinfoAttr(link Link, mode bool, attr int) error {
|
||||
base := link.Attrs()
|
||||
ensureIndex(base)
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
|
||||
msg.Type = syscall.RTM_SETLINK
|
||||
msg.Flags = syscall.NLM_F_REQUEST
|
||||
msg.Index = int32(base.Index)
|
||||
msg.Change = nl.DEFAULT_CHANGE
|
||||
req.AddData(msg)
|
||||
|
||||
br := nl.NewRtAttr(syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED, nil)
|
||||
nl.NewRtAttrChild(br, attr, boolToByte(mode))
|
||||
req.AddData(br)
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
vlan := link.(*Vlan)
|
||||
for _, datum := range data {
|
||||
|
|
|
@ -42,6 +42,30 @@ func LinkDel(link *Link) error {
|
|||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetHairpin(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetGuard(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetFastLeave(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetLearning(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetRootBlock(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetFlood(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkList() ([]Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
|
27
protinfo.go
27
protinfo.go
|
@ -81,30 +81,3 @@ func LinkGetProtinfo(link Link) (Protinfo, error) {
|
|||
}
|
||||
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
||||
}
|
||||
|
||||
func LinkSetProtinfo(link Link, p Protinfo) error {
|
||||
base := link.Attrs()
|
||||
ensureIndex(base)
|
||||
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
|
||||
msg.Type = syscall.RTM_SETLINK
|
||||
msg.Flags = syscall.NLM_F_REQUEST
|
||||
msg.Index = int32(base.Index)
|
||||
msg.Change = nl.DEFAULT_CHANGE
|
||||
req.AddData(msg)
|
||||
|
||||
br := nl.NewRtAttr(syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED, nil)
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRPORT_MODE, boolToByte(p.Hairpin))
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRPORT_GUARD, boolToByte(p.Guard))
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRPORT_FAST_LEAVE, boolToByte(p.FastLeave))
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRPORT_PROTECT, boolToByte(p.RootBlock))
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRPORT_LEARNING, boolToByte(p.Learning))
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRPORT_UNICAST_FLOOD, boolToByte(p.Flood))
|
||||
req.AddData(br)
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -23,54 +23,76 @@ func TestProtinfo(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pi1 := Protinfo{
|
||||
Hairpin: true,
|
||||
RootBlock: true,
|
||||
}
|
||||
|
||||
pi2 := Protinfo{
|
||||
Guard: true,
|
||||
Learning: false,
|
||||
}
|
||||
|
||||
pi3 := Protinfo{}
|
||||
|
||||
if err := LinkSetProtinfo(iface1, pi1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gpi1, err := LinkGetProtinfo(iface1)
|
||||
oldpi1, err := LinkGetProtinfo(iface1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !gpi1.Hairpin {
|
||||
oldpi2, err := LinkGetProtinfo(iface2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkSetHairpin(iface1, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := LinkSetRootBlock(iface1, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pi1, err := LinkGetProtinfo(iface1)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !pi1.Hairpin {
|
||||
t.Fatalf("Hairpin mode is not enabled for %s, but should", iface1.Name)
|
||||
}
|
||||
|
||||
if !gpi1.RootBlock {
|
||||
if !pi1.RootBlock {
|
||||
t.Fatalf("RootBlock is not enabled for %s, but should", iface1.Name)
|
||||
}
|
||||
if pi1.Guard != oldpi1.Guard {
|
||||
t.Fatalf("Guard field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.FastLeave != oldpi1.FastLeave {
|
||||
t.Fatalf("FastLeave field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.Learning != oldpi1.Learning {
|
||||
t.Fatalf("Learning field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
if pi1.Flood != oldpi1.Flood {
|
||||
t.Fatalf("Flood field was changed for %s but shouldn't", iface1.Name)
|
||||
}
|
||||
|
||||
if err := LinkSetProtinfo(iface2, pi2); err != nil {
|
||||
if err := LinkSetGuard(iface2, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gpi2, err := LinkGetProtinfo(iface2)
|
||||
if err := LinkSetLearning(iface2, false); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pi2, err := LinkGetProtinfo(iface2)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if gpi2.Hairpin {
|
||||
if pi2.Hairpin {
|
||||
t.Fatalf("Hairpin mode is enabled for %s, but shouldn't", iface2.Name)
|
||||
}
|
||||
|
||||
if !gpi2.Guard {
|
||||
if !pi2.Guard {
|
||||
t.Fatalf("Guard is not enabled for %s, but should", iface2.Name)
|
||||
}
|
||||
|
||||
if gpi2.Learning {
|
||||
if pi2.Learning {
|
||||
t.Fatalf("Learning is enabled for %s, but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.RootBlock != oldpi2.RootBlock {
|
||||
t.Fatalf("RootBlock field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.FastLeave != oldpi2.FastLeave {
|
||||
t.Fatalf("FastLeave field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
if pi2.Flood != oldpi2.Flood {
|
||||
t.Fatalf("Flood field was changed for %s but shouldn't", iface2.Name)
|
||||
}
|
||||
|
||||
if err := LinkSetProtinfo(iface3, pi3); err == nil || err.Error() != "operation not supported" {
|
||||
t.Fatalf("Set protinfo for link without master is not supported, but err: %s", err)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue