route.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. package netlink
  2. import (
  3. "fmt"
  4. "net"
  5. "strings"
  6. )
  7. // Scope is an enum representing a route scope.
  8. type Scope uint8
  9. type NextHopFlag int
  10. type Destination interface {
  11. Family() int
  12. Decode([]byte) error
  13. Encode() ([]byte, error)
  14. String() string
  15. Equal(Destination) bool
  16. }
  17. type Encap interface {
  18. Type() int
  19. Decode([]byte) error
  20. Encode() ([]byte, error)
  21. String() string
  22. Equal(Encap) bool
  23. }
  24. //Protocol describe what was the originator of the route
  25. type RouteProtocol int
  26. // Route represents a netlink route.
  27. type Route struct {
  28. LinkIndex int
  29. ILinkIndex int
  30. Scope Scope
  31. Dst *net.IPNet
  32. Src net.IP
  33. Gw net.IP
  34. MultiPath []*NexthopInfo
  35. Protocol RouteProtocol
  36. Priority int
  37. Family int
  38. Table int
  39. Type int
  40. Tos int
  41. Flags int
  42. MPLSDst *int
  43. NewDst Destination
  44. Encap Encap
  45. Via Destination
  46. Realm int
  47. MTU int
  48. Window int
  49. Rtt int
  50. RttVar int
  51. Ssthresh int
  52. Cwnd int
  53. AdvMSS int
  54. Reordering int
  55. Hoplimit int
  56. InitCwnd int
  57. Features int
  58. RtoMin int
  59. InitRwnd int
  60. QuickACK int
  61. Congctl string
  62. FastOpenNoCookie int
  63. }
  64. func (r Route) String() string {
  65. elems := []string{}
  66. if len(r.MultiPath) == 0 {
  67. elems = append(elems, fmt.Sprintf("Ifindex: %d", r.LinkIndex))
  68. }
  69. if r.MPLSDst != nil {
  70. elems = append(elems, fmt.Sprintf("Dst: %d", r.MPLSDst))
  71. } else {
  72. elems = append(elems, fmt.Sprintf("Dst: %s", r.Dst))
  73. }
  74. if r.NewDst != nil {
  75. elems = append(elems, fmt.Sprintf("NewDst: %s", r.NewDst))
  76. }
  77. if r.Encap != nil {
  78. elems = append(elems, fmt.Sprintf("Encap: %s", r.Encap))
  79. }
  80. if r.Via != nil {
  81. elems = append(elems, fmt.Sprintf("Via: %s", r.Via))
  82. }
  83. elems = append(elems, fmt.Sprintf("Src: %s", r.Src))
  84. if len(r.MultiPath) > 0 {
  85. elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath))
  86. } else {
  87. elems = append(elems, fmt.Sprintf("Gw: %s", r.Gw))
  88. }
  89. elems = append(elems, fmt.Sprintf("Flags: %s", r.ListFlags()))
  90. elems = append(elems, fmt.Sprintf("Table: %d", r.Table))
  91. elems = append(elems, fmt.Sprintf("Realm: %d", r.Realm))
  92. return fmt.Sprintf("{%s}", strings.Join(elems, " "))
  93. }
  94. func (r Route) Equal(x Route) bool {
  95. return r.LinkIndex == x.LinkIndex &&
  96. r.ILinkIndex == x.ILinkIndex &&
  97. r.Scope == x.Scope &&
  98. ipNetEqual(r.Dst, x.Dst) &&
  99. r.Src.Equal(x.Src) &&
  100. r.Gw.Equal(x.Gw) &&
  101. nexthopInfoSlice(r.MultiPath).Equal(x.MultiPath) &&
  102. r.Protocol == x.Protocol &&
  103. r.Priority == x.Priority &&
  104. r.Realm == x.Realm &&
  105. r.Table == x.Table &&
  106. r.Type == x.Type &&
  107. r.Tos == x.Tos &&
  108. r.Hoplimit == x.Hoplimit &&
  109. r.Flags == x.Flags &&
  110. (r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) &&
  111. (r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) &&
  112. (r.Via == x.Via || (r.Via != nil && r.Via.Equal(x.Via))) &&
  113. (r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap)))
  114. }
  115. func (r *Route) SetFlag(flag NextHopFlag) {
  116. r.Flags |= int(flag)
  117. }
  118. func (r *Route) ClearFlag(flag NextHopFlag) {
  119. r.Flags &^= int(flag)
  120. }
  121. type flagString struct {
  122. f NextHopFlag
  123. s string
  124. }
  125. // RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE
  126. type RouteUpdate struct {
  127. Type uint16
  128. Route
  129. }
  130. type NexthopInfo struct {
  131. LinkIndex int
  132. Hops int
  133. Gw net.IP
  134. Flags int
  135. NewDst Destination
  136. Encap Encap
  137. Via Destination
  138. }
  139. func (n *NexthopInfo) String() string {
  140. elems := []string{}
  141. elems = append(elems, fmt.Sprintf("Ifindex: %d", n.LinkIndex))
  142. if n.NewDst != nil {
  143. elems = append(elems, fmt.Sprintf("NewDst: %s", n.NewDst))
  144. }
  145. if n.Encap != nil {
  146. elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap))
  147. }
  148. if n.Via != nil {
  149. elems = append(elems, fmt.Sprintf("Via: %s", n.Via))
  150. }
  151. elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1))
  152. elems = append(elems, fmt.Sprintf("Gw: %s", n.Gw))
  153. elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
  154. return fmt.Sprintf("{%s}", strings.Join(elems, " "))
  155. }
  156. func (n NexthopInfo) Equal(x NexthopInfo) bool {
  157. return n.LinkIndex == x.LinkIndex &&
  158. n.Hops == x.Hops &&
  159. n.Gw.Equal(x.Gw) &&
  160. n.Flags == x.Flags &&
  161. (n.NewDst == x.NewDst || (n.NewDst != nil && n.NewDst.Equal(x.NewDst))) &&
  162. (n.Encap == x.Encap || (n.Encap != nil && n.Encap.Equal(x.Encap)))
  163. }
  164. type nexthopInfoSlice []*NexthopInfo
  165. func (n nexthopInfoSlice) Equal(x []*NexthopInfo) bool {
  166. if len(n) != len(x) {
  167. return false
  168. }
  169. for i := range n {
  170. if n[i] == nil || x[i] == nil {
  171. return false
  172. }
  173. if !n[i].Equal(*x[i]) {
  174. return false
  175. }
  176. }
  177. return true
  178. }
  179. // ipNetEqual returns true iff both IPNet are equal
  180. func ipNetEqual(ipn1 *net.IPNet, ipn2 *net.IPNet) bool {
  181. if ipn1 == ipn2 {
  182. return true
  183. }
  184. if ipn1 == nil || ipn2 == nil {
  185. return false
  186. }
  187. m1, _ := ipn1.Mask.Size()
  188. m2, _ := ipn2.Mask.Size()
  189. return m1 == m2 && ipn1.IP.Equal(ipn2.IP)
  190. }