From a6e1ed7a516f79d43c2c639c161815eb3705e7ec Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Mon, 21 Nov 2016 11:44:58 -0800 Subject: [PATCH] Vendoring libnetwork @dd0ddde Signed-off-by: Alessandro Boch --- vendor.conf | 2 +- vendor/github.com/docker/libnetwork/agent.go | 71 ++++++++++++++----- .../docker/libnetwork/config/config.go | 8 +-- .../docker/libnetwork/default_gateway.go | 2 +- .../libnetwork/drivers/overlay/ov_endpoint.go | 2 +- .../libnetwork/drivers/overlay/ov_network.go | 5 ++ .../libnetwork/drivers/overlay/ov_utils.go | 6 ++ .../libnetwork/drivers/overlay/peerdb.go | 2 +- .../drivers/solaris/overlay/ov_endpoint.go | 2 +- .../drivers/solaris/overlay/peerdb.go | 2 +- .../github.com/docker/libnetwork/endpoint.go | 29 +++----- .../docker/libnetwork/endpoint_info.go | 6 +- .../docker/libnetwork/ipam/allocator.go | 2 +- .../docker/libnetwork/iptables/iptables.go | 4 +- .../github.com/docker/libnetwork/network.go | 24 ++++++- .../docker/libnetwork/networkdb/networkdb.go | 2 +- .../docker/libnetwork/ns/init_linux.go | 7 ++ .../docker/libnetwork/osl/interface_linux.go | 41 +++++------ .../docker/libnetwork/osl/namespace_linux.go | 10 +++ .../docker/libnetwork/osl/neigh_linux.go | 1 + .../docker/libnetwork/osl/options_linux.go | 6 ++ .../docker/libnetwork/osl/sandbox.go | 10 +-- .../github.com/docker/libnetwork/resolver.go | 8 +++ .../github.com/docker/libnetwork/sandbox.go | 20 +++++- .../docker/libnetwork/service_linux.go | 31 ++------ 25 files changed, 190 insertions(+), 113 deletions(-) diff --git a/vendor.conf b/vendor.conf index b283656299..a2e1b2bce4 100644 --- a/vendor.conf +++ b/vendor.conf @@ -23,7 +23,7 @@ github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e github.com/imdario/mergo 0.2.1 #get libnetwork packages -github.com/docker/libnetwork 57be722e077059d1ee0539be31743a3642ccbeb3 +github.com/docker/libnetwork dd0ddde6749fdffe310087e1c3616142d8c3ef9e github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec diff --git a/vendor/github.com/docker/libnetwork/agent.go b/vendor/github.com/docker/libnetwork/agent.go index f589d7bee2..c4f18ba9a8 100644 --- a/vendor/github.com/docker/libnetwork/agent.go +++ b/vendor/github.com/docker/libnetwork/agent.go @@ -381,7 +381,57 @@ func (n *network) leaveCluster() error { return c.agent.networkDB.LeaveNetwork(n.ID()) } -func (ep *endpoint) addToCluster() error { +func (ep *endpoint) addDriverInfoToCluster() error { + n := ep.getNetwork() + if !n.isClusterEligible() { + return nil + } + if ep.joinInfo == nil { + return nil + } + + ctrlr := n.ctrlr + ctrlr.Lock() + agent := ctrlr.agent + ctrlr.Unlock() + if agent == nil { + return nil + } + + for _, te := range ep.joinInfo.driverTableEntries { + if err := agent.networkDB.CreateEntry(te.tableName, n.ID(), te.key, te.value); err != nil { + return err + } + } + return nil +} + +func (ep *endpoint) deleteDriverInfoFromCluster() error { + n := ep.getNetwork() + if !n.isClusterEligible() { + return nil + } + if ep.joinInfo == nil { + return nil + } + + ctrlr := n.ctrlr + ctrlr.Lock() + agent := ctrlr.agent + ctrlr.Unlock() + if agent == nil { + return nil + } + + for _, te := range ep.joinInfo.driverTableEntries { + if err := agent.networkDB.DeleteEntry(te.tableName, n.ID(), te.key); err != nil { + return err + } + } + return nil +} + +func (ep *endpoint) addServiceInfoToCluster() error { n := ep.getNetwork() if !n.isClusterEligible() { return nil @@ -421,16 +471,10 @@ func (ep *endpoint) addToCluster() error { } } - for _, te := range ep.joinInfo.driverTableEntries { - if err := c.agent.networkDB.CreateEntry(te.tableName, n.ID(), te.key, te.value); err != nil { - return err - } - } - return nil } -func (ep *endpoint) deleteFromCluster() error { +func (ep *endpoint) deleteServiceInfoFromCluster() error { n := ep.getNetwork() if !n.isClusterEligible() { return nil @@ -453,17 +497,6 @@ func (ep *endpoint) deleteFromCluster() error { return err } } - - if ep.joinInfo == nil { - return nil - } - - for _, te := range ep.joinInfo.driverTableEntries { - if err := c.agent.networkDB.DeleteEntry(te.tableName, n.ID(), te.key); err != nil { - return err - } - } - return nil } diff --git a/vendor/github.com/docker/libnetwork/config/config.go b/vendor/github.com/docker/libnetwork/config/config.go index 592ea91113..6e29563df6 100644 --- a/vendor/github.com/docker/libnetwork/config/config.go +++ b/vendor/github.com/docker/libnetwork/config/config.go @@ -17,11 +17,11 @@ import ( "github.com/docker/libnetwork/osl" ) -// RestrictedNameChars collects the characters allowed to represent a network or endpoint name. -const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]` +// restrictedNameRegex represents the regular expression which regulates the allowed network or endpoint names. +const restrictedNameRegex = `^[\w]+[\w-. ]*[\w]+$` // RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters. -var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`) +var restrictedNamePattern = regexp.MustCompile(restrictedNameRegex) // Config encapsulates configurations of various Libnetwork components type Config struct { @@ -234,7 +234,7 @@ func (c *Config) ProcessOptions(options ...Option) { // ValidateName validates configuration objects supported by libnetwork func ValidateName(name string) error { if !restrictedNamePattern.MatchString(name) { - return fmt.Errorf("%s includes invalid characters, only %q are allowed", name, restrictedNameChars) + return fmt.Errorf("%q includes invalid characters, resource name has to conform to %q", name, restrictedNameRegex) } return nil } diff --git a/vendor/github.com/docker/libnetwork/default_gateway.go b/vendor/github.com/docker/libnetwork/default_gateway.go index 163348b49f..b042539b88 100644 --- a/vendor/github.com/docker/libnetwork/default_gateway.go +++ b/vendor/github.com/docker/libnetwork/default_gateway.go @@ -123,7 +123,7 @@ func (sb *sandbox) needDefaultGW() bool { return false } for _, r := range ep.StaticRoutes() { - if r.Destination.String() == "0.0.0.0/0" { + if r.Destination != nil && r.Destination.String() == "0.0.0.0/0" { return false } } diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go index 1906ed35f8..ebcab51501 100644 --- a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go +++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_endpoint.go @@ -77,7 +77,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, } if s := n.getSubnetforIP(ep.addr); s == nil { - return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid) + return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid) } if ep.mac == nil { diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go index c6bc67cab5..703d13f9a5 100644 --- a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go +++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go @@ -320,6 +320,11 @@ func populateVNITbl() { } defer nlh.Delete() + err = nlh.SetSocketTimeout(soTimeout) + if err != nil { + logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vni table population: %v", err) + } + links, err := nlh.LinkList() if err != nil { logrus.Errorf("Failed to list interfaces during vni population for ns %s: %v", path, err) diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go index a702e760af..8a01914fa4 100644 --- a/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go +++ b/vendor/github.com/docker/libnetwork/drivers/overlay/ov_utils.go @@ -13,6 +13,8 @@ import ( "github.com/vishvananda/netns" ) +var soTimeout = ns.NetlinkSocketsTimeout + func validateID(nid, eid string) error { if nid == "" { return fmt.Errorf("invalid network id") @@ -134,6 +136,10 @@ func deleteVxlanByVNI(path string, vni uint32) error { return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err) } defer nlh.Delete() + err = nlh.SetSocketTimeout(soTimeout) + if err != nil { + logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err) + } } links, err := nlh.LinkList() diff --git a/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go b/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go index 87fc2d107b..fff7e31249 100644 --- a/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go +++ b/vendor/github.com/docker/libnetwork/drivers/overlay/peerdb.go @@ -277,7 +277,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask, s := n.getSubnetforIP(IP) if s == nil { - return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id) + return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id) } if err := n.obtainVxlanID(s); err != nil { diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go index 471cc38896..ca0c477dcd 100644 --- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go +++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/ov_endpoint.go @@ -76,7 +76,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, } if s := n.getSubnetforIP(ep.addr); s == nil { - return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid) + return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid) } if ep.mac == nil { diff --git a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go index 6d17067f72..d4b5e8e399 100644 --- a/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go +++ b/vendor/github.com/docker/libnetwork/drivers/solaris/overlay/peerdb.go @@ -263,7 +263,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask, s := n.getSubnetforIP(IP) if s == nil { - return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id) + return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id) } if err := n.obtainVxlanID(s); err != nil { diff --git a/vendor/github.com/docker/libnetwork/endpoint.go b/vendor/github.com/docker/libnetwork/endpoint.go index 519e8ede8d..f47ea4e18f 100644 --- a/vendor/github.com/docker/libnetwork/endpoint.go +++ b/vendor/github.com/docker/libnetwork/endpoint.go @@ -515,6 +515,10 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error { return err } + if err = ep.addDriverInfoToCluster(); err != nil { + return err + } + if sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil { return sb.setupDefaultGW() } @@ -709,8 +713,12 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption) return err } - if e := ep.deleteFromCluster(); e != nil { - logrus.Errorf("Could not delete state for endpoint %s from cluster: %v", ep.Name(), e) + if e := ep.deleteServiceInfoFromCluster(); e != nil { + logrus.Errorf("Could not delete service state for endpoint %s from cluster: %v", ep.Name(), e) + } + + if e := ep.deleteDriverInfoFromCluster(); e != nil { + logrus.Errorf("Could not delete endpoint state for endpoint %s from cluster: %v", ep.Name(), e) } sb.deleteHostsEntries(n.getSvcRecords(ep)) @@ -1140,20 +1148,3 @@ func (c *controller) cleanupLocalEndpoints() { } } } - -func (ep *endpoint) setAliasIP(sb *sandbox, ip net.IP, add bool) error { - sb.Lock() - sbox := sb.osSbox - sb.Unlock() - - for _, i := range sbox.Info().Interfaces() { - if ep.hasInterface(i.SrcName()) { - ipNet := &net.IPNet{IP: ip, Mask: []byte{255, 255, 255, 255}} - if err := i.SetAliasIP(ipNet, add); err != nil { - return err - } - break - } - } - return nil -} diff --git a/vendor/github.com/docker/libnetwork/endpoint_info.go b/vendor/github.com/docker/libnetwork/endpoint_info.go index 6814de0089..4e9592a56d 100644 --- a/vendor/github.com/docker/libnetwork/endpoint_info.go +++ b/vendor/github.com/docker/libnetwork/endpoint_info.go @@ -114,12 +114,12 @@ func (epi *endpointInterface) UnmarshalJSON(b []byte) error { } } if v, ok := epMap["llAddrs"]; ok { - list := v.([]string) + list := v.([]interface{}) epi.llAddrs = make([]*net.IPNet, 0, len(list)) for _, llS := range list { - ll, err := types.ParseCIDR(llS) + ll, err := types.ParseCIDR(llS.(string)) if err != nil { - return types.InternalErrorf("failed to decode endpoint interface link-local address (%s) after json unmarshal: %v", llS, err) + return types.InternalErrorf("failed to decode endpoint interface link-local address (%v) after json unmarshal: %v", llS, err) } epi.llAddrs = append(epi.llAddrs, ll) } diff --git a/vendor/github.com/docker/libnetwork/ipam/allocator.go b/vendor/github.com/docker/libnetwork/ipam/allocator.go index 3d69bd9b4f..bd00a14700 100644 --- a/vendor/github.com/docker/libnetwork/ipam/allocator.go +++ b/vendor/github.com/docker/libnetwork/ipam/allocator.go @@ -413,7 +413,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error) } } - return nil, types.NotFoundErrorf("could not find an available non-overlapping address pool among the defaults to auto assign to the network") + return nil, types.NotFoundErrorf("could not find an available, non-overlapping IPv%d address pool among the defaults to assign to the network", v) } // RequestAddress returns an address from the specified pool ID diff --git a/vendor/github.com/docker/libnetwork/iptables/iptables.go b/vendor/github.com/docker/libnetwork/iptables/iptables.go index a0d83b7ff7..3884257361 100644 --- a/vendor/github.com/docker/libnetwork/iptables/iptables.go +++ b/vendor/github.com/docker/libnetwork/iptables/iptables.go @@ -130,7 +130,7 @@ func NewChain(name string, table Table, hairpinMode bool) (*ChainInfo, error) { // ProgramChain is used to add rules to a chain func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) error { if c.Name == "" { - return fmt.Errorf("Could not program chain, missing chain name.") + return fmt.Errorf("Could not program chain, missing chain name") } switch c.Table { @@ -166,7 +166,7 @@ func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) err } case Filter: if bridgeName == "" { - return fmt.Errorf("Could not program chain %s/%s, missing bridge name.", + return fmt.Errorf("Could not program chain %s/%s, missing bridge name", c.Table, c.Name) } link := []string{ diff --git a/vendor/github.com/docker/libnetwork/network.go b/vendor/github.com/docker/libnetwork/network.go index d58abdcc65..ef40ea2bcc 100644 --- a/vendor/github.com/docker/libnetwork/network.go +++ b/vendor/github.com/docker/libnetwork/network.go @@ -65,6 +65,7 @@ type NetworkInfo interface { Scope() string IPv6Enabled() bool Internal() bool + Attachable() bool Labels() map[string]string Dynamic() bool Created() time.Time @@ -196,6 +197,7 @@ type network struct { resolverOnce sync.Once resolver []Resolver internal bool + attachable bool inDelete bool ingress bool driverTables []string @@ -348,6 +350,7 @@ func (n *network) CopyTo(o datastore.KVObject) error { dstN.dbExists = n.dbExists dstN.drvOnce = n.drvOnce dstN.internal = n.internal + dstN.attachable = n.attachable dstN.inDelete = n.inDelete dstN.ingress = n.ingress @@ -456,6 +459,7 @@ func (n *network) MarshalJSON() ([]byte, error) { netMap["ipamV6Info"] = string(iis) } netMap["internal"] = n.internal + netMap["attachable"] = n.attachable netMap["inDelete"] = n.inDelete netMap["ingress"] = n.ingress return json.Marshal(netMap) @@ -550,6 +554,9 @@ func (n *network) UnmarshalJSON(b []byte) (err error) { if v, ok := netMap["internal"]; ok { n.internal = v.(bool) } + if v, ok := netMap["attachable"]; ok { + n.attachable = v.(bool) + } if s, ok := netMap["scope"]; ok { n.scope = s.(string) } @@ -628,6 +635,13 @@ func NetworkOptionInternalNetwork() NetworkOption { } } +// NetworkOptionAttachable returns an option setter to set attachable for a network +func NetworkOptionAttachable(attachable bool) NetworkOption { + return func(n *network) { + n.attachable = attachable + } +} + // NetworkOptionIpam function returns an option setter for the ipam configuration for this network func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf, opts map[string]string) NetworkOption { return func(n *network) { @@ -1289,9 +1303,6 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error { } if len(*cfgList) == 0 { - if ipVer == 6 { - return nil - } *cfgList = []*IpamConf{{}} } @@ -1555,6 +1566,13 @@ func (n *network) Internal() bool { return n.internal } +func (n *network) Attachable() bool { + n.Lock() + defer n.Unlock() + + return n.attachable +} + func (n *network) Dynamic() bool { n.Lock() defer n.Unlock() diff --git a/vendor/github.com/docker/libnetwork/networkdb/networkdb.go b/vendor/github.com/docker/libnetwork/networkdb/networkdb.go index 087398e3cf..71a4e2b9ee 100644 --- a/vendor/github.com/docker/libnetwork/networkdb/networkdb.go +++ b/vendor/github.com/docker/libnetwork/networkdb/networkdb.go @@ -265,7 +265,7 @@ func (nDB *NetworkDB) CreateEntry(tname, nid, key string, value []byte) error { } if err := nDB.sendTableEvent(TableEventTypeCreate, nid, tname, key, entry); err != nil { - return fmt.Errorf("cannot send table create event: %v", err) + return fmt.Errorf("cannot send create event for table %s, %v", tname, err) } nDB.Lock() diff --git a/vendor/github.com/docker/libnetwork/ns/init_linux.go b/vendor/github.com/docker/libnetwork/ns/init_linux.go index 3022e8ddbf..2c3aff5668 100644 --- a/vendor/github.com/docker/libnetwork/ns/init_linux.go +++ b/vendor/github.com/docker/libnetwork/ns/init_linux.go @@ -7,6 +7,7 @@ import ( "strings" "sync" "syscall" + "time" "github.com/Sirupsen/logrus" "github.com/vishvananda/netlink" @@ -17,6 +18,8 @@ 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 @@ -30,6 +33,10 @@ func Init() { 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 diff --git a/vendor/github.com/docker/libnetwork/osl/interface_linux.go b/vendor/github.com/docker/libnetwork/osl/interface_linux.go index 65ad2ea144..2be99d72ea 100644 --- a/vendor/github.com/docker/libnetwork/osl/interface_linux.go +++ b/vendor/github.com/docker/libnetwork/osl/interface_linux.go @@ -26,6 +26,7 @@ type nwIface struct { mac net.HardwareAddr address *net.IPNet addressIPv6 *net.IPNet + ipAliases []*net.IPNet llAddrs []*net.IPNet routes []*net.IPNet bridge bool @@ -96,6 +97,13 @@ func (i *nwIface) LinkLocalAddresses() []*net.IPNet { return i.llAddrs } +func (i *nwIface) IPAliases() []*net.IPNet { + i.Lock() + defer i.Unlock() + + return i.ipAliases +} + func (i *nwIface) Routes() []*net.IPNet { i.Lock() defer i.Unlock() @@ -122,28 +130,6 @@ func (n *networkNamespace) Interfaces() []Interface { return ifaces } -func (i *nwIface) SetAliasIP(ip *net.IPNet, add bool) error { - i.Lock() - n := i.ns - i.Unlock() - - n.Lock() - nlh := n.nlHandle - n.Unlock() - - // Find the network interface identified by the DstName attribute. - iface, err := nlh.LinkByName(i.DstName()) - if err != nil { - return err - } - - ipAddr := &netlink.Addr{IPNet: ip, Label: ""} - if add { - return nlh.AddrAdd(iface, ipAddr) - } - return nlh.AddrDel(iface, ipAddr) -} - func (i *nwIface) Remove() error { i.Lock() n := i.ns @@ -347,6 +333,7 @@ func configureInterface(nlh *netlink.Handle, iface netlink.Link, i *nwIface) err {setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %v", ifaceName, i.AddressIPv6())}, {setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())}, {setInterfaceLinkLocalIPs, fmt.Sprintf("error setting interface %q link local IPs to %v", ifaceName, i.LinkLocalAddresses())}, + {setInterfaceIPAliases, fmt.Sprintf("error setting interface %q IP Aliases to %v", ifaceName, i.IPAliases())}, } for _, config := range ifaceConfigurators { @@ -405,6 +392,16 @@ func setInterfaceLinkLocalIPs(nlh *netlink.Handle, iface netlink.Link, i *nwIfac return nil } +func setInterfaceIPAliases(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { + for _, si := range i.IPAliases() { + ipAddr := &netlink.Addr{IPNet: si} + if err := nlh.AddrAdd(iface, ipAddr); err != nil { + return err + } + } + return nil +} + func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { return nlh.LinkSetName(iface, i.DstName()) } diff --git a/vendor/github.com/docker/libnetwork/osl/namespace_linux.go b/vendor/github.com/docker/libnetwork/osl/namespace_linux.go index 4f0d446a05..fe8065a31e 100644 --- a/vendor/github.com/docker/libnetwork/osl/namespace_linux.go +++ b/vendor/github.com/docker/libnetwork/osl/namespace_linux.go @@ -211,6 +211,11 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) { return nil, fmt.Errorf("failed to create a netlink handle: %v", err) } + err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout) + if err != nil { + logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err) + } + if err = n.loopbackUp(); err != nil { n.nlHandle.Delete() return nil, err @@ -253,6 +258,11 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) { return nil, fmt.Errorf("failed to create a netlink handle: %v", err) } + err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout) + if err != nil { + logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err) + } + if err = n.loopbackUp(); err != nil { n.nlHandle.Delete() return nil, err diff --git a/vendor/github.com/docker/libnetwork/osl/neigh_linux.go b/vendor/github.com/docker/libnetwork/osl/neigh_linux.go index a7669a111b..673522ad63 100644 --- a/vendor/github.com/docker/libnetwork/osl/neigh_linux.go +++ b/vendor/github.com/docker/libnetwork/osl/neigh_linux.go @@ -80,6 +80,7 @@ func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, for i, nh := range n.neighbors { if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) { n.neighbors = append(n.neighbors[:i], n.neighbors[i+1:]...) + break } } n.Unlock() diff --git a/vendor/github.com/docker/libnetwork/osl/options_linux.go b/vendor/github.com/docker/libnetwork/osl/options_linux.go index 818669647f..64309d0506 100644 --- a/vendor/github.com/docker/libnetwork/osl/options_linux.go +++ b/vendor/github.com/docker/libnetwork/osl/options_linux.go @@ -66,6 +66,12 @@ func (n *networkNamespace) LinkLocalAddresses(list []*net.IPNet) IfaceOption { } } +func (n *networkNamespace) IPAliases(list []*net.IPNet) IfaceOption { + return func(i *nwIface) { + i.ipAliases = list + } +} + func (n *networkNamespace) Routes(routes []*net.IPNet) IfaceOption { return func(i *nwIface) { i.routes = routes diff --git a/vendor/github.com/docker/libnetwork/osl/sandbox.go b/vendor/github.com/docker/libnetwork/osl/sandbox.go index 051a7facc2..18085c9082 100644 --- a/vendor/github.com/docker/libnetwork/osl/sandbox.go +++ b/vendor/github.com/docker/libnetwork/osl/sandbox.go @@ -91,6 +91,9 @@ type IfaceOptionSetter interface { // LinkLocalAddresses returns an option setter to set the link-local IP addresses. LinkLocalAddresses([]*net.IPNet) IfaceOption + // IPAliases returns an option setter to set IP address Aliases + IPAliases([]*net.IPNet) IfaceOption + // Master returns an option setter to set the master interface if any for this // interface. The master interface name should refer to the srcname of a // previously added interface of type bridge. @@ -147,6 +150,9 @@ type Interface interface { // LinkLocalAddresses returns the link-local IP addresses assigned to the interface. LinkLocalAddresses() []*net.IPNet + // IPAliases returns the IP address aliases assigned to the interface. + IPAliases() []*net.IPNet + // IP routes for the interface. Routes() []*net.IPNet @@ -160,10 +166,6 @@ type Interface interface { // and moving it out of the sandbox. Remove() error - // SetAliasIP adds or deletes the passed IP as an alias on the interface. - // ex: set the vip of services in the same network as secondary IP. - SetAliasIP(ip *net.IPNet, add bool) error - // Statistics returns the statistics for this interface Statistics() (*types.InterfaceStatistics, error) } diff --git a/vendor/github.com/docker/libnetwork/resolver.go b/vendor/github.com/docker/libnetwork/resolver.go index e92c24887c..68e4831d53 100644 --- a/vendor/github.com/docker/libnetwork/resolver.go +++ b/vendor/github.com/docker/libnetwork/resolver.go @@ -87,6 +87,7 @@ type resolver struct { listenAddress string proxyDNS bool resolverKey string + startCh chan struct{} } func init() { @@ -101,6 +102,7 @@ func NewResolver(address string, proxyDNS bool, resolverKey string, backend DNSB listenAddress: address, resolverKey: resolverKey, err: fmt.Errorf("setup not done yet"), + startCh: make(chan struct{}, 1), } } @@ -136,6 +138,9 @@ func (r *resolver) SetupFunc(port int) func() { } func (r *resolver) Start() error { + r.startCh <- struct{}{} + defer func() { <-r.startCh }() + // make sure the resolver has been setup before starting if r.err != nil { return r.err @@ -160,6 +165,9 @@ func (r *resolver) Start() error { } func (r *resolver) Stop() { + r.startCh <- struct{}{} + defer func() { <-r.startCh }() + if r.server != nil { r.server.Shutdown() } diff --git a/vendor/github.com/docker/libnetwork/sandbox.go b/vendor/github.com/docker/libnetwork/sandbox.go index 1ca1271cc7..1fd585cd28 100644 --- a/vendor/github.com/docker/libnetwork/sandbox.go +++ b/vendor/github.com/docker/libnetwork/sandbox.go @@ -427,7 +427,13 @@ func (sb *sandbox) ResolveIP(ip string) string { } func (sb *sandbox) ExecFunc(f func()) error { - return sb.osSbox.InvokeFunc(f) + sb.Lock() + osSbox := sb.osSbox + sb.Unlock() + if osSbox != nil { + return osSbox.InvokeFunc(f) + } + return fmt.Errorf("osl sandbox unavailable in ExecFunc for %v", sb.ContainerID()) } func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) { @@ -664,7 +670,7 @@ func (sb *sandbox) SetKey(basePath string) error { func (sb *sandbox) EnableService() error { for _, ep := range sb.getConnectedEndpoints() { if ep.enableService(true) { - if err := ep.addToCluster(); err != nil { + if err := ep.addServiceInfoToCluster(); err != nil { ep.enableService(false) return fmt.Errorf("could not update state for endpoint %s into cluster: %v", ep.Name(), err) } @@ -676,7 +682,7 @@ func (sb *sandbox) EnableService() error { func (sb *sandbox) DisableService() error { for _, ep := range sb.getConnectedEndpoints() { if ep.enableService(false) { - if err := ep.deleteFromCluster(); err != nil { + if err := ep.deleteServiceInfoFromCluster(); err != nil { ep.enableService(true) return fmt.Errorf("could not delete state for endpoint %s from cluster: %v", ep.Name(), err) } @@ -755,6 +761,10 @@ func (sb *sandbox) restoreOslSandbox() error { if len(i.llAddrs) != 0 { ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs)) } + if len(ep.virtualIP) != 0 { + vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)} + ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias})) + } Ifaces[fmt.Sprintf("%s+%s", i.srcName, i.dstPrefix)] = ifaceOptions if joinInfo != nil { for _, r := range joinInfo.StaticRoutes { @@ -808,6 +818,10 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error { if len(i.llAddrs) != 0 { ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs)) } + if len(ep.virtualIP) != 0 { + vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)} + ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias})) + } if i.mac != nil { ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac)) } diff --git a/vendor/github.com/docker/libnetwork/service_linux.go b/vendor/github.com/docker/libnetwork/service_linux.go index 8d382d5540..be8dc84d3e 100644 --- a/vendor/github.com/docker/libnetwork/service_linux.go +++ b/vendor/github.com/docker/libnetwork/service_linux.go @@ -101,14 +101,6 @@ func (sb *sandbox) populateLoadbalancers(ep *endpoint) { for _, ip := range lb.backEnds { sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts, eIP, gwIP, addService, n.ingress) - // For a new service program the vip as an alias on the task's sandbox interface - // connected to this network. - if !addService { - continue - } - if err := ep.setAliasIP(sb, lb.vip, true); err != nil { - logrus.Errorf("Adding Service VIP %v to ep %v(%v) failed: %v", lb.vip, ep.ID(), ep.Name(), err) - } addService = false } lb.service.Unlock() @@ -132,16 +124,8 @@ func (n *network) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Po } sb.addLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, addService, n.ingress) - - // For a new service program the vip as an alias on the task's sandbox interface - // connected to this network. - if !addService { - return false - } - if err := ep.setAliasIP(sb, vip, true); err != nil { - logrus.Errorf("Adding Service VIP %v to ep %v(%v) failed: %v", vip, ep.ID(), ep.Name(), err) - } } + return false }) } @@ -163,16 +147,8 @@ func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Por } sb.rmLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService, n.ingress) - - // If the service is being remove its vip alias on on the task's sandbox interface - // has to be removed as well. - if !rmService { - return false - } - if err := ep.setAliasIP(sb, vip, false); err != nil { - logrus.Errorf("Removing Service VIP %v from ep %v(%v) failed: %v", vip, ep.ID(), ep.Name(), err) - } } + return false }) } @@ -678,6 +654,9 @@ func fwMarker() { rule := strings.Fields(fmt.Sprintf("-t mangle %s OUTPUT -d %s/32 -j MARK --set-mark %d", addDelOpt, vip, fwMark)) rules = append(rules, rule) + rule = strings.Fields(fmt.Sprintf("-t nat %s OUTPUT -p icmp --icmp echo-request -d %s -j DNAT --to 127.0.0.1", addDelOpt, vip)) + rules = append(rules, rule) + for _, rule := range rules { if err := iptables.RawCombinedOutputNative(rule...); err != nil { logrus.Errorf("setting up rule failed, %v: %v", rule, err)