MARK associates "marks" with packets. CONNMARK associates "marks" with connections. The second one is useful because you can mark all the packets of a connection or related to a connection with the same mark (for example, FTP). Another usefull use of CONNMARK is that you can mark packets using the criteria that only matches with the first packet.
For all chains you can -F :
+---------------+ +---------------+
| | | |
| Chain MyChain | | Chain MyChain |
| Rule 1 | -F | is |
| Rule 2 | | empty |
| Rule 3 | ==> | |
| | | |
+---------------+ +---------------+
For user defined chains only (chain created with iptables -N MyChain) you can -X if it is empty :
+---------------+
| |
| Chain MyChain | Chain MyChain
| is | -X does not exist
| empty |
| | ==>
| |
+---------------+
Both
iptables -F
iptables -X
are used because one can delete a user defined chain only when it is empty. Built-in chains cannot be deleted, but can be flushed.
Best Answer
iif
looks up and compares the interface index of the received packet, whileiifname
does string comparison with the interface name. Both have advantages and drawbacks.So
iif
is using less ressources, because the interface index is a simple number already stored in the packet traversing the network stack and nftables and thus immediately available for comparison. But its drawback is that if the interface is deleted (and most probably recreated, but with a newer index value), then the corresponding rule in nftables won't match anymore. The only garanteed interface index at all times is the loopback interface (namedlo
by default): it's always the first created in the namespace and can't be deleted (nor added a second time), so its index value is always1
.iifname
on the other hand, just like iptables'--in-interface
does a string comparison with the current interface's name. This uses more ressources, but allows to create a rule for a non-existing interface, in advance, with a deterministic name, whichiif
won't do easily.iifname
can also do wildcard match, like iniifname "ppp*"
, whichiif
can't do and can be handy when interfaces get created and deleted often, but keeping a naming convention (like starting withppp
for PPP links).Example (using nftables 0.9.2):
The interface being gone, its index value is displayed instead. Likewise, an index value can be used, even in advance, when adding a rule:
Because interface index values are not recycled within the namespace but only increasing, the rule about index 2 is "lost" (it will never have a chance to match anymore). The next created interface, dummy4 got assigned index 3, which now resolves into
dummy4
in the ruleset. dummy0 received index value 4, which is not referenced in anyiif
rule but will still match with theiifname
rule.What is recommended?
My advice:
You should use
iif
for "stable" interfaces that won't change once created, like physical ethernet interfaces available at boot, before the rule is applied (if using the newer physical interface stable naming convention, that won't change if enumeration order changes), and of course the lo interface. It wasn't shown in the example, but you can still match a list of interfaces withiif
too, likeiif { lo, dummy4 }
. So you still can have a singleiif
statement matching multiple interfaces.You should use
iifname
for dynamic interfaces not known at boot (and at rules creation) but expected to appear later, or to match a group of interfaces with a naming convention when using a wildcard match.Not very known, to optimize, instead of using wildcards, you could assign a group to each newly created interface, (eg using
ip link set dev interface group 99
) and then match the interface group withiifgroup
rather thaniifname
+ wildcard. But this requires some extra mechanism to group tag newly created interfaces.You can also use interface named sets, thus keeping generic rules using
iif
andiifname
and changing the contents of the named sets, rather than the rules themselves. Note that the previous wiki link doesn't tell about using interfaces in sets, but it's simply not up to date. More informations about this in my UL SE answer to this question: How do I create a named set of strings in nftables (for interface names)?.