Browse code

Merge pull request #1501 from sanimej/vip

Enable ping for service vip address

Jana Radhakrishnan authored on 2016/11/03 01:45:14
Showing 6 changed files
... ...
@@ -1131,3 +1131,20 @@ func (c *controller) cleanupLocalEndpoints() {
1131 1131
 		}
1132 1132
 	}
1133 1133
 }
1134
+
1135
+func (ep *endpoint) setAliasIP(sb *sandbox, ip net.IP, add bool) error {
1136
+	sb.Lock()
1137
+	sbox := sb.osSbox
1138
+	sb.Unlock()
1139
+
1140
+	for _, i := range sbox.Info().Interfaces() {
1141
+		if ep.hasInterface(i.SrcName()) {
1142
+			ipNet := &net.IPNet{IP: ip, Mask: []byte{255, 255, 255, 255}}
1143
+			if err := i.SetAliasIP(ipNet, add); err != nil {
1144
+				return err
1145
+			}
1146
+			break
1147
+		}
1148
+	}
1149
+	return nil
1150
+}
... ...
@@ -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
 }
... ...
@@ -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
 }