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 }