@@ -29,33 +29,71 @@ var (
2929
3030func 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+
5997func restoreBridgeForwarding (states []sysctlState ) {
6098 for _ , state := range states {
6199 _ = os .WriteFile (state .name , []byte (state .value ), 0o644 )
0 commit comments