protinfo_linux.go 1.4 KB

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