protinfo_linux.go 1.8 KB

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