tun_common.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package nebula
  2. import (
  3. "fmt"
  4. "net"
  5. "strconv"
  6. )
  7. type route struct {
  8. mtu int
  9. route *net.IPNet
  10. }
  11. func parseRoutes(config *Config, network *net.IPNet) ([]route, error) {
  12. var err error
  13. r := config.Get("tun.routes")
  14. if r == nil {
  15. return []route{}, nil
  16. }
  17. rawRoutes, ok := r.([]interface{})
  18. if !ok {
  19. return nil, fmt.Errorf("tun.routes is not an array")
  20. }
  21. if len(rawRoutes) < 1 {
  22. return []route{}, nil
  23. }
  24. routes := make([]route, len(rawRoutes))
  25. for i, r := range rawRoutes {
  26. m, ok := r.(map[interface{}]interface{})
  27. if !ok {
  28. return nil, fmt.Errorf("entry %v in tun.routes is invalid", i+1)
  29. }
  30. rMtu, ok := m["mtu"]
  31. if !ok {
  32. return nil, fmt.Errorf("entry %v.mtu in tun.routes is not present", i+1)
  33. }
  34. mtu, ok := rMtu.(int)
  35. if !ok {
  36. mtu, err = strconv.Atoi(rMtu.(string))
  37. if err != nil {
  38. return nil, fmt.Errorf("entry %v.mtu in tun.routes is not an integer: %v", i+1, err)
  39. }
  40. }
  41. if mtu < 500 {
  42. return nil, fmt.Errorf("entry %v.mtu in tun.routes is below 500: %v", i+1, mtu)
  43. }
  44. rRoute, ok := m["route"]
  45. if !ok {
  46. return nil, fmt.Errorf("entry %v.route in tun.routes is not present", i+1)
  47. }
  48. r := route{
  49. mtu: mtu,
  50. }
  51. _, r.route, err = net.ParseCIDR(fmt.Sprintf("%v", rRoute))
  52. if err != nil {
  53. return nil, fmt.Errorf("entry %v.route in tun.routes failed to parse: %v", i+1, err)
  54. }
  55. if !ipWithin(network, r.route) {
  56. return nil, fmt.Errorf(
  57. "entry %v.route in tun.routes is not contained within the network attached to the certificate; route: %v, network: %v",
  58. i+1,
  59. r.route.String(),
  60. network.String(),
  61. )
  62. }
  63. routes[i] = r
  64. }
  65. return routes, nil
  66. }
  67. func ipWithin(o *net.IPNet, i *net.IPNet) bool {
  68. // Make sure o contains the lowest form of i
  69. if !o.Contains(i.IP.Mask(i.Mask)) {
  70. return false
  71. }
  72. // Find the max ip in i
  73. ip4 := i.IP.To4()
  74. if ip4 == nil {
  75. return false
  76. }
  77. last := make(net.IP, len(ip4))
  78. copy(last, ip4)
  79. for x := range ip4 {
  80. last[x] |= ^i.Mask[x]
  81. }
  82. // Make sure o contains the max
  83. if !o.Contains(last) {
  84. return false
  85. }
  86. return true
  87. }