github.com/tonistiigi/docker@v0.10.1-0.20240229224939-974013b0dc6a/libnetwork/service_windows.go (about)

     1  package libnetwork
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  
     7  	"github.com/Microsoft/hcsshim"
     8  	"github.com/containerd/log"
     9  )
    10  
    11  type policyLists struct {
    12  	ilb *hcsshim.PolicyList
    13  	elb *hcsshim.PolicyList
    14  }
    15  
    16  var lbPolicylistMap = make(map[*loadBalancer]*policyLists)
    17  
    18  func (n *Network) addLBBackend(ip net.IP, lb *loadBalancer) {
    19  	if len(lb.vip) == 0 {
    20  		return
    21  	}
    22  
    23  	vip := lb.vip
    24  	ingressPorts := lb.service.ingressPorts
    25  
    26  	lb.Lock()
    27  	defer lb.Unlock()
    28  	// find the load balancer IP for the network.
    29  	var sourceVIP string
    30  	for _, e := range n.Endpoints() {
    31  		epInfo := e.Info()
    32  		if epInfo == nil {
    33  			continue
    34  		}
    35  		if epInfo.LoadBalancer() {
    36  			sourceVIP = epInfo.Iface().Address().IP.String()
    37  			break
    38  		}
    39  	}
    40  
    41  	if sourceVIP == "" {
    42  		log.G(context.TODO()).Errorf("Failed to find load balancer IP for network %s", n.Name())
    43  		return
    44  	}
    45  
    46  	var endpoints []hcsshim.HNSEndpoint
    47  
    48  	for eid, be := range lb.backEnds {
    49  		if be.disabled {
    50  			continue
    51  		}
    52  		// Call HNS to get back ID (GUID) corresponding to the endpoint.
    53  		hnsEndpoint, err := hcsshim.GetHNSEndpointByName(eid)
    54  		if err != nil {
    55  			log.G(context.TODO()).Errorf("Failed to find HNS ID for endpoint %v: %v", eid, err)
    56  			return
    57  		}
    58  
    59  		endpoints = append(endpoints, *hnsEndpoint)
    60  	}
    61  
    62  	if policies, ok := lbPolicylistMap[lb]; ok {
    63  
    64  		if policies.ilb != nil {
    65  			policies.ilb.Delete()
    66  			policies.ilb = nil
    67  		}
    68  
    69  		if policies.elb != nil {
    70  			policies.elb.Delete()
    71  			policies.elb = nil
    72  		}
    73  		delete(lbPolicylistMap, lb)
    74  	}
    75  
    76  	ilbPolicy, err := hcsshim.AddLoadBalancer(endpoints, true, sourceVIP, vip.String(), 0, 0, 0)
    77  	if err != nil {
    78  		log.G(context.TODO()).Errorf("Failed to add ILB policy for service %s (%s) with endpoints %v using load balancer IP %s on network %s: %v",
    79  			lb.service.name, vip.String(), endpoints, sourceVIP, n.Name(), err)
    80  		return
    81  	}
    82  
    83  	lbPolicylistMap[lb] = &policyLists{
    84  		ilb: ilbPolicy,
    85  	}
    86  
    87  	publishedPorts := make(map[uint32]uint32)
    88  
    89  	for i, port := range ingressPorts {
    90  		protocol := uint16(6)
    91  
    92  		// Skip already published port
    93  		if publishedPorts[port.PublishedPort] == port.TargetPort {
    94  			continue
    95  		}
    96  
    97  		if port.Protocol == ProtocolUDP {
    98  			protocol = 17
    99  		}
   100  
   101  		// check if already has udp matching to add wild card publishing
   102  		for j := i + 1; j < len(ingressPorts); j++ {
   103  			if ingressPorts[j].TargetPort == port.TargetPort &&
   104  				ingressPorts[j].PublishedPort == port.PublishedPort {
   105  				protocol = 0
   106  			}
   107  		}
   108  
   109  		publishedPorts[port.PublishedPort] = port.TargetPort
   110  
   111  		lbPolicylistMap[lb].elb, err = hcsshim.AddLoadBalancer(endpoints, false, sourceVIP, "", protocol, uint16(port.TargetPort), uint16(port.PublishedPort))
   112  		if err != nil {
   113  			log.G(context.TODO()).Errorf("Failed to add ELB policy for service %s (ip:%s target port:%v published port:%v) with endpoints %v using load balancer IP %s on network %s: %v",
   114  				lb.service.name, vip.String(), uint16(port.TargetPort), uint16(port.PublishedPort), endpoints, sourceVIP, n.Name(), err)
   115  			return
   116  		}
   117  	}
   118  }
   119  
   120  func (n *Network) rmLBBackend(ip net.IP, lb *loadBalancer, rmService bool, fullRemove bool) {
   121  	if len(lb.vip) == 0 {
   122  		return
   123  	}
   124  
   125  	if numEnabledBackends(lb) > 0 {
   126  		// Reprogram HNS (actually VFP) with the existing backends.
   127  		n.addLBBackend(ip, lb)
   128  	} else {
   129  		lb.Lock()
   130  		defer lb.Unlock()
   131  		log.G(context.TODO()).Debugf("No more backends for service %s (ip:%s).  Removing all policies", lb.service.name, lb.vip.String())
   132  
   133  		if policyLists, ok := lbPolicylistMap[lb]; ok {
   134  			if policyLists.ilb != nil {
   135  				if _, err := policyLists.ilb.Delete(); err != nil {
   136  					log.G(context.TODO()).Errorf("Failed to remove HNS ILB policylist %s: %s", policyLists.ilb.ID, err)
   137  				}
   138  				policyLists.ilb = nil
   139  			}
   140  
   141  			if policyLists.elb != nil {
   142  				if _, err := policyLists.elb.Delete(); err != nil {
   143  					log.G(context.TODO()).Errorf("Failed to remove HNS ELB policylist %s: %s", policyLists.elb.ID, err)
   144  				}
   145  				policyLists.elb = nil
   146  			}
   147  			delete(lbPolicylistMap, lb)
   148  
   149  		} else {
   150  			log.G(context.TODO()).Errorf("Failed to find policies for service %s (%s)", lb.service.name, lb.vip.String())
   151  		}
   152  	}
   153  }
   154  
   155  func numEnabledBackends(lb *loadBalancer) int {
   156  	nEnabled := 0
   157  	for _, be := range lb.backEnds {
   158  		if !be.disabled {
   159  			nEnabled++
   160  		}
   161  	}
   162  	return nEnabled
   163  }
   164  
   165  func (sb *Sandbox) populateLoadBalancers(ep *Endpoint) {
   166  }
   167  
   168  func arrangeIngressFilterRule() {
   169  }