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 }