| package libnetwork | |
| import ( | |
| "context" | |
| "net" | |
| "github.com/Microsoft/hcsshim" | |
| "github.com/containerd/log" | |
| ) | |
| type policyLists struct { | |
| ilb *hcsshim.PolicyList | |
| elb *hcsshim.PolicyList | |
| } | |
| var lbPolicylistMap = make(map[*loadBalancer]*policyLists) | |
| func (n *Network) addLBBackend(ip net.IP, lb *loadBalancer) { | |
| if len(lb.vip) == 0 { | |
| return | |
| } | |
| vip := lb.vip | |
| ingressPorts := lb.service.ingressPorts | |
| lb.Lock() | |
| defer lb.Unlock() | |
| // find the load balancer IP for the network. | |
| var sourceVIP string | |
| for _, e := range n.Endpoints() { | |
| epInfo := e.Info() | |
| if epInfo == nil { | |
| continue | |
| } | |
| if epInfo.LoadBalancer() { | |
| sourceVIP = epInfo.Iface().Address().IP.String() | |
| break | |
| } | |
| } | |
| if sourceVIP == "" { | |
| log.G(context.TODO()).Errorf("Failed to find load balancer IP for network %s", n.Name()) | |
| return | |
| } | |
| var endpoints []hcsshim.HNSEndpoint | |
| for eid, be := range lb.backEnds { | |
| if be.disabled { | |
| continue | |
| } | |
| // Call HNS to get back ID (GUID) corresponding to the endpoint. | |
| hnsEndpoint, err := hcsshim.GetHNSEndpointByName(eid) | |
| if err != nil { | |
| log.G(context.TODO()).Errorf("Failed to find HNS ID for endpoint %v: %v", eid, err) | |
| return | |
| } | |
| endpoints = append(endpoints, *hnsEndpoint) | |
| } | |
| if policies, ok := lbPolicylistMap[lb]; ok { | |
| if policies.ilb != nil { | |
| policies.ilb.Delete() | |
| policies.ilb = nil | |
| } | |
| if policies.elb != nil { | |
| policies.elb.Delete() | |
| policies.elb = nil | |
| } | |
| delete(lbPolicylistMap, lb) | |
| } | |
| ilbPolicy, err := hcsshim.AddLoadBalancer(endpoints, true, sourceVIP, vip.String(), 0, 0, 0) | |
| if err != nil { | |
| 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", | |
| lb.service.name, vip.String(), endpoints, sourceVIP, n.Name(), err) | |
| return | |
| } | |
| lbPolicylistMap[lb] = &policyLists{ | |
| ilb: ilbPolicy, | |
| } | |
| publishedPorts := make(map[uint32]uint32) | |
| for i, port := range ingressPorts { | |
| protocol := uint16(6) | |
| // Skip already published port | |
| if publishedPorts[port.PublishedPort] == port.TargetPort { | |
| continue | |
| } | |
| if port.Protocol == ProtocolUDP { | |
| protocol = 17 | |
| } | |
| // check if already has udp matching to add wild card publishing | |
| for j := i + 1; j < len(ingressPorts); j++ { | |
| if ingressPorts[j].TargetPort == port.TargetPort && | |
| ingressPorts[j].PublishedPort == port.PublishedPort { | |
| protocol = 0 | |
| } | |
| } | |
| publishedPorts[port.PublishedPort] = port.TargetPort | |
| lbPolicylistMap[lb].elb, err = hcsshim.AddLoadBalancer(endpoints, false, sourceVIP, "", protocol, uint16(port.TargetPort), uint16(port.PublishedPort)) | |
| if err != nil { | |
| 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", | |
| lb.service.name, vip.String(), uint16(port.TargetPort), uint16(port.PublishedPort), endpoints, sourceVIP, n.Name(), err) | |
| return | |
| } | |
| } | |
| } | |
| func (n *Network) rmLBBackend(ip net.IP, lb *loadBalancer, rmService bool, fullRemove bool) { | |
| if len(lb.vip) == 0 { | |
| return | |
| } | |
| if numEnabledBackends(lb) > 0 { | |
| // Reprogram HNS (actually VFP) with the existing backends. | |
| n.addLBBackend(ip, lb) | |
| } else { | |
| lb.Lock() | |
| defer lb.Unlock() | |
| log.G(context.TODO()).Debugf("No more backends for service %s (ip:%s). Removing all policies", lb.service.name, lb.vip.String()) | |
| if policyLists, ok := lbPolicylistMap[lb]; ok { | |
| if policyLists.ilb != nil { | |
| if _, err := policyLists.ilb.Delete(); err != nil { | |
| log.G(context.TODO()).Errorf("Failed to remove HNS ILB policylist %s: %s", policyLists.ilb.ID, err) | |
| } | |
| policyLists.ilb = nil | |
| } | |
| if policyLists.elb != nil { | |
| if _, err := policyLists.elb.Delete(); err != nil { | |
| log.G(context.TODO()).Errorf("Failed to remove HNS ELB policylist %s: %s", policyLists.elb.ID, err) | |
| } | |
| policyLists.elb = nil | |
| } | |
| delete(lbPolicylistMap, lb) | |
| } else { | |
| log.G(context.TODO()).Errorf("Failed to find policies for service %s (%s)", lb.service.name, lb.vip.String()) | |
| } | |
| } | |
| } | |
| func numEnabledBackends(lb *loadBalancer) int { | |
| nEnabled := 0 | |
| for _, be := range lb.backEnds { | |
| if !be.disabled { | |
| nEnabled++ | |
| } | |
| } | |
| return nEnabled | |
| } | |
| func (sb *Sandbox) populateLoadBalancers(ep *Endpoint) { | |
| } | |
| func arrangeIngressFilterRule() { | |
| } |