mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #16130 from aboch/vnd
Vendoring libnetwork 3e31cead05cba8ec20241630d051e6d73765b3a2
This commit is contained in:
commit
eb5c81e799
11 changed files with 133 additions and 77 deletions
|
@ -14,4 +14,9 @@ func (s *Server) registerSubRouter() {
|
||||||
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
|
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
|
||||||
subrouter = s.router.PathPrefix("/services").Subrouter()
|
subrouter = s.router.PathPrefix("/services").Subrouter()
|
||||||
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
|
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
|
||||||
|
|
||||||
|
subrouter = s.router.PathPrefix("/v{version:[0-9.]+}/sandboxes").Subrouter()
|
||||||
|
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
|
||||||
|
subrouter = s.router.PathPrefix("/sandboxes").Subrouter()
|
||||||
|
subrouter.Methods("GET", "POST", "PUT", "DELETE").HandlerFunc(httpHandler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ clone git github.com/tchap/go-patricia v2.1.0
|
||||||
clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git
|
clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git
|
||||||
|
|
||||||
#get libnetwork packages
|
#get libnetwork packages
|
||||||
clone git github.com/docker/libnetwork dc52820147f40fe424c8959987af3b396f842639
|
clone git github.com/docker/libnetwork 3e31cead05cba8ec20241630d051e6d73765b3a2
|
||||||
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||||
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
||||||
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
|
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
|
||||||
|
|
|
@ -252,9 +252,8 @@ func (h *Handle) set(ordinal uint32, any bool, release bool) (uint32, error) {
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a private copy of h and work on it, also copy the current db index
|
// Create a private copy of h and work on it
|
||||||
nh := h.getCopy()
|
nh := h.getCopy()
|
||||||
ci := h.dbIndex
|
|
||||||
h.Unlock()
|
h.Unlock()
|
||||||
|
|
||||||
nh.head = pushReservation(bytePos, bitPos, nh.head, release)
|
nh.head = pushReservation(bytePos, bitPos, nh.head, release)
|
||||||
|
@ -273,12 +272,9 @@ func (h *Handle) set(ordinal uint32, any bool, release bool) (uint32, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unless unexpected error, save private copy to local copy
|
// Previous atomic push was succesfull. Save private copy to local copy
|
||||||
h.Lock()
|
h.Lock()
|
||||||
defer h.Unlock()
|
defer h.Unlock()
|
||||||
if h.dbIndex != ci {
|
|
||||||
return ret, fmt.Errorf("unexected database index change")
|
|
||||||
}
|
|
||||||
h.unselected = nh.unselected
|
h.unselected = nh.unselected
|
||||||
h.head = nh.head
|
h.head = nh.head
|
||||||
h.dbExists = nh.dbExists
|
h.dbExists = nh.dbExists
|
||||||
|
|
|
@ -268,14 +268,12 @@ func getBackendID(cli *NetworkCli, servID string) (string, error) {
|
||||||
)
|
)
|
||||||
|
|
||||||
if obj, _, err = readBody(cli.call("GET", "/services/"+servID+"/backend", nil, nil)); err == nil {
|
if obj, _, err = readBody(cli.call("GET", "/services/"+servID+"/backend", nil, nil)); err == nil {
|
||||||
var bkl []sandboxResource
|
var sr sandboxResource
|
||||||
if err := json.NewDecoder(bytes.NewReader(obj)).Decode(&bkl); err == nil {
|
if err := json.NewDecoder(bytes.NewReader(obj)).Decode(&sr); err == nil {
|
||||||
if len(bkl) > 0 {
|
bk = sr.ContainerID
|
||||||
bk = bkl[0].ID
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Only print a message, don't make the caller cli fail for this
|
// Only print a message, don't make the caller cli fail for this
|
||||||
fmt.Fprintf(cli.out, "Failed to retrieve backend list for service %s (%v)", servID, err)
|
fmt.Fprintf(cli.out, "Failed to retrieve backend list for service %s (%v)\n", servID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ type bridgeNetwork struct {
|
||||||
|
|
||||||
type driver struct {
|
type driver struct {
|
||||||
config *configuration
|
config *configuration
|
||||||
|
configured bool
|
||||||
network *bridgeNetwork
|
network *bridgeNetwork
|
||||||
natChain *iptables.ChainInfo
|
natChain *iptables.ChainInfo
|
||||||
filterChain *iptables.ChainInfo
|
filterChain *iptables.ChainInfo
|
||||||
|
@ -105,13 +106,10 @@ type driver struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
ipAllocator = ipallocator.New()
|
|
||||||
}
|
|
||||||
|
|
||||||
// New constructs a new bridge driver
|
// New constructs a new bridge driver
|
||||||
func newDriver() driverapi.Driver {
|
func newDriver() driverapi.Driver {
|
||||||
return &driver{networks: map[string]*bridgeNetwork{}}
|
ipAllocator = ipallocator.New()
|
||||||
|
return &driver{networks: map[string]*bridgeNetwork{}, config: &configuration{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init registers a new instance of bridge driver
|
// Init registers a new instance of bridge driver
|
||||||
|
@ -436,12 +434,15 @@ func (d *driver) Config(option map[string]interface{}) error {
|
||||||
d.Lock()
|
d.Lock()
|
||||||
defer d.Unlock()
|
defer d.Unlock()
|
||||||
|
|
||||||
if d.config != nil {
|
if d.configured {
|
||||||
return &ErrConfigExists{}
|
return &ErrConfigExists{}
|
||||||
}
|
}
|
||||||
|
|
||||||
genericData, ok := option[netlabel.GenericData]
|
genericData, ok := option[netlabel.GenericData]
|
||||||
if ok && genericData != nil {
|
if !ok || genericData == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
switch opt := genericData.(type) {
|
switch opt := genericData.(type) {
|
||||||
case options.Generic:
|
case options.Generic:
|
||||||
opaqueConfig, err := options.GenerateFromModel(opt, &configuration{})
|
opaqueConfig, err := options.GenerateFromModel(opt, &configuration{})
|
||||||
|
@ -455,12 +456,6 @@ func (d *driver) Config(option map[string]interface{}) error {
|
||||||
return &ErrInvalidDriverConfig{}
|
return &ErrInvalidDriverConfig{}
|
||||||
}
|
}
|
||||||
|
|
||||||
d.config = config
|
|
||||||
} else {
|
|
||||||
config = &configuration{}
|
|
||||||
d.config = config
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.EnableIPForwarding {
|
if config.EnableIPForwarding {
|
||||||
err = setupIPForwarding()
|
err = setupIPForwarding()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -470,9 +465,13 @@ func (d *driver) Config(option map[string]interface{}) error {
|
||||||
|
|
||||||
if config.EnableIPTables {
|
if config.EnableIPTables {
|
||||||
d.natChain, d.filterChain, err = setupIPChains(config)
|
d.natChain, d.filterChain, err = setupIPChains(config)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.configured = true
|
||||||
|
d.config = config
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,12 +568,20 @@ func (d *driver) getNetworks() []*bridgeNetwork {
|
||||||
|
|
||||||
// Create a new network using bridge plugin
|
// Create a new network using bridge plugin
|
||||||
func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
||||||
var err error
|
var (
|
||||||
|
err error
|
||||||
|
configLocked bool
|
||||||
|
)
|
||||||
|
|
||||||
defer osl.InitOSContext()()
|
defer osl.InitOSContext()()
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
d.Lock()
|
d.Lock()
|
||||||
|
if !d.configured {
|
||||||
|
configLocked = true
|
||||||
|
d.configured = true
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := d.networks[id]; ok {
|
if _, ok := d.networks[id]; ok {
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
return types.ForbiddenErrorf("network %s exists", id)
|
return types.ForbiddenErrorf("network %s exists", id)
|
||||||
|
@ -613,6 +620,10 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.Lock()
|
d.Lock()
|
||||||
|
if configLocked {
|
||||||
|
d.configured = false
|
||||||
|
}
|
||||||
|
|
||||||
delete(d.networks, id)
|
delete(d.networks, id)
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
}
|
}
|
||||||
|
@ -654,7 +665,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}) error {
|
||||||
bridgeSetup.queueStep(setupBridgeIPv4)
|
bridgeSetup.queueStep(setupBridgeIPv4)
|
||||||
|
|
||||||
enableIPv6Forwarding := false
|
enableIPv6Forwarding := false
|
||||||
if d.config != nil && d.config.EnableIPForwarding && config.FixedCIDRv6 != nil {
|
if d.config.EnableIPForwarding && config.FixedCIDRv6 != nil {
|
||||||
enableIPv6Forwarding = true
|
enableIPv6Forwarding = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,6 +802,18 @@ func (d *driver) DeleteNetwork(nid string) error {
|
||||||
// Programming
|
// Programming
|
||||||
err = netlink.LinkDel(n.bridge.Link)
|
err = netlink.LinkDel(n.bridge.Link)
|
||||||
|
|
||||||
|
// Release ip addresses (ignore errors)
|
||||||
|
if config.FixedCIDR == nil || config.FixedCIDR.Contains(config.DefaultGatewayIPv4) {
|
||||||
|
if e := ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, n.bridge.gatewayIPv4); e != nil {
|
||||||
|
logrus.Warnf("Failed to release default gateway address %s: %v", n.bridge.gatewayIPv4.String(), e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if config.FixedCIDR == nil || config.FixedCIDR.Contains(n.bridge.bridgeIPv4.IP) {
|
||||||
|
if e := ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, n.bridge.bridgeIPv4.IP); e != nil {
|
||||||
|
logrus.Warnf("Failed to release bridge IP %s: %v", n.bridge.bridgeIPv4.IP.String(), e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Creating bridge interface %q with network %s", config.BridgeName, bridgeIPv4)
|
log.Debugf("Creating bridge interface %s with network %s", config.BridgeName, bridgeIPv4)
|
||||||
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
|
if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: bridgeIPv4}); err != nil {
|
||||||
return &IPv4AddrAddError{IP: bridgeIPv4, Err: err}
|
return &IPv4AddrAddError{IP: bridgeIPv4, Err: err}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,9 @@ func allocateBridgeIP(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
// reserve bridge address only if it belongs to the container network
|
// reserve bridge address only if it belongs to the container network
|
||||||
// (if defined), no need otherwise
|
// (if defined), no need otherwise
|
||||||
if config.FixedCIDR == nil || config.FixedCIDR.Contains(i.bridgeIPv4.IP) {
|
if config.FixedCIDR == nil || config.FixedCIDR.Contains(i.bridgeIPv4.IP) {
|
||||||
ipAllocator.RequestIP(i.bridgeIPv4, i.bridgeIPv4.IP)
|
if _, err := ipAllocator.RequestIP(i.bridgeIPv4, i.bridgeIPv4.IP); err != nil {
|
||||||
|
return fmt.Errorf("failed to reserve bridge IP %s: %v", i.bridgeIPv4.IP.String(), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -120,7 +122,7 @@ func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
||||||
// (if defined), no need otherwise
|
// (if defined), no need otherwise
|
||||||
if config.FixedCIDR == nil || config.FixedCIDR.Contains(config.DefaultGatewayIPv4) {
|
if config.FixedCIDR == nil || config.FixedCIDR.Contains(config.DefaultGatewayIPv4) {
|
||||||
if _, err := ipAllocator.RequestIP(i.bridgeIPv4, config.DefaultGatewayIPv4); err != nil {
|
if _, err := ipAllocator.RequestIP(i.bridgeIPv4, config.DefaultGatewayIPv4); err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to reserve default gateway %s: %v", config.DefaultGatewayIPv4.String(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,15 +35,31 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the container interface and its peer MTU to 1450 to allow
|
||||||
|
// for 50 bytes vxlan encap (inner eth header(14) + outer IP(20) +
|
||||||
|
// outer UDP(8) + vxlan header(8))
|
||||||
|
veth, err := netlink.LinkByName(name1)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cound not find link by name %s: %v", name1, err)
|
||||||
|
}
|
||||||
|
err = netlink.LinkSetMTU(veth, vxlanVethMTU)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := sbox.AddInterface(name1, "veth",
|
if err := sbox.AddInterface(name1, "veth",
|
||||||
sbox.InterfaceOptions().Master("bridge1")); err != nil {
|
sbox.InterfaceOptions().Master("bridge1")); err != nil {
|
||||||
return fmt.Errorf("could not add veth pair inside the network sandbox: %v", err)
|
return fmt.Errorf("could not add veth pair inside the network sandbox: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
veth, err := netlink.LinkByName(name2)
|
veth, err = netlink.LinkByName(name2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not find link by name %s: %v", name2, err)
|
return fmt.Errorf("could not find link by name %s: %v", name2, err)
|
||||||
}
|
}
|
||||||
|
err = netlink.LinkSetMTU(veth, vxlanVethMTU)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := netlink.LinkSetHardwareAddr(veth, ep.mac); err != nil {
|
if err := netlink.LinkSetHardwareAddr(veth, ep.mac); err != nil {
|
||||||
return fmt.Errorf("could not set mac address to the container interface: %v", err)
|
return fmt.Errorf("could not set mac address to the container interface: %v", err)
|
||||||
|
|
|
@ -21,6 +21,7 @@ const (
|
||||||
vxlanIDStart = 256
|
vxlanIDStart = 256
|
||||||
vxlanIDEnd = 1000
|
vxlanIDEnd = 1000
|
||||||
vxlanPort = 4789
|
vxlanPort = 4789
|
||||||
|
vxlanVethMTU = 1450
|
||||||
)
|
)
|
||||||
|
|
||||||
type driver struct {
|
type driver struct {
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package netutils
|
|
||||||
|
|
||||||
import "flag"
|
|
||||||
|
|
||||||
var runningInContainer = flag.Bool("incontainer", false, "Indicates if the test is running in a container")
|
|
||||||
|
|
||||||
// IsRunningInContainer returns whether the test is running inside a container.
|
|
||||||
func IsRunningInContainer() bool {
|
|
||||||
return (*runningInContainer)
|
|
||||||
}
|
|
43
vendor/src/github.com/docker/libnetwork/ns/init_linux.go
vendored
Normal file
43
vendor/src/github.com/docker/libnetwork/ns/init_linux.go
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package ns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/vishvananda/netns"
|
||||||
|
)
|
||||||
|
|
||||||
|
var initNs netns.NsHandle
|
||||||
|
|
||||||
|
// Init initializes a new network namespace
|
||||||
|
func Init() {
|
||||||
|
var err error
|
||||||
|
initNs, err = netns.Get()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("could not get initial namespace: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNamespace sets the initial namespace handler
|
||||||
|
func SetNamespace() error {
|
||||||
|
if err := netns.Set(initNs); err != nil {
|
||||||
|
linkInfo, linkErr := getLink()
|
||||||
|
if linkErr != nil {
|
||||||
|
linkInfo = linkErr.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("failed to set to initial namespace, %v, initns fd %d: %v", linkInfo, initNs, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseHandlerInt transforms the namespace handler into a integer
|
||||||
|
func ParseHandlerInt() int {
|
||||||
|
return int(initNs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLink() (string, error) {
|
||||||
|
return os.Readlink(fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid()))
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/docker/pkg/reexec"
|
"github.com/docker/docker/pkg/reexec"
|
||||||
|
"github.com/docker/libnetwork/ns"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
|
@ -27,7 +28,6 @@ var (
|
||||||
gpmCleanupPeriod = 60 * time.Second
|
gpmCleanupPeriod = 60 * time.Second
|
||||||
gpmChan = make(chan chan struct{})
|
gpmChan = make(chan chan struct{})
|
||||||
nsOnce sync.Once
|
nsOnce sync.Once
|
||||||
initNs netns.NsHandle
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The networkNamespace type is the linux implementation of the Sandbox
|
// The networkNamespace type is the linux implementation of the Sandbox
|
||||||
|
@ -244,30 +244,12 @@ func (n *networkNamespace) InvokeFunc(f func()) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLink() (string, error) {
|
|
||||||
return os.Readlink(fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid()))
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// InitOSContext initializes OS context while configuring network resources
|
||||||
func InitOSContext() func() {
|
func InitOSContext() func() {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
nsOnce.Do(nsInit)
|
nsOnce.Do(ns.Init)
|
||||||
if err := netns.Set(initNs); err != nil {
|
if err := ns.SetNamespace(); err != nil {
|
||||||
linkInfo, linkErr := getLink()
|
log.Error(err)
|
||||||
if linkErr != nil {
|
|
||||||
linkInfo = linkErr.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Errorf("failed to set to initial namespace, %v, initns fd %d: %v",
|
|
||||||
linkInfo, initNs, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return runtime.UnlockOSThread
|
return runtime.UnlockOSThread
|
||||||
|
@ -293,10 +275,10 @@ func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD
|
||||||
if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
|
if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer netns.Set(initNs)
|
defer ns.SetNamespace()
|
||||||
|
|
||||||
// Invoked after the namespace switch.
|
// Invoked after the namespace switch.
|
||||||
return postfunc(int(initNs))
|
return postfunc(ns.ParseHandlerInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *networkNamespace) nsPath() string {
|
func (n *networkNamespace) nsPath() string {
|
||||||
|
|
Loading…
Reference in a new issue