Disable conntrack on TL-WR1043ND-v1 to save memory

I have a TL-WR1043ND-v1 (8/32MB) on v22.03.3 as eth/wifi bridge (wan interface/masq disabled). It works properly most of the time but on high connection count the network sometimes dies (zero traffic) until i reconnect the wifi connection (doesn't need a reboot). Maybe the conntrack table is too large. Unless i'm wrong i think i don't need it for a simple wifi bridge. The conntrack module is loaded but can't be unloaded easily:

Any idea how to remove/unload the conntrack module?

# lsmod |grep conntrack
nf_conntrack           69104  7 nft_redir,nft_nat,nft_masq,nft_flow_offload,nft_ct,nf_nat,nf_flow_table
nf_defrag_ipv4          1216  1 nf_conntrack
nf_defrag_ipv6          5584  1 nf_conntrack
# rmmod nf_conntrack
unloading the module failed

The two defrag modules look like they use it.

1 Like

Yes, but they can't be removed either. I also removed /etc/modules.d/nf-conntrack that holds all three modules indeed but they get loaded anyway. Regarding this post this shouldn't happen (as there is no 'blacklist' option).

If it is operating as a simple bridge then you don't need any firewalling.

What does the following show?
nft list ruleset

You should try:

service firewall stop
service firewall disable

This should stop the contrack module doing anything at all.
But maybe you are just fighting lack of ram regardless. An 8/32 device really is at end of life.....

1 Like

There is /rom/etc/modules.d/nf_conntrack as well laying in squashfs. Not sure how to handle this without manually compiling the image.
rmmod might not be allowed by kconfig (haven't checked though). I think it might make sense to have the module loaded on-demand only on lowmem devices on upstream in the first place.

you can use the online image builder to remove the packages you know you don't need, it'll save space, but also stop unwanted daemons from starting

I will disable the firewall completely to see if it has any impact.

table inet fw4 {
	chain input {
		type filter hook input priority filter; policy accept;
		iifname "lo" accept comment "!fw4: Accept traffic from loopback"
		ct state established,related accept comment "!fw4: Allow inbound established and related flows"
		tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
		iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
		iifname "eth0.2" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
	}

	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "eth0.2" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		jump handle_reject
	}

	chain output {
		type filter hook output priority filter; policy accept;
		oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
		ct state established,related accept comment "!fw4: Allow outbound established and related flows"
		oifname "br-lan" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
		oifname "eth0.2" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
	}

	chain prerouting {
		type filter hook prerouting priority filter; policy accept;
		iifname "br-lan" jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
		iifname "eth0.2" jump helper_wan comment "!fw4: Handle wan IPv4/IPv6 helper assignment"
	}

	chain handle_reject {
		meta l4proto tcp reject with tcp reset comment "!fw4: Reject TCP traffic"
		reject comment "!fw4: Reject any other traffic"
	}

	chain syn_flood {
		limit rate 25/second burst 50 packets return comment "!fw4: Accept SYN packets below rate-limit"
		drop comment "!fw4: Drop excess packets"
	}

	chain input_lan {
		jump accept_from_lan
	}

	chain output_lan {
		jump accept_to_lan
	}

	chain forward_lan {
		jump accept_to_wan comment "!fw4: Accept lan to wan forwarding"
		jump accept_to_lan
	}

	chain helper_lan {
	}

	chain accept_from_lan {
		iifname "br-lan" counter packets 3 bytes 180 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain accept_to_lan {
		oifname "br-lan" counter packets 38 bytes 2888 accept comment "!fw4: accept lan IPv4/IPv6 traffic"
	}

	chain input_wan {
		meta nfproto ipv4 udp dport 68 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCP-Renew"
		icmp type echo-request counter packets 0 bytes 0 accept comment "!fw4: Allow-Ping"
		meta nfproto ipv4 meta l4proto igmp counter packets 0 bytes 0 accept comment "!fw4: Allow-IGMP"
		ip6 saddr fc00::/6 ip6 daddr fc00::/6 udp dport 546 counter packets 0 bytes 0 accept comment "!fw4: Allow-DHCPv6"
		ip6 saddr fe80::/10 icmpv6 type . icmpv6 code { mld-listener-query . no-route, mld-listener-report . no-route, mld-listener-done . no-route, mld2-listener-report . no-route } counter packets 0 bytes 0 accept comment "!fw4: Allow-MLD"
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply, nd-router-solicit, nd-router-advert } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited, nd-neighbor-solicit . no-route, nd-neighbor-advert . no-route } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Input"
		jump reject_from_wan
	}

	chain output_wan {
		jump accept_to_wan
	}

	chain forward_wan {
		icmpv6 type { destination-unreachable, time-exceeded, echo-request, echo-reply } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		icmpv6 type . icmpv6 code { packet-too-big . no-route, parameter-problem . no-route, parameter-problem . admin-prohibited } limit rate 1000/second counter packets 0 bytes 0 accept comment "!fw4: Allow-ICMPv6-Forward"
		meta l4proto esp counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-IPSec-ESP"
		udp dport 500 counter packets 0 bytes 0 jump accept_to_lan comment "!fw4: Allow-ISAKMP"
		jump reject_to_wan
	}

	chain helper_wan {
	}

	chain accept_to_wan {
		oifname "eth0.2" counter packets 0 bytes 0 accept comment "!fw4: accept wan IPv4/IPv6 traffic"
	}

	chain reject_from_wan {
		iifname "eth0.2" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain reject_to_wan {
		oifname "eth0.2" counter packets 0 bytes 0 jump handle_reject comment "!fw4: reject wan IPv4/IPv6 traffic"
	}

	chain dstnat {
		type nat hook prerouting priority dstnat; policy accept;
	}

	chain srcnat {
		type nat hook postrouting priority srcnat; policy accept;
	}

	chain raw_prerouting {
		type filter hook prerouting priority raw; policy accept;
	}

	chain raw_output {
		type filter hook output priority raw; policy accept;
	}

	chain mangle_prerouting {
		type filter hook prerouting priority mangle; policy accept;
	}

	chain mangle_postrouting {
		type filter hook postrouting priority mangle; policy accept;
	}

	chain mangle_input {
		type filter hook input priority mangle; policy accept;
	}

	chain mangle_output {
		type route hook output priority mangle; policy accept;
	}

	chain mangle_forward {
		type filter hook forward priority mangle; policy accept;
		iifname "eth0.2" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 ingress MTU fixing"
		oifname "eth0.2" tcp flags syn tcp option maxseg size set rt mtu comment "!fw4: Zone wan IPv4/IPv6 egress MTU fixing"
	}
}

If there is no solution for stock images i will try that.

Edit:
First quick test shows that 'cat /proc/net/nf_conntrack' remains empty after disabling the firewall service. Will need to test that on high traffic.

If you use LuCI, keep in mind that the meta package luci will bring a lot of dependencies, including the firewall.

So you need to manually specify the individual LuCI packages you need, to avoid getting the firewall automatically installed.

I wish we had a luci-minimal package that would just install the basics.

1 Like

A hypothetical luci-minimal package might do away with https, PPPoE and maybe even opkg dependencies, but it would be very unlikely to drop firewall dependencies.

There are quite a lot of access point devices that are supported by OpenWRT. Having firewall by default on those devices doesn’t make too much sense.

I have an EAP615-Wall that I recently installed OpenWRT. My first task was to find a way to remove the firewall, dnsmasq, nftables and a few other redundant packages.

By default there isn’t even a WAN interface on that device default configuration. So the firewall seems even more pointless.

Fortunately we have the online image builder to help. Because if I had to clone the whole project and build the custom image locally I would have just kept using the original firmware.

And a couple days ago I discovered auc, which will make upgrading the system a bit more manageable.

This seems to be barking up the wrong tree. Does a layer 2 bridge even cause connection tracking?

firewall isn't even a service that is persistent in RAM. It loads rules into the kernel nftables then exits.

The services that do occupy RAM and could potentially be removed in a dumb AP include:

  • wpa_supplicant, and a ujail for wpa_supplicant. It is unnecessary when there are no STA wifi interfaces. hostapd and its ujail are also quite large, but obviously necessary.
  • dnsmasq and its ujail.
  • odhcpd (the IPv6 DHCP server)
  • uhttpd (serves LuCI-- use ssh instead)

In a default install, hostapd and wpa_supplicant are two instances of the same binary. To kill wpa_supplicant, remove the link that is /usr/sbin/wpa_supplicant. Or remove the wpad package and substitute a hostapd package.

1 Like

But wouldn't these rules consume memory over time (on high conntrack count)? I've seen entries in 'cat /proc/net/nf_conntrack' indeed. Now, with the rules flushed its empty so far.

Nice trick. :slight_smile:

RAM goes up/down between 8-10MB 'available' at the moment. First time i see 10MB though. On a fresh stock reboot its usually around 9.2MB and goes down to 7-8MB.

# free
              total        used        free      shared  buff/cache   available
Mem:          24948       11332        6280          60        7336       10272

I have to stresstest that in-depth. Tbh, i'm not sure if it's a memory problem at all. But it only happens on high-connection count (not high bandwidth) and the idea was that conntrack bloats so much it exceeds the ram.

wpa_supplicant was sitting there eating 3% of my AP's memory, nice easy save on some resources.

Added this to https://openwrt.org/docs/guide-user/network/wifi/dumbap . Thanks for the tip @mk24

It's really only necessary if you're trying to run a device with 32MB of RAM, which you should not be doing anyway.

Thanks for all the answers. Disabling the firewall rules seems to effectively disable conntrack usage that more or less answers the initial question.

Regarding my connection issues its probably not the router/openwrt at all but a dying STA WiFi Stick. TX-Power gets worse by the day. Error rates getting high. Traffic can be "heard" by high-pitch noise. I'll maybe try to resolder some components. Otherwise a new one will be needed.

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