6
6
"fmt"
7
7
"net"
8
8
"os/exec"
9
+ "slices"
9
10
"strconv"
10
11
"strings"
11
12
39
40
// EncapType represents the type of encapsulation used for an overlay tunnel in kube-router.
40
41
type EncapType string
41
42
42
- // IsValid checks if the encapsulation type is valid by comparing it against a list of valid types.
43
- // It returns true if the encapsulation type is valid, otherwise it returns false.
44
- func (e EncapType ) IsValid () bool {
45
- for _ , validType := range validEncapTypes {
46
- if e == validType {
47
- return true
48
- }
49
- }
50
- return false
51
- }
52
-
53
43
// ParseEncapType parses the given string and returns an Encap type if valid.
54
44
// It returns an error if the encapsulation type is invalid.
55
45
//
@@ -58,13 +48,13 @@ func (e EncapType) IsValid() bool {
58
48
//
59
49
// Returns:
60
50
// - Encap: The parsed encapsulation type.
61
- // - error: An error if the encapsulation type is invalid .
62
- func ParseEncapType (encapType string ) (EncapType , error ) {
51
+ // - bool: A boolean indicating whether the encapsulation type is valid .
52
+ func ParseEncapType (encapType string ) (EncapType , bool ) {
63
53
encap := EncapType (encapType )
64
- if ! encap . IsValid ( ) {
65
- return "" , fmt . Errorf ( "invalid encapsulation type: %s" , encapType )
54
+ if ! slices . Contains ( validEncapTypes , encap ) {
55
+ return "" , false
66
56
}
67
- return encap , nil
57
+ return encap , true
68
58
}
69
59
70
60
type EncapPort uint16
@@ -92,26 +82,26 @@ type Tunneler interface {
92
82
}
93
83
94
84
type OverlayTunnel struct {
95
- krNode utils.NodeIPAndFamilyAware
96
- overlayEncapPort EncapPort
97
- overlayEncap EncapType
85
+ krNode utils.NodeIPAware
86
+ encapPort EncapPort
87
+ encapType EncapType
98
88
}
99
89
100
- func NewOverlayTunnel (krNode utils.NodeIPAndFamilyAware , overlayEncap EncapType ,
90
+ func NewOverlayTunnel (krNode utils.NodeIPAware , overlayEncap EncapType ,
101
91
overlayEncapPort EncapPort ) * OverlayTunnel {
102
92
return & OverlayTunnel {
103
- krNode : krNode ,
104
- overlayEncapPort : overlayEncapPort ,
105
- overlayEncap : overlayEncap ,
93
+ krNode : krNode ,
94
+ encapPort : overlayEncapPort ,
95
+ encapType : overlayEncap ,
106
96
}
107
97
}
108
98
109
99
func (o * OverlayTunnel ) EncapType () EncapType {
110
- return o .overlayEncap
100
+ return o .encapType
111
101
}
112
102
113
103
func (o * OverlayTunnel ) EncapPort () EncapPort {
114
- return o .overlayEncapPort
104
+ return o .encapPort
115
105
}
116
106
117
107
// setupOverlayTunnel attempts to create a tunnel link and corresponding routes for IPIP based overlay networks
@@ -124,7 +114,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
124
114
var ipipMode , fouLinkType string
125
115
isIPv6 := false
126
116
ipBase := make ([]string , 0 )
127
- strFormattedEncapPort := strconv .FormatInt (int64 (o .overlayEncapPort ), 10 )
117
+ strFormattedEncapPort := strconv .FormatInt (int64 (o .encapPort ), 10 )
128
118
129
119
if nextHop .To4 () != nil {
130
120
bestIPForFamily = o .krNode .FindBestIPv4NodeAddress ()
@@ -151,7 +141,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
151
141
klog .V (1 ).Infof ("Tunnel interface: %s with encap type %s for the node %s already exists." ,
152
142
tunnelName , link .Attrs ().EncapType , nextHop .String ())
153
143
154
- switch o .overlayEncap {
144
+ switch o .encapType {
155
145
case EncapTypeIPIP :
156
146
if linkFOUEnabled (tunnelName ) {
157
147
klog .Infof ("Was configured to use ipip tunnels, but found existing fou tunnels in place, cleaning up" )
@@ -162,7 +152,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
162
152
CleanupTunnel (nextHopSubnet , tunnelName )
163
153
164
154
// If we are transitioning from FoU to IPIP we also need to clean up the old FoU port if it exists
165
- if fouPortAndProtoExist (o .overlayEncapPort , isIPv6 ) {
155
+ if fouPortAndProtoExist (o .encapPort , isIPv6 ) {
166
156
fouArgs := ipBase
167
157
fouArgs = append (fouArgs , "fou" , "del" , "port" , strFormattedEncapPort )
168
158
out , err := exec .Command ("ip" , fouArgs ... ).CombinedOutput ()
@@ -188,17 +178,17 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
188
178
// nothing to do here
189
179
if err != nil || recreate {
190
180
klog .Infof ("Creating tunnel %s of type %s with encap %s for destination %s" ,
191
- tunnelName , fouLinkType , o .overlayEncap , nextHop .String ())
181
+ tunnelName , fouLinkType , o .encapType , nextHop .String ())
192
182
cmdArgs := ipBase
193
- switch o .overlayEncap {
183
+ switch o .encapType {
194
184
case EncapTypeIPIP :
195
185
// Plain IPIP tunnel without any encapsulation
196
186
cmdArgs = append (cmdArgs , "tunnel" , "add" , tunnelName , "mode" , ipipMode , "local" , bestIPForFamily .String (),
197
187
"remote" , nextHop .String ())
198
188
199
189
case EncapTypeFOU :
200
190
// Ensure that the FOU tunnel port is set correctly
201
- if ! fouPortAndProtoExist (o .overlayEncapPort , isIPv6 ) {
191
+ if ! fouPortAndProtoExist (o .encapPort , isIPv6 ) {
202
192
fouArgs := ipBase
203
193
fouArgs = append (fouArgs , "fou" , "add" , "port" , strFormattedEncapPort , "gue" )
204
194
out , err := exec .Command ("ip" , fouArgs ... ).CombinedOutput ()
@@ -216,7 +206,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
216
206
217
207
default :
218
208
return nil , fmt .Errorf ("unknown tunnel encapsulation was passed: %s, unable to continue with overlay " +
219
- "setup" , o .overlayEncap )
209
+ "setup" , o .encapType )
220
210
}
221
211
222
212
klog .V (2 ).Infof ("Executing the following command to create tunnel: ip %s" , cmdArgs )
@@ -276,6 +266,10 @@ func CleanupTunnel(destinationSubnet *net.IPNet, tunnelName string) {
276
266
// Since linux restricts interface names to 15 characters, we take the sha-256 of the node IP after removing
277
267
// non-entropic characters like '.' and ':', and then use the first 12 bytes of it. This allows us to cater to both
278
268
// long IPv4 addresses and much longer IPv6 addresses.
269
+ //
270
+ // TODO: In the future, we should consider using the hexadecimal byte representation of IPv4 addresses and using a the
271
+ // SHA256 of the hash. Additionally, we should not remove non-entropic characters as it can cause hash collisions as
272
+ // "21.3.0.4" would has the same as "2.13.0.4" without "."'s.
279
273
func GenerateTunnelName (nodeIP string ) string {
280
274
// remove dots from an IPv4 address
281
275
strippedIP := strings .ReplaceAll (nodeIP , "." , "" )
0 commit comments