Browse code

Merge pull request #28019 from sanimej/vendor

Vendoring libnetwork @9ab6e13

Madhu Venugopal authored on 2016/11/04 06:35:28
Showing 23 changed files
... ...
@@ -71,7 +71,7 @@ clone git github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e
71 71
 clone git github.com/imdario/mergo 0.2.1
72 72
 
73 73
 #get libnetwork packages
74
-clone git github.com/docker/libnetwork f4338b6f1085ccfe5972e655cca8a1d15d73439d
74
+clone git github.com/docker/libnetwork 9ab6e136fa628b5bb4af4a75f76609ef2c21c024
75 75
 clone git github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894
76 76
 clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
77 77
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -1655,17 +1655,16 @@ func (s *DockerSuite) TestDockerNetworkInternalMode(c *check.C) {
1655 1655
 	c.Assert(err, check.IsNil)
1656 1656
 }
1657 1657
 
1658
-// Test for #21401
1658
+// Test for special characters in network names. only [a-zA-Z0-9][a-zA-Z0-9_.-] are
1659
+// valid characters
1659 1660
 func (s *DockerNetworkSuite) TestDockerNetworkCreateDeleteSpecialCharacters(c *check.C) {
1660
-	dockerCmd(c, "network", "create", "test@#$")
1661
-	assertNwIsAvailable(c, "test@#$")
1662
-	dockerCmd(c, "network", "rm", "test@#$")
1663
-	assertNwNotAvailable(c, "test@#$")
1664
-
1665
-	dockerCmd(c, "network", "create", "kiwl$%^")
1666
-	assertNwIsAvailable(c, "kiwl$%^")
1667
-	dockerCmd(c, "network", "rm", "kiwl$%^")
1668
-	assertNwNotAvailable(c, "kiwl$%^")
1661
+	_, _, err := dockerCmdWithError("network", "create", "test@#$")
1662
+	c.Assert(err, check.NotNil)
1663
+
1664
+	dockerCmd(c, "network", "create", "test-1_0.net")
1665
+	assertNwIsAvailable(c, "test-1_0.net")
1666
+	dockerCmd(c, "network", "rm", "test-1_0.net")
1667
+	assertNwNotAvailable(c, "test-1_0.net")
1669 1668
 }
1670 1669
 
