From b784a13c94d9e8e419cf07832724efaaad597360 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 | 44 ++++++++++++------------ netutils/test_utils.go | 33 +----------------- osl/namespace_linux.go | 42 +++++++++++++++++----- osl/namespace_windows.go | 12 +++++++ osl/sandbox_freebsd.go | 12 +++++++ osl/sandbox_test.go | 7 ++-- osl/test_linux.go | 37 ++++++++++++++++++++ sandbox_test.go | 4 +-- 22 files changed, 205 insertions(+), 131 deletions(-) create mode 100644 osl/test_linux.go diff --git a/api/api_test.go b/api/api_test.go index 3dd2966..d855a8d 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -15,8 +15,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/osl" "github.com/docker/libnetwork/types" ) @@ -178,7 +178,7 @@ func TestJson(t *testing.T) { } func TestCreateDeleteNetwork(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -256,7 +256,7 @@ func TestCreateDeleteNetwork(t *testing.T) { } func TestGetNetworksAndEndpoints(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -529,7 +529,7 @@ func TestGetNetworksAndEndpoints(t *testing.T) { } func TestProcGetServices(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -702,7 +702,7 @@ func TestProcGetServices(t *testing.T) { } func TestProcGetService(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") ep1, err := nw.CreateEndpoint("db") @@ -754,7 +754,7 @@ func TestProcGetService(t *testing.T) { } func TestProcPublishUnpublishService(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, _ := createTestNetwork(t, "network") vars := make(map[string]string) @@ -886,7 +886,7 @@ func TestProcPublishUnpublishService(t *testing.T) { } func TestAttachDetachBackend(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") ep1, err := nw.CreateEndpoint("db") @@ -1026,7 +1026,7 @@ func TestDetectGetNetworksInvalidQueryComposition(t *testing.T) { } func TestDetectGetEndpointsInvalidQueryComposition(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, _ := createTestNetwork(t, "network") @@ -1038,7 +1038,7 @@ func TestDetectGetEndpointsInvalidQueryComposition(t *testing.T) { } func TestDetectGetServicesInvalidQueryComposition(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, _ := createTestNetwork(t, "network") @@ -1055,7 +1055,7 @@ func TestFindNetworkUtilPanic(t *testing.T) { } func TestFindNetworkUtil(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") nid := nw.ID() @@ -1118,7 +1118,7 @@ func TestFindNetworkUtil(t *testing.T) { } func TestCreateDeleteEndpoints(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -1244,7 +1244,7 @@ func TestCreateDeleteEndpoints(t *testing.T) { } func TestJoinLeave(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -1403,7 +1403,7 @@ func TestJoinLeave(t *testing.T) { } func TestFindEndpointUtilPanic(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() defer checkPanic(t) c, nw := createTestNetwork(t, "network") nid := nw.ID() @@ -1411,14 +1411,14 @@ func TestFindEndpointUtilPanic(t *testing.T) { } func TestFindServiceUtilPanic(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() defer checkPanic(t) c, _ := createTestNetwork(t, "network") findService(c, "random_service", -1) } func TestFindEndpointUtil(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, nw := createTestNetwork(t, "network") nid := nw.ID() @@ -1687,7 +1687,7 @@ func TestwriteJSON(t *testing.T) { } func TestHttpHandlerUninit(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() c, err := libnetwork.New() if err != nil { @@ -1756,7 +1756,7 @@ func TestHttpHandlerUninit(t *testing.T) { } func TestHttpHandlerBadBody(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() rsp := newWriter() @@ -1788,7 +1788,7 @@ func TestHttpHandlerBadBody(t *testing.T) { } func TestEndToEnd(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() rsp := newWriter() diff --git a/drivers/bridge/bridge.go b/drivers/bridge/bridge.go index faf9eb6..2d3f55e 100644 --- a/drivers/bridge/bridge.go +++ b/drivers/bridge/bridge.go @@ -20,6 +20,7 @@ import ( "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/netutils" "github.com/docker/libnetwork/options" + "github.com/docker/libnetwork/osl" "github.com/docker/libnetwork/portmapper" "github.com/docker/libnetwork/types" "github.com/vishvananda/netlink" @@ -570,6 +571,8 @@ func (d *driver) getNetworks() []*bridgeNetwork { func (d *driver) CreateNetwork(id string, option map[string]interface{}) error { var err error + defer osl.InitOSContext()() + // Sanity checks d.Lock() if _, ok := d.networks[id]; ok { @@ -722,6 +725,8 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}) error { func (d *driver) DeleteNetwork(nid string) error { var err error + defer osl.InitOSContext()() + // Get network handler and remove it from driver d.Lock() n, ok := d.networks[nid] @@ -849,6 +854,8 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo, err error ) + defer osl.InitOSContext()() + if epInfo == nil { return errors.New("invalid endpoint info passed") } @@ -1057,6 +1064,8 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo, func (d *driver) DeleteEndpoint(nid, eid string) error { var err error + defer osl.InitOSContext()() + // Get the network handler and make sure it exists d.Lock() n, ok := d.networks[nid] @@ -1196,6 +1205,8 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro // Join method is invoked when a Sandbox is attached to an endpoint. func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { + defer osl.InitOSContext()() + network, err := d.getNetwork(nid) if err != nil { return err @@ -1239,6 +1250,8 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, // Leave method is invoked when a Sandbox detaches from an endpoint. func (d *driver) Leave(nid, eid string) error { + defer osl.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 60f0257..5276d7b 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/osl" "github.com/docker/libnetwork/types" "github.com/vishvananda/netlink" ) func TestCreateFullOptions(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.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 osl.SetupTestOSContext(t)() d := newDriver() if err := d.Config(nil); err != nil { @@ -101,7 +101,7 @@ func TestCreate(t *testing.T) { } func TestCreateFail(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() if err := d.Config(nil); err != nil { @@ -118,7 +118,7 @@ func TestCreateFail(t *testing.T) { } func TestCreateMultipleNetworks(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() dd, _ := d.(*driver) @@ -282,7 +282,7 @@ func TestQueryEndpointInfoHairpin(t *testing.T) { } func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() dd, _ := d.(*driver) @@ -353,7 +353,7 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) { } func TestCreateLinkWithOptions(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() if err := d.Config(nil); err != nil { @@ -412,7 +412,7 @@ func getPortMapping() []types.PortBinding { } func TestLinkContainers(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() @@ -629,7 +629,7 @@ func TestValidateConfig(t *testing.T) { } func TestSetDefaultGw(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() if err := d.Config(nil); err != nil { diff --git a/drivers/bridge/interface_test.go b/drivers/bridge/interface_test.go index 836cb9b..999bef4 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/osl" "github.com/vishvananda/netlink" ) func TestInterfaceDefaultName(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.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 osl.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 13a996e..fe5095d 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/osl" "github.com/vishvananda/netlink" ) func TestLinkCreate(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() dr := d.(*driver) @@ -109,7 +109,7 @@ func TestLinkCreate(t *testing.T) { } func TestLinkCreateTwo(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() if err := d.Config(nil); err != nil { @@ -145,7 +145,7 @@ func TestLinkCreateTwo(t *testing.T) { } func TestLinkCreateNoEnableIPv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() if err := d.Config(nil); err != nil { @@ -179,7 +179,7 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) { } func TestLinkDelete(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() if err := d.Config(nil); err != nil { diff --git a/drivers/bridge/port_mapping_test.go b/drivers/bridge/port_mapping_test.go index 8b6887c..14a5843 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/osl" "github.com/docker/libnetwork/types" ) @@ -18,7 +18,7 @@ func TestMain(m *testing.M) { } func TestPortMappingConfig(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() d := newDriver() config := &configuration{ diff --git a/drivers/bridge/setup_device_test.go b/drivers/bridge/setup_device_test.go index 4bca316..040f2b9 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/osl" "github.com/vishvananda/netlink" ) func TestSetupNewBridge(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.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 osl.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 osl.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 osl.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..6849d3c 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/osl" ) func TestSetupFixedCIDRv4(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.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 osl.SetupTestOSContext(t)() config := &networkConfiguration{ BridgeName: DefaultBridgeName, diff --git a/drivers/bridge/setup_fixedcidrv6_test.go b/drivers/bridge/setup_fixedcidrv6_test.go index 06eaf7c..0b479a0 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/osl" ) func TestSetupFixedCIDRv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.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 c1f81ba..fa0bdce 100644 --- a/drivers/bridge/setup_ip_tables_test.go +++ b/drivers/bridge/setup_ip_tables_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/docker/libnetwork/iptables" - "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/osl" "github.com/docker/libnetwork/portmapper" ) @@ -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 osl.SetupTestOSContext(t)() createTestBridge(getBasicTestConfig(), &bridgeInterface{}, t) // Store various iptables chain rules we care for. @@ -39,7 +39,7 @@ func TestProgramIPTable(t *testing.T) { func TestSetupIPChains(t *testing.T) { // Create a test bridge with a basic bridge configuration (name + IPv4). - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() driverconfig := &configuration{ EnableIPTables: true, diff --git a/drivers/bridge/setup_ipv4_test.go b/drivers/bridge/setup_ipv4_test.go index e9f26d7..fb0409d 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/osl" "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 osl.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 osl.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 osl.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..c47db08 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/osl" "github.com/vishvananda/netlink" ) func TestSetupIPv6(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.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 osl.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..66d0778 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/osl" "github.com/vishvananda/netlink" ) @@ -23,7 +23,7 @@ func setupVerifyTest(t *testing.T) *bridgeInterface { } func TestSetupVerify(t *testing.T) { - defer netutils.SetupTestNetNS(t)() + defer osl.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 osl.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 osl.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 osl.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 osl.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 d5a1a0b..5bb257b 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/osl" "github.com/vishvananda/netlink" "github.com/vishvananda/netlink/nl" ) @@ -21,6 +22,8 @@ func validateID(nid, eid string) error { } func createVethPair() (string, string, error) { + defer osl.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 osl.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 osl.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 8fba632..fc05c23 100644 --- a/libnetwork_test.go +++ b/libnetwork_test.go @@ -257,7 +257,7 @@ func TestHost(t *testing.T) { func TestBridge(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } ip, subnet, err := net.ParseCIDR("192.168.100.1/24") @@ -330,7 +330,7 @@ func TestBridge(t *testing.T) { func TestUnknownDriver(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } _, err := createTestNetwork("unknowndriver", "testnetwork", options.Generic{}) @@ -357,7 +357,7 @@ func TestNilRemoteDriver(t *testing.T) { func TestDuplicateNetwork(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } // Creating a default bridge name network (can't be removed) @@ -378,7 +378,7 @@ func TestDuplicateNetwork(t *testing.T) { func TestNetworkName(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -415,7 +415,7 @@ func TestNetworkName(t *testing.T) { func TestNetworkType(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -442,7 +442,7 @@ func TestNetworkType(t *testing.T) { func TestNetworkID(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -469,7 +469,7 @@ func TestNetworkID(t *testing.T) { func TestDeleteNetworkWithActiveEndpoints(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -510,7 +510,7 @@ func TestDeleteNetworkWithActiveEndpoints(t *testing.T) { func TestUnknownNetwork(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -542,7 +542,7 @@ func TestUnknownNetwork(t *testing.T) { func TestUnknownEndpoint(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } ip, subnet, err := net.ParseCIDR("192.168.100.1/24") @@ -590,7 +590,7 @@ func TestUnknownEndpoint(t *testing.T) { func TestNetworkEndpointsWalkers(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } // Create network 1 and add 2 endpoint: ep11, ep12 @@ -722,7 +722,7 @@ func TestNetworkEndpointsWalkers(t *testing.T) { func TestDuplicateEndpoint(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } netOption := options.Generic{ @@ -772,7 +772,7 @@ func TestDuplicateEndpoint(t *testing.T) { func TestControllerQuery(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } // Create network 1 @@ -876,7 +876,7 @@ func TestControllerQuery(t *testing.T) { func TestNetworkQuery(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } // Create network 1 and add 2 endpoint: ep11, ep12 @@ -998,7 +998,7 @@ func checkSandbox(t *testing.T, info libnetwork.EndpointInfo) { func TestEndpointJoin(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } // Create network 1 and add 2 endpoint: ep11, ep12 @@ -1186,7 +1186,7 @@ func (f *fakeSandbox) Delete() error { func TestEndpointDeleteWithActiveContainer(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1250,7 +1250,7 @@ func TestEndpointDeleteWithActiveContainer(t *testing.T) { func TestEndpointMultipleJoins(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testmultiple", options.Generic{ @@ -1322,7 +1322,7 @@ func TestEndpointMultipleJoins(t *testing.T) { func TestLeaveAll(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1386,7 +1386,7 @@ func TestLeaveAll(t *testing.T) { func TestontainerInvalidLeave(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } n, err := createTestNetwork(bridgeNetType, "testnetwork", options.Generic{ @@ -1453,7 +1453,7 @@ func TestontainerInvalidLeave(t *testing.T) { func TestEndpointUpdateParent(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } n, err := createTestNetwork("bridge", "testnetwork", options.Generic{ @@ -1539,7 +1539,7 @@ func TestEndpointUpdateParent(t *testing.T) { func TestEnableIPv6(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } tmpResolvConf := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888\n") @@ -1635,7 +1635,7 @@ func TestEnableIPv6(t *testing.T) { func TestResolvConfHost(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } tmpResolvConf := []byte("search localhost.net\nnameserver 127.0.0.1\nnameserver 2001:4860:4860::8888\n") @@ -1714,7 +1714,7 @@ func TestResolvConfHost(t *testing.T) { func TestResolvConf(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } tmpResolvConf1 := []byte("search pommesfrites.fr\nnameserver 12.34.56.78\nnameserver 2001:4860:4860::8888\n") 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/osl/namespace_linux.go b/osl/namespace_linux.go index 843ef97..21619ed 100644 --- a/osl/namespace_linux.go +++ b/osl/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,37 @@ 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() - - origns, err := netns.Get() +func getLink() string { + l, err := os.Readlink(fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid())) if err != nil { - return err + return fmt.Sprintf("(nil: %v)", err) } - defer origns.Close() + + return l +} + +func nsInit() { + var err error + + if initNs, err = netns.Get(); err != nil { + log.Errorf("could not get initial namespace: %v", err) + } +} + +// InitOSContext initializes OS context while configuring network resources +func InitOSContext() func() { + runtime.LockOSThread() + nsOnce.Do(nsInit) + if err := netns.Set(initNs); err != nil { + log.Errorf("failed to set to initial namespace, link %s, initns fd %d: %v", + getLink(), initNs, 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 +293,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/osl/namespace_windows.go b/osl/namespace_windows.go index 6a79787..36bd6c8 100644 --- a/osl/namespace_windows.go +++ b/osl/namespace_windows.go @@ -1,5 +1,7 @@ package osl +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/osl/sandbox_freebsd.go b/osl/sandbox_freebsd.go index 6a79787..36bd6c8 100644 --- a/osl/sandbox_freebsd.go +++ b/osl/sandbox_freebsd.go @@ -1,5 +1,7 @@ package osl +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/osl/sandbox_test.go b/osl/sandbox_test.go index 585db31..892629d 100644 --- a/osl/sandbox_test.go +++ b/osl/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/osl/test_linux.go b/osl/test_linux.go new file mode 100644 index 0000000..eda915a --- /dev/null +++ b/osl/test_linux.go @@ -0,0 +1,37 @@ +package osl + +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() + } +} diff --git a/sandbox_test.go b/sandbox_test.go index 1434dbc..b6cd9a9 100644 --- a/sandbox_test.go +++ b/sandbox_test.go @@ -84,7 +84,7 @@ func TestSandboxAddEmpty(t *testing.T) { func TestSandboxAddMultiPrio(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } c, nw, _ := getTestEnv(t) @@ -161,7 +161,7 @@ func TestSandboxAddMultiPrio(t *testing.T) { func TestSandboxAddSamePrio(t *testing.T) { if !netutils.IsRunningInContainer() { - defer netutils.SetupTestNetNS(t)() + defer osl.SetupTestOSContext(t)() } c, nw1, nw2 := getTestEnv(t)