interface.go 2.7 KB

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