mirror of
https://github.com/daeuniverse/dae.git
synced 2025-07-12 08:49:53 +07:00
fix: set accept_ra=2 to fix missing ipv6 address on WAN interface if necessary (#504)
This commit is contained in:
@ -208,6 +208,7 @@ func NewControlPlane(
|
|||||||
if len(global.LanInterface) > 0 {
|
if len(global.LanInterface) > 0 {
|
||||||
if global.AutoConfigKernelParameter {
|
if global.AutoConfigKernelParameter {
|
||||||
_ = SetIpv4forward("1")
|
_ = SetIpv4forward("1")
|
||||||
|
_ = setForwarding("all", consts.IpVersionStr_6, "1")
|
||||||
}
|
}
|
||||||
global.LanInterface = common.Deduplicate(global.LanInterface)
|
global.LanInterface = common.Deduplicate(global.LanInterface)
|
||||||
for _, ifname := range global.LanInterface {
|
for _, ifname := range global.LanInterface {
|
||||||
@ -227,6 +228,19 @@ func NewControlPlane(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, ifname := range global.WanInterface {
|
for _, ifname := range global.WanInterface {
|
||||||
|
if len(global.LanInterface) > 0 {
|
||||||
|
// FIXME: Code is not elegant here.
|
||||||
|
// bindLan setting conf.ipv6.all.forwarding=1 suppresses accept_ra=1,
|
||||||
|
// thus we set it 2 as a workaround.
|
||||||
|
// See https://sysctl-explorer.net/net/ipv6/accept_ra/ for more information.
|
||||||
|
if global.AutoConfigKernelParameter {
|
||||||
|
acceptRa := sysctl.Keyf("net.ipv6.conf.%v.accept_ra", ifname)
|
||||||
|
val, _ := acceptRa.Get()
|
||||||
|
if val == "1" {
|
||||||
|
_ = acceptRa.Set("2", false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if err = core.bindWan(ifname, global.AutoConfigKernelParameter); err != nil {
|
if err = core.bindWan(ifname, global.AutoConfigKernelParameter); err != nil {
|
||||||
return nil, fmt.Errorf("bindWan: %v: %w", ifname, err)
|
return nil, fmt.Errorf("bindWan: %v: %w", ifname, err)
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,6 @@ func (c *controlPlaneCore) bindLan(ifname string, autoConfigKernelParameter bool
|
|||||||
if autoConfigKernelParameter {
|
if autoConfigKernelParameter {
|
||||||
SetSendRedirects(ifname, "0")
|
SetSendRedirects(ifname, "0")
|
||||||
SetForwarding(ifname, "1")
|
SetForwarding(ifname, "1")
|
||||||
setForwarding("all", consts.IpVersionStr_6, "1")
|
|
||||||
}
|
}
|
||||||
if err := c._bindLan(ifname); err != nil {
|
if err := c._bindLan(ifname); err != nil {
|
||||||
var notFoundErr netlink.LinkNotFoundError
|
var notFoundErr netlink.LinkNotFoundError
|
||||||
|
@ -281,11 +281,11 @@ func (ns *DaeNetns) setupNetns() (err error) {
|
|||||||
|
|
||||||
func (ns *DaeNetns) setupSysctl() (err error) {
|
func (ns *DaeNetns) setupSysctl() (err error) {
|
||||||
// sysctl net.ipv6.conf.dae0.disable_ipv6=0
|
// sysctl net.ipv6.conf.dae0.disable_ipv6=0
|
||||||
if err = sysctl.Set(fmt.Sprintf("net.ipv6.conf.%s.disable_ipv6", HostVethName), "0", true); err != nil {
|
if err = sysctl.Keyf("net.ipv6.conf.%s.disable_ipv6", HostVethName).Set("0", true); err != nil {
|
||||||
return fmt.Errorf("failed to set disable_ipv6 for dae0: %v", err)
|
return fmt.Errorf("failed to set disable_ipv6 for dae0: %v", err)
|
||||||
}
|
}
|
||||||
// sysctl net.ipv6.conf.dae0.forwarding=1
|
// sysctl net.ipv6.conf.dae0.forwarding=1
|
||||||
if err = sysctl.Set(fmt.Sprintf("net.ipv6.conf.%s.forwarding", HostVethName), "1", true); err != nil {
|
if err = sysctl.Keyf("net.ipv6.conf.%s.forwarding", HostVethName).Set("1", true); err != nil {
|
||||||
return fmt.Errorf("failed to set forwarding for dae0: %v", err)
|
return fmt.Errorf("failed to set forwarding for dae0: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,12 +295,12 @@ func (ns *DaeNetns) setupSysctl() (err error) {
|
|||||||
defer netns.Set(ns.hostNs)
|
defer netns.Set(ns.hostNs)
|
||||||
|
|
||||||
// *_early_demux is not mandatory, but it's recommended to enable it for better performance
|
// *_early_demux is not mandatory, but it's recommended to enable it for better performance
|
||||||
sysctl.Set("net.ipv4.tcp_early_demux", "1", false)
|
sysctl.Keyf("net.ipv4.tcp_early_demux").Set("1", false)
|
||||||
sysctl.Set("net.ipv4.ip_early_demux", "1", false)
|
sysctl.Keyf("net.ipv4.ip_early_demux").Set("1", false)
|
||||||
|
|
||||||
// (ip net e daens) sysctl net.ipv4.conf.dae0peer.accept_local=1
|
// (ip net e daens) sysctl net.ipv4.conf.dae0peer.accept_local=1
|
||||||
// This is to prevent kernel from dropping skb due to "martian source" check: https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/fib_frontend.c#L381
|
// This is to prevent kernel from dropping skb due to "martian source" check: https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/fib_frontend.c#L381
|
||||||
if err = sysctl.Set(fmt.Sprintf("net.ipv4.conf.%s.accept_local", NsVethName), "1", false); err != nil {
|
if err = sysctl.Keyf("net.ipv4.conf.%s.accept_local", NsVethName).Set("1", false); err != nil {
|
||||||
return fmt.Errorf("failed to set accept_local for dae0peer: %v", err)
|
return fmt.Errorf("failed to set accept_local for dae0peer: %v", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -76,8 +77,29 @@ func (s *SysctlManager) startWatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SysctlManager) Set(key string, value string, watch bool) (err error) {
|
type SysctlKey string
|
||||||
path := SysctlPrefixPath + strings.Replace(key, ".", "/", -1)
|
|
||||||
|
func (s *SysctlManager) Keyf(format string, a ...any) SysctlKey {
|
||||||
|
return SysctlKey(SysctlPrefixPath + fmt.Sprintf(strings.ReplaceAll(format, ".", "/"), a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k SysctlKey) Get() (value string, err error) {
|
||||||
|
return sysctl.get(string(k))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k SysctlKey) Set(value string, watch bool) (err error) {
|
||||||
|
return sysctl.set(string(k), value, watch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SysctlManager) get(path string) (value string, err error) {
|
||||||
|
val, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(string(val)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SysctlManager) set(path string, value string, watch bool) (err error) {
|
||||||
if watch {
|
if watch {
|
||||||
s.mux.Lock()
|
s.mux.Lock()
|
||||||
s.expectations[path] = value
|
s.expectations[path] = value
|
||||||
|
@ -10,7 +10,7 @@ For every LAN interfaces you want to proxy:
|
|||||||
```shell
|
```shell
|
||||||
export lan_ifname=docker0
|
export lan_ifname=docker0
|
||||||
|
|
||||||
sudo tee /etc/sysctl.d/60-dae-$lan_ifname.conf << EOF
|
sudo tee /etc/sysctl.d/60-dae-lan-$lan_ifname.conf << EOF
|
||||||
net.ipv4.conf.$lan_ifname.forwarding = 1
|
net.ipv4.conf.$lan_ifname.forwarding = 1
|
||||||
net.ipv6.conf.$lan_ifname.forwarding = 1
|
net.ipv6.conf.$lan_ifname.forwarding = 1
|
||||||
net.ipv4.conf.$lan_ifname.send_redirects = 0
|
net.ipv4.conf.$lan_ifname.send_redirects = 0
|
||||||
@ -27,3 +27,20 @@ sudo sysctl --system
|
|||||||
```
|
```
|
||||||
|
|
||||||
Please modify `docker0` to your LAN interface.
|
Please modify `docker0` to your LAN interface.
|
||||||
|
|
||||||
|
For your WAN interfaces that accept RA:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
export wan_ifname=eth0
|
||||||
|
|
||||||
|
if [ "$(cat /proc/sys/net/ipv6/conf/$wan_ifname/accept_ra)" == "1" ]; then
|
||||||
|
sudo tee /etc/sysctl.d/60-dae-wan-$wan_ifname.conf << EOF
|
||||||
|
net.ipv6.conf.$wan_ifname.accept_ra = 2
|
||||||
|
EOF
|
||||||
|
sudo sysctl --system
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
Please modify `eth0` to your WAN interface.
|
||||||
|
|
||||||
|
Setting accept_ra to 2 if it is 1 because `net.ipv6.conf.all.forwarding = 1` will suppress it. See <https://sysctl-explorer.net/net/ipv6/accept_ra/> for more information.
|
||||||
|
Reference in New Issue
Block a user