Skip to content

Commit a7eccc1

Browse files
committed
bridge: Raise accept_ra to 2 when enabling IPv6 forwarding
1 parent a3328ab commit a7eccc1

1 file changed

Lines changed: 43 additions & 5 deletions

File tree

protocol/bridge/netfilter_linux.go

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,71 @@ var (
2929

3030
func enableBridgeForwarding(logger logger.ContextLogger, tunName string, inet4 bool, inet6 bool) []sysctlState {
3131
var restore []sysctlState
32-
enable := func(path string) {
32+
enable := func(path string) bool {
3333
content, err := os.ReadFile(path)
3434
if err != nil {
3535
logger.Debug(E.Cause(err, "read ", path))
36-
return
36+
return false
3737
}
3838
value := strings.TrimSpace(string(content))
3939
if value == "1" {
40-
return
40+
return false
4141
}
4242
err = os.WriteFile(path, []byte("1"), 0o644)
4343
if err != nil {
4444
logger.Debug(E.Cause(err, "enable ", path))
45-
return
45+
return false
4646
}
4747
restore = append(restore, sysctlState{name: path, value: value})
48+
return true
4849
}
4950
if inet4 {
5051
enable("/proc/sys/net/ipv4/ip_forward")
5152
}
5253
if inet6 {
53-
enable("/proc/sys/net/ipv6/conf/all/forwarding")
54+
if enable("/proc/sys/net/ipv6/conf/all/forwarding") {
55+
restore = append(restore, overruleAcceptRA(logger)...)
56+
}
5457
}
5558
_ = os.WriteFile("/proc/sys/net/ipv4/conf/"+tunName+"/rp_filter", []byte("2"), 0o644)
5659
return restore
5760
}
5861

62+
// Writing conf/all/forwarding copies forwarding=1 to conf/default and to every
63+
// existing interface (addrconf_fixup_forwarding), and ipv6_accept_ra() then
64+
// requires accept_ra=2 on a forwarding interface; raise interfaces left at the
65+
// host default of 1 so SLAAC (e.g. on PPPoE WANs) survives forwarding.
66+
// conf/default is included so interfaces created afterwards inherit 2.
67+
func overruleAcceptRA(logger logger.ContextLogger) []sysctlState {
68+
var restore []sysctlState
69+
entries, err := os.ReadDir("/proc/sys/net/ipv6/conf")
70+
if err != nil {
71+
logger.Debug(E.Cause(err, "read /proc/sys/net/ipv6/conf"))
72+
return nil
73+
}
74+
for _, entry := range entries {
75+
if entry.Name() == "all" {
76+
continue
77+
}
78+
path := "/proc/sys/net/ipv6/conf/" + entry.Name() + "/accept_ra"
79+
content, err := os.ReadFile(path)
80+
if err != nil {
81+
continue
82+
}
83+
value := strings.TrimSpace(string(content))
84+
if value != "1" {
85+
continue
86+
}
87+
err = os.WriteFile(path, []byte("2"), 0o644)
88+
if err != nil {
89+
logger.Debug(E.Cause(err, "overrule ", path))
90+
continue
91+
}
92+
restore = append(restore, sysctlState{name: path, value: value})
93+
}
94+
return restore
95+
}
96+
5997
func restoreBridgeForwarding(states []sysctlState) {
6098
for _, state := range states {
6199
_ = os.WriteFile(state.name, []byte(state.value), 0o644)

0 commit comments

Comments
 (0)