public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH docs/network/perl-rs v2 0/5] sdn: enable force_forwarding for ipv6 forwarding
@ 2026-06-03 14:29 Lukas Sichert
  2026-06-03 14:29 ` [PATCH network v2 1/5] sdn: evpn: enable force_forwarding for ipv6 forwarding to subnets Lukas Sichert
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Lukas Sichert @ 2026-06-03 14:29 UTC (permalink / raw)
  To: pve-devel; +Cc: Lukas Sichert

Gabriel's upstream kernel patch [1] added
net.ipv6.conf.<iface>.force_forwarding. This allows enabling IPv6
forwarding on selected interfaces without requiring
net.ipv6.conf.all.forwarding.

This is useful for SDN setups because all.forwarding has host-wide side
effects. In particular, it disables Router Advertisement processing by
default, which can break SLAAC on unrelated interfaces. SDN only needs
forwarding on the VNet, exit-node, or fabric interfaces that participate
in routed IPv6 traffic.

This series generates ifupdown post-up/post-down commands for those
interfaces so force_forwarding is enabled when the interface is brought
up and reset when it is brought down.
The tests are adjusted for the generated /etc/network/interfaces.d/sdn
output.
Also the series rewrites the documenation to reflect the updated
behaviour.


[1] lkml.org/lkml/2025/7/7/577

changes from v1 to v2 (thanks @Gabriel, @Hannes):
-add force_fowarding also to bgp fabrics
-explictly mention the force_forwarding flag in the documenation
-add a reference link to the sysctl documentation
-mention bgp as a fabric with ipv6 support


network:

Lukas Sichert (2):
  sdn: evpn: enable force_forwarding for ipv6 forwarding to subnets
  sdn: simple: enable force_forwarding for ipv6 forwarding to subnets

 src/PVE/Network/SDN/Zones/EvpnPlugin.pm       | 20 +++++++++++++++----
 src/PVE/Network/SDN/Zones/SimplePlugin.pm     | 20 +++++++++++++++----
 .../expected_sdn_interfaces                   |  4 ++++
 .../exitnode_snat/expected_sdn_interfaces     |  4 ++++
 .../exitnodenullroute/expected_sdn_interfaces |  4 ++++
 .../evpn/ipv4ipv6/expected_sdn_interfaces     |  4 ++++
 .../zones/evpn/ipv6/expected_sdn_interfaces   |  4 ++++
 .../evpn/ipv6underlay/expected_sdn_interfaces |  4 ++++
 .../simple/ipv4v6/expected_sdn_interfaces     |  4 ++++
 .../simple/ipv6snat/expected_sdn_interfaces   |  4 ++++
 10 files changed, 64 insertions(+), 8 deletions(-)


perl-rs:

Lukas Sichert (2):
  fabrics: openfabric: enable force_forwarding for ipv6 transit traffic
  fabrics: bgp: enable force_forwardgin for ipv6 transit traffic

 pve-rs/src/bindings/sdn/fabrics.rs | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)


docs:

Lukas Sichert (1):
  sdn: drop global iv6 forwarding workaround from OpenFabric docs

 pvesdn.adoc | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)


Summary over all repositories:
  12 files changed, 87 insertions(+), 24 deletions(-)

-- 
Generated by murpp 0.12.0




^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH network v2 1/5] sdn: evpn: enable force_forwarding for ipv6 forwarding to subnets
  2026-06-03 14:29 [PATCH docs/network/perl-rs v2 0/5] sdn: enable force_forwarding for ipv6 forwarding Lukas Sichert
@ 2026-06-03 14:29 ` Lukas Sichert
  2026-06-03 14:29 ` [PATCH network v2 2/5] sdn: simple: " Lukas Sichert
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Lukas Sichert @ 2026-06-03 14:29 UTC (permalink / raw)
  To: pve-devel; +Cc: Lukas Sichert

EVPN zones can route IPv6 subnet traffic through a VNet and an outgoing
interface. Until now, this depended on global IPv6 forwarding state,
which also changes Router Advertisement handling for the whole host.

Use the per-interface 'force_forwarding' setting instead. For IPv6
subnets that need forwarding, generate post-up/post-down commands for
both the VNet interface and the outgoing interface. Track interfaces
that already received 'force_forwarding' commands to avoid duplicates
when multiple subnets share the same outgoing path. Update the expected
SDN interface output in the zone tests accordingly.

Signed-off-by: Lukas Sichert <l.sichert@proxmox.com>
---
 src/PVE/Network/SDN/Zones/EvpnPlugin.pm       | 20 +++++++++++++++----
 .../expected_sdn_interfaces                   |  4 ++++
 .../exitnode_snat/expected_sdn_interfaces     |  4 ++++
 .../exitnodenullroute/expected_sdn_interfaces |  4 ++++
 .../evpn/ipv4ipv6/expected_sdn_interfaces     |  4 ++++
 .../zones/evpn/ipv6/expected_sdn_interfaces   |  4 ++++
 .../evpn/ipv6underlay/expected_sdn_interfaces |  4 ++++
 7 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/src/PVE/Network/SDN/Zones/EvpnPlugin.pm b/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
index dfbd7e9..7622457 100644
--- a/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
+++ b/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
@@ -238,11 +238,13 @@ sub generate_sdn_config {
     my $ipv6 = undef;
     my $enable_forward_v4 = undef;
     my $enable_forward_v6 = undef;
+    my $force_forward_enabled = {};
     my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
     foreach my $subnetid (sort keys %{$subnets}) {
         my $subnet = $subnets->{$subnetid};
         my $cidr = $subnet->{cidr};
         my $mask = $subnet->{mask};
+        my $vnet = $subnet->{vnet};
 
         my $gateway = $subnet->{gateway};
         if ($gateway) {
@@ -266,11 +268,21 @@ sub generate_sdn_config {
             $enable_forward_v4 = 1 if $gateway;
         }
 
-        if ($subnet->{snat}) {
+        #find outgoing interface
+        my ($outip, $outiface) =
+            PVE::Network::SDN::Zones::Plugin::get_local_route_ip($checkrouteip);
+
+        if ($outiface && $enable_forward_v6 && !($force_forward_enabled->{$outiface})) {
+            push @iface_config,
+                "post-up echo 1 > /proc/sys/net/ipv6/conf/$outiface/force_forwarding";
+            push @iface_config,
+                "post-down echo 0 > /proc/sys/net/ipv6/conf/$outiface/force_forwarding";
+            push @iface_config, "post-up echo 1 > /proc/sys/net/ipv6/conf/$vnet/force_forwarding";
+            push @iface_config, "post-down echo 0 > /proc/sys/net/ipv6/conf/$vnet/force_forwarding";
+            $force_forward_enabled->{$outiface} = 1;
+        }
 
-            #find outgoing interface
-            my ($outip, $outiface) =
-                PVE::Network::SDN::Zones::Plugin::get_local_route_ip($checkrouteip);
+        if ($subnet->{snat}) {
             if ($outip && $outiface && $is_evpn_gateway) {
                 #use snat, faster than masquerade
                 push @iface_config,
diff --git a/src/test/zones/evpn/exitnode_local_routing_ipv6/expected_sdn_interfaces b/src/test/zones/evpn/exitnode_local_routing_ipv6/expected_sdn_interfaces
index b46d4e7..e620e15 100644
--- a/src/test/zones/evpn/exitnode_local_routing_ipv6/expected_sdn_interfaces
+++ b/src/test/zones/evpn/exitnode_local_routing_ipv6/expected_sdn_interfaces
@@ -3,6 +3,10 @@
 auto myvnet
 iface myvnet
 	address 2a08:2142:302:3::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
 	bridge_ports vxlan_myvnet
 	bridge_stp off
 	bridge_fd 0
diff --git a/src/test/zones/evpn/exitnode_snat/expected_sdn_interfaces b/src/test/zones/evpn/exitnode_snat/expected_sdn_interfaces
index 0d7d174..bdd6dd3 100644
--- a/src/test/zones/evpn/exitnode_snat/expected_sdn_interfaces
+++ b/src/test/zones/evpn/exitnode_snat/expected_sdn_interfaces
@@ -18,6 +18,10 @@ iface myvnet
 auto myvnet2
 iface myvnet2
 	address 2a08:2142:302:3::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet2/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet2/force_forwarding
 	post-up ip6tables -t nat -A POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 2001:db8::2
 	post-down ip6tables -t nat -D POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 2001:db8::2
 	post-up ip6tables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1
diff --git a/src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces b/src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces
index 4bf5ccf..557ccd3 100644
--- a/src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces
+++ b/src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces
@@ -6,6 +6,10 @@ iface myvnet
 	address 192.168.0.1/24
 	address 192.168.10.1/24
 	address 2b0f:1480:4000:6000::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
 	address 2b0f:1480:4000:8000::1/64
 	address 2b0f:1480::1/64
 	bridge_ports vxlan_myvnet
diff --git a/src/test/zones/evpn/ipv4ipv6/expected_sdn_interfaces b/src/test/zones/evpn/ipv4ipv6/expected_sdn_interfaces
index 7a5d741..fcff2ba 100644
--- a/src/test/zones/evpn/ipv4ipv6/expected_sdn_interfaces
+++ b/src/test/zones/evpn/ipv4ipv6/expected_sdn_interfaces
@@ -4,6 +4,10 @@ auto myvnet
 iface myvnet
 	address 10.0.0.1/24
 	address 2a08:2142:302:3::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
 	hwaddress A2:1D:CB:1A:C0:8B
 	bridge_ports vxlan_myvnet
 	bridge_stp off
diff --git a/src/test/zones/evpn/ipv6/expected_sdn_interfaces b/src/test/zones/evpn/ipv6/expected_sdn_interfaces
index b2bdbfe..2ab9bf9 100644
--- a/src/test/zones/evpn/ipv6/expected_sdn_interfaces
+++ b/src/test/zones/evpn/ipv6/expected_sdn_interfaces
@@ -3,6 +3,10 @@
 auto myvnet
 iface myvnet
 	address 2a08:2142:302:3::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
 	hwaddress A2:1D:CB:1A:C0:8B
 	bridge_ports vxlan_myvnet
 	bridge_stp off
diff --git a/src/test/zones/evpn/ipv6underlay/expected_sdn_interfaces b/src/test/zones/evpn/ipv6underlay/expected_sdn_interfaces
index 3b91f75..624f38a 100644
--- a/src/test/zones/evpn/ipv6underlay/expected_sdn_interfaces
+++ b/src/test/zones/evpn/ipv6underlay/expected_sdn_interfaces
@@ -3,6 +3,10 @@
 auto myvnet
 iface myvnet
 	address 2a08:2142:302:3::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
 	hwaddress A2:1D:CB:1A:C0:8B
 	bridge_ports vxlan_myvnet
 	bridge_stp off
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH network v2 2/5] sdn: simple: enable force_forwarding for ipv6 forwarding to subnets
  2026-06-03 14:29 [PATCH docs/network/perl-rs v2 0/5] sdn: enable force_forwarding for ipv6 forwarding Lukas Sichert
  2026-06-03 14:29 ` [PATCH network v2 1/5] sdn: evpn: enable force_forwarding for ipv6 forwarding to subnets Lukas Sichert
