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  }