|
@@ -3,8 +3,10 @@ package overlay
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
+ "io/ioutil"
|
|
|
"net"
|
|
|
"os"
|
|
|
+ "os/exec"
|
|
|
"path/filepath"
|
|
|
"strconv"
|
|
|
"strings"
|
|
@@ -12,6 +14,7 @@ import (
|
|
|
"syscall"
|
|
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
|
+ "github.com/docker/docker/pkg/reexec"
|
|
|
"github.com/docker/libnetwork/datastore"
|
|
|
"github.com/docker/libnetwork/driverapi"
|
|
|
"github.com/docker/libnetwork/netlabel"
|
|
@@ -67,6 +70,54 @@ type network struct {
|
|
|
sync.Mutex
|
|
|
}
|
|
|
|
|
|
+func init() {
|
|
|
+ reexec.Register("set-default-vlan", setDefaultVlan)
|
|
|
+}
|
|
|
+
|
|
|
+func setDefaultVlan() {
|
|
|
+ if len(os.Args) < 3 {
|
|
|
+ logrus.Error("insufficient number of arguments")
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ nsPath := os.Args[1]
|
|
|
+ ns, err := netns.GetFromPath(nsPath)
|
|
|
+ if err != nil {
|
|
|
+ logrus.Errorf("overlay namespace get failed, %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ if err = netns.Set(ns); err != nil {
|
|
|
+ logrus.Errorf("setting into overlay namespace failed, %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure the sysfs mount doesn't propagate back
|
|
|
+ if err = syscall.Unshare(syscall.CLONE_NEWNS); err != nil {
|
|
|
+ logrus.Errorf("unshare failed, %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ flag := syscall.MS_PRIVATE | syscall.MS_REC
|
|
|
+ if err = syscall.Mount("", "/", "", uintptr(flag), ""); err != nil {
|
|
|
+ logrus.Errorf("root mount failed, %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err = syscall.Mount("sysfs", "/sys", "sysfs", 0, ""); err != nil {
|
|
|
+ logrus.Errorf("mounting sysfs failed, %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ brName := os.Args[2]
|
|
|
+ path := filepath.Join("/sys/class/net", brName, "bridge/default_pvid")
|
|
|
+ data := []byte{'0', '\n'}
|
|
|
+
|
|
|
+ if err = ioutil.WriteFile(path, data, 0644); err != nil {
|
|
|
+ logrus.Errorf("endbling default vlan on bridge %s failed %v", brName, err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ os.Exit(0)
|
|
|
+}
|
|
|
+
|
|
|
func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
|
|
|
return nil, types.NotImplementedErrorf("not implemented")
|
|
|
}
|
|
@@ -505,6 +556,25 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
|
|
|
return fmt.Errorf("vxlan interface creation failed for subnet %q: %v", s.subnetIP.String(), err)
|
|
|
}
|
|
|
|
|
|
+ if !hostMode {
|
|
|
+ var name string
|
|
|
+ for _, i := range sbox.Info().Interfaces() {
|
|
|
+ if i.Bridge() {
|
|
|
+ name = i.DstName()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cmd := &exec.Cmd{
|
|
|
+ Path: reexec.Self(),
|
|
|
+ Args: []string{"set-default-vlan", sbox.Key(), name},
|
|
|
+ Stdout: os.Stdout,
|
|
|
+ Stderr: os.Stderr,
|
|
|
+ }
|
|
|
+ if err := cmd.Run(); err != nil {
|
|
|
+ // not a fatal error
|
|
|
+ logrus.Errorf("reexec to set bridge default vlan failed %v", err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if hostMode {
|
|
|
if err := addFilters(n.id[:12], brName); err != nil {
|
|
|
return err
|