It seems linux already has a module for nftables nf_xfrm, which contains some code about reqid, however there is no description about it in man page.

So, how to translate the following command to nftables?

iptables -D FORWARD -s -i eth0 -m policy --dir in --pol ipsec --reqid 1 --proto esp -j ACCEPT

nftables version, 0.9.0, was released on 2018-06-08, more than a year ago, and this feature is not available in this version. Only testing having been decapsulated is available.

UPDATE: nftables 0.9.1 has been released on 2019-06-24, so one can hope it will be packaged in one's favorite distribution soon.

Kernel support for additional handling of ipsec in nftables was added in version 4.201. On userland side, corresponding support for additional ipsec features was added in git master branches around 2018-09-21 for libnftnl 2,3 and nftables 4,5,6.

The last patch is what provides reqid:

src: add ipsec (xfrm) expression This allows matching on ipsec tunnel/beet addresses in xfrm state associated with a packet, ipsec request id and the SPI.


ipsec in ip saddr
ipsec out ip6 daddr @endpoints
ipsec in spi 1-65536

(Well there isn't an example for a request id, nor matching the underlying protocol which might not be implemented, see later)

So to be able to use this feature, currently at least this is needed:

If OP's iptables rule was an append rather than a delete (which currently can only be done in nftables by using the handle keyword) it should translate into this (including boilerplate):

nft add table ip filter
nft add 'chain ip filter forward { type filter hook forward priority filter; policy accept; }'
nft add rule ip filter forward ip saddr iifname "eth0" ipsec in reqid 1 accept

I didn't add meta ipsec exists before ipsec in reqid 1: testing the reqid should require and thus test having already been subject to ipsec decapsulation.

What doesn't appear to be made available and not mentioned in the documentation is the equivalent of --proto esp, so I couldn't put it.

If matching the esp protocol is really needed, one can imagine that using a mark on the outer envelope packet should do it, knowing that the mark is preserved after decapsulation:

nft add table ip filter
nft add 'chain ip filter input { type filter hook input priority filter; policy accept; }'
nft add 'chain ip filter forward { type filter hook forward priority filter; policy accept; }'
nft add rule ip filter input ip protocol esp meta mark set 1
nft add rule ip filter forward meta mark 1 ip saddr iifname "eth0" ipsec in reqid 1 accept

Disclaimer: take with a grain of salt, only the syntax was tested (using nftables from git commit 01e5c6f0ed0315046537612f5a80e506d37a7f8e). This wasn't actually verified on IPSec. There's probably also a rule to add for 4500/UDP for UDP encapsulated ESP.

1 netfilter: nf_tables: add xfrm expression
2 expr: rt: ipsec match support
3 expr: add xfrm support
4 src: rt: add support to check if route will perform ipsec transformation
5 src: rename meta secpath to meta ipsec
6 src: add ipsec (xfrm) expression

  • Just curious, why don’t they release a new version after such long time? – user762750 Jun 18 '19 at 1:55
  • The mail I link about tells: "There are a few bugs that are sorted out right now, a new release should happen soon once that is resolved." – A.B Jun 18 '19 at 1:56
  • 0.9.1 has been released on 2019-06-24 – A.B Jun 27 '19 at 10:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.