1671 1670
 func (s *DockerDaemonSuite) TestDaemonRestartRestoreBridgeNetwork(t *check.C) {
... ...
@@ -328,22 +328,26 @@ func (c *controller) agentDriverNotify(d driverapi.Driver) {
328 328
 }
329 329
 
330 330
 func (c *controller) agentClose() {
331
-	if c.agent == nil {
331
+	// Acquire current agent instance and reset its pointer
332
+	// then run closing functions
333
+	c.Lock()
334
+	agent := c.agent
335
+	c.agent = nil
336
+	c.Unlock()
337
+
338
+	if agent == nil {
332 339
 		return
333 340
 	}
334 341
 
335
-	for _, cancelFuncs := range c.agent.driverCancelFuncs {
342
+	for _, cancelFuncs := range agent.driverCancelFuncs {
336 343
 		for _, cancel := range cancelFuncs {
337 344
 			cancel()
338 345
 		}
339 346
 	}
340
-	c.agent.epTblCancel()
341 347
 
342
-	c.agent.networkDB.Close()
348
+	agent.epTblCancel()
343 349
 
344
-	c.Lock()
345
-	c.agent = nil
346
-	c.Unlock()
350
+	agent.networkDB.Close()
347 351
 }
348 352
 
349 353
 func (n *network) isClusterEligible() bool {
... ...
@@ -1,6 +1,8 @@
1 1
 package config
2 2
 
3 3
 import (
4
+	"fmt"
5
+	"regexp"
4 6
 	"strings"
5 7
 
6 8
 	"github.com/BurntSushi/toml"
... ...
@@ -15,6 +17,12 @@ import (
15 15
 	"github.com/docker/libnetwork/osl"
16 16
 )
17 17
 
18
+// RestrictedNameChars collects the characters allowed to represent a network or endpoint name.
19
+const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
20
+
21
+// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters.
22
+var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`)
23
+
18 24
 // Config encapsulates configurations of various Libnetwork components
19 25
 type Config struct {
20 26
 	Daemon          DaemonCfg
... ...
@@ -223,12 +231,12 @@ func (c *Config) ProcessOptions(options ...Option) {
223 223
 	}
224 224
 }
225 225
 
226
-// IsValidName validates configuration objects supported by libnetwork
227
-func IsValidName(name string) bool {
228
-	if strings.TrimSpace(name) == "" {
229
-		return false
226
+// ValidateName validates configuration objects supported by libnetwork
227
+func ValidateName(name string) error {
228
+	if !restrictedNamePattern.MatchString(name) {
229
+		return fmt.Errorf("%s includes invalid characters, only %q are allowed", name, restrictedNameChars)
230 230
 	}
231
-	return true
231
+	return nil
232 232
 }
233 233
 
234 234
 // OptionLocalKVProvider function returns an option setter for kvstore provider
... ...
@@ -626,8 +626,8 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
626 626
 		}
627 627
 	}
628 628
 
629
-	if !config.IsValidName(name) {
630
-		return nil, ErrInvalidName(name)
629
+	if err := config.ValidateName(name); err != nil {
630
+		return nil, ErrInvalidName(err.Error())
631 631
 	}
632 632
 
633 633
 	if id == "" {
... ...
@@ -145,7 +145,7 @@ func makeDefaultScopes() map[string]*ScopeCfg {
145 145
 var defaultRootChain = []string{"docker", "network", "v1.0"}
146 146
 var rootChain = defaultRootChain
147 147
 
148
-// DefaultScopes returns a map of default scopes and it's config for clients to use.
148
+// DefaultScopes returns a map of default scopes and its config for clients to use.
149 149
 func DefaultScopes(dataDir string) map[string]*ScopeCfg {
150 150
 	if dataDir != "" {
151 151
 		defaultScopes[LocalScope].Client.Address = dataDir + "/network/files/local-kv.db"
... ...
@@ -1,6 +1,6 @@
1 1
 package discoverapi
2 2
 
3
-// Discover is an interface to be implemented by the componenet interested in receiving discover events
3
+// Discover is an interface to be implemented by the component interested in receiving discover events
4 4
 // like new node joining the cluster or datastore updates
5 5
 type Discover interface {
6 6
 	// DiscoverNew is a notification for a new discovery event, Example:a new node joining a cluster
... ...
@@ -79,11 +79,11 @@ func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInt
79 79
 		Mask: i.bridgeIPv4.Mask,
80 80
 	}
81 81
 	if config.Internal {
82
-		if err = setupInternalNetworkRules(config.BridgeName, maskedAddrv4, true); err != nil {
82
+		if err = setupInternalNetworkRules(config.BridgeName, maskedAddrv4, config.EnableICC, true); err != nil {
83 83
 			return fmt.Errorf("Failed to Setup IP tables: %s", err.Error())
84 84
 		}
85 85
 		n.registerIptCleanFunc(func() error {
86
-			return setupInternalNetworkRules(config.BridgeName, maskedAddrv4, false)
86
+			return setupInternalNetworkRules(config.BridgeName, maskedAddrv4, config.EnableICC, false)
87 87
 		})
88 88
 	} else {
89 89
 		if err = setupIPTablesInternal(config.BridgeName, maskedAddrv4, config.EnableICC, config.EnableIPMasquerade, hairpinMode, true); err != nil {
... ...
@@ -333,7 +333,7 @@ func removeIPChains() {
333 333
 	}
334 334
 }
335 335
 
336
-func setupInternalNetworkRules(bridgeIface string, addr net.Addr, insert bool) error {
336
+func setupInternalNetworkRules(bridgeIface string, addr net.Addr, icc, insert bool) error {
337 337
 	var (
338 338
 		inDropRule  = iptRule{table: iptables.Filter, chain: IsolationChain, args: []string{"-i", bridgeIface, "!", "-d", addr.String(), "-j", "DROP"}}
339 339
 		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
344 344
 	if err := programChainRule(outDropRule, "DROP OUTGOING", insert); err != nil {
345 345
 		return err
346 346
 	}
347
+	// Set Inter Container Communication.
348
+	if err := setIcc(bridgeIface, icc, insert); err != nil {
349
+		return err
350
+	}
347 351
 	return nil
348 352
 }
... ...
@@ -66,7 +66,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
66 66
 	return nil
67 67
 }
68 68
 
69
-// DeleteEndpoint remove the endpoint and associated netlink interface
69
+// DeleteEndpoint removes the endpoint and associated netlink interface
70 70
 func (d *driver) DeleteEndpoint(nid, eid string) error {
71 71
 	defer osl.InitOSContext()()
72 72
 	if err := validateID(nid, eid); err != nil {
... ...
@@ -124,7 +124,7 @@ func (d *driver) createNetwork(config *configuration) error {
124 124
 	return nil
125 125
 }
126 126
 
127
-// DeleteNetwork the network for the specified driver type
127
+// DeleteNetwork deletes the network for the specified driver type
128 128
 func (d *driver) DeleteNetwork(nid string) error {
129 129
 	defer osl.InitOSContext()()
130 130
 	n := d.network(nid)
... ...
@@ -171,7 +171,7 @@ func (d *driver) DeleteNetwork(nid string) error {
171 171
 	return nil
172 172
 }
173 173
 
174
-// parseNetworkOptions parse docker network options
174
+// parseNetworkOptions parses docker network options
175 175
 func parseNetworkOptions(id string, option options.Generic) (*configuration, error) {
176 176
 	var (
177 177
 		err    error
... ...
@@ -193,7 +193,7 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err
193 193
 	return config, nil
194 194
 }
195 195
 
196
-// parseNetworkGenericOptions parse generic driver docker network options
196
+// parseNetworkGenericOptions parses generic driver docker network options
197 197
 func parseNetworkGenericOptions(data interface{}) (*configuration, error) {
198 198
 	var (
199 199
 		err    error
... ...
@@ -64,7 +64,7 @@ func setMacVlanMode(mode string) (netlink.MacvlanMode, error) {
64 64
 	}
65 65
 }
66 66
 
67
-// parentExists check if the specified interface exists in the default namespace
67
+// parentExists checks if the specified interface exists in the default namespace
68 68
 func parentExists(ifaceStr string) bool {
69 69
 	_, err := ns.NlHandle().LinkByName(ifaceStr)
70 70
 	if err != nil {
... ...
@@ -469,12 +469,14 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
469 469
 		n.getController().watchSvcRecord(ep)
470 470
 	}
471 471
 
472
-	address := ""
473
-	if ip := ep.getFirstInterfaceAddress(); ip != nil {
474
-		address = ip.String()
475
-	}
476
-	if err = sb.updateHostsFile(address); err != nil {
477
-		return err
472
+	if doUpdateHostsFile(n, sb) {
473
+		address := ""
474
+		if ip := ep.getFirstInterfaceAddress(); ip != nil {
475
+			address = ip.String()
476
+		}
477
+		if err = sb.updateHostsFile(address); err != nil {
478
+			return err
479
+		}
478 480
 	}
479 481
 	if err = sb.updateDNS(n.enableIPv6); err != nil {
480 482
 		return err
... ...
@@ -556,6 +558,10 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
556 556
 	return nil
557 557
 }
558 558
 
559
+func doUpdateHostsFile(n *network, sb *sandbox) bool {
560
+	return !n.ingress && n.Name() != libnGWNetwork
561
+}
562
+
559 563
 func (ep *endpoint) rename(name string) error {
560 564
 	var err error
561 565
 	n := ep.getNetwork()
... ...
@@ -783,7 +789,7 @@ func (ep *endpoint) Delete(force bool) error {
783 783
 	ep.releaseAddress()
784 784
 
785 785
 	if err := n.getEpCnt().DecEndpointCnt(); err != nil {
786
-		log.Warnf("failed to decrement endpoint coint for ep %s: %v", ep.ID(), err)
786
+		log.Warnf("failed to decrement endpoint count for ep %s: %v", ep.ID(), err)
787 787
 	}
788 788
 
789 789
 	return nil
... ...
@@ -1125,3 +1131,20 @@ func (c *controller) cleanupLocalEndpoints() {
1125 1125
 		}
1126 1126
 	}
1127 1127
 }
1128
+
1129
+func (ep *endpoint) setAliasIP(sb *sandbox, ip net.IP, add bool) error {
1130
+	sb.Lock()
1131
+	sbox := sb.osSbox
1132
+	sb.Unlock()
1133
+
1134
+	for _, i := range sbox.Info().Interfaces() {
1135
+		if ep.hasInterface(i.SrcName()) {
1136
+			ipNet := &net.IPNet{IP: ip, Mask: []byte{255, 255, 255, 255}}
1137
+			if err := i.SetAliasIP(ipNet, add); err != nil {
1138
+				return err
1139
+			}
1140
+			break
1141
+		}
1142
+	}
1143
+	return nil
1144
+}
... ...
@@ -69,7 +69,7 @@ func (ii ErrInvalidID) Error() string {
69 69
 func (ii ErrInvalidID) BadRequest() {}
70 70
 
71 71
 // ErrInvalidName is returned when a query-by-name or resource create method is
72
-// invoked with an empty name parameter
72
+// invoked with an invalid name parameter
73 73
 type ErrInvalidName string
74 74
 
75 75
 func (in ErrInvalidName) Error() string {
... ...
@@ -107,7 +107,7 @@ func (nnr NetworkNameError) Error() string {
107 107
 // Forbidden denotes the type of this error
108 108
 func (nnr NetworkNameError) Forbidden() {}
109 109
 
110
-// UnknownNetworkError is returned when libnetwork could not find in it's database
110
+// UnknownNetworkError is returned when libnetwork could not find in its database
111 111
 // a network with the same name and id.
112 112
 type UnknownNetworkError struct {
113 113
 	name string
... ...
@@ -135,7 +135,7 @@ func (aee *ActiveEndpointsError) Error() string {
135 135
 // Forbidden denotes the type of this error
136 136
 func (aee *ActiveEndpointsError) Forbidden() {}
137 137
 
138
-// UnknownEndpointError is returned when libnetwork could not find in it's database
138
+// UnknownEndpointError is returned when libnetwork could not find in its database
139 139
 // an endpoint with the same name and id.
140 140
 type UnknownEndpointError struct {
141 141
 	name string
... ...
@@ -326,6 +326,21 @@ func (c *ChainInfo) Remove() error {
326 326
 
327 327
 // Exists checks if a rule exists
328 328
 func Exists(table Table, chain string, rule ...string) bool {
329
+	return exists(false, table, chain, rule...)
330
+}
331
+
332
+// ExistsNative behaves as Exists with the difference it
333
+// will always invoke `iptables` binary.
334
+func ExistsNative(table Table, chain string, rule ...string) bool {
335
+	return exists(true, table, chain, rule...)
336
+}
337
+
338
+func exists(native bool, table Table, chain string, rule ...string) bool {
339
+	f := Raw
340
+	if native {
341
+		f = raw
342
+	}
343
+
329 344
 	if string(table) == "" {
330 345
 		table = Filter
331 346
 	}
... ...
@@ -334,7 +349,7 @@ func Exists(table Table, chain string, rule ...string) bool {
334 334
 
335 335
 	if supportsCOpt {
336 336
 		// if exit status is 0 then return true, the rule exists
337
-		_, err := Raw(append([]string{"-t", string(table), "-C", chain}, rule...)...)
337
+		_, err := f(append([]string{"-t", string(table), "-C", chain}, rule...)...)
338 338
 		return err == nil
339 339
 	}
340 340
 
... ...
@@ -17,6 +17,7 @@ import (
17 17
 	"github.com/docker/libnetwork/ipamapi"
18 18
 	"github.com/docker/libnetwork/netlabel"
19 19
 	"github.com/docker/libnetwork/netutils"
20
+	"github.com/docker/libnetwork/networkdb"
20 21
 	"github.com/docker/libnetwork/options"
21 22
 	"github.com/docker/libnetwork/types"
22 23
 )
... ...
@@ -34,7 +35,7 @@ type Network interface {
34 34
 	Type() string
35 35
 
36 36
 	// Create a new endpoint to this network symbolically identified by the
37
-	// specified unique name. The options parameter carry driver specific options.
37
+	// specified unique name. The options parameter carries driver specific options.
38 38
 	CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error)
39 39
 
40 40
 	// Delete the network.
... ...
@@ -67,6 +68,11 @@ type NetworkInfo interface {
67 67
 	Labels() map[string]string
68 68
 	Dynamic() bool
69 69
 	Created() time.Time
70
+	// Peers returns a slice of PeerInfo structures which has the information about the peer
71
+	// nodes participating in the same overlay network. This is currently the per-network
72
+	// gossip cluster. For non-dynamic overlay networks and bridge networks it returns an
73
+	// empty slice
74
+	Peers() []networkdb.PeerInfo
70 75
 }
71 76
 
72 77
 // 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 {
848 848
 
849 849
 func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
850 850
 	var err error
851
-	if !config.IsValidName(name) {
852
-		return nil, ErrInvalidName(name)
851
+
852
+	if err = config.ValidateName(name); err != nil {
853
+		return nil, ErrInvalidName(err.Error())
853 854
 	}
854 855
 
855 856
 	if _, err = n.EndpointByName(name); err == nil {
... ...
@@ -1459,6 +1466,24 @@ func (n *network) Info() NetworkInfo {
1459 1459
 	return n
1460 1460
 }
1461 1461
 
1462
+func (n *network) Peers() []networkdb.PeerInfo {
1463
+	if !n.Dynamic() {
1464
+		return []networkdb.PeerInfo{}
1465
+	}
1466
+
1467
+	var nDB *networkdb.NetworkDB
1468
+	n.ctrlr.Lock()
1469
+	if n.ctrlr.agentInitDone == nil && n.ctrlr.agent != nil {
1470
+		nDB = n.ctrlr.agent.networkDB
1471
+	}
1472
+	n.ctrlr.Unlock()
1473
+
1474
+	if nDB != nil {
1475
+		return n.ctrlr.agent.networkDB.Peers(n.id)
1476
+	}
1477
+	return []networkdb.PeerInfo{}
1478
+}
1479
+
1462 1480
 func (n *network) DriverOptions() map[string]string {
1463 1481
 	n.Lock()
1464 1482
 	defer n.Unlock()
... ...
@@ -30,6 +30,10 @@ func (n *network) startResolver() {
30 30
 		options := n.Info().DriverOptions()
31 31
 		hnsid := options[windows.HNSID]
32 32
 
33
+		if hnsid == "" {
34
+			return
35
+		}
36
+
33 37
 		hnsresponse, err := hcsshim.HNSNetworkRequest("GET", hnsid, "")
34 38
 		if err != nil {
35 39
 			log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err)
... ...
@@ -91,6 +91,12 @@ type NetworkDB struct {
91 91
 	keyring *memberlist.Keyring
92 92
 }
93 93
 
94
+// PeerInfo represents the peer (gossip cluster) nodes of a network
95
+type PeerInfo struct {
96
+	Name string
97
+	IP   string
98
+}
99
+
94 100
 type node struct {
95 101
 	memberlist.Node
96 102
 	ltime serf.LamportTime
... ...
@@ -200,6 +206,20 @@ func (nDB *NetworkDB) Close() {
200 200
 	}
201 201
 }
202 202
 
203
+// Peers returns the gossip peers for a given network.
204
+func (nDB *NetworkDB) Peers(nid string) []PeerInfo {
205
+	nDB.RLock()
206
+	defer nDB.RUnlock()
207
+	peers := make([]PeerInfo, 0, len(nDB.networkNodes[nid]))
208
+	for _, nodeName := range nDB.networkNodes[nid] {
209
+		peers = append(peers, PeerInfo{
210
+			Name: nDB.nodes[nodeName].Name,
211
+			IP:   nDB.nodes[nodeName].Addr.String(),
212
+		})
213
+	}
214
+	return peers
215
+}
216
+
203 217
 // GetEntry retrieves the value of a table entry in a given (network,
204 218
 // table, key) tuple
205 219
 func (nDB *NetworkDB) GetEntry(tname, nid, key string) ([]byte, error) {
... ...
@@ -26,7 +26,6 @@ type nwIface struct {
26 26
 	mac         net.HardwareAddr
27 27
 	address     *net.IPNet
28 28
 	addressIPv6 *net.IPNet
29
-	ipAliases   []*net.IPNet
30 29
 	llAddrs     []*net.IPNet
31 30
 	routes      []*net.IPNet
32 31
 	bridge      bool
... ...
@@ -97,13 +96,6 @@ func (i *nwIface) LinkLocalAddresses() []*net.IPNet {
97 97
 	return i.llAddrs
98 98
 }
99 99
 
100
-func (i *nwIface) IPAliases() []*net.IPNet {
101
-	i.Lock()
102
-	defer i.Unlock()
103
-
104
-	return i.ipAliases
105
-}
106
-
107 100
 func (i *nwIface) Routes() []*net.IPNet {
108 101
 	i.Lock()
109 102
 	defer i.Unlock()
... ...
@@ -130,6 +122,28 @@ func (n *networkNamespace) Interfaces() []Interface {
130 130
 	return ifaces
131 131
 }
132 132
 
133
+func (i *nwIface) SetAliasIP(ip *net.IPNet, add bool) error {
134
+	i.Lock()
135
+	n := i.ns
136
+	i.Unlock()
137
+
138
+	n.Lock()
139
+	nlh := n.nlHandle
140
+	n.Unlock()
141
+
142
+	// Find the network interface identified by the DstName attribute.
143
+	iface, err := nlh.LinkByName(i.DstName())
144
+	if err != nil {
145
+		return err
146
+	}
147
+
148
+	ipAddr := &netlink.Addr{IPNet: ip, Label: ""}
149
+	if add {
150
+		return nlh.AddrAdd(iface, ipAddr)
151
+	}
152
+	return nlh.AddrDel(iface, ipAddr)
153
+}
154
+
133 155
 func (i *nwIface) Remove() error {
134 156
 	i.Lock()
135 157
 	n := i.ns
... ...
@@ -333,7 +347,6 @@ func configureInterface(nlh *netlink.Handle, iface netlink.Link, i *nwIface) err
333 333
 		{setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %v", ifaceName, i.AddressIPv6())},
334 334
 		{setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())},
335 335
 		{setInterfaceLinkLocalIPs, fmt.Sprintf("error setting interface %q link local IPs to %v", ifaceName, i.LinkLocalAddresses())},
336
-		{setInterfaceIPAliases, fmt.Sprintf("error setting interface %q IP Aliases to %v", ifaceName, i.IPAliases())},
337 336
 	}
338 337
 
339 338
 	for _, config := range ifaceConfigurators {
... ...
@@ -387,16 +400,6 @@ func setInterfaceLinkLocalIPs(nlh *netlink.Handle, iface netlink.Link, i *nwIfac
387 387
 	return nil
388 388
 }
389 389
 
390
-func setInterfaceIPAliases(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
391
-	for _, si := range i.IPAliases() {
392
-		ipAddr := &netlink.Addr{IPNet: si}
393
-		if err := nlh.AddrAdd(iface, ipAddr); err != nil {
394
-			return err
395
-		}
396
-	}
397
-	return nil
398
-}
399
-
400 390
 func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
401 391
 	return nlh.LinkSetName(iface, i.DstName())
402 392
 }
... ...
@@ -66,12 +66,6 @@ func (n *networkNamespace) LinkLocalAddresses(list []*net.IPNet) IfaceOption {
66 66
 	}
67 67
 }
68 68
 
69
-func (n *networkNamespace) IPAliases(list []*net.IPNet) IfaceOption {
70
-	return func(i *nwIface) {
71
-		i.ipAliases = list
72
-	}
73
-}
74
-
75 69
 func (n *networkNamespace) Routes(routes []*net.IPNet) IfaceOption {
76 70
 	return func(i *nwIface) {
77 71
 		i.routes = routes
... ...
@@ -91,9 +91,6 @@ type IfaceOptionSetter interface {
91 91
 	// LinkLocalAddresses returns an option setter to set the link-local IP addresses.
92 92
 	LinkLocalAddresses([]*net.IPNet) IfaceOption
93 93
 
94
-	// IPAliases returns an option setter to set IP address Aliases
95
-	IPAliases([]*net.IPNet) IfaceOption
96
-
97 94
 	// Master returns an option setter to set the master interface if any for this
98 95
 	// interface. The master interface name should refer to the srcname of a
99 96
 	// previously added interface of type bridge.
... ...
@@ -150,9 +147,6 @@ type Interface interface {
150 150
 	// LinkLocalAddresses returns the link-local IP addresses assigned to the interface.
151 151
 	LinkLocalAddresses() []*net.IPNet
152 152
 
153
-	// IPAliases returns the IP address aliases assigned to the interface.
154
-	IPAliases() []*net.IPNet
155
-
156 153
 	// IP routes for the interface.
157 154
 	Routes() []*net.IPNet
158 155
 
... ...
@@ -166,6 +160,10 @@ type Interface interface {
166 166
 	// and moving it out of the sandbox.
167 167
 	Remove() error
168 168
 
169
+	// SetAliasIP adds or deletes the passed IP as an alias on the interface.
170
+	// ex: set the vip of services in the same network as secondary IP.
171
+	SetAliasIP(ip *net.IPNet, add bool) error
172
+
169 173
 	// Statistics returns the statistics for this interface
170 174
 	Statistics() (*types.InterfaceStatistics, error)
171 175
 }
... ...
@@ -123,10 +123,10 @@ func FilterResolvDNS(resolvConf []byte, ipv6Enabled bool) (*File, error) {
123 123
 	// if the resulting resolvConf has no more nameservers defined, add appropriate
124 124
 	// default DNS servers for IPv4 and (optionally) IPv6
125 125
 	if len(GetNameservers(cleanedResolvConf, types.IP)) == 0 {
126
-		logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers : %v", defaultIPv4Dns)
126
+		logrus.Infof("No non-localhost DNS nameservers are left in resolv.conf. Using default external servers: %v", defaultIPv4Dns)
127 127
 		dns := defaultIPv4Dns
128 128
 		if ipv6Enabled {
129
-			logrus.Infof("IPv6 enabled; Adding default IPv6 external servers : %v", defaultIPv6Dns)
129
+			logrus.Infof("IPv6 enabled; Adding default IPv6 external servers: %v", defaultIPv6Dns)
130 130
 			dns = append(dns, defaultIPv6Dns...)
131 131
 		}
132 132
 		cleanedResolvConf = append(cleanedResolvConf, []byte("\n"+strings.Join(dns, "\n"))...)
... ...
@@ -725,10 +725,6 @@ func (sb *sandbox) restoreOslSandbox() error {
725 725
 		if len(i.llAddrs) != 0 {
726 726
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
727 727
 		}
728
-		if len(ep.virtualIP) != 0 {
729
-			vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)}
730
-			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias}))
731
-		}
732 728
 		Ifaces[fmt.Sprintf("%s+%s", i.srcName, i.dstPrefix)] = ifaceOptions
733 729
 		if joinInfo != nil {
734 730
 			for _, r := range joinInfo.StaticRoutes {
... ...
@@ -782,10 +778,6 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
782 782
 		if len(i.llAddrs) != 0 {
783 783
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
784 784
 		}
785
-		if len(ep.virtualIP) != 0 {
786
-			vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)}
787
-			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias}))
788
-		}
789 785
 		if i.mac != nil {
790 786
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
791 787
 		}
... ...
@@ -317,6 +317,14 @@ func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
317 317
 		for _, ip := range lb.backEnds {
318 318
 			sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts,
319 319
 				eIP, gwIP, addService, n.ingress)
320
+			// For a new service program the vip as an alias on the task's sandbox interface
321
+			// connected to this network.
322
+			if !addService {
323
+				continue
324
+			}
325
+			if err := ep.setAliasIP(sb, lb.vip, true); err != nil {
326
+				logrus.Errorf("Adding Service VIP %v to ep %v(%v) failed: %v", lb.vip, ep.ID(), ep.Name(), err)
327
+			}
320 328
 			addService = false
321 329
 		}
322 330
 		lb.service.Unlock()
... ...
@@ -340,8 +348,16 @@ func (n *network) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Po
340 340
 			}
341 341
 
342 342
 			sb.addLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, addService, n.ingress)
343
-		}
344 343
 
344
+			// For a new service program the vip as an alias on the task's sandbox interface
345
+			// connected to this network.
346
+			if !addService {
347
+				return false
348
+			}
349
+			if err := ep.setAliasIP(sb, vip, true); err != nil {
350
+				logrus.Errorf("Adding Service VIP %v to ep %v(%v) failed: %v", vip, ep.ID(), ep.Name(), err)
351
+			}
352
+		}
345 353
 		return false
346 354
 	})
347 355
 }
... ...
@@ -363,8 +379,16 @@ func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Por
363 363
 			}
364 364
 
365 365
 			sb.rmLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService, n.ingress)
366
-		}
367 366
 
367
+			// If the service is being remove its vip alias on on the task's sandbox interface
368
+			// has to be removed as well.
369
+			if !rmService {
370
+				return false
371
+			}
372
+			if err := ep.setAliasIP(sb, vip, false); err != nil {
373
+				logrus.Errorf("Removing Service VIP %v from ep %v(%v) failed: %v", vip, ep.ID(), ep.Name(), err)
374
+			}
375
+		}
368 376
 		return false
369 377
 	})
370 378
 }
... ...
@@ -935,6 +959,14 @@ func redirecter() {
935 935
 		rule := strings.Fields(fmt.Sprintf("-t nat -A PREROUTING -d %s -p %s --dport %d -j REDIRECT --to-port %d",
936 936
 			eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, iPort.TargetPort))
937 937
 		rules = append(rules, rule)
938
+		// Allow only incoming connections to exposed ports
939
+		iRule := strings.Fields(fmt.Sprintf("-I INPUT -d %s -p %s --dport %d -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT",
940
+			eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort))
941
+		rules = append(rules, iRule)
942
+		// Allow only outgoing connections from exposed ports
943
+		oRule := strings.Fields(fmt.Sprintf("-I OUTPUT -s %s -p %s --sport %d -m conntrack --ctstate ESTABLISHED -j ACCEPT",
944
+			eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.TargetPort))
945
+		rules = append(rules, oRule)
938 946
 	}
939 947
 
940 948
 	ns, err := netns.GetFromPath(os.Args[1])
... ...
@@ -952,7 +984,31 @@ func redirecter() {
952 952
 	for _, rule := range rules {
953 953
 		if err := iptables.RawCombinedOutputNative(rule...); err != nil {
954 954
 			logrus.Errorf("setting up rule failed, %v: %v", rule, err)
955
-			os.Exit(5)
955
+			os.Exit(6)
956
+		}
957
+	}
958
+
959
+	if len(ingressPorts) == 0 {
960
+		return
961
+	}
962
+
963
+	// Ensure blocking rules for anything else in/to ingress network
964
+	for _, rule := range [][]string{
965
+		{"-d", eIP.String(), "-p", "udp", "-j", "DROP"},
966
+		{"-d", eIP.String(), "-p", "tcp", "-j", "DROP"},
967
+	} {
968
+		if !iptables.ExistsNative(iptables.Filter, "INPUT", rule...) {
969
+			if err := iptables.RawCombinedOutputNative(append([]string{"-A", "INPUT"}, rule...)...); err != nil {
970
+				logrus.Errorf("setting up rule failed, %v: %v", rule, err)
971
+				os.Exit(7)
972
+			}
973
+		}
974
+		rule[0] = "-s"
975
+		if !iptables.ExistsNative(iptables.Filter, "OUTPUT", rule...) {
976
+			if err := iptables.RawCombinedOutputNative(append([]string{"-A", "OUTPUT"}, rule...)...); err != nil {
977
+				logrus.Errorf("setting up rule failed, %v: %v", rule, err)
978
+				os.Exit(8)
979
+			}
956 980
 		}
957 981
 	}
958 982
 }