Browse Source

Enable ping for service vip address

Signed-off-by: Santhosh Manohar <santhosh@docker.com>
Santhosh Manohar 8 years ago
parent
commit
ddc74ffced

+ 17 - 0
libnetwork/endpoint.go

@@ -1109,3 +1109,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
+}

+ 22 - 19
libnetwork/osl/interface_linux.go

@@ -26,7 +26,6 @@ type nwIface struct {
 	mac         net.HardwareAddr
 	mac         net.HardwareAddr
 	address     *net.IPNet
 	address     *net.IPNet
 	addressIPv6 *net.IPNet
 	addressIPv6 *net.IPNet
-	ipAliases   []*net.IPNet
 	llAddrs     []*net.IPNet
 	llAddrs     []*net.IPNet
 	routes      []*net.IPNet
 	routes      []*net.IPNet
 	bridge      bool
 	bridge      bool
@@ -97,13 +96,6 @@ func (i *nwIface) LinkLocalAddresses() []*net.IPNet {
 	return i.llAddrs
 	return i.llAddrs
 }
 }
 
 
-func (i *nwIface) IPAliases() []*net.IPNet {
-	i.Lock()
-	defer i.Unlock()
-
-	return i.ipAliases
-}
-
 func (i *nwIface) Routes() []*net.IPNet {
 func (i *nwIface) Routes() []*net.IPNet {
 	i.Lock()
 	i.Lock()
 	defer i.Unlock()
 	defer i.Unlock()
@@ -130,6 +122,28 @@ func (n *networkNamespace) Interfaces() []Interface {
 	return ifaces
 	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 {
 func (i *nwIface) Remove() error {
 	i.Lock()
 	i.Lock()
 	n := i.ns
 	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())},
 		{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())},
 		{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())},
 		{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 {
 	for _, config := range ifaceConfigurators {
@@ -387,16 +400,6 @@ func setInterfaceLinkLocalIPs(nlh *netlink.Handle, iface netlink.Link, i *nwIfac
 	return nil
 	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 {
 func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
 	return nlh.LinkSetName(iface, i.DstName())
 	return nlh.LinkSetName(iface, i.DstName())
 }
 }

+ 0 - 6
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 {
 func (n *networkNamespace) Routes(routes []*net.IPNet) IfaceOption {
 	return func(i *nwIface) {
 	return func(i *nwIface) {
 		i.routes = routes
 		i.routes = routes

+ 4 - 6
libnetwork/osl/sandbox.go

@@ -91,9 +91,6 @@ type IfaceOptionSetter interface {
 	// LinkLocalAddresses returns an option setter to set the link-local IP addresses.
 	// LinkLocalAddresses returns an option setter to set the link-local IP addresses.
 	LinkLocalAddresses([]*net.IPNet) IfaceOption
 	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
 	// 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
 	// interface. The master interface name should refer to the srcname of a
 	// previously added interface of type bridge.
 	// 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 returns the link-local IP addresses assigned to the interface.
 	LinkLocalAddresses() []*net.IPNet
 	LinkLocalAddresses() []*net.IPNet
 
 
-	// IPAliases returns the IP address aliases assigned to the interface.
-	IPAliases() []*net.IPNet
-
 	// IP routes for the interface.
 	// IP routes for the interface.
 	Routes() []*net.IPNet
 	Routes() []*net.IPNet
 
 
@@ -166,6 +160,10 @@ type Interface interface {
 	// and moving it out of the sandbox.
 	// and moving it out of the sandbox.
 	Remove() error
 	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 returns the statistics for this interface
 	Statistics() (*types.InterfaceStatistics, error)
 	Statistics() (*types.InterfaceStatistics, error)
 }
 }

+ 0 - 8
libnetwork/sandbox.go

@@ -725,10 +725,6 @@ func (sb *sandbox) restoreOslSandbox() error {
 		if len(i.llAddrs) != 0 {
 		if len(i.llAddrs) != 0 {
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
 			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
 		Ifaces[fmt.Sprintf("%s+%s", i.srcName, i.dstPrefix)] = ifaceOptions
 		if joinInfo != nil {
 		if joinInfo != nil {
 			for _, r := range joinInfo.StaticRoutes {
 			for _, r := range joinInfo.StaticRoutes {
@@ -782,10 +778,6 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
 		if len(i.llAddrs) != 0 {
 		if len(i.llAddrs) != 0 {
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
 			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 {
 		if i.mac != nil {
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
 			ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
 		}
 		}

+ 26 - 2
libnetwork/service_linux.go

@@ -311,6 +311,14 @@ func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
 		for _, ip := range lb.backEnds {
 		for _, ip := range lb.backEnds {
 			sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts,
 			sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts,
 				eIP, gwIP, addService, n.ingress)
 				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
 			addService = false
 		}
 		}
 		lb.service.Unlock()
 		lb.service.Unlock()
@@ -334,8 +342,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)
 			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
 		return false
 	})
 	})
 }
 }
@@ -357,8 +373,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)
 			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
 		return false
 	})
 	})
 }
 }