2

I am trying to use iptables to packet mark packets of a certain source/destination IP in the mangle table on a given host. The packets are later forwarded to a particular network namespace on the same host, yet the iptables rules that I've installed in that network namespace do not pick up on the mark. I am thus wondering: is packet marking only local to the network namespace the mark is being placed in? I was under the impression that since the mark is an "attribute" associated with the skb, that the kernel would keep track of the mark anywhere it's routed on the host, irrespective of the namespace.

Alternatively does anyone have any ideas of how to debug this? I installed a TRACE rule inside the network namespace I am targeting, but I am under the impression that I need to run dmesg to view the output and that doesn't make a lot of sense for a network namespace.

1 Answer 1

2

is packet marking only local to the network namespace the mark is being placed in?

Yes. the mark is local to the network namespace. Each namespace has an independent network stack, so when a packet transits from one namespace to an other it's like transiting over the wire: no mark remains.

I installed a TRACE rule inside the network namespace

It depends...

If using iptables-legacy's TRACE target the choices are limited:

  • by default only the initial network namespace can log netfilter events to dmesg
  • or with sysctl -w net.netfilter.nf_log_all_netns=1 then all network namespaces will log to dmesg which can be a problem when a lot of logs are generated by a lot of network namespaces

That's because dmesg is not per-namespace but global and sending logs to dmesg was initially the only available method for TRACE.

Now, if using nftables' nftrace statement or using iptables-nft, the previous method to send messages with the TRACE target is replaced by using the (netfilter) netlink socket API which is namespace-aware and is sent only to listeners (ie: multicasting).

That means that when the nft variant like below:

# iptables-nft -V
iptables v1.8.7 (nf_tables)

but not the legacy variant like below:

# iptables-legacy -V
iptables v1.8.7 (legacy)

is used, then traces aren't sent to dmesg anymore but can be captured with xtables-monitor --trace instead. Again: xtables-monitor is intended only for the iptables-nft variant of iptables.

In this case one way to debug in parallel multiple network namespaces created by ip netns add ..., is to run multiple times in parallel xtables-monitor, once per network namespace, and write in separate logs or for example use ts to tag every line of the output to have a timestamp and identify each namespace, making it easy to split the result later if needed.

Something like this for netns foo bar and baz:

for ns in foo bar baz; do
    ip netns exec "$ns" xtables-monitor --trace | ts -s "%.s $ns" &
done

( pkill xtables-monitor might be required later.)

With network namespaces not created through ip netns add one can replace ip netns exec with nsenter and more elbow grease usually involving information from the application that created them (docker inspect, lxc-info ...)

The command when using nftables is instead nft monitor trace and behaves the same with regard to network namespaces. Actually nft monitor trace will also display traces created by iptables-nft's TRACE target since it's the same API.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .