Browse Source

Add static routes to the remote driver.

Signed-off-by: Tom Denham <tom.denham@metaswitch.com>
Tom Denham 10 năm trước cách đây
mục cha
commit
5c153bd018

+ 11 - 0
libnetwork/drivers/remote/driver.go

@@ -190,6 +190,17 @@ func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinI
 			return errorWithRollback(fmt.Sprintf("failed to set gateway IPv6: %v", addr), d.Leave(nid, eid))
 		}
 	}
+	if len(res.StaticRoutes) > 0 {
+		routes, err := res.parseStaticRoutes()
+		if err != nil {
+			return err
+		}
+		for _, route := range routes {
+			if jinfo.AddStaticRoute(route.Destination, route.RouteType, route.NextHop, route.InterfaceID) != nil {
+				return errorWithRollback(fmt.Sprintf("failed to set static route: %v", route), d.Leave(nid, eid))
+			}
+		}
+	}
 	if jinfo.SetHostsPath(res.HostsPath) != nil {
 		return errorWithRollback(fmt.Sprintf("failed to set hosts path: %s", res.HostsPath), d.Leave(nid, eid))
 	}

+ 35 - 1
libnetwork/drivers/remote/driver_test.go

@@ -69,6 +69,9 @@ type testEndpoint struct {
 	gatewayIPv6    string
 	resolvConfPath string
 	hostsPath      string
+	nextHop        string
+	destination    string
+	routeType      int
 }
 
 func (test *testEndpoint) Interfaces() []driverapi.InterfaceInfo {
@@ -115,6 +118,16 @@ func compareIPs(t *testing.T, kind string, shouldBe string, supplied net.IP) {
 	}
 }
 
+func compareIPNets(t *testing.T, kind string, shouldBe string, supplied net.IPNet) {
+	_, net, _ := net.ParseCIDR(shouldBe)
+	if net == nil {
+		t.Fatalf(`Invalid IP network to test against: "%s"`, shouldBe)
+	}
+	if !types.CompareIPNet(net, &supplied) {
+		t.Fatalf(`%s IP networks are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
+	}
+}
+
 func (test *testEndpoint) SetGateway(ipv4 net.IP) error {
 	compareIPs(test.t, "Gateway", test.gateway, ipv4)
 	return nil
@@ -150,7 +163,17 @@ func (test *testEndpoint) SetNames(src string, dst string) error {
 }
 
 func (test *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP, interfaceID int) error {
-	//TODO
+	compareIPNets(test.t, "Destination", test.destination, *destination)
+	compareIPs(test.t, "NextHop", test.nextHop, nextHop)
+
+	if test.routeType != routeType {
+		test.t.Fatalf(`Wrong RouteType; expected "%d", got "%d"`, test.routeType, routeType)
+	}
+
+	if test.id != interfaceID {
+		test.t.Fatalf(`Wrong InterfaceID; expected "%d", got "%d"`, test.id, interfaceID)
+	}
+
 	return nil
 }
 
@@ -172,6 +195,9 @@ func TestRemoteDriver(t *testing.T) {
 		gatewayIPv6:    "2001:DB8::1",
 		hostsPath:      "/here/comes/the/host/path",
 		resolvConfPath: "/there/goes/the/resolv/conf",
+		destination:    "10.0.0.0/8",
+		nextHop:        "10.0.0.1",
+		routeType:      1,
 	}
 
 	mux := http.NewServeMux()
@@ -221,6 +247,14 @@ func TestRemoteDriver(t *testing.T) {
 					"DstName": ep.dst,
 				},
 			},
+			"StaticRoutes": []map[string]interface{}{
+				map[string]interface{}{
+					"Destination": ep.destination,
+					"RouteType":   ep.routeType,
+					"InterfaceID": ep.id,
+					"NextHop":     ep.nextHop,
+				},
+			},
 		}
 	})
 	handle(t, mux, "Leave", func(msg map[string]interface{}) interface{} {

+ 39 - 4
libnetwork/drivers/remote/messages.go

@@ -1,6 +1,11 @@
 package remote
 
-import "net"
+import (
+	"fmt"
+	"net"
+
+	"github.com/docker/libnetwork/types"
+)
 
 type response struct {
 	Err string
@@ -45,6 +50,13 @@ type endpointInterface struct {
 	MacAddress  string
 }
 
+type staticRoute struct {
+	Destination string
+	RouteType   int
+	NextHop     string
+	InterfaceID int
+}
+
 type createEndpointResponse struct {
 	response
 	Interfaces []*endpointInterface
@@ -67,9 +79,7 @@ type iface struct {
 }
 
 func (r *createEndpointResponse) parseInterfaces() ([]*iface, error) {
-	var (
-		ifaces = make([]*iface, len(r.Interfaces))
-	)
+	var ifaces = make([]*iface, len(r.Interfaces))
 	for i, inIf := range r.Interfaces {
 		var err error
 		outIf := &iface{ID: inIf.ID}
@@ -93,6 +103,30 @@ func (r *createEndpointResponse) parseInterfaces() ([]*iface, error) {
 	return ifaces, nil
 }
 
+func (r *joinResponse) parseStaticRoutes() ([]*types.StaticRoute, error) {
+	var routes = make([]*types.StaticRoute, len(r.StaticRoutes))
+	for i, inRoute := range r.StaticRoutes {
+		var err error
+		outRoute := &types.StaticRoute{InterfaceID: inRoute.InterfaceID, RouteType: inRoute.RouteType}
+
+		if inRoute.Destination != "" {
+			if outRoute.Destination, err = toAddr(inRoute.Destination); err != nil {
+				return nil, err
+			}
+		}
+
+		if inRoute.NextHop != "" {
+			outRoute.NextHop = net.ParseIP(inRoute.NextHop)
+			if outRoute.NextHop == nil {
+				return nil, fmt.Errorf("failed to parse nexthop IP %s", inRoute.NextHop)
+			}
+		}
+
+		routes[i] = outRoute
+	}
+	return routes, nil
+}
+
 type deleteEndpointRequest struct {
 	NetworkID  string
 	EndpointID string
@@ -129,6 +163,7 @@ type joinResponse struct {
 	InterfaceNames []*ifaceName
 	Gateway        string
 	GatewayIPv6    string
+	StaticRoutes   []*staticRoute
 	HostsPath      string
 	ResolvConfPath string
 }