@ 2026-06-03 14:29 ` Lukas Sichert
  2026-06-03 14:29 ` [PATCH perl-rs v2 3/5] fabrics: openfabric: enable force_forwarding for ipv6 transit traffic Lukas Sichert
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Lukas Sichert @ 2026-06-03 14:29 UTC (permalink / raw)
  To: pve-devel; +Cc: Lukas Sichert

Simple zones can route ipv6 subnet traffic through a VNet bridge. Until
now, this depended on global ipv6 forwarding state, which also changes
Router Advertisement handling for the whole host.

Use the per-interface 'force_forwarding' setting instead. For ipv6
subnets that need forwarding, generate post-up/post-down commands for
both the VNet interface and the outgoing interface. Track interfaces
that already received 'force_forwarding' commands to avoid duplicates
when multiple subnets share the same outgoing path.
Update the expected SDN interface output in the zone tests accordingly.

Signed-off-by: Lukas Sichert <l.sichert@proxmox.com>
---
 src/PVE/Network/SDN/Zones/SimplePlugin.pm     | 20 +++++++++++++++----
 .../simple/ipv4v6/expected_sdn_interfaces     |  4 ++++
 .../simple/ipv6snat/expected_sdn_interfaces   |  4 ++++
 3 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/PVE/Network/SDN/Zones/SimplePlugin.pm b/src/PVE/Network/SDN/Zones/SimplePlugin.pm
