github.com/vishvananda/netlink@v1.3.1/protinfo_linux.go (about) 1 package netlink 2 3 import ( 4 "errors" 5 "fmt" 6 "syscall" 7 8 "github.com/vishvananda/netlink/nl" 9 "golang.org/x/sys/unix" 10 ) 11 12 // If the returned error is [ErrDumpInterrupted], results may be inconsistent 13 // or incomplete. 14 func LinkGetProtinfo(link Link) (Protinfo, error) { 15 return pkgHandle.LinkGetProtinfo(link) 16 } 17 18 // If the returned error is [ErrDumpInterrupted], results may be inconsistent 19 // or incomplete. 20 func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) { 21 base := link.Attrs() 22 h.ensureIndex(base) 23 var pi Protinfo 24 req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) 25 msg := nl.NewIfInfomsg(unix.AF_BRIDGE) 26 req.AddData(msg) 27 msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, 0) 28 if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) { 29 return pi, executeErr 30 } 31 32 for _, m := range msgs { 33 ans := nl.DeserializeIfInfomsg(m) 34 if int(ans.Index) != base.Index { 35 continue 36 } 37 attrs, err := nl.ParseRouteAttr(m[ans.Len():]) 38 if err != nil { 39 return pi, err 40 } 41 for _, attr := range attrs { 42 if attr.Attr.Type != unix.IFLA_PROTINFO|unix.NLA_F_NESTED { 43 continue 44 } 45 infos, err := nl.ParseRouteAttr(attr.Value) 46 if err != nil { 47 return pi, err 48 } 49 pi = parseProtinfo(infos) 50 51 return pi, executeErr 52 } 53 } 54 return pi, fmt.Errorf("Device with index %d not found", base.Index) 55 } 56 57 func parseProtinfo(infos []syscall.NetlinkRouteAttr) (pi Protinfo) { 58 for _, info := range infos { 59 switch info.Attr.Type { 60 case nl.IFLA_BRPORT_MODE: 61 pi.Hairpin = byteToBool(info.Value[0]) 62 case nl.IFLA_BRPORT_GUARD: 63 pi.Guard = byteToBool(info.Value[0]) 64 case nl.IFLA_BRPORT_FAST_LEAVE: 65 pi.FastLeave = byteToBool(info.Value[0]) 66 case nl.IFLA_BRPORT_PROTECT: 67 pi.RootBlock = byteToBool(info.Value[0]) 68 case nl.IFLA_BRPORT_LEARNING: 69 pi.Learning = byteToBool(info.Value[0]) 70 case nl.IFLA_BRPORT_UNICAST_FLOOD: 71 pi.Flood = byteToBool(info.Value[0]) 72 case nl.IFLA_BRPORT_PROXYARP: 73 pi.ProxyArp = byteToBool(info.Value[0]) 74 case nl.IFLA_BRPORT_PROXYARP_WIFI: 75 pi.ProxyArpWiFi = byteToBool(info.Value[0]) 76 case nl.IFLA_BRPORT_ISOLATED: 77 pi.Isolated = byteToBool(info.Value[0]) 78 case nl.IFLA_BRPORT_NEIGH_SUPPRESS: 79 pi.NeighSuppress = byteToBool(info.Value[0]) 80 case nl.IFLA_BRPORT_VLAN_TUNNEL: 81 pi.VlanTunnel = byteToBool(info.Value[0]) 82 } 83 84 } 85 return 86 }