diff --git a/docs/userguide/networking/get-started-overlay.md b/docs/userguide/networking/get-started-overlay.md
index 708684e2da..17e840c52f 100644
--- a/docs/userguide/networking/get-started-overlay.md
+++ b/docs/userguide/networking/get-started-overlay.md
@@ -16,7 +16,6 @@ network. Docker Engine supports multi-host networking out-of-the-box through the
 `overlay` network driver.  Unlike `bridge` networks, overlay networks require
 some pre-existing conditions before you can create one. These conditions are:
 
-* A host with a 3.16 kernel version or higher.
 * Access to a key-value store. Docker supports Consul, Etcd, and ZooKeeper (Distributed store) key-value stores.
 * A cluster of hosts with connectivity to the key-value store.
 * A properly configured Engine `daemon` on each host in the cluster.
@@ -46,7 +45,7 @@ key-value stores. This example uses Consul.
 
 1. Log into a system prepared with the prerequisite Docker Engine, Docker Machine, and VirtualBox software.
 
-2. Provision a VirtualBox machine called `mh-keystore`.  
+2. Provision a VirtualBox machine called `mh-keystore`.
 
 		$ docker-machine create -d virtualbox mh-keystore
 
diff --git a/hack/vendor.sh b/hack/vendor.sh
index f57884eaa2..d99f9a4a48 100755
--- a/hack/vendor.sh
+++ b/hack/vendor.sh
@@ -24,7 +24,7 @@ clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
 clone git github.com/docker/go-connections 4e42727957c146776e5de9cec8c39e4059ed9f20
 
 #get libnetwork packages
-clone git github.com/docker/libnetwork bbd6e6d8ca1e7c9b42f6f53277b0bde72847ff90
+clone git github.com/docker/libnetwork 9f0563ea8f430d8828553aac97161cbff4056436
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
 clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
 clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
diff --git a/vendor/src/github.com/docker/libnetwork/controller.go b/vendor/src/github.com/docker/libnetwork/controller.go
index be9b726a28..c1aa6bb9e1 100644
--- a/vendor/src/github.com/docker/libnetwork/controller.go
+++ b/vendor/src/github.com/docker/libnetwork/controller.go
@@ -121,7 +121,8 @@ type driverData struct {
 }
 
 type ipamData struct {
-	driver ipamapi.Ipam
+	driver     ipamapi.Ipam
+	capability *ipamapi.Capability
 	// default address spaces are provided by ipam driver at registration time
 	defaultLocalAddressSpace, defaultGlobalAddressSpace string
 }
@@ -306,7 +307,7 @@ func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver,
 	return nil
 }
 
