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,25 @@ 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 ,
101
- overlayEncapPort EncapPort ) * OverlayTunnel {
90
+ func NewOverlayTunnel (krNode utils.NodeIPAware , encapType EncapType , encapPort EncapPort ) * OverlayTunnel {
102
91
return & OverlayTunnel {
103
- krNode : krNode ,
104
- overlayEncapPort : overlayEncapPort ,
105
- overlayEncap : overlayEncap ,
92
+ krNode : krNode ,
93
+ encapPort : encapPort ,
94
+ encapType : encapType ,
106
95
}
107
96
}
108
97
109
98
func (o * OverlayTunnel ) EncapType () EncapType {
110
- return o .overlayEncap
99
+ return o .encapType
111
100
}
112
101
113
102
func (o * OverlayTunnel ) EncapPort () EncapPort {
114
- return o .overlayEncapPort
103
+ return o .encapPort
115
104
}
116
105
117
106
// setupOverlayTunnel attempts to create a tunnel link and corresponding routes for IPIP based overlay networks
@@ -124,7 +113,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
124
113
var ipipMode , fouLinkType string
125
114
isIPv6 := false
126
115
ipBase := make ([]string , 0 )
127
- strFormattedEncapPort := strconv .FormatInt (int64 (o .overlayEncapPort ), 10 )
116
+ strFormattedEncapPort := strconv .FormatInt (int64 (o .encapPort ), 10 )
128
117
129
118
if nextHop .To4 () != nil {
130
119
bestIPForFamily = o .krNode .FindBestIPv4NodeAddress ()
@@ -151,7 +140,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
151
140
klog .V (1 ).Infof ("Tunnel interface: %s with encap type %s for the node %s already exists." ,
152
141
tunnelName , link .Attrs ().EncapType , nextHop .String ())
153
142
154
- switch o .overlayEncap {
143
+ switch o .encapType {
155
144
case EncapTypeIPIP :
156
145
if linkFOUEnabled (tunnelName ) {
157
146
klog .Infof ("Was configured to use ipip tunnels, but found existing fou tunnels in place, cleaning up" )
@@ -162,7 +151,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
162
151
CleanupTunnel (nextHopSubnet , tunnelName )
163
152
164
153
// 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 ) {
154
+ if fouPortAndProtoExist (o .encapPort , isIPv6 ) {
166
155
fouArgs := ipBase
167
156
fouArgs = append (fouArgs , "fou" , "del" , "port" , strFormattedEncapPort )
168
157
out , err := exec .Command ("ip" , fouArgs ... ).CombinedOutput ()
@@ -188,17 +177,17 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
188
177
// nothing to do here
189
178
if err != nil || recreate {
190
179
klog .Infof ("Creating tunnel %s of type %s with encap %s for destination %s" ,
191
- tunnelName , fouLinkType , o .overlayEncap , nextHop .String ())
180
+ tunnelName , fouLinkType , o .encapType , nextHop .String ())
192
181
cmdArgs := ipBase
193
- switch o .overlayEncap {
182
+ switch o .encapType {
194
183
case EncapTypeIPIP :
195
184
// Plain IPIP tunnel without any encapsulation
196
185
cmdArgs = append (cmdArgs , "tunnel" , "add" , tunnelName , "mode" , ipipMode , "local" , bestIPForFamily .String (),
197
186
"remote" , nextHop .String ())
198
187
199
188
case EncapTypeFOU :
200
189
// Ensure that the FOU tunnel port is set correctly
201
- if ! fouPortAndProtoExist (o .overlayEncapPort , isIPv6 ) {
190
+ if ! fouPortAndProtoExist (o .encapPort , isIPv6 ) {
202
191
fouArgs := ipBase
203
192
fouArgs = append (fouArgs , "fou" , "add" , "port" , strFormattedEncapPort , "gue" )
204
193
out , err := exec .Command ("ip" , fouArgs ... ).CombinedOutput ()
@@ -216,7 +205,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
216
205
217
206
default :
218
207
return nil , fmt .Errorf ("unknown tunnel encapsulation was passed: %s, unable to continue with overlay " +
219
- "setup" , o .overlayEncap )
208
+ "setup" , o .encapType )
220
209
}
221
210
222
211
klog .V (2 ).Infof ("Executing the following command to create tunnel: ip %s" , cmdArgs )
@@ -276,6 +265,10 @@ func CleanupTunnel(destinationSubnet *net.IPNet, tunnelName string) {
276
265
// Since linux restricts interface names to 15 characters, we take the sha-256 of the node IP after removing
277
266
// non-entropic characters like '.' and ':', and then use the first 12 bytes of it. This allows us to cater to both
278
267
// long IPv4 addresses and much longer IPv6 addresses.
268
+ //
269
+ // TODO: In the future, we should consider using the hexadecimal byte representation of IPv4 addresses and using a the
270
+ // SHA256 of the hash. Additionally, we should not remove non-entropic characters as it can cause hash collisions as
271
+ // "21.3.0.4" would has the same as "2.13.0.4" without "."'s.
279
272
func GenerateTunnelName (nodeIP string ) string {
280
273
// remove dots from an IPv4 address
281
274
strippedIP := strings .ReplaceAll (nodeIP , "." , "" )
0 commit comments