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