github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/drivers/bridge/setup_ipv6.go (about)

     1  package bridge
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net"
     7  	"os"
     8  
     9  	"github.com/docker/libnetwork/types"
    10  	"github.com/sirupsen/logrus"
    11  	"github.com/vishvananda/netlink"
    12  )
    13  
    14  var bridgeIPv6 *net.IPNet
    15  
    16  const (
    17  	bridgeIPv6Str          = "fe80::1/64"
    18  	ipv6ForwardConfPerm    = 0644
    19  	ipv6ForwardConfDefault = "/proc/sys/net/ipv6/conf/default/forwarding"
    20  	ipv6ForwardConfAll     = "/proc/sys/net/ipv6/conf/all/forwarding"
    21  )
    22  
    23  func init() {
    24  	// We allow ourselves to panic in this special case because we indicate a
    25  	// failure to parse a compile-time define constant.
    26  	var err error
    27  	if bridgeIPv6, err = types.ParseCIDR(bridgeIPv6Str); err != nil {
    28  		panic(fmt.Sprintf("Cannot parse default bridge IPv6 address %q: %v", bridgeIPv6Str, err))
    29  	}
    30  }
    31  
    32  func setupBridgeIPv6(config *networkConfiguration, i *bridgeInterface) error {
    33  	procFile := "/proc/sys/net/ipv6/conf/" + config.BridgeName + "/disable_ipv6"
    34  	ipv6BridgeData, err := ioutil.ReadFile(procFile)
    35  	if err != nil {
    36  		return fmt.Errorf("Cannot read IPv6 setup for bridge %v: %v", config.BridgeName, err)
    37  	}
    38  	// Enable IPv6 on the bridge only if it isn't already enabled
    39  	if ipv6BridgeData[0] != '0' {
    40  		if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, ipv6ForwardConfPerm); err != nil {
    41  			return fmt.Errorf("Unable to enable IPv6 addresses on bridge: %v", err)
    42  		}
    43  	}
    44  
    45  	// Store bridge network and default gateway
    46  	i.bridgeIPv6 = bridgeIPv6
    47  	i.gatewayIPv6 = i.bridgeIPv6.IP
    48  
    49  	if err := i.programIPv6Address(); err != nil {
    50  		return err
    51  	}
    52  
    53  	if config.AddressIPv6 == nil {
    54  		return nil
    55  	}
    56  
    57  	// Store the user specified bridge network and network gateway and program it
    58  	i.bridgeIPv6 = config.AddressIPv6
    59  	i.gatewayIPv6 = config.AddressIPv6.IP
    60  
    61  	if err := i.programIPv6Address(); err != nil {
    62  		return err
    63  	}
    64  
    65  	// Setting route to global IPv6 subnet
    66  	logrus.Debugf("Adding route to IPv6 network %s via device %s", config.AddressIPv6.String(), config.BridgeName)
    67  	err = i.nlh.RouteAdd(&netlink.Route{
    68  		Scope:     netlink.SCOPE_UNIVERSE,
    69  		LinkIndex: i.Link.Attrs().Index,
    70  		Dst:       config.AddressIPv6,
    71  	})
    72  	if err != nil && !os.IsExist(err) {
    73  		logrus.Errorf("Could not add route to IPv6 network %s via device %s: %s", config.AddressIPv6.String(), config.BridgeName, err)
    74  	}
    75  
    76  	return nil
    77  }
    78  
    79  func setupGatewayIPv6(config *networkConfiguration, i *bridgeInterface) error {
    80  	if config.AddressIPv6 == nil {
    81  		return &ErrInvalidContainerSubnet{}
    82  	}
    83  	if !config.AddressIPv6.Contains(config.DefaultGatewayIPv6) {
    84  		return &ErrInvalidGateway{}
    85  	}
    86  
    87  	// Store requested default gateway
    88  	i.gatewayIPv6 = config.DefaultGatewayIPv6
    89  
    90  	return nil
    91  }
    92  
    93  func setupIPv6Forwarding(config *networkConfiguration, i *bridgeInterface) error {
    94  	// Get current IPv6 default forwarding setup
    95  	ipv6ForwardDataDefault, err := ioutil.ReadFile(ipv6ForwardConfDefault)
    96  	if err != nil {
    97  		return fmt.Errorf("Cannot read IPv6 default forwarding setup: %v", err)
    98  	}
    99  	// Enable IPv6 default forwarding only if it is not already enabled
   100  	if ipv6ForwardDataDefault[0] != '1' {
   101  		if err := ioutil.WriteFile(ipv6ForwardConfDefault, []byte{'1', '\n'}, ipv6ForwardConfPerm); err != nil {
   102  			logrus.Warnf("Unable to enable IPv6 default forwarding: %v", err)
   103  		}
   104  	}
   105  
   106  	// Get current IPv6 all forwarding setup
   107  	ipv6ForwardDataAll, err := ioutil.ReadFile(ipv6ForwardConfAll)
   108  	if err != nil {
   109  		return fmt.Errorf("Cannot read IPv6 all forwarding setup: %v", err)
   110  	}
   111  	// Enable IPv6 all forwarding only if it is not already enabled
   112  	if ipv6ForwardDataAll[0] != '1' {
   113  		if err := ioutil.WriteFile(ipv6ForwardConfAll, []byte{'1', '\n'}, ipv6ForwardConfPerm); err != nil {
   114  			logrus.Warnf("Unable to enable IPv6 all forwarding: %v", err)
   115  		}
   116  	}
   117  
   118  	return nil
   119  }