mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
0d29ca540f
Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
78 lines
1.5 KiB
Go
78 lines
1.5 KiB
Go
package libnetwork
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"runtime"
|
|
"syscall"
|
|
|
|
"github.com/vishvananda/netlink"
|
|
)
|
|
|
|
type setupError struct {
|
|
Message string
|
|
}
|
|
|
|
func (s setupError) Error() string {
|
|
return s.Message
|
|
}
|
|
|
|
func namespaceMoveInterface() {
|
|
runtime.LockOSThread()
|
|
|
|
var (
|
|
err error
|
|
pipe = os.NewFile(3, "child")
|
|
)
|
|
|
|
defer func() {
|
|
if err != nil {
|
|
ioutil.ReadAll(pipe)
|
|
if err := json.NewEncoder(pipe).Encode(setupError{Message: err.Error()}); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
pipe.Close()
|
|
}()
|
|
|
|
n := &Interface{}
|
|
if err = json.NewDecoder(pipe).Decode(n); err == nil {
|
|
err = setupInNS(os.Args[1], n)
|
|
}
|
|
}
|
|
|
|
func setupInNS(nsPath string, settings *Interface) error {
|
|
f, err := os.OpenFile(nsPath, os.O_RDONLY, 0)
|
|
if err != nil {
|
|
return fmt.Errorf("failed get network namespace %q: %v", nsPath, err)
|
|
}
|
|
|
|
// Find the network inteerface identified by the SrcName attribute.
|
|
iface, err := netlink.LinkByName(settings.SrcName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Move the network interface to the destination namespace.
|
|
nsFD := f.Fd()
|
|
if err := netlink.LinkSetNsFd(iface, int(nsFD)); err != nil {
|
|
return err
|
|
}
|
|
f.Close()
|
|
|
|
// Move the executing code to the destination namespace so we can start
|
|
// configure the interface.
|
|
if err := Setns(nsFD, syscall.CLONE_NEWNET); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Configure the interface now this is moved in the proper namespace.
|
|
if err := configureInterface(iface, settings); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Up the interface.
|
|
return netlink.LinkSetUp(iface)
|
|
}
|