|
6 | 6 | "io/ioutil" |
7 | 7 | "net" |
8 | 8 | "net/url" |
| 9 | + "os" |
9 | 10 | "os/exec" |
10 | 11 | "strconv" |
11 | 12 | "strings" |
@@ -95,6 +96,12 @@ func (nrc *NetworkRoutingController) Run(stopCh <-chan struct{}, wg *sync.WaitGr |
95 | 96 | glog.Errorf("Failed to enable IP forwarding of traffic from pods: %s", err.Error()) |
96 | 97 | } |
97 | 98 |
|
| 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 | + |
98 | 105 | // enable netfilter for the bridge |
99 | 106 | if _, err := exec.Command("modprobe", "br_netfilter").CombinedOutput(); err != nil { |
100 | 107 | 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 { |
481 | 488 | } else { |
482 | 489 | glog.Infof("Tunnel interface: " + tunnelName + " for the node " + nexthop.String() + " already exists.") |
483 | 490 | } |
| 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 | + |
484 | 502 | route = &netlink.Route{ |
485 | 503 | LinkIndex: link.Attrs().Index, |
486 | 504 | Dst: dst, |
@@ -736,6 +754,45 @@ func (nrc *NetworkRoutingController) enableForwarding() error { |
736 | 754 | return nil |
737 | 755 | } |
738 | 756 |
|
| 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 | + |
739 | 796 | // Handle updates from Node watcher. Node watcher calls this method whenever there is |
740 | 797 | // new node is added or old node is deleted. So peer up with new node and drop peering |
741 | 798 | // from old node |
|
0 commit comments