mirror of
https://github.com/vishvananda/netlink.git
synced 2025-10-07 00:32:49 +08:00
Parse IFLA_PROTINFO in LinkDeserialize
Extract and parse IFLA_PROTINFO fields from RTM_NEWLINK AF_BRIDGE netlink messages.
This commit is contained in:

committed by
Vish Ishaya

parent
a4f22d8ad2
commit
266f02d3a8
1
link.go
1
link.go
@@ -35,6 +35,7 @@ type LinkAttrs struct {
|
|||||||
Promisc int
|
Promisc int
|
||||||
Xdp *LinkXdp
|
Xdp *LinkXdp
|
||||||
EncapType string
|
EncapType string
|
||||||
|
Protinfo *Protinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLinkAttrs returns LinkAttrs structure filled with default values
|
// NewLinkAttrs returns LinkAttrs structure filled with default values
|
||||||
|
@@ -953,7 +953,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
|
|||||||
return nil, fmt.Errorf("Link not found")
|
return nil, fmt.Errorf("Link not found")
|
||||||
|
|
||||||
case len(msgs) == 1:
|
case len(msgs) == 1:
|
||||||
return LinkDeserialize(msgs[0])
|
return LinkDeserialize(nil, msgs[0])
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("More than one link found")
|
return nil, fmt.Errorf("More than one link found")
|
||||||
@@ -962,7 +962,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
|
|||||||
|
|
||||||
// linkDeserialize deserializes a raw message received from netlink into
|
// linkDeserialize deserializes a raw message received from netlink into
|
||||||
// a link object.
|
// a link object.
|
||||||
func LinkDeserialize(m []byte) (Link, error) {
|
func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
||||||
msg := nl.DeserializeIfInfomsg(m)
|
msg := nl.DeserializeIfInfomsg(m)
|
||||||
|
|
||||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||||
@@ -1074,6 +1074,15 @@ func LinkDeserialize(m []byte) (Link, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
base.Xdp = xdp
|
base.Xdp = xdp
|
||||||
|
case syscall.IFLA_PROTINFO | syscall.NLA_F_NESTED:
|
||||||
|
if hdr != nil && hdr.Type == syscall.RTM_NEWLINK &&
|
||||||
|
msg.Family == syscall.AF_BRIDGE {
|
||||||
|
attrs, err := nl.ParseRouteAttr(attr.Value[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
base.Protinfo = parseProtinfo(attrs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Links that don't have IFLA_INFO_KIND are hardware devices
|
// Links that don't have IFLA_INFO_KIND are hardware devices
|
||||||
@@ -1108,7 +1117,7 @@ func (h *Handle) LinkList() ([]Link, error) {
|
|||||||
|
|
||||||
var res []Link
|
var res []Link
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
link, err := LinkDeserialize(m)
|
link, err := LinkDeserialize(nil, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1157,7 +1166,7 @@ func linkSubscribe(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-cha
|
|||||||
}
|
}
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
||||||
link, err := LinkDeserialize(m.Data)
|
link, err := LinkDeserialize(&m.Header, m.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
52
link_test.go
52
link_test.go
@@ -1006,3 +1006,55 @@ func TestLinkAddDelVti(t *testing.T) {
|
|||||||
Local: net.IPv4(127, 0, 0, 1),
|
Local: net.IPv4(127, 0, 0, 1),
|
||||||
Remote: net.IPv4(127, 0, 0, 1)})
|
Remote: net.IPv4(127, 0, 0, 1)})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLinkSubscribeWithProtinfo(t *testing.T) {
|
||||||
|
tearDown := setUpNetlinkTest(t)
|
||||||
|
defer tearDown()
|
||||||
|
|
||||||
|
master := &Bridge{LinkAttrs{Name: "foo"}}
|
||||||
|
if err := LinkAdd(master); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
slave := &Veth{
|
||||||
|
LinkAttrs: LinkAttrs{
|
||||||
|
Name: "bar",
|
||||||
|
TxQLen: testTxQLen,
|
||||||
|
MTU: 1400,
|
||||||
|
MasterIndex: master.Attrs().Index,
|
||||||
|
},
|
||||||
|
PeerName: "bar-peer",
|
||||||
|
}
|
||||||
|
if err := LinkAdd(slave); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ch := make(chan LinkUpdate)
|
||||||
|
done := make(chan struct{})
|
||||||
|
defer close(done)
|
||||||
|
if err := LinkSubscribe(ch, done); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := LinkSetHairpin(slave, true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case update := <-ch:
|
||||||
|
if !(update.Attrs().Name == "bar" && update.Attrs().Protinfo != nil &&
|
||||||
|
update.Attrs().Protinfo.Hairpin) {
|
||||||
|
t.Fatal("Hairpin update not received as expected")
|
||||||
|
}
|
||||||
|
case <-time.After(time.Minute):
|
||||||
|
t.Fatal("Hairpin update timed out")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := LinkDel(slave); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := LinkDel(master); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -40,6 +40,15 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return pi, err
|
return pi, err
|
||||||
}
|
}
|
||||||
|
pi = *parseProtinfo(infos)
|
||||||
|
|
||||||
|
return pi, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
|
||||||
var pi Protinfo
|
var pi Protinfo
|
||||||
for _, info := range infos {
|
for _, info := range infos {
|
||||||
switch info.Attr.Type {
|
switch info.Attr.Type {
|
||||||
@@ -57,8 +66,5 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
|||||||
pi.Flood = byteToBool(info.Value[0])
|
pi.Flood = byteToBool(info.Value[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pi, nil
|
return &pi
|
||||||
}
|
|
||||||
}
|
|
||||||
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user