Browse code

Endpint.sbLeave: when deleting container, no new gateway

When the endpoint providing a container's default gateway
is removed, there's no need to select a new gateway if the
container is being removed.

Signed-off-by: Rob Murray <rob.murray@docker.com>

Rob Murray authored on 2025/11/26 01:19:15
Showing 1 changed files
... ...
@@ -751,6 +751,9 @@ func (ep *Endpoint) sbLeave(ctx context.Context, sb *Sandbox, n *Network, force
751 751
 		"ep":  ep.Name(),
752 752
 	}))
753 753
 
754
+	sb.mu.Lock()
755
+	sbInDelete := sb.inDelete
756
+	sb.mu.Unlock()
754 757
 	ep.mu.Lock()
755 758
 	sid := ep.sandboxID
756 759
 	ep.mu.Unlock()
... ...
@@ -798,8 +801,9 @@ func (ep *Endpoint) sbLeave(ctx context.Context, sb *Sandbox, n *Network, force
798 798
 	// before the endpoint is deleted, so that they can be removed from /etc/hosts.
799 799
 	etcHostsAddrs := ep.getEtcHostsAddrs()
800 800
 	// Before removing the Endpoint from the Sandbox's list of endpoints, check whether
801
-	// it's acting as a gateway so that new gateways can be selected if it is.
802
-	wasGwEp := sb.isGatewayEndpoint(ep.id)
801
+	// it's acting as a gateway so that new gateways can be selected if it is. If the
802
+	// sandbox is being deleted, skip the check as no new gateway will be needed.
803
+	needNewGwEp := !sbInDelete && sb.isGatewayEndpoint(ep.id)
803 804
 
804 805
 	// Remove the sb's references to ep.
805 806
 	sb.mu.Lock()
... ...
@@ -822,7 +826,7 @@ func (ep *Endpoint) sbLeave(ctx context.Context, sb *Sandbox, n *Network, force
822 822
 
823 823
 	// Update gateway / static routes if the ep was the gateway.
824 824
 	var gwepAfter4, gwepAfter6 *Endpoint
825
-	if wasGwEp {
825
+	if needNewGwEp {
826 826
 		gwepAfter4, gwepAfter6 = sb.getGatewayEndpoint()
827 827
 		if err := sb.updateGateway(gwepAfter4, gwepAfter6); err != nil {
828 828
 			return fmt.Errorf("updating gateway endpoint: %w", err)
... ...
@@ -858,7 +862,7 @@ func (ep *Endpoint) sbLeave(ctx context.Context, sb *Sandbox, n *Network, force
858 858
 	// the hosts entries with addresses on that network.
859 859
 	sb.deleteHostsEntries(etcHostsAddrs)
860 860
 
861
-	if !sb.inDelete && sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
861
+	if !sbInDelete && sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
862 862
 		return sb.setupDefaultGW()
863 863
 	}
864 864
 
... ...
@@ -867,17 +871,16 @@ func (ep *Endpoint) sbLeave(ctx context.Context, sb *Sandbox, n *Network, force
867 867
 		sb.resolver.SetForwardingPolicy(sb.hasExternalAccess())
868 868
 	}
869 869
 
870
-	// Configure the endpoints that now provide external connectivity for the sandbox.
871
-	if wasGwEp {
872
-		if gwepAfter4 != nil {
873
-			if err := gwepAfter4.programExternalConnectivity(ctx, gwepAfter4, gwepAfter6); err != nil {
874
-				log.G(ctx).WithError(err).Error("Failed to set IPv4 gateway")
875
-			}
870
+	// Configure the endpoints that now provide external connectivity for the sandbox
871
+	// if endpoints have been selected.
872
+	if gwepAfter4 != nil {
873
+		if err := gwepAfter4.programExternalConnectivity(ctx, gwepAfter4, gwepAfter6); err != nil {
874
+			log.G(ctx).WithError(err).Error("Failed to set IPv4 gateway")
876 875
 		}
877
-		if gwepAfter6 != nil && gwepAfter6 != gwepAfter4 {
878
-			if err := gwepAfter6.programExternalConnectivity(ctx, gwepAfter4, gwepAfter6); err != nil {
879
-				log.G(ctx).WithError(err).Error("Failed to set IPv6 gateway")
880
-			}
876
+	}
877
+	if gwepAfter6 != nil && gwepAfter6 != gwepAfter4 {
878
+		if err := gwepAfter6.programExternalConnectivity(ctx, gwepAfter4, gwepAfter6); err != nil {
879
+			log.G(ctx).WithError(err).Error("Failed to set IPv6 gateway")
881 880
 		}
882 881
 	}
883 882