Skip to content

Commit af708b4

Browse files
Kartik Ravalaauren
Kartik Raval
authored andcommitted
Support for FoU encapsulation for IPIP tunnel
1 parent e3d6bcc commit af708b4

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

docs/user-guide.md

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ Usage of kube-router:
7979
--metrics-port uint16 Prometheus metrics port, (Default 0, Disabled)
8080
--nodeport-bindon-all-ip For service of NodePort type create IPVS service that listens on all IP's of the node.
8181
--nodes-full-mesh Each node in the cluster will setup BGP peering with rest of the nodes. (default true)
82+
--overlay-encap string Valid encapsulation types are "fou" - If set to "fou", the udp port can be specified via "overlay-encap-port"
83+
--overlay-encap-port uint16 Overlay tunnel encapsulation port (default 5555)
8284
--overlay-type string Possible values: subnet,full - When set to "subnet", the default, default "--enable-overlay=true" behavior is used. When set to "full", it changes "--enable-overlay=true" default behavior so that IP-in-IP tunneling is used for pod-to-pod networking across nodes regardless of the subnet the nodes are in. (default "subnet")
8385
--override-nexthop Override the next-hop in bgp routes sent to peers with the local ip.
8486
--peer-router-asns uints ASN numbers of the BGP peer to which cluster nodes will advertise cluster ip and node's pod cidr. (default [])

pkg/controllers/routing/network_routes_controller.go

