diff options
Diffstat (limited to 'vendor/github.com/docker/libnetwork/ns')
-rw-r--r-- | vendor/github.com/docker/libnetwork/ns/init_linux.go | 140 | ||||
-rw-r--r-- | vendor/github.com/docker/libnetwork/ns/init_windows.go | 3 |
2 files changed, 143 insertions, 0 deletions
diff --git a/vendor/github.com/docker/libnetwork/ns/init_linux.go b/vendor/github.com/docker/libnetwork/ns/init_linux.go new file mode 100644 index 000000000..567a6242a --- /dev/null +++ b/vendor/github.com/docker/libnetwork/ns/init_linux.go @@ -0,0 +1,140 @@ +package ns + +import ( + "fmt" + "os" + "os/exec" + "strings" + "sync" + "syscall" + "time" + + "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" + "github.com/vishvananda/netns" +) + +var ( + initNs netns.NsHandle + initNl *netlink.Handle + initOnce sync.Once + // NetlinkSocketsTimeout represents the default timeout duration for the sockets + NetlinkSocketsTimeout = 3 * time.Second +) + +// Init initializes a new network namespace +func Init() { + var err error + initNs, err = netns.Get() + if err != nil { + logrus.Errorf("could not get initial namespace: %v", err) + } + initNl, err = netlink.NewHandle(getSupportedNlFamilies()...) + if err != nil { + logrus.Errorf("could not create netlink handle on initial namespace: %v", err) + } + err = initNl.SetSocketTimeout(NetlinkSocketsTimeout) + if err != nil { + logrus.Warnf("Failed to set the timeout on the default netlink handle sockets: %v", err) + } +} + +// SetNamespace sets the initial namespace handler +func SetNamespace() error { + initOnce.Do(Init) + 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 an integer +func ParseHandlerInt() int { + return int(getHandler()) +} + +// GetHandler returns the namespace handler +func getHandler() netns.NsHandle { + initOnce.Do(Init) + return initNs +} + +func getLink() (string, error) { + return os.Readlink(fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid())) +} + +// NlHandle returns the netlink handler +func NlHandle() *netlink.Handle { + initOnce.Do(Init) + return initNl +} + +func getSupportedNlFamilies() []int { + fams := []int{syscall.NETLINK_ROUTE} + // NETLINK_XFRM test + if err := loadXfrmModules(); err != nil { + if checkXfrmSocket() != nil { + logrus.Warnf("Could not load necessary modules for IPSEC rules: %v", err) + } else { + fams = append(fams, syscall.NETLINK_XFRM) + } + } else { + fams = append(fams, syscall.NETLINK_XFRM) + } + // NETLINK_NETFILTER test + if err := loadNfConntrackModules(); err != nil { + if checkNfSocket() != nil { + logrus.Warnf("Could not load necessary modules for Conntrack: %v", err) + } else { + fams = append(fams, syscall.NETLINK_NETFILTER) + } + } else { + fams = append(fams, syscall.NETLINK_NETFILTER) + } + + return fams +} + +func loadXfrmModules() error { + if out, err := exec.Command("modprobe", "-va", "xfrm_user").CombinedOutput(); err != nil { + return fmt.Errorf("Running modprobe xfrm_user failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) + } + if out, err := exec.Command("modprobe", "-va", "xfrm_algo").CombinedOutput(); err != nil { + return fmt.Errorf("Running modprobe xfrm_algo failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) + } + return nil +} + +// API check on required xfrm modules (xfrm_user, xfrm_algo) +func checkXfrmSocket() error { + fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_XFRM) + if err != nil { + return err + } + syscall.Close(fd) + return nil +} + +func loadNfConntrackModules() error { + if out, err := exec.Command("modprobe", "-va", "nf_conntrack").CombinedOutput(); err != nil { + return fmt.Errorf("Running modprobe nf_conntrack failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) + } + if out, err := exec.Command("modprobe", "-va", "nf_conntrack_netlink").CombinedOutput(); err != nil { + return fmt.Errorf("Running modprobe nf_conntrack_netlink failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) + } + return nil +} + +// API check on required nf_conntrack* modules (nf_conntrack, nf_conntrack_netlink) +func checkNfSocket() error { + fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER) + if err != nil { + return err + } + syscall.Close(fd) + return nil +} diff --git a/vendor/github.com/docker/libnetwork/ns/init_windows.go b/vendor/github.com/docker/libnetwork/ns/init_windows.go new file mode 100644 index 000000000..f5838f81d --- /dev/null +++ b/vendor/github.com/docker/libnetwork/ns/init_windows.go @@ -0,0 +1,3 @@ +package ns + +// File is present so that go build ./... is closer to working on Windows from repo root. |