Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / docker / libnetwork / endpoint_info.go
1 package libnetwork
2
3 import (
4         "encoding/json"
5         "fmt"
6         "net"
7
8         "github.com/docker/libnetwork/driverapi"
9         "github.com/docker/libnetwork/types"
10 )
11
12 // EndpointInfo provides an interface to retrieve network resources bound to the endpoint.
13 type EndpointInfo interface {
14         // Iface returns InterfaceInfo, go interface that can be used
15         // to get more information on the interface which was assigned to
16         // the endpoint by the driver. This can be used after the
17         // endpoint has been created.
18         Iface() InterfaceInfo
19
20         // Gateway returns the IPv4 gateway assigned by the driver.
21         // This will only return a valid value if a container has joined the endpoint.
22         Gateway() net.IP
23
24         // GatewayIPv6 returns the IPv6 gateway assigned by the driver.
25         // This will only return a valid value if a container has joined the endpoint.
26         GatewayIPv6() net.IP
27
28         // StaticRoutes returns the list of static routes configured by the network
29         // driver when the container joins a network
30         StaticRoutes() []*types.StaticRoute
31
32         // Sandbox returns the attached sandbox if there, nil otherwise.
33         Sandbox() Sandbox
34 }
35
36 // InterfaceInfo provides an interface to retrieve interface addresses bound to the endpoint.
37 type InterfaceInfo interface {
38         // MacAddress returns the MAC address assigned to the endpoint.
39         MacAddress() net.HardwareAddr
40
41         // Address returns the IPv4 address assigned to the endpoint.
42         Address() *net.IPNet
43
44         // AddressIPv6 returns the IPv6 address assigned to the endpoint.
45         AddressIPv6() *net.IPNet
46
47         // LinkLocalAddresses returns the list of link-local (IPv4/IPv6) addresses assigned to the endpoint.
48         LinkLocalAddresses() []*net.IPNet
49 }
50
51 type endpointInterface struct {
52         mac       net.HardwareAddr
53         addr      *net.IPNet
54         addrv6    *net.IPNet
55         llAddrs   []*net.IPNet
56         srcName   string
57         dstPrefix string
58         routes    []*net.IPNet
59         v4PoolID  string
60         v6PoolID  string
61 }
62
63 func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
64         epMap := make(map[string]interface{})
65         if epi.mac != nil {
66                 epMap["mac"] = epi.mac.String()
67         }
68         if epi.addr != nil {
69                 epMap["addr"] = epi.addr.String()
70         }
71         if epi.addrv6 != nil {
72                 epMap["addrv6"] = epi.addrv6.String()
73         }
74         if len(epi.llAddrs) != 0 {
75                 list := make([]string, 0, len(epi.llAddrs))
76                 for _, ll := range epi.llAddrs {
77                         list = append(list, ll.String())
78                 }
79                 epMap["llAddrs"] = list
80         }
81         epMap["srcName"] = epi.srcName
82         epMap["dstPrefix"] = epi.dstPrefix
83         var routes []string
84         for _, route := range epi.routes {
85                 routes = append(routes, route.String())
86         }
87         epMap["routes"] = routes
88         epMap["v4PoolID"] = epi.v4PoolID
89         epMap["v6PoolID"] = epi.v6PoolID
90         return json.Marshal(epMap)
91 }
92
93 func (epi *endpointInterface) UnmarshalJSON(b []byte) error {
94         var (
95                 err   error
96                 epMap map[string]interface{}
97         )
98         if err = json.Unmarshal(b, &epMap); err != nil {
99                 return err
100         }
101         if v, ok := epMap["mac"]; ok {
102                 if epi.mac, err = net.ParseMAC(v.(string)); err != nil {
103                         return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string))
104                 }
105         }
106         if v, ok := epMap["addr"]; ok {
107                 if epi.addr, err = types.ParseCIDR(v.(string)); err != nil {
108                         return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err)
109                 }
110         }
111         if v, ok := epMap["addrv6"]; ok {
112                 if epi.addrv6, err = types.ParseCIDR(v.(string)); err != nil {
113                         return types.InternalErrorf("failed to decode endpoint interface ipv6 address after json unmarshal: %v", err)
114                 }
115         }
116         if v, ok := epMap["llAddrs"]; ok {
117                 list := v.([]interface{})
118                 epi.llAddrs = make([]*net.IPNet, 0, len(list))
119                 for _, llS := range list {
120                         ll, err := types.ParseCIDR(llS.(string))
121                         if err != nil {
122                                 return types.InternalErrorf("failed to decode endpoint interface link-local address (%v) after json unmarshal: %v", llS, err)
123                         }
124                         epi.llAddrs = append(epi.llAddrs, ll)
125                 }
126         }
127         epi.srcName = epMap["srcName"].(string)
128         epi.dstPrefix = epMap["dstPrefix"].(string)
129
130         rb, _ := json.Marshal(epMap["routes"])
131         var routes []string
132         json.Unmarshal(rb, &routes)
133         epi.routes = make([]*net.IPNet, 0)
134         for _, route := range routes {
135                 ip, ipr, err := net.ParseCIDR(route)
136                 if err == nil {
137                         ipr.IP = ip
138                         epi.routes = append(epi.routes, ipr)
139                 }
140         }
141         epi.v4PoolID = epMap["v4PoolID"].(string)
142         epi.v6PoolID = epMap["v6PoolID"].(string)
143
144         return nil
145 }
146
147 func (epi *endpointInterface) CopyTo(dstEpi *endpointInterface) error {
148         dstEpi.mac = types.GetMacCopy(epi.mac)
149         dstEpi.addr = types.GetIPNetCopy(epi.addr)
150         dstEpi.addrv6 = types.GetIPNetCopy(epi.addrv6)
151         dstEpi.srcName = epi.srcName
152         dstEpi.dstPrefix = epi.dstPrefix
153         dstEpi.v4PoolID = epi.v4PoolID
154         dstEpi.v6PoolID = epi.v6PoolID
155         if len(epi.llAddrs) != 0 {
156                 dstEpi.llAddrs = make([]*net.IPNet, 0, len(epi.llAddrs))
157                 for _, ll := range epi.llAddrs {
158                         dstEpi.llAddrs = append(dstEpi.llAddrs, ll)
159                 }
160         }
161
162         for _, route := range epi.routes {
163                 dstEpi.routes = append(dstEpi.routes, types.GetIPNetCopy(route))
164         }
165
166         return nil
167 }
168
169 type endpointJoinInfo struct {
170         gw                    net.IP
171         gw6                   net.IP
172         StaticRoutes          []*types.StaticRoute
173         driverTableEntries    []*tableEntry
174         disableGatewayService bool
175 }
176
177 type tableEntry struct {
178         tableName string
179         key       string
180         value     []byte
181 }
182
183 func (ep *endpoint) Info() EndpointInfo {
184         if ep.sandboxID != "" {
185                 return ep
186         }
187         n, err := ep.getNetworkFromStore()
188         if err != nil {
189                 return nil
190         }
191
192         ep, err = n.getEndpointFromStore(ep.ID())
193         if err != nil {
194                 return nil
195         }
196
197         sb, ok := ep.getSandbox()
198         if !ok {
199                 // endpoint hasn't joined any sandbox.
200                 // Just return the endpoint
201                 return ep
202         }
203
204         if epi := sb.getEndpoint(ep.ID()); epi != nil {
205                 return epi
206         }
207
208         return nil
209 }
210
211 func (ep *endpoint) Iface() InterfaceInfo {
212         ep.Lock()
213         defer ep.Unlock()
214
215         if ep.iface != nil {
216                 return ep.iface
217         }
218
219         return nil
220 }
221
222 func (ep *endpoint) Interface() driverapi.InterfaceInfo {
223         ep.Lock()
224         defer ep.Unlock()
225
226         if ep.iface != nil {
227                 return ep.iface
228         }
229
230         return nil
231 }
232
233 func (epi *endpointInterface) SetMacAddress(mac net.HardwareAddr) error {
234         if epi.mac != nil {
235                 return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", epi.mac, mac)
236         }
237         if mac == nil {
238                 return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface")
239         }
240         epi.mac = types.GetMacCopy(mac)
241         return nil
242 }
243
244 func (epi *endpointInterface) SetIPAddress(address *net.IPNet) error {
245         if address.IP == nil {
246                 return types.BadRequestErrorf("tried to set nil IP address to endpoint interface")
247         }
248         if address.IP.To4() == nil {
249                 return setAddress(&epi.addrv6, address)
250         }
251         return setAddress(&epi.addr, address)
252 }
253
254 func setAddress(ifaceAddr **net.IPNet, address *net.IPNet) error {
255         if *ifaceAddr != nil {
256                 return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with (%s).", *ifaceAddr, address)
257         }
258         *ifaceAddr = types.GetIPNetCopy(address)
259         return nil
260 }
261
262 func (epi *endpointInterface) MacAddress() net.HardwareAddr {
263         return types.GetMacCopy(epi.mac)
264 }
265
266 func (epi *endpointInterface) Address() *net.IPNet {
267         return types.GetIPNetCopy(epi.addr)
268 }
269
270 func (epi *endpointInterface) AddressIPv6() *net.IPNet {
271         return types.GetIPNetCopy(epi.addrv6)
272 }
273
274 func (epi *endpointInterface) LinkLocalAddresses() []*net.IPNet {
275         return epi.llAddrs
276 }
277
278 func (epi *endpointInterface) SetNames(srcName string, dstPrefix string) error {
279         epi.srcName = srcName
280         epi.dstPrefix = dstPrefix
281         return nil
282 }
283
284 func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
285         ep.Lock()
286         defer ep.Unlock()
287
288         if ep.iface != nil {
289                 return ep.iface
290         }
291
292         return nil
293 }
294
295 func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
296         ep.Lock()
297         defer ep.Unlock()
298
299         r := types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop}
300
301         if routeType == types.NEXTHOP {
302                 // If the route specifies a next-hop, then it's loosely routed (i.e. not bound to a particular interface).
303                 ep.joinInfo.StaticRoutes = append(ep.joinInfo.StaticRoutes, &r)
304         } else {
305                 // If the route doesn't specify a next-hop, it must be a connected route, bound to an interface.
306                 ep.iface.routes = append(ep.iface.routes, r.Destination)
307         }
308         return nil
309 }
310
311 func (ep *endpoint) AddTableEntry(tableName, key string, value []byte) error {
312         ep.Lock()
313         defer ep.Unlock()
314
315         ep.joinInfo.driverTableEntries = append(ep.joinInfo.driverTableEntries, &tableEntry{
316                 tableName: tableName,
317                 key:       key,
318                 value:     value,
319         })
320
321         return nil
322 }
323
324 func (ep *endpoint) Sandbox() Sandbox {
325         cnt, ok := ep.getSandbox()
326         if !ok {
327                 return nil
328         }
329         return cnt
330 }
331
332 func (ep *endpoint) StaticRoutes() []*types.StaticRoute {
333         ep.Lock()
334         defer ep.Unlock()
335
336         if ep.joinInfo == nil {
337                 return nil
338         }
339
340         return ep.joinInfo.StaticRoutes
341 }
342
343 func (ep *endpoint) Gateway() net.IP {
344         ep.Lock()
345         defer ep.Unlock()
346
347         if ep.joinInfo == nil {
348                 return net.IP{}
349         }
350
351         return types.GetIPCopy(ep.joinInfo.gw)
352 }
353
354 func (ep *endpoint) GatewayIPv6() net.IP {
355         ep.Lock()
356         defer ep.Unlock()
357
358         if ep.joinInfo == nil {
359                 return net.IP{}
360         }
361
362         return types.GetIPCopy(ep.joinInfo.gw6)
363 }
364
365 func (ep *endpoint) SetGateway(gw net.IP) error {
366         ep.Lock()
367         defer ep.Unlock()
368
369         ep.joinInfo.gw = types.GetIPCopy(gw)
370         return nil
371 }
372
373 func (ep *endpoint) SetGatewayIPv6(gw6 net.IP) error {
374         ep.Lock()
375         defer ep.Unlock()
376
377         ep.joinInfo.gw6 = types.GetIPCopy(gw6)
378         return nil
379 }
380
381 func (ep *endpoint) retrieveFromStore() (*endpoint, error) {
382         n, err := ep.getNetworkFromStore()
383         if err != nil {
384                 return nil, fmt.Errorf("could not find network in store to get latest endpoint %s: %v", ep.Name(), err)
385         }
386         return n.getEndpointFromStore(ep.ID())
387 }
388
389 func (ep *endpoint) DisableGatewayService() {
390         ep.Lock()
391         defer ep.Unlock()
392
393         ep.joinInfo.disableGatewayService = true
394 }
395
396 func (epj *endpointJoinInfo) MarshalJSON() ([]byte, error) {
397         epMap := make(map[string]interface{})
398         if epj.gw != nil {
399                 epMap["gw"] = epj.gw.String()
400         }
401         if epj.gw6 != nil {
402                 epMap["gw6"] = epj.gw6.String()
403         }
404         epMap["disableGatewayService"] = epj.disableGatewayService
405         epMap["StaticRoutes"] = epj.StaticRoutes
406         return json.Marshal(epMap)
407 }
408
409 func (epj *endpointJoinInfo) UnmarshalJSON(b []byte) error {
410         var (
411                 err   error
412                 epMap map[string]interface{}
413         )
414         if err = json.Unmarshal(b, &epMap); err != nil {
415                 return err
416         }
417         if v, ok := epMap["gw"]; ok {
418                 epj.gw6 = net.ParseIP(v.(string))
419         }
420         if v, ok := epMap["gw6"]; ok {
421                 epj.gw6 = net.ParseIP(v.(string))
422         }
423         epj.disableGatewayService = epMap["disableGatewayService"].(bool)
424
425         var tStaticRoute []types.StaticRoute
426         if v, ok := epMap["StaticRoutes"]; ok {
427                 tb, _ := json.Marshal(v)
428                 var tStaticRoute []types.StaticRoute
429                 json.Unmarshal(tb, &tStaticRoute)
430         }
431         var StaticRoutes []*types.StaticRoute
432         for _, r := range tStaticRoute {
433                 StaticRoutes = append(StaticRoutes, &r)
434         }
435         epj.StaticRoutes = StaticRoutes
436
437         return nil
438 }
439
440 func (epj *endpointJoinInfo) CopyTo(dstEpj *endpointJoinInfo) error {
441         dstEpj.disableGatewayService = epj.disableGatewayService
442         dstEpj.StaticRoutes = make([]*types.StaticRoute, len(epj.StaticRoutes))
443         copy(dstEpj.StaticRoutes, epj.StaticRoutes)
444         dstEpj.driverTableEntries = make([]*tableEntry, len(epj.driverTableEntries))
445         copy(dstEpj.driverTableEntries, epj.driverTableEntries)
446         dstEpj.gw = types.GetIPCopy(epj.gw)
447         dstEpj.gw = types.GetIPCopy(epj.gw6)
448         return nil
449 }