iptables nat table missing for tx1 on Jetpack 3.1

Hi everyone,
So I recently updated my tx1 to jetpack 3.1n and now it seems that I cannot use the nat table of iptables anymore:

sudo /sbin/iptables -t nat -A POSTROUTING -j MASQUERADE

returns:

iptables v1.6.0: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

I am running on:

Linux tegra-ubuntu 4.4.38-tegra #1 SMP PREEMPT Thu Jul 20 00:41:06 PDT 2017 aarch64 aarch64 aarch64 GNU/Linux

I have flashed my system using the Jetpack GUI.

Comparing the /lib architecture with the same jetpack release for tx2, it seems that the tx1 version is missing some kernel modules:
On tx1, in kernel/net/, I only have a bluetooth and bridge folder
On tx2, in kernel/net/, I have bluetooth, bridge,can, ipv4, iv6 and netfilter

Why are these modules missing from the tx1 rootfs?

Thank you for your help!

Not all features use modules, so module format is optional in most cases. Looking at your “/proc/config.gz” will tell you what features are enabled (along with whether it is integrated or module format), so to determine what your kernel is configured for:

gunzip < /proc/config.gz | less

I see a couple of useful URLs on iptables kernel config options here (important: I don’t know if all of what is listed here applies to the 4.x kernels, or if perhaps it was written for 3.x kernels or even older):
https://www.frozentux.net/iptables-tutorial/chunkyhtml/x662.html
http://www.linuxtopia.org/Linux_Firewall_iptables/x651.html

I see the following are already present/enabled:

  • CONFIG_IP_NF_IPTABLES=y

I see the following are missing:

  • # CONFIG_IP_NF_NAT is not set
  • CONFIG_IP_NF_CONNTRACK is not found at all...maybe not applicable
  • # CONFIG_NF_NAT_MASQUERADE_IPV4 is not set...not actually required for nat

The following command will summarize this for your kernel:

gunzip < config.gz | egrep '(CONFIG_IP_NF_IPTABLES|CONFIG_IP_NF_IPTABLES|CONFIG_IP_NF_NAT|CONFIG_IP_NF_CONNTRACK|CONFIG_NF_NAT_MASQUERADE)'

I would suggest starting with “/proc/config.gz” for configuration, add CONFIG_IP_NF_NAT as a module, and set CONFIG_LOCALVERSION to “-tegra” (or whatever the suffix is for your “uname -r”). Then you just add the module and “sudo depmod -a”.

Note that if you enable something for iptables which is not needed you will increase kernel size, possibly slow down firewall packet filtering, or add security problems. If you add something as a non-module you may wish to change CONFIG_LOCALVERSION, but if you stick to building as a module you can keep the “-tegra” CONFIG_LOCALVERSION.

I believe you will find only desktop distributions provide modules not needed for the base install. This is not something specific to Jetsons, nor was it left out by accident, it is the intentional approach to minimize excess for all embedded systems. When I look at what is in one Fedora desktop PC’s module directory I see 110MB of modules, but perhaps only 20% of it is used despite my using a lot of features my Jetson never touches.

One of the properties of loading a module is that it becomes part of the kernel and needs a physical address, not just a virtual address…it can’t be swapped out. Enabling features not needed essentially removes physical RAM memory the kernel might need for other purposes. ARMv8 (arm64) is much better than ARMv7 (arm32), but in particular modules have an additional requirement: They must be loaded in kernel address physical memory such that a direct branch instruction does not exceed its maximum branch offset (jumping from one memory location to another implies an address offset magnitude). On arm64 I think it is 128M (128Mbyte offset span), and on arm32 it is 32M…this is also shared with initrd (and thus starting with initrd compounds the issue). If the sum total of initrd and modules exceed this your kernel will mysteriously crash and burn when it runs the kernel code and tries to do a direct branch to an address it can’t reach. I don’t know what the x86_64 direct branch limit is, but it is extremely large in comparison to any ARM architecture…desktops are more or less free to build and install as many modules as desired.

Please try to add this to tegra21_defconfig as first step. It should enable the NAT table and masquerade.

CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_TARGET_MASQUERADE=y

Thank you for the thorough explanation, I know understand more about modules!
It was as you both said, I had to recompile the kernel with these flags to make nat and masquerade work again, thank you very much!