Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / docker / libnetwork / drivers / bridge / interface.go
1 package bridge
2
3 import (
4         "fmt"
5         "net"
6
7         "github.com/Sirupsen/logrus"
8         "github.com/vishvananda/netlink"
9 )
10
11 const (
12         // DefaultBridgeName is the default name for the bridge interface managed
13         // by the driver when unspecified by the caller.
14         DefaultBridgeName = "docker0"
15 )
16
17 // Interface models the bridge network device.
18 type bridgeInterface struct {
19         Link        netlink.Link
20         bridgeIPv4  *net.IPNet
21         bridgeIPv6  *net.IPNet
22         gatewayIPv4 net.IP
23         gatewayIPv6 net.IP
24         nlh         *netlink.Handle
25 }
26
27 // newInterface creates a new bridge interface structure. It attempts to find
28 // an already existing device identified by the configuration BridgeName field,
29 // or the default bridge name when unspecified, but doesn't attempt to create
30 // one when missing
31 func newInterface(nlh *netlink.Handle, config *networkConfiguration) (*bridgeInterface, error) {
32         var err error
33         i := &bridgeInterface{nlh: nlh}
34
35         // Initialize the bridge name to the default if unspecified.
36         if config.BridgeName == "" {
37                 config.BridgeName = DefaultBridgeName
38         }
39
40         // Attempt to find an existing bridge named with the specified name.
41         i.Link, err = nlh.LinkByName(config.BridgeName)
42         if err != nil {
43                 logrus.Debugf("Did not find any interface with name %s: %v", config.BridgeName, err)
44         } else if _, ok := i.Link.(*netlink.Bridge); !ok {
45                 return nil, fmt.Errorf("existing interface %s is not a bridge", i.Link.Attrs().Name)
46         }
47         return i, nil
48 }
49
50 // exists indicates if the existing bridge interface exists on the system.
51 func (i *bridgeInterface) exists() bool {
52         return i.Link != nil
53 }
54
55 // addresses returns all IPv4 addresses and all IPv6 addresses for the bridge interface.
56 func (i *bridgeInterface) addresses() ([]netlink.Addr, []netlink.Addr, error) {
57         v4addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V4)
58         if err != nil {
59                 return nil, nil, fmt.Errorf("Failed to retrieve V4 addresses: %v", err)
60         }
61
62         v6addr, err := i.nlh.AddrList(i.Link, netlink.FAMILY_V6)
63         if err != nil {
64                 return nil, nil, fmt.Errorf("Failed to retrieve V6 addresses: %v", err)
65         }
66
67         if len(v4addr) == 0 {
68                 return nil, v6addr, nil
69         }
70         return v4addr, v6addr, nil
71 }
72
73 func (i *bridgeInterface) programIPv6Address() error {
74         _, nlAddressList, err := i.addresses()
75         if err != nil {
76                 return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: fmt.Errorf("failed to retrieve address list: %v", err)}
77         }
78         nlAddr := netlink.Addr{IPNet: i.bridgeIPv6}
79         if findIPv6Address(nlAddr, nlAddressList) {
80                 return nil
81         }
82         if err := i.nlh.AddrAdd(i.Link, &nlAddr); err != nil {
83                 return &IPv6AddrAddError{IP: i.bridgeIPv6, Err: err}
84         }
85         return nil
86 }