Skip to content

Commit c9c6107

Browse files
authored
Merge pull request #143 from cloudnativelabs/pbr_tunnels
Setup policy-based routing so that traffic arriving on a tunnel interface leaves on same tunnel interface irrespective of rp_filter value
2 parents 22330ab + 7b9eedc commit c9c6107

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

app/controllers/network_routes_controller.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io/ioutil"
77
"net"
88
"net/url"
9+
"os"
910
"os/exec"
1011
"strconv"
1112
"strings"
@@ -95,6 +96,12 @@ func (nrc *NetworkRoutingController) Run(stopCh <-chan struct{}, wg *sync.WaitGr
9596
glog.Errorf("Failed to enable IP forwarding of traffic from pods: %s", err.Error())
9697
}
9798

99+
// enable policy based routing rules
100+
err = nrc.enablePolicyBasedRouting()
101+
if err != nil {
102+
glog.Errorf("Failed to enable required policy based routing: %s", err.Error())
103+
}
104+
98105
// enable netfilter for the bridge
99106
if _, err := exec.Command("modprobe", "br_netfilter").CombinedOutput(); err != nil {
100107
glog.Errorf("Failed to enable netfilter for bridge. Network policies and service proxy may not work: %s", err.Error())
@@ -481,6 +488,17 @@ func (nrc *NetworkRoutingController) injectRoute(path *table.Path) error {
481488
} else {
482489
glog.Infof("Tunnel interface: " + tunnelName + " for the node " + nexthop.String() + " already exists.")
483490
}
491+
492+
out, err := exec.Command("ip", "route", "list", "table", "kube-router").Output()
493+
if err != nil {
494+
return errors.New("Failed to verify if route already exists in kube-router table due to " + err.Error())
495+
}
496+
if !strings.Contains(string(out), tunnelName) {
497+
if err = exec.Command("ip", "route", "add", nexthop.String(), "dev", tunnelName, "table", "kube-router").Run(); err != nil {
498+
return errors.New("Failed to add route in custom route table due to: " + err.Error())
499+
}
500+
}
501+
484502
route = &netlink.Route{
485503
LinkIndex: link.Attrs().Index,
486504
Dst: dst,
@@ -736,6 +754,45 @@ func (nrc *NetworkRoutingController) enableForwarding() error {
736754
return nil
737755
}
738756

757+
// setup a custom routing table that will be used for policy based routing to ensure traffic originating
758+
// on tunnel interface only leaves through tunnel interface irrespective rp_filter enabled/disabled
759+
func (nrc *NetworkRoutingController) enablePolicyBasedRouting() error {
760+
b, err := ioutil.ReadFile("/etc/iproute2/rt_tables")
761+
if err != nil {
762+
return fmt.Errorf("Failed to enable required policy based routing due to: %s", err.Error())
763+
}
764+
765+
if !strings.Contains(string(b), "kube-router") {
766+
f, err := os.OpenFile("/etc/iproute2/rt_tables", os.O_APPEND|os.O_WRONLY, 0600)
767+
if err != nil {
768+
return fmt.Errorf("Failed to enable required policy based routing. Failed to create custom route table to route tunneled traffic properly due to: %s", err.Error())
769+
} else {
770+
if _, err = f.WriteString("77 kube-router"); err != nil {
771+
return fmt.Errorf("Failed to enable required policy based routing.Failed to add custom router table entry in /etc/iproute2/rt_tables due to: %s", err.Error())
772+
}
773+
}
774+
}
775+
776+
cidr, err := utils.GetPodCidrFromNodeSpec(nrc.clientset, nrc.hostnameOverride)
777+
if err != nil {
778+
return fmt.Errorf("Failed to enable required policy based routing.Failed to get the pod CIDR allocated for the node due to: %s", err.Error())
779+
}
780+
781+
out, err := exec.Command("ip", "rule", "list").Output()
782+
if err != nil {
783+
return fmt.Errorf("Failed to enable required policy based routing as failed to verify if `ip rule` exists due to %s", err.Error())
784+
}
785+
786+
if !strings.Contains(string(out), cidr) {
787+
err = exec.Command("ip", "rule", "add", "from", cidr, "table", "kube-router").Run()
788+
if err != nil {
789+
return fmt.Errorf("Failed to add ip rule due to: %s", err.Error())
790+
}
791+
}
792+
793+
return nil
794+
}
795+
739796
// Handle updates from Node watcher. Node watcher calls this method whenever there is
740797
// new node is added or old node is deleted. So peer up with new node and drop peering
741798
// from old node

0 commit comments

Comments
 (0)