protinfo_linux.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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) *Protinfo {
  46. var pi Protinfo
  47. for _, info := range infos {
  48. switch info.Attr.Type {
  49. case nl.IFLA_BRPORT_MODE:
  50. pi.Hairpin = byteToBool(info.Value[0])
  51. case nl.IFLA_BRPORT_GUARD:
  52. pi.Guard = byteToBool(info.Value[0])
  53. case nl.IFLA_BRPORT_FAST_LEAVE:
  54. pi.FastLeave = byteToBool(info.Value[0])
  55. case nl.IFLA_BRPORT_PROTECT:
  56. pi.RootBlock = byteToBool(info.Value[0])
  57. case nl.IFLA_BRPORT_LEARNING:
  58. pi.Learning = byteToBool(info.Value[0])
  59. case nl.IFLA_BRPORT_UNICAST_FLOOD:
  60. pi.Flood = byteToBool(info.Value[0])
  61. case nl.IFLA_BRPORT_PROXYARP:
  62. pi.ProxyArp = byteToBool(info.Value[0])
  63. case nl.IFLA_BRPORT_PROXYARP_WIFI:
  64. pi.ProxyArpWiFi = byteToBool(info.Value[0])
  65. }
  66. }
  67. return &pi
  68. }