diff --git a/hack/vendor.sh b/hack/vendor.sh index d9ddecf964..a2ea6ddc87 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -70,7 +70,7 @@ clone git github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e clone git github.com/imdario/mergo 0.2.1 #get libnetwork packages -clone git github.com/docker/libnetwork f4338b6f1085ccfe5972e655cca8a1d15d73439d +clone git github.com/docker/libnetwork 9ab6e136fa628b5bb4af4a75f76609ef2c21c024 clone git github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec diff --git a/vendor/src/github.com/docker/libnetwork/agent.go b/vendor/src/github.com/docker/libnetwork/agent.go index 4c8980b2e1..f589d7bee2 100644 --- a/vendor/src/github.com/docker/libnetwork/agent.go +++ b/vendor/src/github.com/docker/libnetwork/agent.go @@ -328,22 +328,26 @@ func (c *controller) agentDriverNotify(d driverapi.Driver) { } func (c *controller) agentClose() { - if c.agent == nil { + // Acquire current agent instance and reset its pointer + // then run closing functions + c.Lock() + agent := c.agent + c.agent = nil + c.Unlock() + + if agent == nil { return } - for _, cancelFuncs := range c.agent.driverCancelFuncs { + for _, cancelFuncs := range agent.driverCancelFuncs { for _, cancel := range cancelFuncs { cancel() } } - c.agent.epTblCancel() - c.agent.networkDB.Close() + agent.epTblCancel() - c.Lock() - c.agent = nil - c.Unlock() + agent.networkDB.Close() } func (n *network) isClusterEligible() bool { diff --git a/vendor/src/github.com/docker/libnetwork/config/config.go b/vendor/src/github.com/docker/libnetwork/config/config.go index 8c3af13b22..a6ebd05284 100644 --- a/vendor/src/github.com/docker/libnetwork/config/config.go +++ b/vendor/src/github.com/docker/libnetwork/config/config.go @@ -1,6 +1,8 @@ package config import ( + "fmt" + "regexp" "strings" "github.com/BurntSushi/toml" @@ -15,6 +17,12 @@ 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_.-]` + +// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters. +var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`) + // Config encapsulates configurations of various Libnetwork components type Config struct { Daemon DaemonCfg @@ -223,12 +231,12 @@ func (c *Config) ProcessOptions(options ...Option) { } } -// IsValidName validates configuration objects supported by libnetwork -func IsValidName(name string) bool { - if strings.TrimSpace(name) == "" { - return false +// 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 true + return nil } // OptionLocalKVProvider function returns an option setter for kvstore provider diff --git a/vendor/src/github.com/docker/libnetwork/controller.go b/vendor/src/github.com/docker/libnetwork/controller.go index a8c30adc95..aee0827f1d 100644 --- a/vendor/src/github.com/docker/libnetwork/controller.go +++ b/vendor/src/github.com/docker/libnetwork/controller.go @@ -626,8 +626,8 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ... } } - if !config.IsValidName(name) { - return nil, ErrInvalidName(name) + if err := config.ValidateName(name); err != nil { + return nil, ErrInvalidName(err.Error()) } if id == "" { diff --git a/vendor/src/github.com/docker/libnetwork/datastore/datastore.go b/vendor/src/github.com/docker/libnetwork/datastore/datastore.go index b045eab28a..fa6942d837 100644 --- a/vendor/src/github.com/docker/libnetwork/datastore/datastore.go +++ b/vendor/src/github.com/docker/libnetwork/datastore/datastore.go @@ -145,7 +145,7 @@ func makeDefaultScopes() map[string]*ScopeCfg { var defaultRootChain = []string{"docker", "network", "v1.0"} var rootChain = defaultRootChain -// DefaultScopes returns a map of default scopes and it's config for clients to use. +// DefaultScopes returns a map of default scopes and its config for clients to use. func DefaultScopes(dataDir string) map[string]*ScopeCfg { if dataDir != "" { defaultScopes[LocalScope].Client.Address = dataDir + "/network/files/local-kv.db" diff --git a/vendor/src/github.com/docker/libnetwork/discoverapi/discoverapi.go b/vendor/src/github.com/docker/libnetwork/discoverapi/discoverapi.go index 3710ea447e..7ac36155db 100644 --- a/vendor/src/github.com/docker/libnetwork/discoverapi/discoverapi.go +++ b/vendor/src/github.com/docker/libnetwork/discoverapi/discoverapi.go @@ -1,6 +1,6 @@ package discoverapi -// Discover is an interface to be implemented by the componenet interested in receiving discover events +// Discover is an interface to be implemented by the component interested in receiving discover events // like new node joining the cluster or datastore updates type Discover interface { // DiscoverNew is a notification for a new discovery event, Example:a new node joining a cluster diff --git a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go index 78ab10f053..862d9e4491 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go @@ -79,11 +79,11 @@ func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInt Mask: i.bridgeIPv4.Mask, } if config.Internal { - if err = setupInternalNetworkRules(config.BridgeName, maskedAddrv4, true); err != nil { + if err = setupInternalNetworkRules(config.BridgeName, maskedAddrv4, config.EnableICC, true); err != nil { return fmt.Errorf("Failed to Setup IP tables: %s", err.Error()) } n.registerIptCleanFunc(func() error { - return setupInternalNetworkRules(config.BridgeName, maskedAddrv4, false) + return setupInternalNetworkRules(config.BridgeName, maskedAddrv4, config.EnableICC, false) }) } else { if err = setupIPTablesInternal(config.BridgeName, maskedAddrv4, config.EnableICC, config.EnableIPMasquerade, hairpinMode, true); err != nil { @@ -333,7 +333,7 @@ func removeIPChains() { } } -func setupInternalNetworkRules(bridgeIface string, addr net.Addr, insert bool) error { +func setupInternalNetworkRules(bridgeIface string, addr net.Addr, icc, insert bool) error { var ( inDropRule = iptRule{table: iptables.Filter, chain: IsolationChain, args: []string{"-i", bridgeIface, "!", "-d", addr.String(), "-j", "DROP"}} outDropRule = iptRule{table: iptables.Filter, chain: IsolationChain, args: []string{"-o", bridgeIface, "!", "-s", addr.String(), "-j", "DROP"}} @@ -344,5 +344,9 @@ func setupInternalNetworkRules(bridgeIface string, addr net.Addr, insert bool) e if err := programChainRule(outDropRule, "DROP OUTGOING", insert); err != nil { return err } + // Set Inter Container Communication. + if err := setIcc(bridgeIface, icc, insert); err != nil { + return err + } return nil } diff --git a/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go b/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go index d76858ea36..3e5ccb29f8 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_endpoint.go @@ -66,7 +66,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, return nil } -// DeleteEndpoint remove the endpoint and associated netlink interface +// DeleteEndpoint removes the endpoint and associated netlink interface func (d *driver) DeleteEndpoint(nid, eid string) error { defer osl.InitOSContext()() if err := validateID(nid, eid); err != nil { diff --git a/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go b/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go index fcc6ccc9e1..c455b9124d 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go @@ -124,7 +124,7 @@ func (d *driver) createNetwork(config *configuration) error { return nil } -// DeleteNetwork the network for the specified driver type +// DeleteNetwork deletes the network for the specified driver type func (d *driver) DeleteNetwork(nid string) error { defer osl.InitOSContext()() n := d.network(nid) @@ -171,7 +171,7 @@ func (d *driver) DeleteNetwork(nid string) error { return nil } -// parseNetworkOptions parse docker network options +// parseNetworkOptions parses docker network options func parseNetworkOptions(id string, option options.Generic) (*configuration, error) { var ( err error @@ -193,7 +193,7 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err return config, nil } -// parseNetworkGenericOptions parse generic driver docker network options +// parseNetworkGenericOptions parses generic driver docker network options func parseNetworkGenericOptions(data interface{}) (*configuration, error) { var ( err error diff --git a/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go b/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go index a3e17f28e2..b5b4be3499 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go @@ -64,7 +64,7 @@ func setMacVlanMode(mode string) (netlink.MacvlanMode, error) { } } -// parentExists check if the specified interface exists in the default namespace +// parentExists checks if the specified interface exists in the default namespace func parentExists(ifaceStr string) bool { _, err := ns.NlHandle().LinkByName(ifaceStr) if err != nil { diff --git a/vendor/src/github.com/docker/libnetwork/endpoint.go b/vendor/src/github.com/docker/libnetwork/endpoint.go index 65a7295424..5c56b8a08d 100644 --- a/vendor/src/github.com/docker/libnetwork/endpoint.go +++ b/vendor/src/github.com/docker/libnetwork/endpoint.go @@ -469,12 +469,14 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error { n.getController().watchSvcRecord(ep) } - address := "" - if ip := ep.getFirstInterfaceAddress(); ip != nil { - address = ip.String() - } - if err = sb.updateHostsFile(address); err != nil { - return err + if doUpdateHostsFile(n, sb) { + address := "" + if ip := ep.getFirstInterfaceAddress(); ip != nil { + address = ip.String() + } + if err = sb.updateHostsFile(address); err != nil { + return err + } } if err = sb.updateDNS(n.enableIPv6); err != nil { return err @@ -556,6 +558,10 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error { return nil } +func doUpdateHostsFile(n *network, sb *sandbox) bool { + return !n.ingress && n.Name() != libnGWNetwork +} + func (ep *endpoint) rename(name string) error { var err error n := ep.getNetwork() @@ -783,7 +789,7 @@ func (ep *endpoint) Delete(force bool) error { ep.releaseAddress() if err := n.getEpCnt().DecEndpointCnt(); err != nil { - log.Warnf("failed to decrement endpoint coint for ep %s: %v", ep.ID(), err) + log.Warnf("failed to decrement endpoint count for ep %s: %v", ep.ID(), err) } return nil @@ -1125,3 +1131,20 @@ 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/src/github.com/docker/libnetwork/error.go b/vendor/src/github.com/docker/libnetwork/error.go index d1291f1db6..81b8604ac6 100644 --- a/vendor/src/github.com/docker/libnetwork/error.go +++ b/vendor/src/github.com/docker/libnetwork/error.go @@ -69,7 +69,7 @@ func (ii ErrInvalidID) Error() string { func (ii ErrInvalidID) BadRequest() {} // ErrInvalidName is returned when a query-by-name or resource create method is -// invoked with an empty name parameter +// invoked with an invalid name parameter type ErrInvalidName string func (in ErrInvalidName) Error() string { @@ -107,7 +107,7 @@ func (nnr NetworkNameError) Error() string { // Forbidden denotes the type of this error func (nnr NetworkNameError) Forbidden() {} -// UnknownNetworkError is returned when libnetwork could not find in it's database +// UnknownNetworkError is returned when libnetwork could not find in its database // a network with the same name and id. type UnknownNetworkError struct { name string @@ -135,7 +135,7 @@ func (aee *ActiveEndpointsError) Error() string { // Forbidden denotes the type of this error func (aee *ActiveEndpointsError) Forbidden() {} -// UnknownEndpointError is returned when libnetwork could not find in it's database +// UnknownEndpointError is returned when libnetwork could not find in its database // an endpoint with the same name and id. type UnknownEndpointError struct { name string diff --git a/vendor/src/github.com/docker/libnetwork/iptables/iptables.go b/vendor/src/github.com/docker/libnetwork/iptables/iptables.go index 340bba6b0b..b7fe816261 100644 --- a/vendor/src/github.com/docker/libnetwork/iptables/iptables.go +++ b/vendor/src/github.com/docker/libnetwork/iptables/iptables.go @@ -326,6 +326,21 @@ func (c *ChainInfo) Remove() error { // Exists checks if a rule exists func Exists(table Table, chain string, rule ...string) bool { + return exists(false, table, chain, rule...) +} + +// ExistsNative behaves as Exists with the difference it +// will always invoke `iptables` binary. +func ExistsNative(table Table, chain string, rule ...string) bool { + return exists(true, table, chain, rule...) +} + +func exists(native bool, table Table, chain string, rule ...string) bool { + f := Raw + if native { + f = raw + } + if string(table) == "" { table = Filter } @@ -334,7 +349,7 @@ func Exists(table Table, chain string, rule ...string) bool { if supportsCOpt { // if exit status is 0 then return true, the rule exists - _, err := Raw(append([]string{"-t", string(table), "-C", chain}, rule...)...) + _, err := f(append([]string{"-t", string(table), "-C", chain}, rule...)...) return err == nil } diff --git a/vendor/src/github.com/docker/libnetwork/network.go b/vendor/src/github.com/docker/libnetwork/network.go index 8a068d22e9..90d77998c5 100644 --- a/vendor/src/github.com/docker/libnetwork/network.go +++ b/vendor/src/github.com/docker/libnetwork/network.go @@ -17,6 +17,7 @@ import ( "github.com/docker/libnetwork/ipamapi" "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/netutils" + "github.com/docker/libnetwork/networkdb" "github.com/docker/libnetwork/options" "github.com/docker/libnetwork/types" ) @@ -34,7 +35,7 @@ type Network interface { Type() string // Create a new endpoint to this network symbolically identified by the - // specified unique name. The options parameter carry driver specific options. + // specified unique name. The options parameter carries driver specific options. CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) // Delete the network. @@ -67,6 +68,11 @@ type NetworkInfo interface { Labels() map[string]string Dynamic() bool Created() time.Time + // Peers returns a slice of PeerInfo structures which has the information about the peer + // nodes participating in the same overlay network. This is currently the per-network + // gossip cluster. For non-dynamic overlay networks and bridge networks it returns an + // empty slice + Peers() []networkdb.PeerInfo } // EndpointWalker is a client provided function which will be used to walk the Endpoints. @@ -848,8 +854,9 @@ func (n *network) addEndpoint(ep *endpoint) error { func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { var err error - if !config.IsValidName(name) { - return nil, ErrInvalidName(name) + + if err = config.ValidateName(name); err != nil { + return nil, ErrInvalidName(err.Error()) } if _, err = n.EndpointByName(name); err == nil { @@ -1459,6 +1466,24 @@ func (n *network) Info() NetworkInfo { return n } +func (n *network) Peers() []networkdb.PeerInfo { + if !n.Dynamic() { + return []networkdb.PeerInfo{} + } + + var nDB *networkdb.NetworkDB + n.ctrlr.Lock() + if n.ctrlr.agentInitDone == nil && n.ctrlr.agent != nil { + nDB = n.ctrlr.agent.networkDB + } + n.ctrlr.Unlock() + + if nDB != nil { + return n.ctrlr.agent.networkDB.Peers(n.id) + } + return []networkdb.PeerInfo{} +} + func (n *network) DriverOptions() map[string]string { n.Lock() defer n.Unlock() diff --git a/vendor/src/github.com/docker/libnetwork/network_windows.go b/vendor/src/github.com/docker/libnetwork/network_windows.go index f529d5b799..4bf95c75d3 100644 --- a/vendor/src/github.com/docker/libnetwork/network_windows.go +++ b/vendor/src/github.com/docker/libnetwork/network_windows.go @@ -30,6 +30,10 @@ func (n *network) startResolver() { options := n.Info().DriverOptions() hnsid := options[windows.HNSID] + if hnsid == "" { + return + } + hnsresponse, err := hcsshim.HNSNetworkRequest("GET", hnsid, "") if err != nil { log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err) diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go index a79b4231d2..04ac498b5a 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go @@ -91,6 +91,12 @@ type NetworkDB struct { keyring *memberlist.Keyring } +// PeerInfo represents the peer (gossip cluster) nodes of a network +type PeerInfo struct { + Name string + IP string +} + type node struct { memberlist.Node ltime serf.LamportTime @@ -200,6 +206,20 @@ func (nDB *NetworkDB) Close() { } } +// Peers returns the gossip peers for a given network. +func (nDB *NetworkDB) Peers(nid string) []PeerInfo { + nDB.RLock() + defer nDB.RUnlock() + peers := make([]PeerInfo, 0, len(nDB.networkNodes[nid])) + for _, nodeName := range nDB.networkNodes[nid] { + peers = append(peers, PeerInfo{ + Name: nDB.nodes[nodeName].Name, + IP: nDB.nodes[nodeName].Addr.String(), + }) + } + return peers +} + // GetEntry retrieves the value of a table entry in a given (network, // table, key) tuple func (nDB *NetworkDB) GetEntry(tname, nid, key string) ([]byte, error) { 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 72b1b13b6a..643939322e 100644 --- a/vendor/src/github.com/docker/libnetwork/osl/interface_linux.go +++ b/vendor/src/github.com/docker/libnetwork/osl/interface_linux.go @@ -26,7 +26,6 @@ type nwIface struct { mac net.HardwareAddr address *net.IPNet addressIPv6 *net.IPNet - ipAliases []*net.IPNet llAddrs []*net.IPNet routes []*net.IPNet bridge bool @@ -97,13 +96,6 @@ 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() @@ -130,6 +122,28 @@ 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 @@ -333,7 +347,6 @@ 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 { @@ -387,16 +400,6 @@ 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/src/github.com/docker/libnetwork/osl/options_linux.go b/vendor/src/github.com/docker/libnetwork/osl/options_linux.go index 64309d0506..818669647f 100644 --- a/vendor/src/github.com/docker/libnetwork/osl/options_linux.go +++ b/vendor/src/github.com/docker/libnetwork/osl/options_linux.go @@ -66,12 +66,6 @@ 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/src/github.com/docker/libnetwork/osl/sandbox.go b/vendor/src/github.com/docker/libnetwork/osl/sandbox.go index 18085c9082..051a7facc2 100644 --- a/vendor/src/github.com/docker/libnetwork/osl/sandbox.go +++ b/vendor/src/github.com/docker/libnetwork/osl/sandbox.go @@ -91,9 +91,6 @@ 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. @@ -150,9 +147,6 @@ 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 @@ -166,6 +160,10 @@ 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/src/github.com/docker/libnetwork/resolvconf/resolvconf.go b/vendor/src/github.com/docker/libnetwork/resolvconf/resolvconf.go index 017b413dfc..e1db6191e4 100644 --- a/vendor/src/github.com/docker/libnetwork/resolvconf/resolvconf.go +++ b/vendor/src/github.com/docker/libnetwork/resolvconf/resolvconf.go @@ -123,10 +123,10 @@ func FilterResolvDNS(resolvConf []byte, ipv6Enabled bool) (*File, error) { // if the resulting resolvConf has no more nameservers defined, add appropriate // default DNS servers for IPv4 and (optionally) IPv6 if len(GetNameservers(cleanedResolvConf, types.IP)) == 0 { - logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers : %v", defaultIPv4Dns) + logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: %v", defaultIPv4Dns) dns := defaultIPv4Dns if ipv6Enabled { - logrus.Infof("IPv6 enabled; Adding default IPv6 external servers : %v", defaultIPv6Dns) + logrus.Infof("IPv6 enabled; Adding default IPv6 external servers: %v", defaultIPv6Dns) dns = append(dns, defaultIPv6Dns...) } cleanedResolvConf = append(cleanedResolvConf, []byte("\n"+strings.Join(dns, "\n"))...) diff --git a/vendor/src/github.com/docker/libnetwork/sandbox.go b/vendor/src/github.com/docker/libnetwork/sandbox.go index 7d1eef5b73..f4dbfd392a 100644 --- a/vendor/src/github.com/docker/libnetwork/sandbox.go +++ b/vendor/src/github.com/docker/libnetwork/sandbox.go @@ -725,10 +725,6 @@ 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 { @@ -782,10 +778,6 @@ 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/src/github.com/docker/libnetwork/service_linux.go b/vendor/src/github.com/docker/libnetwork/service_linux.go index 158411d140..669eda9fb3 100644 --- a/vendor/src/github.com/docker/libnetwork/service_linux.go +++ b/vendor/src/github.com/docker/libnetwork/service_linux.go @@ -317,6 +317,14 @@ 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() @@ -340,8 +348,16 @@ 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 }) } @@ -363,8 +379,16 @@ 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 }) } @@ -935,6 +959,14 @@ func redirecter() { rule := strings.Fields(fmt.Sprintf("-t nat -A PREROUTING -d %s -p %s --dport %d -j REDIRECT --to-port %d", eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, iPort.TargetPort)) rules = append(rules, rule) + // Allow only incoming connections to exposed ports + iRule := strings.Fields(fmt.Sprintf("-I INPUT -d %s -p %s --dport %d -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT", + eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort)) + rules = append(rules, iRule) + // Allow only outgoing connections from exposed ports + oRule := strings.Fields(fmt.Sprintf("-I OUTPUT -s %s -p %s --sport %d -m conntrack --ctstate ESTABLISHED -j ACCEPT", + eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort)) + rules = append(rules, oRule) } ns, err := netns.GetFromPath(os.Args[1]) @@ -952,7 +984,31 @@ func redirecter() { for _, rule := range rules { if err := iptables.RawCombinedOutputNative(rule...); err != nil { logrus.Errorf("setting up rule failed, %v: %v", rule, err) - os.Exit(5) + os.Exit(6) + } + } + + if len(ingressPorts) == 0 { + return + } + + // Ensure blocking rules for anything else in/to ingress network + for _, rule := range [][]string{ + {"-d", eIP.String(), "-p", "udp", "-j", "DROP"}, + {"-d", eIP.String(), "-p", "tcp", "-j", "DROP"}, + } { + if !iptables.ExistsNative(iptables.Filter, "INPUT", rule...) { + if err := iptables.RawCombinedOutputNative(append([]string{"-A", "INPUT"}, rule...)...); err != nil { + logrus.Errorf("setting up rule failed, %v: %v", rule, err) + os.Exit(7) + } + } + rule[0] = "-s" + if !iptables.ExistsNative(iptables.Filter, "OUTPUT", rule...) { + if err := iptables.RawCombinedOutputNative(append([]string{"-A", "OUTPUT"}, rule...)...); err != nil { + logrus.Errorf("setting up rule failed, %v: %v", rule, err) + os.Exit(8) + } } } }