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:
Alexander Morozov 2015-02-17 14:16:48 -08:00
parent 8bde0c8190
commit 2e9d285a71
4 changed files with 121 additions and 56 deletions

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}
}