Skip to content

Commit d99b7e9

Browse files
committed
fix: add PR review suggestions
1 parent 1010e48 commit d99b7e9

File tree

5 files changed

+62
-67
lines changed

5 files changed

+62
-67
lines changed

pkg/bgp/id.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"fmt"
77
"hash/fnv"
88
"net"
9-
"regexp"
109
"strconv"
10+
"strings"
1111

1212
"github.com/cloudnativelabs/kube-router/v2/pkg/utils"
1313
gobgp "github.com/osrg/gobgp/v3/pkg/packet/bgp"
@@ -49,11 +49,10 @@ func ValidateCommunity(arg string) error {
4949
return nil
5050
}
5151

52-
_regexpCommunity := regexp.MustCompile(`(\d+):(\d+)`)
53-
elems := _regexpCommunity.FindStringSubmatch(arg)
54-
if len(elems) == 3 {
55-
if _, err := strconv.ParseUint(elems[1], 10, CommunityMaxPartSize); err == nil {
56-
if _, err = strconv.ParseUint(elems[2], 10, CommunityMaxPartSize); err == nil {
52+
elem1, elem2, found := strings.Cut(arg, ":")
53+
if found {
54+
if _, err := strconv.ParseUint(elem1, 10, CommunityMaxPartSize); err == nil {
55+
if _, err = strconv.ParseUint(elem2, 10, CommunityMaxPartSize); err == nil {
5756
return nil
5857
}
5958
}

pkg/controllers/routing/network_routes_controller.go

+21-7
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ const (
6969
ipv4MaskMinBits = 32
7070
)
7171

72+
// RouteSyncer is an interface that defines the methods needed to sync routes to the kernel's routing table
73+
type RouteSyncer interface {
74+
AddInjectedRoute(dst *net.IPNet, route *netlink.Route)
75+
DelInjectedRoute(dst *net.IPNet)
76+
Run(stopCh <-chan struct{}, wg *sync.WaitGroup)
77+
SyncLocalRouteTable()
78+
}
79+
80+
// PolicyBasedRouting is an interface that defines the methods needed to enable/disable policy based routing
81+
type PolicyBasedRouter interface {
82+
Enable() error
83+
Disable() error
84+
}
85+
7286
// NetworkRoutingController is struct to hold necessary information required by controller
7387
type NetworkRoutingController struct {
7488
krNode utils.NodeAware
@@ -124,8 +138,8 @@ type NetworkRoutingController struct {
124138
podIPv6CIDRs []string
125139
CNIFirewallSetup *sync.Cond
126140
ipsetMutex *sync.Mutex
127-
routeSyncer routes.RouteSyncer
128-
pbr routes.PBRer
141+
routeSyncer RouteSyncer
142+
pbr PolicyBasedRouter
129143
tunneler tunnels.Tunneler
130144

131145
nodeLister cache.Indexer
@@ -165,13 +179,13 @@ func (nrc *NetworkRoutingController) Run(healthChan chan<- *healthcheck.Controll
165179

166180
nrc.CNIFirewallSetup.Broadcast()
167181

168-
nrc.pbr = routes.NewPBR(nrc.krNode, nrc.podIPv4CIDRs, nrc.podIPv6CIDRs)
182+
nrc.pbr = routes.NewPolicyBasedRules(nrc.krNode, nrc.podIPv4CIDRs, nrc.podIPv6CIDRs)
169183

170184
// Handle ipip tunnel overlay
171185
if nrc.enableOverlays {
172186
klog.V(1).Info("Tunnel Overlay enabled in configuration.")
173187
klog.V(1).Info("Setting up overlay networking.")
174-
err = nrc.pbr.EnablePolicyBasedRouting()
188+
err = nrc.pbr.Enable()
175189
if err != nil {
176190
klog.Errorf("Failed to enable required policy based routing: %s", err.Error())
177191
}
@@ -187,7 +201,7 @@ func (nrc *NetworkRoutingController) Run(healthChan chan<- *healthcheck.Controll
187201
} else {
188202
klog.V(1).Info("Tunnel Overlay disabled in configuration.")
189203
klog.V(1).Info("Cleaning up old overlay networking if needed.")
190-
err = nrc.pbr.DisablePolicyBasedRouting()
204+
err = nrc.pbr.Disable()
191205
if err != nil {
192206
klog.Errorf("Failed to disable policy based routing: %s", err.Error())
193207
}
@@ -1365,8 +1379,8 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
13651379
nrc.autoMTU = kubeRouterConfig.AutoMTU
13661380
nrc.enableOverlays = kubeRouterConfig.EnableOverlay
13671381
nrc.overlayType = kubeRouterConfig.OverlayType
1368-
overlayEncap, err := tunnels.ParseEncapType(kubeRouterConfig.OverlayEncap)
1369-
if err != nil {
1382+
overlayEncap, ok := tunnels.ParseEncapType(kubeRouterConfig.OverlayEncap)
1383+
if !ok {
13701384
return nil, fmt.Errorf("unknown --overlay-encap option '%s' selected, unable to continue", overlayEncap)
13711385
}
13721386
overlayEncapPort, err := tunnels.ParseEncapPort(kubeRouterConfig.OverlayEncapPort)

pkg/routes/pbr.go

+10-13
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,16 @@ const (
1515
CustomTableName = "kube-router"
1616
)
1717

18-
type PBR struct {
18+
// PolicyBasedRules is a struct that holds all of the information needed for manipulating policy based routing rules
19+
type PolicyBasedRules struct {
1920
nfa utils.NodeFamilyAware
2021
podIPv4CIDRs []string
2122
podIPv6CIDRs []string
2223
}
2324

24-
type PBRer interface {
25-
EnablePolicyBasedRouting() error
26-
DisablePolicyBasedRouting() error
27-
}
28-
29-
// NewPBR creates a new PBR object which will be used to manipulate policy based routing rules
30-
func NewPBR(nfa utils.NodeFamilyAware, podIPv4CIDRs, podIPv6CIDRs []string) *PBR {
31-
return &PBR{
25+
// NewPolicyBasedRules creates a new PBR object which will be used to manipulate policy based routing rules
26+
func NewPolicyBasedRules(nfa utils.NodeFamilyAware, podIPv4CIDRs, podIPv6CIDRs []string) *PolicyBasedRules {
27+
return &PolicyBasedRules{
3228
nfa: nfa,
3329
podIPv4CIDRs: podIPv4CIDRs,
3430
podIPv6CIDRs: podIPv6CIDRs,
@@ -60,9 +56,9 @@ func ipRuleAbstraction(ipProtocol, ipOp, cidr string) error {
6056
return nil
6157
}
6258

63-
// setup a custom routing table that will be used for policy based routing to ensure traffic originating
64-
// on tunnel interface only leaves through tunnel interface irrespective rp_filter enabled/disabled
65-
func (pbr *PBR) EnablePolicyBasedRouting() error {
59+
// Enable setup a custom routing table that will be used for policy based routing to ensure traffic
60+
// originating on tunnel interface only leaves through tunnel interface irrespective rp_filter enabled/disabled
61+
func (pbr *PolicyBasedRules) Enable() error {
6662
err := utils.RouteTableAdd(CustomTableID, CustomTableName)
6763
if err != nil {
6864
return fmt.Errorf("failed to update rt_tables file: %s", err)
@@ -86,7 +82,8 @@ func (pbr *PBR) EnablePolicyBasedRouting() error {
8682
return nil
8783
}
8884

89-
func (pbr *PBR) DisablePolicyBasedRouting() error {
85+
// Disable removes the custom routing table that was used for policy based routing
86+
func (pbr *PolicyBasedRules) Disable() error {
9087
err := utils.RouteTableAdd(CustomTableID, CustomTableName)
9188
if err != nil {
9289
return fmt.Errorf("failed to update rt_tables file: %s", err)

pkg/routes/route_sync.go

-8
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@ import (
99
"k8s.io/klog/v2"
1010
)
1111

12-
// RouteSyncer is an interface that defines the methods needed to sync routes to the kernel's routing table
13-
type RouteSyncer interface {
14-
AddInjectedRoute(dst *net.IPNet, route *netlink.Route)
15-
DelInjectedRoute(dst *net.IPNet)
16-
Run(stopCh <-chan struct{}, wg *sync.WaitGroup)
17-
SyncLocalRouteTable()
18-
}
19-
2012
// RouteSync is a struct that holds all of the information needed for syncing routes to the kernel's routing table
2113
type RouteSync struct {
2214
routeTableStateMap map[string]*netlink.Route

pkg/tunnels/linux_tunnels.go

+26-33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"net"
88
"os/exec"
9+
"slices"
910
"strconv"
1011
"strings"
1112

@@ -39,17 +40,6 @@ var (
3940
// EncapType represents the type of encapsulation used for an overlay tunnel in kube-router.
4041
type EncapType string
4142

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-
5343
// ParseEncapType parses the given string and returns an Encap type if valid.
5444
// It returns an error if the encapsulation type is invalid.
5545
//
@@ -58,13 +48,13 @@ func (e EncapType) IsValid() bool {
5848
//
5949
// Returns:
6050
// - 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) {
6353
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
6656
}
67-
return encap, nil
57+
return encap, true
6858
}
6959

7060
type EncapPort uint16
@@ -92,26 +82,25 @@ type Tunneler interface {
9282
}
9383

9484
type OverlayTunnel struct {
95-
krNode utils.NodeIPAndFamilyAware
96-
overlayEncapPort EncapPort
97-
overlayEncap EncapType
85+
krNode utils.NodeIPAware
86+
encapPort EncapPort
87+
encapType EncapType
9888
}
9989

100-
func NewOverlayTunnel(krNode utils.NodeIPAndFamilyAware, overlayEncap EncapType,
101-
overlayEncapPort EncapPort) *OverlayTunnel {
90+
func NewOverlayTunnel(krNode utils.NodeIPAware, encapType EncapType, encapPort EncapPort) *OverlayTunnel {
10291
return &OverlayTunnel{
103-
krNode: krNode,
104-
overlayEncapPort: overlayEncapPort,
105-
overlayEncap: overlayEncap,
92+
krNode: krNode,
93+
encapPort: encapPort,
94+
encapType: encapType,
10695
}
10796
}
10897

10998
func (o *OverlayTunnel) EncapType() EncapType {
110-
return o.overlayEncap
99+
return o.encapType
111100
}
112101

113102
func (o *OverlayTunnel) EncapPort() EncapPort {
114-
return o.overlayEncapPort
103+
return o.encapPort
115104
}
116105

117106
// 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,
124113
var ipipMode, fouLinkType string
125114
isIPv6 := false
126115
ipBase := make([]string, 0)
127-
strFormattedEncapPort := strconv.FormatInt(int64(o.overlayEncapPort), 10)
116+
strFormattedEncapPort := strconv.FormatInt(int64(o.encapPort), 10)
128117

129118
if nextHop.To4() != nil {
130119
bestIPForFamily = o.krNode.FindBestIPv4NodeAddress()
@@ -151,7 +140,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
151140
klog.V(1).Infof("Tunnel interface: %s with encap type %s for the node %s already exists.",
152141
tunnelName, link.Attrs().EncapType, nextHop.String())
153142

154-
switch o.overlayEncap {
143+
switch o.encapType {
155144
case EncapTypeIPIP:
156145
if linkFOUEnabled(tunnelName) {
157146
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,
162151
CleanupTunnel(nextHopSubnet, tunnelName)
163152

164153
// 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) {
166155
fouArgs := ipBase
167156
fouArgs = append(fouArgs, "fou", "del", "port", strFormattedEncapPort)
168157
out, err := exec.Command("ip", fouArgs...).CombinedOutput()
@@ -188,17 +177,17 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
188177
// nothing to do here
189178
if err != nil || recreate {
190179
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())
192181
cmdArgs := ipBase
193-
switch o.overlayEncap {
182+
switch o.encapType {
194183
case EncapTypeIPIP:
195184
// Plain IPIP tunnel without any encapsulation
196185
cmdArgs = append(cmdArgs, "tunnel", "add", tunnelName, "mode", ipipMode, "local", bestIPForFamily.String(),
197186
"remote", nextHop.String())
198187

199188
case EncapTypeFOU:
200189
// Ensure that the FOU tunnel port is set correctly
201-
if !fouPortAndProtoExist(o.overlayEncapPort, isIPv6) {
190+
if !fouPortAndProtoExist(o.encapPort, isIPv6) {
202191
fouArgs := ipBase
203192
fouArgs = append(fouArgs, "fou", "add", "port", strFormattedEncapPort, "gue")
204193
out, err := exec.Command("ip", fouArgs...).CombinedOutput()
@@ -216,7 +205,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
216205

217206
default:
218207
return nil, fmt.Errorf("unknown tunnel encapsulation was passed: %s, unable to continue with overlay "+
219-
"setup", o.overlayEncap)
208+
"setup", o.encapType)
220209
}
221210

222211
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) {
276265
// Since linux restricts interface names to 15 characters, we take the sha-256 of the node IP after removing
277266
// non-entropic characters like '.' and ':', and then use the first 12 bytes of it. This allows us to cater to both
278267
// 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.
279272
func GenerateTunnelName(nodeIP string) string {
280273
// remove dots from an IPv4 address
281274
strippedIP := strings.ReplaceAll(nodeIP, ".", "")

0 commit comments

Comments
 (0)