+37-5
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ type NetworkRoutingController struct {
115115
iptablesCmdHandlers map[v1core.IPFamily]utils.IPTablesHandler
116116
enableOverlays bool
117117
overlayType string
118+
overlayEncap string
119+
overlayEncapPort uint16
118120
peerMultihopTTL uint8
119121
MetricsEnabled bool
120122
bgpServerStarted bool
@@ -178,14 +180,23 @@ func (nrc *NetworkRoutingController) Run(healthChan chan<- *healthcheck.Controll
178180

179181
// Handle ipip tunnel overlay
180182
if nrc.enableOverlays {
181-
klog.V(1).Info("IPIP Tunnel Overlay enabled in configuration.")
183+
klog.V(1).Info("Tunnel Overlay enabled in configuration.")
182184
klog.V(1).Info("Setting up overlay networking.")
183185
err = nrc.enablePolicyBasedRouting()
184186
if err != nil {
185187
klog.Errorf("Failed to enable required policy based routing: %s", err.Error())
186188
}
189+
if nrc.overlayEncap == "fou" {
190+
// enable FoU module for the overlay tunnel
191+
if _, err := exec.Command("modprobe", "fou").CombinedOutput(); err != nil {
192+
klog.Errorf("Failed to enable FoU for tunnel overlay: %s", err.Error())
193+
}
194+
if _, err := exec.Command("modprobe", "fou6").CombinedOutput(); err != nil {
195+
klog.Errorf("Failed to enable FoU6 for tunnel overlay: %s", err.Error())
196+
}
197+
}
187198
} else {
188-
klog.V(1).Info("IPIP Tunnel Overlay disabled in configuration.")
199+
klog.V(1).Info("Tunnel Overlay disabled in configuration.")
189200
klog.V(1).Info("Cleaning up old overlay networking if needed.")
190201
err = nrc.disablePolicyBasedRouting()
191202
if err != nil {
@@ -748,9 +759,28 @@ func (nrc *NetworkRoutingController) setupOverlayTunnel(tunnelName string, nextH
748759
// an error here indicates that the tunnel didn't exist, so we need to create it, if it already exists there's
749760
// nothing to do here
750761
if err != nil {
751-
//nolint:gocritic // we understand that we are appending to a new slice
752-
cmdArgs := append(ipBase, "tunnel", "add", tunnelName, "mode", ipipMode, "local", bestIPForFamily.String(),
753-
"remote", nextHop.String())
762+
cmdArgs := ipBase
763+
if nrc.overlayEncap == "" {
764+
// Plain IPIP tunnel without any encapsulation
765+
cmdArgs = append(cmdArgs, "tunnel", "add", tunnelName, "mode", ipipMode, "local", bestIPForFamily.String(),
766+
"remote", nextHop.String())
767+
768+
} else if nrc.overlayEncap == "fou" {
769+
770+
cmdArgs = append(cmdArgs, "fou", "add", "port", strconv.FormatInt(int64(nrc.overlayEncapPort), 10), "ipproto", "4")
771+
out, err := exec.Command("ip", cmdArgs...).CombinedOutput()
772+
if err != nil {
773+
return nil, fmt.Errorf("route not injected for the route advertised by the node %s "+
774+
"Failed to set FoU tunnel port - error: %s, output: %s", tunnelName, err, string(out))
775+
}
776+
cmdArgs = ipBase
777+
cmdArgs = append(cmdArgs,
778+
"link", "add", "name", tunnelName, "type", "ipip",
779+
"remote", nextHop.String(), "local", bestIPForFamily.String(),
780+
"ttl", "225", "encap", "fou", "encap-sport", "auto", "encap-dport",
781+
strconv.FormatInt(int64(nrc.overlayEncapPort), 10),
782+
"mode", ipipMode)
783+
}
754784
// need to skip binding device if nrc.nodeInterface is loopback, otherwise packets never leave
755785
// from egress interface to the tunnel peer.
756786
if nrc.nodeInterface != "lo" {
@@ -1480,6 +1510,8 @@ func NewNetworkRoutingController(clientset kubernetes.Interface,
14801510
nrc.autoMTU = kubeRouterConfig.AutoMTU
14811511
nrc.enableOverlays = kubeRouterConfig.EnableOverlay
14821512
nrc.overlayType = kubeRouterConfig.OverlayType
1513+
nrc.overlayEncap = kubeRouterConfig.OverlayEncap
1514+
nrc.overlayEncapPort = kubeRouterConfig.OverlayEncapPort
14831515
nrc.CNIFirewallSetup = sync.NewCond(&sync.Mutex{})
14841516

14851517
nrc.bgpPort = kubeRouterConfig.BGPPort

pkg/options/options.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import (
99
)
1010

1111
const (
12-
DefaultBgpPort = 179
13-
DefaultBgpHoldTime = 90 * time.Second
14-
defaultHealthCheckPort = 20244
12+
DefaultBgpPort = 179
13+
DefaultBgpHoldTime = 90 * time.Second
14+
defaultHealthCheckPort = 20244
15+
defaultOverlayTunnelEncapPort = 5555
1516
)
1617

1718
type KubeRouterConfig struct {
@@ -59,6 +60,8 @@ type KubeRouterConfig struct {
5960
NodePortBindOnAllIP bool
6061
NodePortRange string
6162
OverlayType string
63+
OverlayEncap string
64+
OverlayEncapPort uint16
6265
OverrideNextHop bool
6366
PeerASNs []uint
6467
PeerMultihopTTL uint8
@@ -180,6 +183,11 @@ func (s *KubeRouterConfig) AddFlags(fs *pflag.FlagSet) {
180183
"For service of NodePort type create IPVS service that listens on all IP's of the node.")
181184
fs.BoolVar(&s.FullMeshMode, "nodes-full-mesh", true,
182185
"Each node in the cluster will setup BGP peering with rest of the nodes.")
186+
fs.StringVar(&s.OverlayEncap, "overlay-encap", s.OverlayEncap,
187+
"Valid encapsulation types are \"fou\" - "+
188+
"If set to \"fou\", the udp port can be specified via \"overlay-encap-port\"")
189+
fs.Uint16Var(&s.OverlayEncapPort, "overlay-encap-port", uint16(defaultOverlayTunnelEncapPort),
190+
"Overlay tunnel encapsulation port")
183191
fs.StringVar(&s.OverlayType, "overlay-type", s.OverlayType,
184192
"Possible values: subnet,full - "+
185193
"When set to \"subnet\", the default, default \"--enable-overlay=true\" behavior is used. "+

0 commit comments

Comments
 (0)