|  | 
| 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