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