-func (c *controller) RegisterIpamDriver(name string, driver ipamapi.Ipam) error {
+func (c *controller) registerIpamDriver(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error {
 	if !config.IsValidName(name) {
 		return ErrInvalidName(name)
 	}
@@ -322,7 +323,7 @@ func (c *controller) RegisterIpamDriver(name string, driver ipamapi.Ipam) error
 		return types.InternalErrorf("ipam driver %q failed to return default address spaces: %v", name, err)
 	}
 	c.Lock()
-	c.ipamDrivers[name] = &ipamData{driver: driver, defaultLocalAddressSpace: locAS, defaultGlobalAddressSpace: glbAS}
+	c.ipamDrivers[name] = &ipamData{driver: driver, defaultLocalAddressSpace: locAS, defaultGlobalAddressSpace: glbAS, capability: caps}
 	c.Unlock()
 
 	log.Debugf("Registering ipam driver: %q", name)
@@ -330,6 +331,14 @@ func (c *controller) RegisterIpamDriver(name string, driver ipamapi.Ipam) error
 	return nil
 }
 
+func (c *controller) RegisterIpamDriver(name string, driver ipamapi.Ipam) error {
+	return c.registerIpamDriver(name, driver, &ipamapi.Capability{})
+}
+
+func (c *controller) RegisterIpamDriverWithCapabilities(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error {
+	return c.registerIpamDriver(name, driver, caps)
+}
+
 // NewNetwork creates a new network of the specified network type. The options
 // are network specific and modeled in a generic way.
 func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) {
diff --git a/vendor/src/github.com/docker/libnetwork/default_gateway.go b/vendor/src/github.com/docker/libnetwork/default_gateway.go
index 139242c6a5..d9277ba577 100644
--- a/vendor/src/github.com/docker/libnetwork/default_gateway.go
+++ b/vendor/src/github.com/docker/libnetwork/default_gateway.go
@@ -103,6 +103,9 @@ func (sb *sandbox) needDefaultGW() bool {
 		if ep.getNetwork().Type() == "null" || ep.getNetwork().Type() == "host" {
 			continue
 		}
+		if ep.getNetwork().Internal() {
+			return false
+		}
 		if ep.joinInfo.disableGatewayService {
 			return false
 		}
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go
index 7991c6f67c..04f5a4c81b 100644
--- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go
+++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/bridge.go
@@ -490,6 +490,12 @@ func parseNetworkOptions(id string, option options.Generic) (*networkConfigurati
 		config.EnableIPv6 = val.(bool)
 	}
 
+	if val, ok := option[netlabel.Internal]; ok {
+		if internal, ok := val.(bool); ok && internal {
+			return nil, &driverapi.ErrNotImplemented{}
+		}
+	}
+
 	// Finally validate the configuration
 	if err = config.Validate(); err != nil {
 		return nil, err
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go
index f7a536adb0..aa6c8eba4c 100644
--- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go
+++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go
@@ -157,6 +157,6 @@ func isPacketForwardingEnabled(ipVer ipVersion, iface string) (bool, error) {
 }
 
 func isRunningInContainer() bool {
-	_, err := os.Stat("/.dockerinit")
+	_, err := os.Stat("/.dockerenv")
 	return !os.IsNotExist(err)
 }
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go
index 5ce53dd879..2613b3e95a 100644
--- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go
+++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ipv6.go
@@ -62,6 +62,13 @@ func setupBridgeIPv6(config *networkConfiguration, i *bridgeInterface) error {
 		return nil
 	}
 
+	// Store and program user specified bridge network and network gateway
+	i.bridgeIPv6 = config.AddressIPv6
+	i.gatewayIPv6 = config.AddressIPv6.IP
+	if err := netlink.AddrAdd(i.Link, &netlink.Addr{IPNet: i.bridgeIPv6}); err != nil {
+		return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: err}
+	}
+
 	// Setting route to global IPv6 subnet
 	logrus.Debugf("Adding route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
 	err = netlink.RouteAdd(&netlink.Route{
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/filter.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/filter.go
new file mode 100644
index 0000000000..0607548140
--- /dev/null
+++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/filter.go
@@ -0,0 +1,131 @@
+package overlay
+
+import (
+	"fmt"
+	"sync"
+
+	"github.com/Sirupsen/logrus"
+	"github.com/docker/libnetwork/iptables"
+)
+
+const globalChain = "DOCKER-OVERLAY"
+
+var filterOnce sync.Once
+
+func rawIPTables(args ...string) error {
+	if output, err := iptables.Raw(args...); err != nil {
+		return fmt.Errorf("unable to add overlay filter: %v", err)
+	} else if len(output) != 0 {
+		return fmt.Errorf("unable to add overlay filter: %s", string(output))
+	}
+
+	return nil
+}
+
+func chainExists(cname string) bool {
+	if _, err := iptables.Raw("-L", cname); err != nil {
+		return false
+	}
+
+	return true
+}
+
+func setupGlobalChain() {
+	if err := rawIPTables("-N", globalChain); err != nil {
+		logrus.Debugf("could not create global overlay chain: %v", err)
+	}
+
+	if err := rawIPTables("-A", globalChain, "-j", "RETURN"); err != nil {
+		logrus.Debugf("could not install default return chain in the overlay global chain: %v", err)
+	}
+}
+
+func setNetworkChain(cname string, remove bool) error {
+	// Initialize the onetime global overlay chain
+	filterOnce.Do(setupGlobalChain)
+
+	exists := chainExists(cname)
+
+	opt := "-N"
+	// In case of remove, make sure to flush the rules in the chain
+	if remove && exists {
+		if err := rawIPTables("-F", cname); err != nil {
+			return fmt.Errorf("failed to flush overlay network chain %s rules: %v", cname, err)
+		}
+		opt = "-X"
+	}
+
+	if (!remove && !exists) || (remove && exists) {
+		if err := rawIPTables(opt, cname); err != nil {
+			return fmt.Errorf("failed network chain operation %q for chain %s: %v", opt, cname, err)
+		}
+	}
+
+	if !remove {
+		if !iptables.Exists(iptables.Filter, cname, "-j", "DROP") {
+			if err := rawIPTables("-A", cname, "-j", "DROP"); err != nil {
+				return fmt.Errorf("failed adding default drop rule to overlay network chain %s: %v", cname, err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func addNetworkChain(cname string) error {
+	return setNetworkChain(cname, false)
+}
+
+func removeNetworkChain(cname string) error {
+	return setNetworkChain(cname, true)
+}
+
+func setFilters(cname, brName string, remove bool) error {
+	opt := "-I"
+	if remove {
+		opt = "-D"
+	}
+
+	// Everytime we set filters for a new subnet make sure to move the global overlay hook to the top of the both the OUTPUT and forward chains
+	if !remove {
+		for _, chain := range []string{"OUTPUT", "FORWARD"} {
+			exists := iptables.Exists(iptables.Filter, chain, "-j", globalChain)
+			if exists {
+				if err := rawIPTables("-D", chain, "-j", globalChain); err != nil {
+					return fmt.Errorf("failed to delete overlay hook in chain %s while moving the hook: %v", chain, err)
+				}
+			}
+
+			if err := rawIPTables("-I", chain, "-j", globalChain); err != nil {
+				return fmt.Errorf("failed to insert overlay hook in chain %s: %v", chain, err)
+			}
+		}
+	}
+
+	// Insert/Delete the rule to jump to per-bridge chain
+	exists := iptables.Exists(iptables.Filter, globalChain, "-o", brName, "-j", cname)
+	if (!remove && !exists) || (remove && exists) {
+		if err := rawIPTables(opt, globalChain, "-o", brName, "-j", cname); err != nil {
+			return fmt.Errorf("failed to add per-bridge filter rule for bridge %s, network chain %s: %v", brName, cname, err)
+		}
+	}
+
+	exists = iptables.Exists(iptables.Filter, cname, "-i", brName, "-j", "ACCEPT")
+	if (!remove && exists) || (remove && !exists) {
+		return nil
+	}
+
+	if err := rawIPTables(opt, cname, "-i", brName, "-j", "ACCEPT"); err != nil {
+		return fmt.Errorf("failed to add overlay filter rile for network chain %s, bridge %s: %v", cname, brName, err)
+	}
+
+	return nil
+}
+
+func addFilters(cname, brName string) error {
+	return setFilters(cname, brName, false)
+}
+
+func removeFilters(cname, brName string) error {
+	return setFilters(cname, brName, true)
+}
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go
index e67757b4f0..0a891c0e5e 100644
--- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go
+++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_network.go
@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"net"
+	"os"
 	"sync"
 	"syscall"
 
@@ -12,11 +13,17 @@ import (
 	"github.com/docker/libnetwork/driverapi"
 	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/osl"
+	"github.com/docker/libnetwork/resolvconf"
 	"github.com/docker/libnetwork/types"
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netlink/nl"
 )
 
+var (
+	hostMode     bool
+	hostModeOnce sync.Once
+)
+
 type networkTable map[string]*network
 
 type subnet struct {
@@ -87,22 +94,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, ipV4Dat
 	return nil
 }
 
-/* func (d *driver) createNetworkfromStore(nid string) (*network, error) {
-	n := &network{
-		id:        nid,
-		driver:    d,
-		endpoints: endpointTable{},
-		once:      &sync.Once{},
-		subnets:   []*subnet{},
-	}
-
-	err := d.store.GetObject(datastore.Key(n.Key()...), n)
-	if err != nil {
-		return nil, fmt.Errorf("unable to get network %q from data store, %v", nid, err)
-	}
-	return n, nil
-}*/
-
 func (d *driver) DeleteNetwork(nid string) error {
 	if nid == "" {
 		return fmt.Errorf("invalid network id")
@@ -171,24 +162,110 @@ func (n *network) destroySandbox() {
 		}
 
 		for _, s := range n.subnets {
+			if hostMode {
+				if err := removeFilters(n.id[:12], s.brName); err != nil {
+					logrus.Warnf("Could not remove overlay filters: %v", err)
+				}
+			}
+
 			if s.vxlanName != "" {
-				err := deleteVxlan(s.vxlanName)
+				err := deleteInterface(s.vxlanName)
 				if err != nil {
 					logrus.Warnf("could not cleanup sandbox properly: %v", err)
 				}
 			}
 		}
+
+		if hostMode {
+			if err := removeNetworkChain(n.id[:12]); err != nil {
+				logrus.Warnf("could not remove network chain: %v", err)
+			}
+		}
+
 		sbox.Destroy()
 		n.setSandbox(nil)
 	}
 }
 
-func (n *network) initSubnetSandbox(s *subnet) error {
-	// create a bridge and vxlan device for this subnet and move it to the sandbox
-	brName, err := netutils.GenerateIfaceName("bridge", 7)
-	if err != nil {
-		return err
+func setHostMode() {
+	if os.Getenv("_OVERLAY_HOST_MODE") != "" {
+		hostMode = true
+		return
 	}
+
+	err := createVxlan("testvxlan", 1)
+	if err != nil {
+		logrus.Errorf("Failed to create testvxlan interface: %v", err)
+		return
+	}
+
+	defer deleteInterface("testvxlan")
+
+	path := "/proc/self/ns/net"
+	f, err := os.OpenFile(path, os.O_RDONLY, 0)
+	if err != nil {
+		logrus.Errorf("Failed to open path %s for network namespace for setting host mode: %v", path, err)
+		return
+	}
+	defer f.Close()
+
+	nsFD := f.Fd()
+
+	iface, err := netlink.LinkByName("testvxlan")
+	if err != nil {
+		logrus.Errorf("Failed to get link testvxlan: %v", err)
+		return
+	}
+
+	// If we are not able to move the vxlan interface to a namespace
+	// then fallback to host mode
+	if err := netlink.LinkSetNsFd(iface, int(nsFD)); err != nil {
+		hostMode = true
+	}
+}
+
+func (n *network) generateVxlanName(s *subnet) string {
+	return "vx-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + n.id[:5]
+}
+
+func (n *network) generateBridgeName(s *subnet) string {
+	return "ov-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + n.id[:5]
+}
+
+func isOverlap(nw *net.IPNet) bool {
+	var nameservers []string
+
+	if rc, err := resolvconf.Get(); err == nil {
+		nameservers = resolvconf.GetNameserversAsCIDR(rc.Content)
+	}
+
+	if err := netutils.CheckNameserverOverlaps(nameservers, nw); err != nil {
+		return true
+	}
+
+	if err := netutils.CheckRouteOverlaps(nw); err != nil {
+		return true
+	}
+
+	return false
+}
+
+func (n *network) initSubnetSandbox(s *subnet) error {
+	brName := n.generateBridgeName(s)
+	vxlanName := n.generateVxlanName(s)
+
+	if hostMode {
+		// Try to delete stale bridge interface if it exists
+		deleteInterface(brName)
+		// Try to delete the vxlan interface by vni if already present
+		deleteVxlanByVNI(n.vxlanID(s))
+
+		if isOverlap(s.subnetIP) {
+			return fmt.Errorf("overlay subnet %s has conflicts in the host while running in host mode", s.subnetIP.String())
+		}
+	}
+
+	// create a bridge and vxlan device for this subnet and move it to the sandbox
 	sbox := n.sandbox()
 
 	if err := sbox.AddInterface(brName, "br",
@@ -197,7 +274,7 @@ func (n *network) initSubnetSandbox(s *subnet) error {
 		return fmt.Errorf("bridge creation in sandbox failed for subnet %q: %v", s.subnetIP.String(), err)
 	}
 
-	vxlanName, err := createVxlan(n.vxlanID(s))
+	err := createVxlan(vxlanName, n.vxlanID(s))
 	if err != nil {
 		return err
 	}
@@ -207,6 +284,12 @@ func (n *network) initSubnetSandbox(s *subnet) error {
 		return fmt.Errorf("vxlan interface creation failed for subnet %q: %v", s.subnetIP.String(), err)
 	}
 
+	if hostMode {
+		if err := addFilters(n.id[:12], brName); err != nil {
+			return err
+		}
+	}
+
 	n.Lock()
 	s.vxlanName = vxlanName
 	s.brName = brName
@@ -220,8 +303,16 @@ func (n *network) initSandbox() error {
 	n.initEpoch++
 	n.Unlock()
 
+	hostModeOnce.Do(setHostMode)
+
+	if hostMode {
+		if err := addNetworkChain(n.id[:12]); err != nil {
+			return err
+		}
+	}
+
 	sbox, err := osl.NewSandbox(
-		osl.GenerateKey(fmt.Sprintf("%d-", n.initEpoch)+n.id), true)
+		osl.GenerateKey(fmt.Sprintf("%d-", n.initEpoch)+n.id), !hostMode)
 	if err != nil {
 		return fmt.Errorf("could not create network sandbox: %v", err)
 	}
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_utils.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_utils.go
index 5bb257bf51..42c44b9675 100644
--- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_utils.go
+++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/ov_utils.go
@@ -47,14 +47,9 @@ func createVethPair() (string, string, error) {
 	return name1, name2, nil
 }
 
-func createVxlan(vni uint32) (string, error) {
+func createVxlan(name string, vni uint32) error {
 	defer osl.InitOSContext()()
 
-	name, err := netutils.GenerateIfaceName("vxlan", 7)
-	if err != nil {
-		return "", fmt.Errorf("error generating vxlan name: %v", err)
-	}
-
 	vxlan := &netlink.Vxlan{
 		LinkAttrs: netlink.LinkAttrs{Name: name},
 		VxlanId:   int(vni),
@@ -66,23 +61,45 @@ func createVxlan(vni uint32) (string, error) {
 	}
 
 	if err := netlink.LinkAdd(vxlan); err != nil {
-		return "", fmt.Errorf("error creating vxlan interface: %v", err)
-	}
-
-	return name, nil
-}
-
-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)
-	}
-
-	if err := netlink.LinkDel(link); err != nil {
-		return fmt.Errorf("error deleting vxlan interface: %v", err)
+		return fmt.Errorf("error creating vxlan interface: %v", err)
 	}
 
 	return nil
 }
+
+func deleteInterface(name string) error {
+	defer osl.InitOSContext()()
+
+	link, err := netlink.LinkByName(name)
+	if err != nil {
+		return fmt.Errorf("failed to find interface with name %s: %v", name, err)
+	}
+
+	if err := netlink.LinkDel(link); err != nil {
+		return fmt.Errorf("error deleting interface with name %s: %v", name, err)
+	}
+
+	return nil
+}
+
+func deleteVxlanByVNI(vni uint32) error {
+	defer osl.InitOSContext()()
+
+	links, err := netlink.LinkList()
+	if err != nil {
+		return fmt.Errorf("failed to list interfaces while deleting vxlan interface by vni: %v", err)
+	}
+
+	for _, l := range links {
+		if l.Type() == "vxlan" && l.(*netlink.Vxlan).VxlanId == int(vni) {
+			err = netlink.LinkDel(l)
+			if err != nil {
+				return fmt.Errorf("error deleting vxlan interface with id %d: %v", vni, err)
+			}
+
+			return nil
+		}
+	}
+
+	return fmt.Errorf("could not find a vxlan interface to delete with id %d", vni)
+}
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go
index 982310d7a2..9e5eba4013 100644
--- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go
+++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go
@@ -51,7 +51,7 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
 	d := &driver{
 		networks: networkTable{},
 		peerDb: peerNetworkMap{
-			mp: map[string]peerMap{},
+			mp: map[string]*peerMap{},
 		},
 		config: config,
 	}
diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go
index 22a677d8ba..c820da9f05 100644
--- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go
+++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go
@@ -26,7 +26,7 @@ type peerMap struct {
 }
 
 type peerNetworkMap struct {
-	mp map[string]peerMap
+	mp map[string]*peerMap
 	sync.Mutex
 }
 
@@ -138,7 +138,7 @@ func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
 	d.peerDb.Lock()
 	pMap, ok := d.peerDb.mp[nid]
 	if !ok {
-		d.peerDb.mp[nid] = peerMap{
+		d.peerDb.mp[nid] = &peerMap{
 			mp: make(map[string]peerEntry),
 		}
 
diff --git a/vendor/src/github.com/docker/libnetwork/endpoint.go b/vendor/src/github.com/docker/libnetwork/endpoint.go
index 524287fc8f..d5f38c51a2 100644
--- a/vendor/src/github.com/docker/libnetwork/endpoint.go
+++ b/vendor/src/github.com/docker/libnetwork/endpoint.go
@@ -748,11 +748,8 @@ func (ep *endpoint) DataScope() string {
 	return ep.getNetwork().DataScope()
 }
 
-func (ep *endpoint) assignAddress(assignIPv4, assignIPv6 bool) error {
-	var (
-		ipam ipamapi.Ipam
-		err  error
-	)
+func (ep *endpoint) assignAddress(ipam ipamapi.Ipam, assignIPv4, assignIPv6 bool) error {
+	var err error
 
 	n := ep.getNetwork()
 	if n.Type() == "host" || n.Type() == "null" {
@@ -761,11 +758,6 @@ func (ep *endpoint) assignAddress(assignIPv4, assignIPv6 bool) error {
 
 	log.Debugf("Assigning addresses for endpoint %s's interface on network %s", ep.Name(), n.Name())
 
-	ipam, err = n.getController().getIpamDriver(n.ipamType)
-	if err != nil {
-		return err
-	}
-
 	if assignIPv4 {
 		if err = ep.assignAddressVersion(4, ipam); err != nil {
 			return err
diff --git a/vendor/src/github.com/docker/libnetwork/ipam/allocator.go b/vendor/src/github.com/docker/libnetwork/ipam/allocator.go
index 1ca9127cc2..be8b4ac029 100644
--- a/vendor/src/github.com/docker/libnetwork/ipam/allocator.go
+++ b/vendor/src/github.com/docker/libnetwork/ipam/allocator.go
@@ -486,21 +486,28 @@ func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddres
 // DumpDatabase dumps the internal info
 func (a *Allocator) DumpDatabase() string {
 	a.Lock()
-	defer a.Unlock()
+	aspaces := make(map[string]*addrSpace, len(a.addrSpaces))
+	for as, aSpace := range a.addrSpaces {
+		aspaces[as] = aSpace
+	}
+	a.Unlock()
 
 	var s string
-	for as, aSpace := range a.addrSpaces {
+	for as, aSpace := range aspaces {
 		s = fmt.Sprintf("\n\n%s Config", as)
 		aSpace.Lock()
 		for k, config := range aSpace.subnets {
 			s = fmt.Sprintf("%s%s", s, fmt.Sprintf("\n%v: %v", k, config))
+			if config.Range == nil {
+				a.retrieveBitmask(k, config.Pool)
+			}
 		}
 		aSpace.Unlock()
 	}
 
 	s = fmt.Sprintf("%s\n\nBitmasks", s)
 	for k, bm := range a.addresses {
-		s = fmt.Sprintf("%s%s", s, fmt.Sprintf("\n\t%s: %s\n\t%d", k, bm, bm.Unselected()))
+		s = fmt.Sprintf("%s%s", s, fmt.Sprintf("\n%s: %s", k, bm))
 	}
 
 	return s
diff --git a/vendor/src/github.com/docker/libnetwork/ipamapi/contract.go b/vendor/src/github.com/docker/libnetwork/ipamapi/contract.go
index 5323c4f7df..5d561d81df 100644
--- a/vendor/src/github.com/docker/libnetwork/ipamapi/contract.go
+++ b/vendor/src/github.com/docker/libnetwork/ipamapi/contract.go
@@ -22,8 +22,10 @@ const (
 
 // Callback provides a Callback interface for registering an IPAM instance into LibNetwork
 type Callback interface {
-	// RegisterDriver provides a way for Remote drivers to dynamically register new NetworkType and associate with a ipam instance
+	// RegisterIpamDriver provides a way for Remote drivers to dynamically register with libnetwork
 	RegisterIpamDriver(name string, driver Ipam) error
+	// RegisterIpamDriverWithCapabilities provides a way for Remote drivers to dynamically register with libnetwork and specify cpaabilities
+	RegisterIpamDriverWithCapabilities(name string, driver Ipam, capability *Capability) error
 }
 
 /**************
@@ -70,3 +72,8 @@ type Ipam interface {
 	// Release the address from the specified pool ID
 	ReleaseAddress(string, net.IP) error
 }
+
+// Capability represents the requirements and capabilities of the IPAM driver
+type Capability struct {
+	RequiresMACAddress bool
+}
diff --git a/vendor/src/github.com/docker/libnetwork/ipams/remote/api/api.go b/vendor/src/github.com/docker/libnetwork/ipams/remote/api/api.go
index b8d21fdc6b..e357630cbb 100644
--- a/vendor/src/github.com/docker/libnetwork/ipams/remote/api/api.go
+++ b/vendor/src/github.com/docker/libnetwork/ipams/remote/api/api.go
@@ -2,6 +2,8 @@
 // messages between libnetwork and the remote ipam plugin
 package api
 
+import "github.com/docker/libnetwork/ipamapi"
+
 // Response is the basic response structure used in all responses
 type Response struct {
 	Error string
@@ -17,6 +19,17 @@ func (r *Response) GetError() string {
 	return r.Error
 }
 
+// GetCapabilityResponse is the response of GetCapability request
+type GetCapabilityResponse struct {
+	Response
+	RequiresMACAddress bool
+}
+
+// ToCapability converts the capability response into the internal ipam driver capaility structure
+func (capRes GetCapabilityResponse) ToCapability() *ipamapi.Capability {
+	return &ipamapi.Capability{RequiresMACAddress: capRes.RequiresMACAddress}
+}
+
 // GetAddressSpacesResponse is the response to the ``get default address spaces`` request message
 type GetAddressSpacesResponse struct {
 	Response
diff --git a/vendor/src/github.com/docker/libnetwork/ipams/remote/remote.go b/vendor/src/github.com/docker/libnetwork/ipams/remote/remote.go
index 3aefd430ab..581a9c8871 100644
--- a/vendor/src/github.com/docker/libnetwork/ipams/remote/remote.go
+++ b/vendor/src/github.com/docker/libnetwork/ipams/remote/remote.go
@@ -30,8 +30,17 @@ func newAllocator(name string, client *plugins.Client) ipamapi.Ipam {
 // Init registers a remote ipam when its plugin is activated
 func Init(cb ipamapi.Callback, l, g interface{}) error {
 	plugins.Handle(ipamapi.PluginEndpointType, func(name string, client *plugins.Client) {
-		if err := cb.RegisterIpamDriver(name, newAllocator(name, client)); err != nil {
-			log.Errorf("error registering remote ipam %s due to %v", name, err)
+		a := newAllocator(name, client)
+		if cps, err := a.(*allocator).getCapabilities(); err == nil {
+			if err := cb.RegisterIpamDriverWithCapabilities(name, a, cps); err != nil {
+				log.Errorf("error registering remote ipam driver %s due to %v", name, err)
+			}
+		} else {
+			log.Infof("remote ipam driver %s does not support capabilities", name)
+			log.Debug(err)
+			if err := cb.RegisterIpamDriver(name, a); err != nil {
+				log.Errorf("error registering remote ipam driver %s due to %v", name, err)
+			}
 		}
 	})
 	return nil
@@ -49,6 +58,14 @@ func (a *allocator) call(methodName string, arg interface{}, retVal PluginRespon
 	return nil
 }
 
+func (a *allocator) getCapabilities() (*ipamapi.Capability, error) {
+	var res api.GetCapabilityResponse
+	if err := a.call("GetCapabilities", nil, &res); err != nil {
+		return nil, err
+	}
+	return res.ToCapability(), nil
+}
+
 // GetDefaultAddressSpaces returns the local and global default address spaces
 func (a *allocator) GetDefaultAddressSpaces() (string, string, error) {
 	res := &api.GetAddressSpacesResponse{}
diff --git a/vendor/src/github.com/docker/libnetwork/ipamutils/utils_freebsd.go b/vendor/src/github.com/docker/libnetwork/ipamutils/utils_freebsd.go
new file mode 100644
index 0000000000..09eced12d1
--- /dev/null
+++ b/vendor/src/github.com/docker/libnetwork/ipamutils/utils_freebsd.go
@@ -0,0 +1,22 @@
+// Package ipamutils provides utililty functions for ipam management
+package ipamutils
+
+import (
+	"net"
+
+	"github.com/docker/libnetwork/types"
+)
+
+// ElectInterfaceAddresses looks for an interface on the OS with the specified name
+// and returns its IPv4 and IPv6 addresses in CIDR form. If the interface does not exist,
+// it chooses from a predifined list the first IPv4 address which does not conflict
+// with other interfaces on the system.
+func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
+	return nil, nil, types.NotImplementedErrorf("not supported on freebsd")
+}
+
+// FindAvailableNetwork returns a network from the passed list which does not
+// overlap with existing interfaces in the system
+func FindAvailableNetwork(list []*net.IPNet) (*net.IPNet, error) {
+	return nil, types.NotImplementedErrorf("not supported on freebsd")
+}
diff --git a/vendor/src/github.com/docker/libnetwork/netlabel/labels.go b/vendor/src/github.com/docker/libnetwork/netlabel/labels.go
index cb0c2f5402..c6d7f13477 100644
--- a/vendor/src/github.com/docker/libnetwork/netlabel/labels.go
+++ b/vendor/src/github.com/docker/libnetwork/netlabel/labels.go
@@ -41,6 +41,9 @@ const (
 
 	// Gateway represents the gateway for the network
 	Gateway = Prefix + ".gateway"
+
+	// Internal constant represents that the network is internal which disables default gateway service
+	Internal = Prefix + ".internal"
 )
 
 var (
diff --git a/vendor/src/github.com/docker/libnetwork/network.go b/vendor/src/github.com/docker/libnetwork/network.go
index be4ab70505..f18c91a19b 100644
--- a/vendor/src/github.com/docker/libnetwork/network.go
+++ b/vendor/src/github.com/docker/libnetwork/network.go
@@ -16,6 +16,7 @@ import (
 	"github.com/docker/libnetwork/etchosts"
 	"github.com/docker/libnetwork/ipamapi"
 	"github.com/docker/libnetwork/netlabel"
+	"github.com/docker/libnetwork/netutils"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/types"
 )
@@ -58,6 +59,7 @@ type Network interface {
 // NetworkInfo returns some configuration and operational information about the network
 type NetworkInfo interface {
 	IpamConfig() (string, []*IpamConf, []*IpamConf)
+	IpamInfo() ([]*IpamInfo, []*IpamInfo)
 	DriverOptions() map[string]string
 	Scope() string
 }
@@ -161,6 +163,7 @@ type network struct {
 	persist      bool
 	stopWatchCh  chan struct{}
 	drvOnce      *sync.Once
+	internal     bool
 	sync.Mutex
 }
 
@@ -303,6 +306,7 @@ func (n *network) CopyTo(o datastore.KVObject) error {
 	dstN.dbIndex = n.dbIndex
 	dstN.dbExists = n.dbExists
 	dstN.drvOnce = n.drvOnce
+	dstN.internal = n.internal
 
 	for _, v4conf := range n.ipamV4Config {
 		dstV4Conf := &IpamConf{}
@@ -389,6 +393,7 @@ func (n *network) MarshalJSON() ([]byte, error) {
 		}
 		netMap["ipamV6Info"] = string(iis)
 	}
+	netMap["internal"] = n.internal
 	return json.Marshal(netMap)
 }
 
@@ -452,6 +457,9 @@ func (n *network) UnmarshalJSON(b []byte) (err error) {
 			return err
 		}
 	}
+	if v, ok := netMap["internal"]; ok {
+		n.internal = v.(bool)
+	}
 	return nil
 }
 
@@ -478,6 +486,18 @@ func NetworkOptionPersist(persist bool) NetworkOption {
 	}
 }
 
+// NetworkOptionInternalNetwork returns an option setter to config the network
+// to be internal which disables default gateway service
+func NetworkOptionInternalNetwork() NetworkOption {
+	return func(n *network) {
+		n.internal = true
+		if n.generic == nil {
+			n.generic = make(map[string]interface{})
+		}
+		n.generic[netlabel.Internal] = true
+	}
+}
+
 // NetworkOptionIpam function returns an option setter for the ipam configuration for this network
 func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf) NetworkOption {
 	return func(n *network) {
@@ -678,7 +698,22 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
 		}
 	}
 
-	if err = ep.assignAddress(true, !n.postIPv6); err != nil {
+	ipam, err := n.getController().getIPAM(n.ipamType)
+	if err != nil {
+		return nil, err
+	}
+
+	if ipam.capability.RequiresMACAddress {
+		if ep.iface.mac == nil {
+			ep.iface.mac = netutils.GenerateRandomMAC()
+		}
+		if ep.ipamOptions == nil {
+			ep.ipamOptions = make(map[string]string)
+		}
+		ep.ipamOptions[netlabel.MacAddress] = ep.iface.mac.String()
+	}
+
+	if err = ep.assignAddress(ipam.driver, true, !n.postIPv6); err != nil {
 		return nil, err
 	}
 	defer func() {
@@ -698,7 +733,7 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
 		}
 	}()
 
-	if err = ep.assignAddress(false, n.postIPv6); err != nil {
+	if err = ep.assignAddress(ipam.driver, false, n.postIPv6); err != nil {
 		return nil, err
 	}
 
@@ -1148,3 +1183,32 @@ func (n *network) IpamConfig() (string, []*IpamConf, []*IpamConf) {
 
 	return n.ipamType, v4L, v6L
 }
+
+func (n *network) IpamInfo() ([]*IpamInfo, []*IpamInfo) {
+	n.Lock()
+	defer n.Unlock()
+
+	v4Info := make([]*IpamInfo, len(n.ipamV4Info))
+	v6Info := make([]*IpamInfo, len(n.ipamV6Info))
+
+	for i, info := range n.ipamV4Info {
+		ic := &IpamInfo{}
+		info.CopyTo(ic)
+		v4Info[i] = ic
+	}
+
+	for i, info := range n.ipamV6Info {
+		ic := &IpamInfo{}
+		info.CopyTo(ic)
+		v6Info[i] = ic
+	}
+
+	return v4Info, v6Info
+}
+
+func (n *network) Internal() bool {
+	n.Lock()
+	defer n.Unlock()
+
+	return n.internal
+}
diff --git a/vendor/src/github.com/docker/libnetwork/osl/interface_linux.go b/vendor/src/github.com/docker/libnetwork/osl/interface_linux.go
index d57e7601b1..720bf09764 100644
--- a/vendor/src/github.com/docker/libnetwork/osl/interface_linux.go
+++ b/vendor/src/github.com/docker/libnetwork/osl/interface_linux.go
@@ -109,6 +109,7 @@ func (i *nwIface) Remove() error {
 
 	n.Lock()
 	path := n.path
+	isDefault := n.isDefault
 	n.Unlock()
 
 	return nsInvoke(path, func(nsFD int) error { return nil }, func(callerFD int) error {
@@ -134,7 +135,7 @@ func (i *nwIface) Remove() error {
 			if err := netlink.LinkDel(iface); err != nil {
 				return fmt.Errorf("failed deleting bridge %q: %v", i.SrcName(), err)
 			}
-		} else {
+		} else if !isDefault {
 			// Move the network interface to caller namespace.
 			if err := netlink.LinkSetNsFd(iface, callerFD); err != nil {
 				fmt.Println("LinkSetNsPid failed: ", err)
@@ -213,9 +214,15 @@ func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...If
 	}
 
 	n.Lock()
-	i.dstName = fmt.Sprintf("%s%d", i.dstName, n.nextIfIndex)
-	n.nextIfIndex++
+	if n.isDefault {
+		i.dstName = i.srcName
+	} else {
+		i.dstName = fmt.Sprintf("%s%d", i.dstName, n.nextIfIndex)
+		n.nextIfIndex++
+	}
+
 	path := n.path
+	isDefault := n.isDefault
 	n.Unlock()
 
 	return nsInvoke(path, func(nsFD int) error {
@@ -231,9 +238,13 @@ func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...If
 			return fmt.Errorf("failed to get link by name %q: %v", i.srcName, err)
 		}
 
-		// Move the network interface to the destination namespace.
-		if err := netlink.LinkSetNsFd(iface, nsFD); err != nil {
-			return fmt.Errorf("failed to set namespace on link %q: %v", i.srcName, err)
+		// Move the network interface to the destination
+		// namespace only if the namespace is not a default
+		// type
+		if !isDefault {
+			if err := netlink.LinkSetNsFd(iface, nsFD); err != nil {
+				return fmt.Errorf("failed to set namespace on link %q: %v", i.srcName, err)
+			}
 		}
 
 		return nil
diff --git a/vendor/src/github.com/docker/libnetwork/osl/namespace_linux.go b/vendor/src/github.com/docker/libnetwork/osl/namespace_linux.go
index 1b7b230380..07b725c290 100644
--- a/vendor/src/github.com/docker/libnetwork/osl/namespace_linux.go
+++ b/vendor/src/github.com/docker/libnetwork/osl/namespace_linux.go
@@ -41,6 +41,7 @@ type networkNamespace struct {
 	staticRoutes []*types.StaticRoute
 	neighbors    []*neigh
 	nextIfIndex  int
+	isDefault    bool
 	sync.Mutex
 }
 
@@ -146,7 +147,7 @@ func NewSandbox(key string, osCreate bool) (Sandbox, error) {
 		return nil, err
 	}
 
-	return &networkNamespace{path: key}, nil
+	return &networkNamespace{path: key, isDefault: !osCreate}, nil
 }
 
 func (n *networkNamespace) InterfaceOptions() IfaceOptionSetter {
diff --git a/vendor/src/github.com/docker/libnetwork/osl/sandbox_freebsd.go b/vendor/src/github.com/docker/libnetwork/osl/sandbox_freebsd.go
index 36bd6c8002..7c6dcacead 100644
--- a/vendor/src/github.com/docker/libnetwork/osl/sandbox_freebsd.go
+++ b/vendor/src/github.com/docker/libnetwork/osl/sandbox_freebsd.go
@@ -19,6 +19,11 @@ func NewSandbox(key string, osCreate bool) (Sandbox, error) {
 	return nil, nil
 }
 
+// GetSandboxForExternalKey returns sandbox object for the supplied path
+func GetSandboxForExternalKey(path string, key string) (Sandbox, error) {
+	return nil, nil
+}
+
 // GC triggers garbage collection of namespace path right away
 // and waits for it.
 func GC() {