Skip to content

Commit

Permalink
Change logic of setting protinfo attrs
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
LK4D4 committed Feb 17, 2015
1 parent 8bde0c8 commit 2e9d285
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 49 deletions.
46 changes: 46 additions & 0 deletions link_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
24 changes: 24 additions & 0 deletions netlink_unspecified.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
27 changes: 0 additions & 27 deletions protinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
66 changes: 44 additions & 22 deletions protinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,54 +23,76 @@ func TestProtinfo(t *testing.T) {
t.Fatal(err)
}

pi1 := Protinfo{
Hairpin: true,
RootBlock: true,
oldpi1, err := LinkGetProtinfo(iface1)
if err != nil {
t.Fatal(err)
}

pi2 := Protinfo{
Guard: true,
Learning: false,
oldpi2, err := LinkGetProtinfo(iface2)
if err != nil {
t.Fatal(err)
}

pi3 := Protinfo{}
if err := LinkSetHairpin(iface1, true); err != nil {
t.Fatal(err)
}

if err := LinkSetProtinfo(iface1, pi1); err != nil {
if err := LinkSetRootBlock(iface1, true); err != nil {
t.Fatal(err)
}

gpi1, err := LinkGetProtinfo(iface1)
pi1, err := LinkGetProtinfo(iface1)
if err != nil {
t.Fatal(err)
}
if !gpi1.Hairpin {
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)
}
}

0 comments on commit 2e9d285

Please sign in to comment.