github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/bridge/interface_linux.go (about)

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