Skip to content

Commit 78588fc

Browse files
andrewsykimmurali-reddy
authored andcommitted
tunnel interface names cannot be longer than 15 characters (#274)
1 parent 5155c8d commit 78588fc

File tree

2 files changed

+58
-12
lines changed

2 files changed

+58
-12
lines changed

app/controllers/network_routes_controller.go

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ func (nrc *NetworkRoutingController) injectRoute(path *table.Path) error {
760760

761761
// check if the neighbour is in same subnet
762762
if !nrc.nodeSubnet.Contains(nexthop) {
763-
tunnelName := "tun-" + strings.Replace(nexthop.String(), ".", "", -1)
763+
tunnelName := generateTunnelName(nexthop.String())
764764
glog.Infof("Found node: " + nexthop.String() + " to be in different subnet.")
765765

766766
// if overlay is not enabled then skip creating tunnels and adding route
@@ -785,17 +785,18 @@ func (nrc *NetworkRoutingController) injectRoute(path *table.Path) error {
785785
link, err = netlink.LinkByName(tunnelName)
786786
if err != nil {
787787
glog.Infof("Found node: " + nexthop.String() + " to be in different subnet. Creating tunnel: " + tunnelName)
788-
cmd := exec.Command("ip", "tunnel", "add", tunnelName, "mode", "ipip", "local", nrc.nodeIP.String(),
789-
"remote", nexthop.String(), "dev", nrc.nodeInterface)
790-
err = cmd.Run()
788+
out, err := exec.Command("ip", "tunnel", "add", tunnelName, "mode", "ipip", "local", nrc.nodeIP.String(),
789+
"remote", nexthop.String(), "dev", nrc.nodeInterface).CombinedOutput()
791790
if err != nil {
792-
return errors.New("Route not injected for the route advertised by the node " + nexthop.String() +
793-
". Failed to create tunnel interface " + tunnelName)
791+
return fmt.Errorf("Route not injected for the route advertised by the node %s "+
792+
"Failed to create tunnel interface %s. error: %s, output: %s",
793+
nexthop.String(), tunnelName, err, string(out))
794794
}
795+
795796
link, err = netlink.LinkByName(tunnelName)
796797
if err != nil {
797-
return errors.New("Route not injected for the route advertised by the node " + nexthop.String() +
798-
". Failed to create tunnel interface " + tunnelName)
798+
return fmt.Errorf("Route not injected for the route advertised by the node %s "+
799+
"Failed to get tunnel interface by name error: %s", tunnelName, err)
799800
}
800801
if err := netlink.LinkSetUp(link); err != nil {
801802
return errors.New("Failed to bring tunnel interface " + tunnelName + " up due to: " + err.Error())
@@ -808,15 +809,15 @@ func (nrc *NetworkRoutingController) injectRoute(path *table.Path) error {
808809
glog.Infof("Tunnel interface: " + tunnelName + " for the node " + nexthop.String() + " already exists.")
809810
}
810811

811-
out, err := exec.Command("ip", "route", "list", "table", customRouteTableID).Output()
812+
out, err := exec.Command("ip", "route", "list", "table", customRouteTableID).CombinedOutput()
812813
if err != nil {
813814
return fmt.Errorf("Failed to verify if route already exists in %s table: %s",
814815
customRouteTableName, err.Error())
815816
}
816817
if !strings.Contains(string(out), tunnelName) {
817-
if err = exec.Command("ip", "route", "add", nexthop.String(), "dev", tunnelName, "table",
818-
customRouteTableID).Run(); err != nil {
819-
return errors.New("Failed to add route in custom route table due to: " + err.Error())
818+
if out, err = exec.Command("ip", "route", "add", nexthop.String(), "dev", tunnelName, "table",
819+
customRouteTableID).CombinedOutput(); err != nil {
820+
return fmt.Errorf("failed to add route in custom route table, err: %s, output: %s", err, string(out))
820821
}
821822
}
822823

@@ -1402,6 +1403,21 @@ func getNodeSubnet(nodeIp net.IP) (net.IPNet, string, error) {
14021403
return net.IPNet{}, "", errors.New("Failed to find interface with specified node ip")
14031404
}
14041405

1406+
// generateTunnelName will generate a name for a tunnel interface given a node IP
1407+
// for example, if the node IP is 10.0.0.1 the tunnel interface will be named tun-10001
1408+
// Since linux restricts interface names to 15 characters, if length of a node IP
1409+
// is greater than 12 (after removing "."), then the interface name is tunXYZ
1410+
// as opposed to tun-XYZ
1411+
func generateTunnelName(nodeIP string) string {
1412+
hash := strings.Replace(nodeIP, ".", "", -1)
1413+
1414+
if len(hash) < 12 {
1415+
return "tun-" + hash
1416+
}
1417+
1418+
return "tun" + hash
1419+
}
1420+
14051421
// func (nrc *NetworkRoutingController) getExternalNodeIPs(
14061422

14071423
// NewNetworkRoutingController returns new NetworkRoutingController object

app/controllers/network_routes_controller_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,36 @@ func Test_OnNodeUpdate(t *testing.T) {
884884
}
885885
}
886886

887+
func Test_generateTunnelName(t *testing.T) {
888+
testcases := []struct {
889+
name string
890+
nodeIP string
891+
tunnelName string
892+
}{
893+
{
894+
"IP less than 12 characters after removing '.'",
895+
"10.0.0.1",
896+
"tun-10001",
897+
},
898+
{
899+
"IP has 12 characters after removing '.'",
900+
"100.200.300.400",
901+
"tun100200300400",
902+
},
903+
}
904+
905+
for _, testcase := range testcases {
906+
t.Run(testcase.name, func(t *testing.T) {
907+
tunnelName := generateTunnelName(testcase.nodeIP)
908+
if tunnelName != testcase.tunnelName {
909+
t.Logf("actual tunnel interface name: %s", tunnelName)
910+
t.Logf("expected tunnel interface name: %s", testcase.tunnelName)
911+
t.Error("did not get expected tunnel interface name")
912+
}
913+
})
914+
}
915+
}
916+
887917
func createServices(clientset kubernetes.Interface, svcs []*v1core.Service) error {
888918
for _, svc := range svcs {
889919
_, err := clientset.CoreV1().Services("default").Create(svc)

0 commit comments

Comments
 (0)