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