From 5c153bd0183cb8b48c5bc5ee18e33dd21435b168 Mon Sep 17 00:00:00 2001 From: Tom Denham Date: Wed, 27 May 2015 18:39:46 -0700 Subject: [PATCH] Add static routes to the remote driver. Signed-off-by: Tom Denham --- libnetwork/drivers/remote/driver.go | 11 ++++++ libnetwork/drivers/remote/driver_test.go | 36 +++++++++++++++++++- libnetwork/drivers/remote/messages.go | 43 +++++++++++++++++++++--- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/libnetwork/drivers/remote/driver.go b/libnetwork/drivers/remote/driver.go index ffeb720ca7..78a91c13a9 100644 --- a/libnetwork/drivers/remote/driver.go +++ b/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)) } diff --git a/libnetwork/drivers/remote/driver_test.go b/libnetwork/drivers/remote/driver_test.go index 27703ea890..0df38126f2 100644 --- a/libnetwork/drivers/remote/driver_test.go +++ b/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{} { diff --git a/libnetwork/drivers/remote/messages.go b/libnetwork/drivers/remote/messages.go index 8e03a16daf..6fb31057a4 100644 --- a/libnetwork/drivers/remote/messages.go +++ b/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 }