route.go 5.3 KB

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