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