Browse Source

Possible race on ingress programming

Make sure that iptables operations on ingress
are serialized.
Before 2 racing routines trying to create the ingress chain
were allowed and one was failing reporting the chain as
already existing.
The lock guarantees that this condition does not happen anymore

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Flavio Crisciani 7 years ago
parent
commit
3d2b2f1c7e
1 changed files with 4 additions and 5 deletions
  1. 4 5
      libnetwork/service_linux.go

+ 4 - 5
libnetwork/service_linux.go

@@ -279,7 +279,7 @@ const ingressChain = "DOCKER-INGRESS"
 
 
 var (
 var (
 	ingressOnce     sync.Once
 	ingressOnce     sync.Once
-	ingressProxyMu  sync.Mutex
+	ingressMu       sync.Mutex // lock for operations on ingress
 	ingressProxyTbl = make(map[string]io.Closer)
 	ingressProxyTbl = make(map[string]io.Closer)
 	portConfigMu    sync.Mutex
 	portConfigMu    sync.Mutex
 	portConfigTbl   = make(map[PortConfig]int)
 	portConfigTbl   = make(map[PortConfig]int)
@@ -328,6 +328,9 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
 		addDelOpt = "-D"
 		addDelOpt = "-D"
 	}
 	}
 
 
+	ingressMu.Lock()
+	defer ingressMu.Unlock()
+
 	chainExists := iptables.ExistChain(ingressChain, iptables.Nat)
 	chainExists := iptables.ExistChain(ingressChain, iptables.Nat)
 	filterChainExists := iptables.ExistChain(ingressChain, iptables.Filter)
 	filterChainExists := iptables.ExistChain(ingressChain, iptables.Filter)
 
 
@@ -497,13 +500,11 @@ func plumbProxy(iPort *PortConfig, isDelete bool) error {
 
 
 	portSpec := fmt.Sprintf("%d/%s", iPort.PublishedPort, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]))
 	portSpec := fmt.Sprintf("%d/%s", iPort.PublishedPort, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]))
 	if isDelete {
 	if isDelete {
-		ingressProxyMu.Lock()
 		if listener, ok := ingressProxyTbl[portSpec]; ok {
 		if listener, ok := ingressProxyTbl[portSpec]; ok {
 			if listener != nil {
 			if listener != nil {
 				listener.Close()
 				listener.Close()
 			}
 			}
 		}
 		}
-		ingressProxyMu.Unlock()
 
 
 		return nil
 		return nil
 	}
 	}
@@ -523,9 +524,7 @@ func plumbProxy(iPort *PortConfig, isDelete bool) error {
 		return err
 		return err
 	}
 	}
 
 
-	ingressProxyMu.Lock()
 	ingressProxyTbl[portSpec] = l
 	ingressProxyTbl[portSpec] = l
-	ingressProxyMu.Unlock()
 
 
 	return nil
 	return nil
 }
 }