github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/libnetwork/drivers/bridge/setup_ipv4.go (about) 1 // +build linux 2 3 package bridge 4 5 import ( 6 "errors" 7 "fmt" 8 "io/ioutil" 9 "net" 10 "path/filepath" 11 12 "github.com/docker/docker/libnetwork/types" 13 "github.com/sirupsen/logrus" 14 "github.com/vishvananda/netlink" 15 ) 16 17 func selectIPv4Address(addresses []netlink.Addr, selector *net.IPNet) (netlink.Addr, error) { 18 if len(addresses) == 0 { 19 return netlink.Addr{}, errors.New("unable to select an address as the address pool is empty") 20 } 21 if selector != nil { 22 for _, addr := range addresses { 23 if selector.Contains(addr.IP) { 24 return addr, nil 25 } 26 } 27 } 28 return addresses[0], nil 29 } 30 31 func setupBridgeIPv4(config *networkConfiguration, i *bridgeInterface) error { 32 if !config.InhibitIPv4 { 33 addrv4List, _, err := i.addresses() 34 if err != nil { 35 return fmt.Errorf("failed to retrieve bridge interface addresses: %v", err) 36 } 37 38 addrv4, _ := selectIPv4Address(addrv4List, config.AddressIPv4) 39 40 if !types.CompareIPNet(addrv4.IPNet, config.AddressIPv4) { 41 if addrv4.IPNet != nil { 42 if err := i.nlh.AddrDel(i.Link, &addrv4); err != nil { 43 return fmt.Errorf("failed to remove current ip address from bridge: %v", err) 44 } 45 } 46 logrus.Debugf("Assigning address to bridge interface %s: %s", config.BridgeName, config.AddressIPv4) 47 if err := i.nlh.AddrAdd(i.Link, &netlink.Addr{IPNet: config.AddressIPv4}); err != nil { 48 return &IPv4AddrAddError{IP: config.AddressIPv4, Err: err} 49 } 50 } 51 } 52 53 // Store bridge network and default gateway 54 i.bridgeIPv4 = config.AddressIPv4 55 i.gatewayIPv4 = config.AddressIPv4.IP 56 57 return nil 58 } 59 60 func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error { 61 if !i.bridgeIPv4.Contains(config.DefaultGatewayIPv4) { 62 return &ErrInvalidGateway{} 63 } 64 65 // Store requested default gateway 66 i.gatewayIPv4 = config.DefaultGatewayIPv4 67 68 return nil 69 } 70 71 func setupLoopbackAddressesRouting(config *networkConfiguration, i *bridgeInterface) error { 72 sysPath := filepath.Join("/proc/sys/net/ipv4/conf", config.BridgeName, "route_localnet") 73 ipv4LoRoutingData, err := ioutil.ReadFile(sysPath) 74 if err != nil { 75 return fmt.Errorf("Cannot read IPv4 local routing setup: %v", err) 76 } 77 // Enable loopback addresses routing only if it isn't already enabled 78 if ipv4LoRoutingData[0] != '1' { 79 if err := ioutil.WriteFile(sysPath, []byte{'1', '\n'}, 0644); err != nil { 80 return fmt.Errorf("Unable to enable local routing for hairpin mode: %v", err) 81 } 82 } 83 return nil 84 }