Rules in firewall.user not applied at reboot

I'm new to OpenWRT. I want to add a firewall rule that allows UDP traffic from the WAN gateway to the OpenWRT router. Seems like a simple matter of a few lines in /etc/firewall.user. Thus, the contents of my firewall.user are as follows:

. /lib/functions/network.sh
network_get_gateway wan_gateway wan

iptables -I input_wan_rule -p udp -s $wan_gateway -m comment --comment "Allow-SSDP" -j ACCEPT;

When I test by restarting the firewall, it works:

root@OpenWrt:~# iptables -L input_wan_rule
Chain input_wan_rule (1 references)
target     prot opt source               destination
$ /etc/init.d/firewall restart
<firewall_script_output>
root@OpenWrt:~# iptables -L input_wan_rule
Chain input_wan_rule (1 references)
target     prot opt source               destination
ACCEPT     udp  --  10.0.0.1             anywhere             /* Allow-SSDP */

So that works, but when I do a simple reboot, I do NOT see the rule being applied.

root@OpenWrt:~# reboot
<wait_for_reboot>
root@OpenWrt:~# iptables -L input_wan_rule
Chain input_wan_rule (1 references)
target     prot opt source               destination

What dumb thing am I doing wrong? Is there something in my firewall.user that doesn't work in the boot context? If there are errors encountered in firewall.user during boot, in which log would I find that information? I'm not seeing anything in syslog.

Possibly a race condition where network_get_gateway wan_gateway wan doesn't evaluate until the interface is stable?

It might work if you put in a hotplug.d script that is tickled when the interface comes up.

2 Likes

ifstate triggers user reload if reload = 1

config include
	option path '/etc/firewall.user'
	option reload '1'
4 Likes

Yes, that does appear to be the culprit. If I remove the call to network_get_gateway and provided a hard coded IP, I see the rule applied out of reset.

I'll reevaluate if I really need the -s $wan_gateway constraint.

I thought about that, but I then the rule would be repeatedly added on every reload, right? I mean, does a reload clear out the input_wan_rule table of any existing rules before executing firewall.user? Would I need to deal with that in my firewall.user?

I went ahead and tried setting option reload '1' on firewall.user. It does result in duplicate rules, but simply flushing input_wan_rule seems innocuous enough to me for my situation:

. /lib/functions/network.sh
network_get_gateway wan_gateway wan

iptables -F input_wan_rule
iptables -I input_wan_rule -p udp -s $wan_gateway -m comment --comment "Allow-SSDP" -j ACCEPT;

Thanks to both @IanC and @anon50098793 for your help.

Or you can add a 30 secs wait until the interface comes up
ubus -t 30 wait_for network.interface.wan

Thanks for that idea, but it did not appear to work for me. The 30s timeout must have elapsed before the interface came up. I'm guessing the interface gets brought up by a separate thread during boot? Perhaps a longer timeout would do the trick, but I think in a case where the WAN interface is brought up/down after boot this approach would not always yield the desired outcome.

If I'm interpreting @anon50098793 correctly, the firewall is reloaded whenever an interface is brought up, so I think option reload '1' and the table flush may be the most robust solution for my specific case.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.