Vendoring libnetwork @dd0ddde

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2016-11-21 11:44:58 -08:00
parent 2c832d7d66
commit a6e1ed7a51
25 changed files with 190 additions and 113 deletions

View file

@ -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

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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 {

View file

@ -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)

View file

@ -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()

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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
}

View file

@ -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)
}

View file

@ -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

View file

@ -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{

View file

@ -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()

View file

@ -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()

View file

@ -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

View file

@ -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())
}

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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)
}

View file

@ -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()
}

View file

@ -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))
}

View file

@ -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)