ipip.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2019 the Kilo authors
  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. package encapsulation
  15. import (
  16. "fmt"
  17. "net"
  18. "github.com/squat/kilo/pkg/iproute"
  19. "github.com/squat/kilo/pkg/iptables"
  20. )
  21. // Strategy identifies which packets within a location should
  22. // be encapsulated.
  23. type Strategy string
  24. const (
  25. // Never indicates that no packets within a location
  26. // should be encapsulated.
  27. Never Strategy = "never"
  28. // CrossSubnet indicates that only packets that
  29. // traverse subnets within a location should be encapsulated.
  30. CrossSubnet Strategy = "crosssubnet"
  31. // Always indicates that all packets within a location
  32. // should be encapsulated.
  33. Always Strategy = "always"
  34. )
  35. // Interface can configure
  36. // the encapsulation interface, init itself,
  37. // get the encapsulation interface index,
  38. // set the interface IP address,
  39. // return the required IPTables rules,
  40. // return the encapsulation strategy,
  41. // and clean up any changes applied to the backend.
  42. type Interface interface {
  43. CleanUp() error
  44. Index() int
  45. Init(int) error
  46. Rules([]*net.IPNet) []iptables.Rule
  47. Set(*net.IPNet) error
  48. Strategy() Strategy
  49. }
  50. type ipip struct {
  51. iface int
  52. strategy Strategy
  53. }
  54. // NewIPIP returns an encapsulation that uses IPIP.
  55. func NewIPIP(strategy Strategy) Interface {
  56. return &ipip{strategy: strategy}
  57. }
  58. // CleanUp will remove any created IPIP devices.
  59. func (i *ipip) CleanUp() error {
  60. if err := iproute.DeleteAddresses(i.iface); err != nil {
  61. return nil
  62. }
  63. return iproute.RemoveInterface(i.iface)
  64. }
  65. // Index returns the index of the IPIP interface.
  66. func (i *ipip) Index() int {
  67. return i.iface
  68. }
  69. // Init initializes the IPIP interface.
  70. func (i *ipip) Init(base int) error {
  71. iface, err := iproute.NewIPIP(base)
  72. if err != nil {
  73. return fmt.Errorf("failed to create tunnel interface: %v", err)
  74. }
  75. if err := iproute.Set(iface, true); err != nil {
  76. return fmt.Errorf("failed to set tunnel interface up: %v", err)
  77. }
  78. i.iface = iface
  79. return nil
  80. }
  81. // Rules returns a set of iptables rules that are necessary
  82. // when traffic between nodes must be encapsulated.
  83. func (i *ipip) Rules(nodes []*net.IPNet) []iptables.Rule {
  84. return iptables.IPIPRules(nodes)
  85. }
  86. // Set sets the IP address of the IPIP interface.
  87. func (i *ipip) Set(cidr *net.IPNet) error {
  88. return iproute.SetAddress(i.iface, cidr)
  89. }
  90. // Strategy returns the configured strategy for encapsulation.
  91. func (i *ipip) Strategy() Strategy {
  92. return i.strategy
  93. }