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 }