index f5cd18e..acc482c 100644
--- a/src/PVE/Network/SDN/Zones/SimplePlugin.pm
+++ b/src/PVE/Network/SDN/Zones/SimplePlugin.pm
@@ -80,11 +80,13 @@ sub generate_sdn_config {
     my $ipv6 = undef;
     my $enable_forward_v4 = undef;
     my $enable_forward_v6 = undef;
+    my $force_forward_enabled = {};
 
     foreach my $subnetid (sort keys %{$subnets}) {
         my $subnet = $subnets->{$subnetid};
         my $cidr = $subnet->{cidr};
         my $mask = $subnet->{mask};
+        my $vnet = $subnet->{vnet};
 
         my $gateway = $subnet->{gateway};
         if ($gateway) {
@@ -108,12 +110,23 @@ sub generate_sdn_config {
             $enable_forward_v4 = 1 if $gateway;
         }
 
+        #find outgoing interface
+        my ($outip, $outiface) =
+            PVE::Network::SDN::Zones::Plugin::get_local_route_ip($checkrouteip);
+
+        if ($outiface && $enable_forward_v6 && !($force_forward_enabled->{$outiface})) {
+            push @iface_config,
+                "post-up echo 1 > /proc/sys/net/ipv6/conf/$outiface/force_forwarding";
+            push @iface_config,
+                "post-down echo 0 > /proc/sys/net/ipv6/conf/$outiface/force_forwarding";
+            push @iface_config, "post-up echo 1 > /proc/sys/net/ipv6/conf/$vnet/force_forwarding";
+            push @iface_config, "post-down echo 0 > /proc/sys/net/ipv6/conf/$vnet/force_forwarding";
+            $force_forward_enabled->{$outiface} = 1;
+        }
+
         #add route for /32 pointtopoint
         push @iface_config, "up ip route add $cidr dev $vnetid" if $mask == 32 && $ipversion == 4;
         if ($subnet->{snat}) {
-            #find outgoing interface
-            my ($outip, $outiface) =
-                PVE::Network::SDN::Zones::Plugin::get_local_route_ip($checkrouteip);
             if ($outip && $outiface) {
                 #use snat, faster than masquerade
                 push @iface_config,
@@ -141,7 +154,6 @@ sub generate_sdn_config {
     push @iface_config, "alias $alias" if $alias;
     push @iface_config, "ip-forward on" if $enable_forward_v4;
     push @iface_config, "ip6-forward on" if $enable_forward_v6;
-
     push @{ $config->{$vnetid} }, @iface_config;
 
     return $config;
diff --git a/src/test/zones/simple/ipv4v6/expected_sdn_interfaces b/src/test/zones/simple/ipv4v6/expected_sdn_interfaces
index 34ed5db..cd19fda 100644
--- a/src/test/zones/simple/ipv4v6/expected_sdn_interfaces
+++ b/src/test/zones/simple/ipv4v6/expected_sdn_interfaces
@@ -4,6 +4,10 @@ auto myvnet
 iface myvnet
 	address 192.168.0.1/24
 	address 2a08:2142:302:3::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
 	bridge_ports none
 	bridge_stp off
 	bridge_fd 0
diff --git a/src/test/zones/simple/ipv6snat/expected_sdn_interfaces b/src/test/zones/simple/ipv6snat/expected_sdn_interfaces
index 5f6d40b..f426774 100644
--- a/src/test/zones/simple/ipv6snat/expected_sdn_interfaces
+++ b/src/test/zones/simple/ipv6snat/expected_sdn_interfaces
@@ -3,6 +3,10 @@
 auto myvnet
 iface myvnet
 	address 2a08:2142:302:3::1/64
+	post-up echo 1 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/vmbr0/force_forwarding
+	post-up echo 1 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
+	post-down echo 0 > /proc/sys/net/ipv6/conf/myvnet/force_forwarding
 	post-up ip6tables -t nat -A POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 2001:db8::2
 	post-down ip6tables -t nat -D POSTROUTING -s '2a08:2142:302:3::/64' -o vmbr0 -j SNAT --to-source 2001:db8::2
 	post-up ip6tables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH perl-rs v2 3/5] fabrics: openfabric: enable force_forwarding for ipv6 transit traffic
  2026-06-03 14:29 [PATCH docs/network/perl-rs v2 0/5] sdn: enable force_forwarding for ipv6 forwarding Lukas Sichert
  2026-06-03 14:29 ` [PATCH network v2 1/5] sdn: evpn: enable force_forwarding for ipv6 forwarding to subnets Lukas Sichert
  2026-06-03 14:29 ` [PATCH network v2 2/5] sdn: simple: " Lukas Sichert
@ 2026-06-03 14:29 ` Lukas Sichert
  2026-06-03 14:29 ` [PATCH perl-rs v2 4/5] fabrics: bgp: enable force_forwardgin " Lukas Sichert
  2026-06-03 14:29 ` [PATCH docs v2 5/5] sdn: drop global iv6 forwarding workaround from OpenFabric docs Lukas Sichert
  4 siblings, 0 replies; 6+ messages in thread
From: Lukas Sichert @ 2026-06-03 14:29 UTC (permalink / raw)
  To: pve-devel; +Cc: Lukas Sichert

In a non-full-mesh OpenFabric setup, nodes may need to relay traffic
between peers that are not directly connected. This requires forwarding
ipv6 packets between fabric bridges. With the addition of
'force_forwarding' to the Linux kernel, this can be done without
enabling 'all.forwarding', which disables Router Advertisements.

Configure fabric bridges with the required 'post-up'/'post-down'
commands to enable 'force_forwarding'.

Signed-off-by: Lukas Sichert <l.sichert@proxmox.com>
---
 pve-rs/src/bindings/sdn/fabrics.rs | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/pve-rs/src/bindings/sdn/fabrics.rs b/pve-rs/src/bindings/sdn/fabrics.rs
index f96b6b1..785b537 100644
--- a/pve-rs/src/bindings/sdn/fabrics.rs
+++ b/pve-rs/src/bindings/sdn/fabrics.rs
@@ -596,6 +596,16 @@ pub mod pve_rs_sdn_fabrics {
             writeln!(interface, "\tlink-type {link_type}")?;
         }
         writeln!(interface, "\tip-forward 1")?;
+        if cidr.is_ipv6() {
+            writeln!(
+                interface,
+                "\tpost-up echo 1 > /proc/sys/net/ipv6/conf/{name}/force_forwarding"
+            )?;
+            writeln!(
+                interface,
+                "\tpost-down echo 0 > /proc/sys/net/ipv6/conf/{name}/force_forwarding"
+            )?;
+        }
 
         Ok(interface)
     }
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH perl-rs v2 4/5] fabrics: bgp: enable force_forwardgin for ipv6 transit traffic
  2026-06-03 14:29 [PATCH docs/network/perl-rs v2 0/5] sdn: enable force_forwarding for ipv6 forwarding Lukas Sichert
                   ` (2 preceding siblings ...)
  2026-06-03 14:29 ` [PATCH perl-rs v2 3/5] fabrics: openfabric: enable force_forwarding for ipv6 transit traffic Lukas Sichert
@ 2026-06-03 14:29 ` Lukas Sichert
  2026-06-03 14:29 ` [PATCH docs v2 5/5] sdn: drop global iv6 forwarding workaround from OpenFabric docs Lukas Sichert
  4 siblings, 0 replies; 6+ messages in thread
From: Lukas Sichert @ 2026-06-03 14:29 UTC (permalink / raw)
  To: pve-devel; +Cc: Lukas Sichert

In a non-full-mesh BGP-fabric setup, nodes may need to relay traffic
between peers that are not directly connected. This requires forwarding
ipv6 packets between fabric bridges. With the addition of
'force_forwarding' to the Linux kernel, this can be done without
enabling 'all.forwarding', which disables Router Advertisements.

Configure fabric bridges with the required 'post-up'/'post-down'
commands to enable 'force_forwarding'.

Signed-off-by: Lukas Sichert <l.sichert@proxmox.com>
---
 pve-rs/src/bindings/sdn/fabrics.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/pve-rs/src/bindings/sdn/fabrics.rs b/pve-rs/src/bindings/sdn/fabrics.rs
index 785b537..000ecb7 100644
--- a/pve-rs/src/bindings/sdn/fabrics.rs
+++ b/pve-rs/src/bindings/sdn/fabrics.rs
@@ -774,6 +774,14 @@ pub mod pve_rs_sdn_fabrics {
                             writeln!(interfaces, "iface {name} inet manual")?;
                             writeln!(interfaces, "\tip-forward 1")?;
                             writeln!(interfaces, "\tip6-forward 1")?;
+                            writeln!(
+                                interfaces,
+                                "\tpost-up echo 1 > /proc/sys/net/ipv6/conf/{name}/force_forwarding"
+                            )?;
+                            writeln!(
+                                interfaces,
+                                "\tpost-down echo 0 > /proc/sys/net/ipv6/conf/{name}/force_forwarding"
+                            )?;
                             // BGP unnumbered uses RAs to discover peer link-local
                             // addresses. frr listens for them itself, but the kernel
                             // would otherwise install RA-derived routes we don't want.
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH docs v2 5/5] sdn: drop global iv6 forwarding workaround from OpenFabric docs
  2026-06-03 14:29 [PATCH docs/network/perl-rs v2 0/5] sdn: enable force_forwarding for ipv6 forwarding Lukas Sichert
                   ` (3 preceding siblings ...)
  2026-06-03 14:29 ` [PATCH perl-rs v2 4/5] fabrics: bgp: enable force_forwardgin " Lukas Sichert
@ 2026-06-03 14:29 ` Lukas Sichert
  4 siblings, 0 replies; 6+ messages in thread
From: Lukas Sichert @ 2026-06-03 14:29 UTC (permalink / raw)
  To: pve-devel; +Cc: Lukas Sichert

OpenFabric fabrics with ipv6 need forwarding on transit nodes so packets
can be relayed between peers that are not directly connected.

Drop the old recommendation to enable host-wide
net.ipv6.conf.all.forwarding from the documentation. The generated fabric
interface configuration now handles the required forwarding setup, so the
manual global forwarding workaround is no longer needed.

Signed-off-by: Lukas Sichert <l.sichert@proxmox.com>
---
 pvesdn.adoc | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/pvesdn.adoc b/pvesdn.adoc
index d20a0eb..fed9664 100644
--- a/pvesdn.adoc
+++ b/pvesdn.adoc
@@ -604,23 +604,12 @@ behavior and proper source address selection throughout the fabric.
 Notes on IPv6
 ^^^^^^^^^^^^^
 
-IPv6 is currently only usable on OpenFabric fabrics. These IPv6 Fabrics need
-global IPv6 forwarding enabled on all nodes contained in the fabric. Without
+IPv6 is currently only usable on OpenFabric and BGP fabrics. These IPv6 Fabrics
+need IPv6 forwarding enabled on all transit nodes contained in the fabric. Without
 IPv6 forwarding, non-full-mesh fabrics won't work because the transit nodes
-don't forward packets to the outer nodes. Currently there isn't an easy way to
-enable IPv6 forwarding per-interface like with IPv4, so it has to be enabled
-globally. This can be accomplished by appending this line:
-
-----
-post-up sysctl -w net.ipv6.conf.all.forwarding=1
-----
-
-to a fabric interface in the `/etc/network/interfaces` file. This will enable
-IPv6 forwarding globally once that interface comes up. Note that this affects
-how your interfaces handle automatic IPv6 setup (SLAAC), Neighbour
-Advertisements, Router Solicitations, and Router Advertisements. More details
-here: https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt under
-`net.ipv6.conf.all.forwarding`.
+don't forward packets to the outer nodes. IPv6 fowarding is enabled per default
+on the necessary interfaces using the force_forwarding flag. More details here:
+docs.kernel.org/networking/ip-sysctl.html
 
 [[pvesdn_openfabric]]
 OpenFabric
-- 
2.47.3





^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-06-03 14:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-03 14:29 [PATCH docs/network/perl-rs v2 0/5] sdn: enable force_forwarding for ipv6 forwarding Lukas Sichert
2026-06-03 14:29 ` [PATCH network v2 1/5] sdn: evpn: enable force_forwarding for ipv6 forwarding to subnets Lukas Sichert
2026-06-03 14:29 ` [PATCH network v2 2/5] sdn: simple: " Lukas Sichert
2026-06-03 14:29 ` [PATCH perl-rs v2 3/5] fabrics: openfabric: enable force_forwarding for ipv6 transit traffic Lukas Sichert
2026-06-03 14:29 ` [PATCH perl-rs v2 4/5] fabrics: bgp: enable force_forwardgin " Lukas Sichert
2026-06-03 14:29 ` [PATCH docs v2 5/5] sdn: drop global iv6 forwarding workaround from OpenFabric docs Lukas Sichert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal