github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/bridge/setup_ipv6_linux.go (about)

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