Skip to content

Commit 44e25b1

Browse files
Merge pull request #962 from Luap99/strict-rpf
fix port forward with strict RPF and multi networks
2 parents 6f09b02 + 9a73a52 commit 44e25b1

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

src/network/bridge.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,17 @@ fn create_interfaces(
570570
CoreUtils::apply_sysctl_value(br_accept_ra, "0")?;
571571
}
572572

573+
// Disable strict reverse path search validation. On RHEL it is set to strict mode
574+
// which breaks port forwarding when multiple networks are attached as the package
575+
// may be routed over a different interface on the reverse path.
576+
// As documented for the sysctl for complicated or asymmetric routing loose mode (2)
577+
// is recommended.
578+
let br_rp_filter = format!(
579+
"/proc/sys/net/ipv4/conf/{}/rp_filter",
580+
&data.bridge_interface_name
581+
);
582+
CoreUtils::apply_sysctl_value(br_rp_filter, "2")?;
583+
573584
let link = host
574585
.get_link(netlink::LinkID::Name(
575586
data.bridge_interface_name.to_string(),
@@ -690,6 +701,13 @@ fn create_veth_pair<'fd>(
690701
&data.container_interface_name
691702
);
692703
core_utils::CoreUtils::apply_sysctl_value(enable_arp_notify, "1")?;
704+
705+
// disable strict reverse path search validation
706+
let rp_filter = format!(
707+
"/proc/sys/net/ipv4/conf/{}/rp_filter",
708+
&data.container_interface_name
709+
);
710+
CoreUtils::apply_sysctl_value(rp_filter, "2")?;
693711
Ok::<(), NetavarkError>(())
694712
});
695713
// check the result and return error

test/100-bridge-iptables.bats

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,35 @@ fw_driver=iptables
554554
test_port_fw ip=6 proto=udp hostip="fd65:8371:648b:0c06::1"
555555
}
556556

557+
# Test that port forwarding works with strict Reverse Path Forwarding enabled on the host
558+
@test "$fw_driver - port forwarding with two networks and RPF - tcp" {
559+
# First, enable strict RPF on host/container ns.
560+
run_in_host_netns sysctl -w net.ipv4.conf.all.rp_filter=1
561+
run_in_host_netns sysctl -w net.ipv4.conf.default.rp_filter=1
562+
run_in_container_netns sysctl -w net.ipv4.conf.all.rp_filter=1
563+
run_in_container_netns sysctl -w net.ipv4.conf.default.rp_filter=1
564+
565+
# We need a dummy interface with a host ip,
566+
# if we connect directly to the bridge ip it doesn't reproduce.
567+
add_dummy_interface_on_host dummy0 "10.0.0.1/24"
568+
569+
run_netavark --file ${TESTSDIR}/testfiles/two-networks.json setup $(get_container_netns_path)
570+
result="$output"
571+
572+
run_in_host_netns cat /proc/sys/net/ipv4/conf/podman2/rp_filter
573+
assert "2" "rp_filter podman2 bridge"
574+
run_in_host_netns cat /proc/sys/net/ipv4/conf/podman3/rp_filter
575+
assert "2" "rp_filter podman3 bridge"
576+
577+
run_in_container_netns cat /proc/sys/net/ipv4/conf/eth0/rp_filter
578+
assert "2" "rp_filter eth0 interface"
579+
run_in_container_netns cat /proc/sys/net/ipv4/conf/eth1/rp_filter
580+
assert "2" "rp_filter eth1 interface"
581+
582+
# Important: Use the "host" ip here and not localhost or bridge ip.
583+
run_nc_test "0" "tcp" 8080 "10.0.0.1" 8080
584+
}
585+
557586
@test "bridge ipam none" {
558587
read -r -d '\0' config <<EOF
559588
{
@@ -789,6 +818,8 @@ EOF
789818
# when the sysctl value is already set correctly we should not error
790819
run_in_host_netns sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
791820
run_in_container_netns sh -c "echo 1 > /proc/sys/net/ipv4/conf/default/arp_notify"
821+
run_in_host_netns sh -c "echo 2 > /proc/sys/net/ipv4/conf/default/rp_filter"
822+
run_in_container_netns sh -c "echo 2 > /proc/sys/net/ipv4/conf/default/rp_filter"
792823
run_in_host_netns mount -t proc -o ro,nosuid,nodev,noexec proc /proc
793824

794825
run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json setup $(get_container_netns_path)

test/250-bridge-nftables.bats

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,8 @@ EOF
696696
# when the sysctl value is already set correctly we should not error
697697
run_in_host_netns sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
698698
run_in_container_netns sh -c "echo 1 > /proc/sys/net/ipv4/conf/default/arp_notify"
699+
run_in_host_netns sh -c "echo 2 > /proc/sys/net/ipv4/conf/default/rp_filter"
700+
run_in_container_netns sh -c "echo 2 > /proc/sys/net/ipv4/conf/default/rp_filter"
699701
run_in_host_netns mount -t proc -o ro,nosuid,nodev,noexec proc /proc
700702

701703
run_netavark --file ${TESTSDIR}/testfiles/simplebridge.json setup $(get_container_netns_path)

test/testfiles/two-networks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"container_name": "heuristic_archimedes",
44
"port_mappings": [
55
{
6-
"host_ip": "127.0.0.1",
6+
"host_ip": "",
77
"container_port": 8080,
88
"host_port": 8080,
99
"range": 1,

0 commit comments

Comments
 (0)