route_others.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //go:build !linux
  15. // +build !linux
  16. package iproute2
  17. import (
  18. "net"
  19. "github.com/vishvananda/netlink"
  20. "yunion.io/x/pkg/errors"
  21. )
  22. const (
  23. errBadIP = errors.Error("bad ip")
  24. )
  25. type RouteSpec = netlink.Route
  26. type Route struct {
  27. *Link
  28. }
  29. func NewRoute(ifname string) *Route {
  30. l := NewLink(ifname)
  31. route := &Route{
  32. Link: l,
  33. }
  34. return route
  35. }
  36. func (route *Route) link() (link netlink.Link, ok bool) {
  37. link = route.Link.link
  38. if link != nil {
  39. ok = true
  40. }
  41. return
  42. }
  43. func (route *Route) List4() ([]RouteSpec, error) {
  44. return nil, errors.ErrNotImplemented
  45. }
  46. func (route *Route) AddByIPNet(ipnet *net.IPNet, gw net.IP) *Route {
  47. r := RouteSpec{
  48. Dst: ipnet,
  49. }
  50. if len(gw) > 0 {
  51. r.Gw = gw
  52. }
  53. return route.AddByRouteSpec(r)
  54. }
  55. func (route *Route) AddByCidr(cidr string, gwStr string) *Route {
  56. dst, gw, err := route.parseCidr(cidr, gwStr)
  57. if err != nil {
  58. route.addErr2(err)
  59. return route
  60. }
  61. return route.AddByIPNet(dst, gw)
  62. }
  63. func (route *Route) AddByRouteSpec(r RouteSpec) *Route {
  64. _, ok := route.link()
  65. if !ok {
  66. return route
  67. }
  68. return route
  69. }
  70. func (route *Route) parseCidr(cidr, gwStr string) (dst *net.IPNet, gw net.IP, err error) {
  71. if _, dst, err = net.ParseCIDR(cidr); err != nil {
  72. err = errors.Wrap(err, "parse cidr")
  73. return
  74. }
  75. if gwStr != "" {
  76. gw = net.ParseIP(gwStr)
  77. if len(gw) == 0 {
  78. err = errors.Wrapf(errBadIP, "gwStr: %s", gwStr)
  79. return
  80. }
  81. }
  82. return
  83. }
  84. func (route *Route) parse(netStr, maskStr, gwStr string) (ip net.IP, mask net.IPMask, gw net.IP, err error) {
  85. if ip = net.ParseIP(netStr); len(ip) == 0 {
  86. err = errors.Wrapf(errBadIP, "netStr %s", netStr)
  87. return
  88. }
  89. if maskIp := net.ParseIP(maskStr); len(maskIp) == 0 {
  90. err = errors.Wrapf(errBadIP, "maskStr %s", maskStr)
  91. return
  92. } else {
  93. if ip := maskIp.To4(); len(ip) > 0 {
  94. maskIp = ip
  95. }
  96. mask = net.IPMask(maskIp)
  97. ones, bits := mask.Size()
  98. if ones == 0 && bits == 0 {
  99. err = errors.Wrapf(errBadIP, "bad mask %s", maskStr)
  100. return
  101. }
  102. }
  103. if gwStr != "" {
  104. if gw = net.ParseIP(gwStr); len(gw) == 0 {
  105. err = errors.Wrapf(errBadIP, "gwStr %s", gwStr)
  106. return
  107. }
  108. }
  109. return
  110. }
  111. func (route *Route) Add(netStr, maskStr, gwStr string) *Route {
  112. var (
  113. ip net.IP
  114. mask net.IPMask
  115. gw net.IP
  116. )
  117. ip, mask, gw, err := route.parse(netStr, maskStr, gwStr)
  118. if err != nil {
  119. route.addErr2(err)
  120. }
  121. ipnet := &net.IPNet{
  122. IP: ip,
  123. Mask: mask,
  124. }
  125. return route.AddByIPNet(ipnet, gw)
  126. }
  127. func (route *Route) Del(netStr, maskStr string) *Route {
  128. ip, mask, _, err := route.parse(netStr, maskStr, "")
  129. if err != nil {
  130. route.addErr2(err)
  131. return route
  132. }
  133. ipnet := &net.IPNet{
  134. IP: ip,
  135. Mask: mask,
  136. }
  137. return route.DelByIPNet(ipnet)
  138. }
  139. func (route *Route) DelByCidr(cidr string) *Route {
  140. dst, _, err := route.parseCidr(cidr, "")
  141. if err != nil {
  142. route.addErr2(err)
  143. return route
  144. }
  145. return route.DelByIPNet(dst)
  146. }
  147. func (route *Route) DelByIPNet(ipnet *net.IPNet) *Route {
  148. link, ok := route.link()
  149. if !ok {
  150. return route
  151. }
  152. r := &netlink.Route{
  153. LinkIndex: link.Attrs().Index,
  154. Dst: ipnet,
  155. }
  156. if err := netlink.RouteDel(r); err != nil {
  157. route.addErr(err, "RouteDel %s", r)
  158. return route
  159. }
  160. return route
  161. }
  162. func RouteGetByDst(dstStr string) ([]RouteSpec, error) {
  163. return nil, errors.ErrNotImplemented
  164. }