Policy routing based on firewall marks blocked by reverse path filter

What's the recommended way to configure IP rules with mark in OpenWrt to avoid the reverse path filter (rpfilter) blocking traffic?

Often the rpfilter will block (response) traffic when you use IP rules with mark. That's because rpfilter won't respect the firewall mark unless enabled with net.ipv4.conf.<IFACE>.src_valid_mark=1. In this case you also need to save and restore the firewall mark, and make sure packets can be forwarded correctly in both directions with the mark set.

It's also possible to disable rpfilter globally in /etc/sysctl.d/,:

net.ipv4.conf.default.rp_filter=0          
net.ipv4.conf.all.rp_filter=0

But how can it be done on a single interface such as a GRE tunnel?

The current documentation doesn't seem to mention rp_filter and src_valid_mark.

Could you explain a bit the scenario you are trying to achieve here and what problems do you face?

I'm using ipset in dnsmasq to route some DNS domains via a GRE tunnel.

A rule in the prerouting chain of the mangle table marks the packets that matches the IP set. Then an IP rule looks up a table with a default route on the GRE tunnel.

The IPv4 traffic from the GRE tunnel is blocked unless I disable rpfilter or enable src_valid_mark. The latter also requires me to save and restore the mark. It also forced me to move the default route from the main to the default table, and to put the IP rule mentioned above between the main and default rules. Otherwise also the traffic from the GRE tunnel would match the IP rule.

32766:	from all lookup main 
32766:	from all fwmark 0x1 lookup 300 
32767:	from all lookup default

(A better solution might be to generate routes for the IP addresses instead of adding them to IP sets. The host routes would replace the default route to the GRE tunnel and avoid problems with rpfilter. But it would require extending dnsmasq or another DNS forwarder.)

I think it's probably easiest to just disable rpfilter and use firewall rules to set up all the filtering you need instead of relying on rpfilter.

1 Like