interface.go 2.5 KB

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