github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/libnetwork/drivers/bridge/interface.go (about)

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