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