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