interface_linux.go 2.7 KB

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