From 043ddc0471536449f9e37d27100d9a9ede78a1b7 Mon Sep 17 00:00:00 2001 From: Jana Radhakrishnan Date: Mon, 31 Aug 2015 11:55:58 -0700 Subject: [PATCH] Explicitly set namespace for all network operations Make sure to always explicitly set namespace for all kernel bound network operations irrespective of whether the operation is performed in init namespace or a user defined namespace. This already happens for user defined netns. But doesn't happen for initial netns that libnetwork runs in. Signed-off-by: Jana Radhakrishnan --- api/api_test.go | 36 +++++++++--------- drivers/bridge/bridge.go | 13 +++++++ drivers/bridge/bridge_test.go | 18 ++++----- drivers/bridge/interface_test.go | 6 +-- drivers/bridge/network_test.go | 10 ++--- drivers/bridge/port_mapping_test.go | 4 +- drivers/bridge/setup_device_test.go | 9 +++-- drivers/bridge/setup_fixedcidrv4_test.go | 6 +-- drivers/bridge/setup_fixedcidrv6_test.go | 4 +- drivers/bridge/setup_ip_tables_test.go | 6 +-- drivers/bridge/setup_ipv4_test.go | 8 ++-- drivers/bridge/setup_ipv6_test.go | 6 +-- drivers/bridge/setup_verify_test.go | 12 +++--- drivers/overlay/ov_utils.go | 7 ++++ libnetwork_test.go | 47 ++++++++++++------------ netutils/test_utils.go | 33 +---------------- sandbox/namespace_linux.go | 32 +++++++++++----- sandbox/namespace_windows.go | 12 ++++++ sandbox/sandbox_freebsd.go | 12 ++++++ sandbox/sandbox_test.go | 7 ++-- sandbox/test_linux.go | 37 +++++++++++++++++++ 21 files changed, 195 insertions(+), 130 deletions(-) create mode 100644 sandbox/test_linux.go diff --git a/api/api_test.go b/api/api_test.go index 69b93cb..9916747 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -14,8 +14,8 @@ import ( "github.com/docker/docker/pkg/reexec" "github.com/docker/libnetwork" "github.com/docker/libnetwork/netlabel" - "github.com/docker/libnetwork/netutils" "github.com/docker/libnetwork/options" + "github.com/docker/libnetwork/sandbox" "github.com/docker/libnetwork/types" ) @@ -172,7 +172,7 @@ func TestJson(t *testing.T) { } func TestCreateDeleteNetwork(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -250,7 +250,7 @@ func TestCreateDeleteNetwork(t *testing.T) { } func TestGetNetworksAndEndpoints(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -523,7 +523,7 @@ func TestGetNetworksAndEndpoints(t *testing.T) { } func TestProcGetServices(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -696,7 +696,7 @@ func TestProcGetServices(t *testing.T) { } func TestProcGetService(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") ep1, err := nw.CreateEndpoint("db") @@ -748,7 +748,7 @@ func TestProcGetService(t *testing.T) { } func TestProcPublishUnpublishService(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, _ := createTestNetwork(t, "network") vars := make(map[string]string) @@ -880,7 +880,7 @@ func TestProcPublishUnpublishService(t *testing.T) { } func TestAttachDetachBackend(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") ep1, err := nw.CreateEndpoint("db") @@ -1014,7 +1014,7 @@ func TestDetectGetNetworksInvalidQueryComposition(t *testing.T) { } func TestDetectGetEndpointsInvalidQueryComposition(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, _ := createTestNetwork(t, "network") @@ -1026,7 +1026,7 @@ func TestDetectGetEndpointsInvalidQueryComposition(t *testing.T) { } func TestDetectGetServicesInvalidQueryComposition(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, _ := createTestNetwork(t, "network") @@ -1043,7 +1043,7 @@ func TestFindNetworkUtilPanic(t *testing.T) { } func TestFindNetworkUtil(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") nid := nw.ID() @@ -1106,7 +1106,7 @@ func TestFindNetworkUtil(t *testing.T) { } func TestCreateDeleteEndpoints(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -1232,7 +1232,7 @@ func TestCreateDeleteEndpoints(t *testing.T) { } func TestJoinLeave(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -1388,7 +1388,7 @@ func TestJoinLeave(t *testing.T) { } func TestFindEndpointUtilPanic(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() defer checkPanic(t) c, nw := createTestNetwork(t, "network") nid := nw.ID() @@ -1396,14 +1396,14 @@ func TestFindEndpointUtilPanic(t *testing.T) { } func TestFindServiceUtilPanic(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() defer checkPanic(t) c, _ := createTestNetwork(t, "network") findService(c, "random_service", -1) } func TestFindEndpointUtil(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") nid := nw.ID() @@ -1672,7 +1672,7 @@ func TestwriteJSON(t *testing.T) { } func TestHttpHandlerUninit(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -1736,7 +1736,7 @@ func TestHttpHandlerUninit(t *testing.T) { } func TestHttpHandlerBadBody(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() rsp := newWriter() @@ -1768,7 +1768,7 @@ func TestHttpHandlerBadBody(t *testing.T) { } func TestEndToEnd(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() rsp := newWriter() diff --git a/drivers/bridge/bridge.go b/drivers/bridge/bridge.go index 8fc05ae..3ff8f70 100644 --- a/drivers/bridge/bridge.go +++ b/drivers/bridge/bridge.go @@ -19,6 +19,7 @@ import ( "github.com/docker/libnetwork/netutils" "github.com/docker/libnetwork/options" "github.com/docker/libnetwork/portmapper" + "github.com/docker/libnetwork/sandbox" "github.com/docker/libnetwork/types" "github.com/vishvananda/netlink" ) @@ -544,6 +545,8 @@ func (d *driver) getNetworks() []*bridgeNetwork { func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error { var err error + defer sandbox.InitOSContext()() + // Sanity checks d.Lock() if _, ok := d.networks[id]; ok { @@ -695,6 +698,8 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err func (d *driver) DeleteNetwork(nid types.UUID) error { var err error + defer sandbox.InitOSContext()() + // Get network handler and remove it from driver d.Lock() n, ok := d.networks[nid] @@ -822,6 +827,8 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn err error ) + defer sandbox.InitOSContext()() + if epInfo == nil { return errors.New("invalid endpoint info passed") } @@ -1029,6 +1036,8 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn func (d *driver) DeleteEndpoint(nid, eid types.UUID) error { var err error + defer sandbox.InitOSContext()() + // Get the network handler and make sure it exists d.Lock() n, ok := d.networks[nid] @@ -1168,6 +1177,8 @@ func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{}, // Join method is invoked when a Sandbox is attached to an endpoint. func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + defer sandbox.InitOSContext()() + network, err := d.getNetwork(nid) if err != nil { return err @@ -1211,6 +1222,8 @@ func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinI // Leave method is invoked when a Sandbox detaches from an endpoint. func (d *driver) Leave(nid, eid types.UUID) error { + defer sandbox.InitOSContext()() + network, err := d.getNetwork(nid) if err != nil { return err diff --git a/drivers/bridge/bridge_test.go b/drivers/bridge/bridge_test.go index ffd2c94..94f820e 100644 --- a/drivers/bridge/bridge_test.go +++ b/drivers/bridge/bridge_test.go @@ -10,13 +10,13 @@ import ( "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/iptables" "github.com/docker/libnetwork/netlabel" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/docker/libnetwork/types" "github.com/vishvananda/netlink" ) func TestCreateFullOptions(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() config := &configuration{ @@ -68,7 +68,7 @@ func TestCreateFullOptions(t *testing.T) { } func TestCreate(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() config := &networkConfiguration{BridgeName: DefaultBridgeName} @@ -97,7 +97,7 @@ func TestCreate(t *testing.T) { } func TestCreateFail(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() config := &networkConfiguration{BridgeName: "dummy0"} @@ -110,7 +110,7 @@ func TestCreateFail(t *testing.T) { } func TestCreateMultipleNetworks(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() dd, _ := d.(*driver) @@ -274,7 +274,7 @@ func TestQueryEndpointInfoHairpin(t *testing.T) { } func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() dd, _ := d.(*driver) @@ -336,7 +336,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { } func TestCreateLinkWithOptions(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() config := &networkConfiguration{BridgeName: DefaultBridgeName} @@ -391,7 +391,7 @@ func getPortMapping() []types.PortBinding { } func TestLinkContainers(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() @@ -599,7 +599,7 @@ func TestValidateConfig(t *testing.T) { } func TestSetDefaultGw(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() _, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80") diff --git a/drivers/bridge/interface_test.go b/drivers/bridge/interface_test.go index 836cb9b..542d6d5 100644 --- a/drivers/bridge/interface_test.go +++ b/drivers/bridge/interface_test.go @@ -3,12 +3,12 @@ package bridge import ( "testing" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/vishvananda/netlink" ) func TestInterfaceDefaultName(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := &networkConfiguration{} if _ = newInterface(config); config.BridgeName != DefaultBridgeName { @@ -17,7 +17,7 @@ func TestInterfaceDefaultName(t *testing.T) { } func TestAddressesEmptyInterface(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() inf := newInterface(&networkConfiguration{}) addrv4, addrsv6, err := inf.addresses() diff --git a/drivers/bridge/network_test.go b/drivers/bridge/network_test.go index 2a7a469..005448b 100644 --- a/drivers/bridge/network_test.go +++ b/drivers/bridge/network_test.go @@ -5,12 +5,12 @@ import ( "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/netlabel" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/vishvananda/netlink" ) func TestLinkCreate(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() dr := d.(*driver) @@ -105,7 +105,7 @@ func TestLinkCreate(t *testing.T) { } func TestLinkCreateTwo(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() config := &networkConfiguration{ @@ -137,7 +137,7 @@ func TestLinkCreateTwo(t *testing.T) { } func TestLinkCreateNoEnableIPv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() config := &networkConfiguration{ @@ -167,7 +167,7 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) { } func TestLinkDelete(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() config := &networkConfiguration{ diff --git a/drivers/bridge/port_mapping_test.go b/drivers/bridge/port_mapping_test.go index 52cb3ea..0094335 100644 --- a/drivers/bridge/port_mapping_test.go +++ b/drivers/bridge/port_mapping_test.go @@ -6,7 +6,7 @@ import ( "github.com/docker/docker/pkg/reexec" "github.com/docker/libnetwork/netlabel" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/docker/libnetwork/types" ) @@ -18,7 +18,7 @@ func TestMain(m *testing.M) { } func TestPortMappingConfig(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() d := newDriver() binding1 := types.PortBinding{Proto: types.UDP, Port: uint16(400), HostPort: uint16(54000)} diff --git a/drivers/bridge/setup_device_test.go b/drivers/bridge/setup_device_test.go index 4bca316..1ce867c 100644 --- a/drivers/bridge/setup_device_test.go +++ b/drivers/bridge/setup_device_test.go @@ -6,11 +6,12 @@ import ( "testing" "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/vishvananda/netlink" ) func TestSetupNewBridge(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := &networkConfiguration{BridgeName: DefaultBridgeName} br := &bridgeInterface{} @@ -30,7 +31,7 @@ func TestSetupNewBridge(t *testing.T) { } func TestSetupNewNonDefaultBridge(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := &networkConfiguration{BridgeName: "test0"} br := &bridgeInterface{} @@ -46,7 +47,7 @@ func TestSetupNewNonDefaultBridge(t *testing.T) { } func TestSetupDeviceUp(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := &networkConfiguration{BridgeName: DefaultBridgeName} br := &bridgeInterface{} @@ -65,7 +66,7 @@ func TestSetupDeviceUp(t *testing.T) { } func TestGenerateRandomMAC(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() mac1 := netutils.GenerateRandomMAC() mac2 := netutils.GenerateRandomMAC() diff --git a/drivers/bridge/setup_fixedcidrv4_test.go b/drivers/bridge/setup_fixedcidrv4_test.go index 7c7019a..8daf0f0 100644 --- a/drivers/bridge/setup_fixedcidrv4_test.go +++ b/drivers/bridge/setup_fixedcidrv4_test.go @@ -4,11 +4,11 @@ import ( "net" "testing" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" ) func TestSetupFixedCIDRv4(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := &networkConfiguration{ BridgeName: DefaultBridgeName, @@ -35,7 +35,7 @@ func TestSetupFixedCIDRv4(t *testing.T) { } func TestSetupBadFixedCIDRv4(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := &networkConfiguration{ BridgeName: DefaultBridgeName, diff --git a/drivers/bridge/setup_fixedcidrv6_test.go b/drivers/bridge/setup_fixedcidrv6_test.go index 06eaf7c..1fa1327 100644 --- a/drivers/bridge/setup_fixedcidrv6_test.go +++ b/drivers/bridge/setup_fixedcidrv6_test.go @@ -4,11 +4,11 @@ import ( "net" "testing" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" ) func TestSetupFixedCIDRv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := &networkConfiguration{} br := newInterface(config) diff --git a/drivers/bridge/setup_ip_tables_test.go b/drivers/bridge/setup_ip_tables_test.go index b371822..14420bf 100644 --- a/drivers/bridge/setup_ip_tables_test.go +++ b/drivers/bridge/setup_ip_tables_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/docker/libnetwork/iptables" - "github.com/docker/libnetwork/netutils" "github.com/docker/libnetwork/portmapper" + "github.com/docker/libnetwork/sandbox" ) const ( @@ -15,7 +15,7 @@ const ( func TestProgramIPTable(t *testing.T) { // Create a test bridge with a basic bridge configuration (name + IPv4). - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() createTestBridge(getBasicTestConfig(), &bridgeInterface{}, t) // Store various iptables chain rules we care for. @@ -39,7 +39,7 @@ func TestProgramIPTable(t *testing.T) { func TestSetupIPTables(t *testing.T) { // Create a test bridge with a basic bridge configuration (name + IPv4). - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config := getBasicTestConfig() br := &bridgeInterface{} diff --git a/drivers/bridge/setup_ipv4_test.go b/drivers/bridge/setup_ipv4_test.go index e9f26d7..3710219 100644 --- a/drivers/bridge/setup_ipv4_test.go +++ b/drivers/bridge/setup_ipv4_test.go @@ -4,7 +4,7 @@ import ( "net" "testing" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/vishvananda/netlink" ) @@ -20,7 +20,7 @@ func setupTestInterface(t *testing.T) (*networkConfiguration, *bridgeInterface) } func TestSetupBridgeIPv4Fixed(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() ip, netw, err := net.ParseCIDR("192.168.1.1/24") if err != nil { @@ -52,7 +52,7 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) { } func TestSetupBridgeIPv4Auto(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config, br := setupTestInterface(t) if err := setupBridgeIPv4(config, br); err != nil { @@ -78,7 +78,7 @@ func TestSetupBridgeIPv4Auto(t *testing.T) { } func TestSetupGatewayIPv4(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() ip, nw, _ := net.ParseCIDR("192.168.0.24/16") nw.IP = ip diff --git a/drivers/bridge/setup_ipv6_test.go b/drivers/bridge/setup_ipv6_test.go index 71e3f3d..b3dc499 100644 --- a/drivers/bridge/setup_ipv6_test.go +++ b/drivers/bridge/setup_ipv6_test.go @@ -7,12 +7,12 @@ import ( "net" "testing" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/vishvananda/netlink" ) func TestSetupIPv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() config, br := setupTestInterface(t) if err := setupBridgeIPv6(config, br); err != nil { @@ -48,7 +48,7 @@ func TestSetupIPv6(t *testing.T) { } func TestSetupGatewayIPv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() _, nw, _ := net.ParseCIDR("2001:db8:ea9:9abc:ffff::/80") gw := net.ParseIP("2001:db8:ea9:9abc:ffff::254") diff --git a/drivers/bridge/setup_verify_test.go b/drivers/bridge/setup_verify_test.go index 29c77cb..27f3fa2 100644 --- a/drivers/bridge/setup_verify_test.go +++ b/drivers/bridge/setup_verify_test.go @@ -4,7 +4,7 @@ import ( "net" "testing" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/vishvananda/netlink" ) @@ -23,7 +23,7 @@ func setupVerifyTest(t *testing.T) *bridgeInterface { } func TestSetupVerify(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() addrv4 := net.IPv4(192, 168, 1, 1) inf := setupVerifyTest(t) @@ -40,7 +40,7 @@ func TestSetupVerify(t *testing.T) { } func TestSetupVerifyBad(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() addrv4 := net.IPv4(192, 168, 1, 1) inf := setupVerifyTest(t) @@ -58,7 +58,7 @@ func TestSetupVerifyBad(t *testing.T) { } func TestSetupVerifyMissing(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() addrv4 := net.IPv4(192, 168, 1, 1) inf := setupVerifyTest(t) @@ -71,7 +71,7 @@ func TestSetupVerifyMissing(t *testing.T) { } func TestSetupVerifyIPv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() addrv4 := net.IPv4(192, 168, 1, 1) inf := setupVerifyTest(t) @@ -92,7 +92,7 @@ func TestSetupVerifyIPv6(t *testing.T) { } func TestSetupVerifyIPv6Missing(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() addrv4 := net.IPv4(192, 168, 1, 1) inf := setupVerifyTest(t) diff --git a/drivers/overlay/ov_utils.go b/drivers/overlay/ov_utils.go index 46f7ea1..bddf8cc 100644 --- a/drivers/overlay/ov_utils.go +++ b/drivers/overlay/ov_utils.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/sandbox" "github.com/docker/libnetwork/types" "github.com/vishvananda/netlink" ) @@ -21,6 +22,8 @@ func validateID(nid, eid types.UUID) error { } func createVethPair() (string, string, error) { + defer sandbox.InitOSContext()() + // Generate a name for what will be the host side pipe interface name1, err := netutils.GenerateIfaceName(vethPrefix, vethLen) if err != nil { @@ -45,6 +48,8 @@ func createVethPair() (string, string, error) { } func createVxlan(vni uint32) (string, error) { + defer sandbox.InitOSContext()() + name, err := netutils.GenerateIfaceName("vxlan", 7) if err != nil { return "", fmt.Errorf("error generating vxlan name: %v", err) @@ -68,6 +73,8 @@ func createVxlan(vni uint32) (string, error) { } func deleteVxlan(name string) error { + defer sandbox.InitOSContext()() + link, err := netlink.LinkByName(name) if err != nil { return fmt.Errorf("failed to find vxlan interface with name %s: %v", name, err) diff --git a/libnetwork_test.go b/libnetwork_test.go index 3bf62bf..ec3d194 100644 --- a/libnetwork_test.go +++ b/libnetwork_test.go @@ -23,6 +23,7 @@ import ( "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/netutils" "github.com/docker/libnetwork/options" + "github.com/docker/libnetwork/sandbox" "github.com/docker/libnetwork/types" "github.com/vishvananda/netlink" "github.com/vishvananda/netns" @@ -221,7 +222,7 @@ func TestHost(t *testing.T) { func TestBridge(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } ip, subnet, err := net.ParseCIDR("192.168.100.1/24") @@ -295,7 +296,7 @@ func TestBridge(t *testing.T) { func TestUnknownDriver(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } _, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{}) @@ -322,7 +323,7 @@ func TestNilRemoteDriver(t *testing.T) { func TestDuplicateNetwork(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } // Creating a default bridge name network (can't be removed) @@ -343,7 +344,7 @@ func TestDuplicateNetwork(t *testing.T) { func TestNetworkName(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -380,7 +381,7 @@ func TestNetworkName(t *testing.T) { func TestNetworkType(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -407,7 +408,7 @@ func TestNetworkType(t *testing.T) { func TestNetworkID(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -434,7 +435,7 @@ func TestNetworkID(t *testing.T) { func TestDeleteNetworkWithActiveEndpoints(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -475,7 +476,7 @@ func TestDeleteNetworkWithActiveEndpoints(t *testing.T) { func TestUnknownNetwork(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -507,7 +508,7 @@ func TestUnknownNetwork(t *testing.T) { func TestUnknownEndpoint(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } ip, subnet, err := net.ParseCIDR("192.168.100.1/24") @@ -555,7 +556,7 @@ func TestUnknownEndpoint(t *testing.T) { func TestNetworkEndpointsWalkers(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } // Create network 1 and add 2 endpoint: ep11, ep12 @@ -687,7 +688,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) { func TestDuplicateEndpoint(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -737,7 +738,7 @@ func TestDuplicateEndpoint(t *testing.T) { func TestControllerQuery(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } // Create network 1 @@ -841,7 +842,7 @@ func TestControllerQuery(t *testing.T) { func TestNetworkQuery(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } // Create network 1 and add 2 endpoint: ep11, ep12 @@ -963,7 +964,7 @@ func checkSandbox(t *testing.T, info libnetwork.EndpointInfo) { func TestEndpointJoin(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } // Create network 1 and add 2 endpoint: ep11, ep12 @@ -1101,7 +1102,7 @@ func TestEndpointJoin(t *testing.T) { func TestEndpointJoinInvalidContainerId(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1141,7 +1142,7 @@ func TestEndpointJoinInvalidContainerId(t *testing.T) { func TestEndpointDeleteWithActiveContainer(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1200,7 +1201,7 @@ func TestEndpointDeleteWithActiveContainer(t *testing.T) { func TestEndpointMultipleJoins(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1258,7 +1259,7 @@ func TestEndpointMultipleJoins(t *testing.T) { func TestLeaveAll(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1323,7 +1324,7 @@ func TestLeaveAll(t *testing.T) { func TestEndpointInvalidLeave(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1401,7 +1402,7 @@ func TestEndpointInvalidLeave(t *testing.T) { func TestEndpointUpdateParent(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } n, err := createTestNetwork("bridge", "testnetwork", options.Generic{ @@ -1477,7 +1478,7 @@ func TestEndpointUpdateParent(t *testing.T) { func TestEnableIPv6(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888") @@ -1566,7 +1567,7 @@ func TestEnableIPv6(t *testing.T) { func TestResolvConfHost(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } tmpResolvConf := []byte("search localhost.net\nnameserver 127.0.0.1\nnameserver 2001:4860:4860::8888") @@ -1634,7 +1635,7 @@ func TestResolvConfHost(t *testing.T) { func TestResolvConf(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer sandbox.SetupTestOSContext(t)() } tmpResolvConf1 := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888") diff --git a/netutils/test_utils.go b/netutils/test_utils.go index d0a2fab..7ebc16e 100644 --- a/netutils/test_utils.go +++ b/netutils/test_utils.go @@ -1,11 +1,6 @@ package netutils -import ( - "flag" - "runtime" - "syscall" - "testing" -) +import "flag" var runningInContainer = flag.Bool("incontainer", false, "Indicates if the test is running in a container") @@ -13,29 +8,3 @@ var runningInContainer = flag.Bool("incontainer", false, "Indicates if the test func IsRunningInContainer() bool { return (*runningInContainer) } - -// SetupTestNetNS joins a new network namespace, and returns its associated -// teardown function. -// -// Example usage: -// -// defer SetupTestNetNS(t)() -// -func SetupTestNetNS(t *testing.T) func() { - runtime.LockOSThread() - if err := syscall.Unshare(syscall.CLONE_NEWNET); err != nil { - t.Fatalf("Failed to enter netns: %v", err) - } - - fd, err := syscall.Open("/proc/self/ns/net", syscall.O_RDONLY, 0) - if err != nil { - t.Fatal("Failed to open netns file") - } - - return func() { - if err := syscall.Close(fd); err != nil { - t.Logf("Warning: netns closing failed (%v)", err) - } - runtime.UnlockOSThread() - } -} diff --git a/sandbox/namespace_linux.go b/sandbox/namespace_linux.go index 3ab011c..cadd487 100644 --- a/sandbox/namespace_linux.go +++ b/sandbox/namespace_linux.go @@ -26,6 +26,8 @@ var ( gpmWg sync.WaitGroup gpmCleanupPeriod = 60 * time.Second gpmChan = make(chan chan struct{}) + nsOnce sync.Once + initNs netns.NsHandle ) // The networkNamespace type is the linux implementation of the Sandbox @@ -242,15 +244,27 @@ func (n *networkNamespace) InvokeFunc(f func()) error { }) } -func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD int) error) error { - runtime.LockOSThread() - defer runtime.UnlockOSThread() +func nsInit() { + var err error - origns, err := netns.Get() - if err != nil { - return err + if initNs, err = netns.Get(); err != nil { + panic(fmt.Sprintf("could not get initial namespace: %v", err)) } - defer origns.Close() +} + +// InitOSContext initializes OS context while configuring network resources +func InitOSContext() func() { + runtime.LockOSThread() + nsOnce.Do(nsInit) + if err := netns.Set(initNs); err != nil { + panic(fmt.Sprintf("failed to set to initial namespace: %v", err)) + } + + return runtime.UnlockOSThread +} + +func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD int) error) error { + defer InitOSContext()() f, err := os.OpenFile(path, os.O_RDONLY, 0) if err != nil { @@ -269,10 +283,10 @@ func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD if err = netns.Set(netns.NsHandle(nsFD)); err != nil { return err } - defer netns.Set(origns) + defer netns.Set(initNs) // Invoked after the namespace switch. - return postfunc(int(origns)) + return postfunc(int(initNs)) } func (n *networkNamespace) nsPath() string { diff --git a/sandbox/namespace_windows.go b/sandbox/namespace_windows.go index 4aa7787..00d8679 100644 --- a/sandbox/namespace_windows.go +++ b/sandbox/namespace_windows.go @@ -1,5 +1,7 @@ package sandbox +import "testing" + // GenerateKey generates a sandbox key based on the passed // container id. func GenerateKey(containerID string) string { @@ -21,3 +23,13 @@ func NewSandbox(key string, osCreate bool) (Sandbox, error) { // and waits for it. func GC() { } + +// InitOSContext initializes OS context while configuring network resources +func InitOSContext() func() { + return func() {} +} + +// SetupTestOSContext sets up a separate test OS context in which tests will be executed. +func SetupTestOSContext(t *testing.T) func() { + return func() {} +} diff --git a/sandbox/sandbox_freebsd.go b/sandbox/sandbox_freebsd.go index 4aa7787..00d8679 100644 --- a/sandbox/sandbox_freebsd.go +++ b/sandbox/sandbox_freebsd.go @@ -1,5 +1,7 @@ package sandbox +import "testing" + // GenerateKey generates a sandbox key based on the passed // container id. func GenerateKey(containerID string) string { @@ -21,3 +23,13 @@ func NewSandbox(key string, osCreate bool) (Sandbox, error) { // and waits for it. func GC() { } + +// InitOSContext initializes OS context while configuring network resources +func InitOSContext() func() { + return func() {} +} + +// SetupTestOSContext sets up a separate test OS context in which tests will be executed. +func SetupTestOSContext(t *testing.T) func() { + return func() {} +} diff --git a/sandbox/sandbox_test.go b/sandbox/sandbox_test.go index 32f89a7..10cdb97 100644 --- a/sandbox/sandbox_test.go +++ b/sandbox/sandbox_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/docker/docker/pkg/reexec" - "github.com/docker/libnetwork/netutils" ) func TestMain(m *testing.M) { @@ -17,7 +16,7 @@ func TestMain(m *testing.M) { } func TestSandboxCreate(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer SetupTestOSContext(t)() key, err := newKey(t) if err != nil { @@ -73,7 +72,7 @@ func TestSandboxCreate(t *testing.T) { } func TestSandboxCreateTwice(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer SetupTestOSContext(t)() key, err := newKey(t) if err != nil { @@ -123,7 +122,7 @@ func TestSandboxGC(t *testing.T) { } func TestAddRemoveInterface(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer SetupTestOSContext(t)() key, err := newKey(t) if err != nil { diff --git a/sandbox/test_linux.go b/sandbox/test_linux.go new file mode 100644 index 0000000..cfabdd9 --- /dev/null +++ b/sandbox/test_linux.go @@ -0,0 +1,37 @@ +package sandbox + +import ( + "runtime" + "syscall" + "testing" +) + +// SetupTestOSContext joins a new network namespace, and returns its associated +// teardown function. +// +// Example usage: +// +// defer SetupTestOSContext(t)() +// +func SetupTestOSContext(t *testing.T) func() { + runtime.LockOSThread() + if err := syscall.Unshare(syscall.CLONE_NEWNET); err != nil { + t.Fatalf("Failed to enter netns: %v", err) + } + + fd, err := syscall.Open("/proc/self/ns/net", syscall.O_RDONLY, 0) + if err != nil { + t.Fatal("Failed to open netns file") + } + + // Since we are switching to a new test namespace make + // sure to re-initialize initNs context + nsInit() + + return func() { + if err := syscall.Close(fd); err != nil { + t.Logf("Warning: netns closing failed (%v)", err) + } + runtime.UnlockOSThread() + } +}