protinfo_linux.go 2.3 KB

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