Skip to content

Commit 1ad57bf

Browse files
committed
fix: add PR review suggestions
1 parent 2a01df3 commit 1ad57bf

File tree

5 files changed

+62
-66
lines changed

5 files changed

+62
-66
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-32
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,26 @@ 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,
90+
func NewOverlayTunnel(krNode utils.NodeIPAware, overlayEncap EncapType,
10191
overlayEncapPort EncapPort) *OverlayTunnel {
10292
return &OverlayTunnel{
103-
krNode: krNode,
104-
overlayEncapPort: overlayEncapPort,
105-
overlayEncap: overlayEncap,
93+
krNode: krNode,
94+
encapPort: overlayEncapPort,
95+
encapType: overlayEncap,
10696
}
10797
}
10898

10999
func (o *OverlayTunnel) EncapType() EncapType {
110-
return o.overlayEncap
100+
return o.encapType
111101
}
112102

113103
func (o *OverlayTunnel) EncapPort() EncapPort {
114-
return o.overlayEncapPort
104+
return o.encapPort
115105
}
116106

117107
// 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,
124114
var ipipMode, fouLinkType string
125115
isIPv6 := false
126116
ipBase := make([]string, 0)
127-
strFormattedEncapPort := strconv.FormatInt(int64(o.overlayEncapPort), 10)
117+
strFormattedEncapPort := strconv.FormatInt(int64(o.encapPort), 10)
128118

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

154-
switch o.overlayEncap {
144+
switch o.encapType {
155145
case EncapTypeIPIP:
156146
if linkFOUEnabled(tunnelName) {
157147
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,
162152
CleanupTunnel(nextHopSubnet, tunnelName)
163153

164154
// 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) {
166156
fouArgs := ipBase
167157
fouArgs = append(fouArgs, "fou", "del", "port", strFormattedEncapPort)
168158
out, err := exec.Command("ip", fouArgs...).CombinedOutput()
@@ -188,17 +178,17 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
188178
// nothing to do here
189179
if err != nil || recreate {
190180
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())
192182
cmdArgs := ipBase
193-
switch o.overlayEncap {
183+
switch o.encapType {
194184
case EncapTypeIPIP:
195185
// Plain IPIP tunnel without any encapsulation
196186
cmdArgs = append(cmdArgs, "tunnel", "add", tunnelName, "mode", ipipMode, "local", bestIPForFamily.String(),
197187
"remote", nextHop.String())
198188

199189
case EncapTypeFOU:
200190
// Ensure that the FOU tunnel port is set correctly
201-
if !fouPortAndProtoExist(o.overlayEncapPort, isIPv6) {
191+
if !fouPortAndProtoExist(o.encapPort, isIPv6) {
202192
fouArgs := ipBase
203193
fouArgs = append(fouArgs, "fou", "add", "port", strFormattedEncapPort, "gue")
204194
out, err := exec.Command("ip", fouArgs...).CombinedOutput()
@@ -216,7 +206,7 @@ func (o *OverlayTunnel) SetupOverlayTunnel(tunnelName string, nextHop net.IP,
216206

217207
default:
218208
return nil, fmt.Errorf("unknown tunnel encapsulation was passed: %s, unable to continue with overlay "+
219-
"setup", o.overlayEncap)
209+
"setup", o.encapType)
220210
}
221211

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

0 commit comments

Comments
 (0)