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 }