diff options
author | Phil Sutter <phil@nwl.cc> | 2018-08-20 15:30:03 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2018-08-21 17:57:16 +0200 |
commit | 5ee03e6df41727652e0dc6ffaef8411b8840d812 (patch) | |
tree | e459442cfb4035a6bba51db4bd7c49ea344cb14f | |
parent | 37b68b2bc903112a74545c7f4a49c89e889582a9 (diff) |
xtables: Use meta l4proto for -p match
Use of payload expression to match against IPv6 nexthdr field does not
work if extension headers are present. A simple example for that is
matching for fragmented icmpv6 traffic. Instead, generate a 'meta
l4proto' expression which works even if extension headers are present.
For consistency, apply the same change to iptables-nft as well.
No adjustment to reverse path required as the needed bits were added by
commit 6ea7579e6fe24 ("nft: decode meta l4proto") already.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r-- | iptables/nft-ipv4.c | 3 | ||||
-rw-r--r-- | iptables/nft-ipv6.c | 3 | ||||
-rw-r--r-- | iptables/nft-shared.c | 6 | ||||
-rw-r--r-- | iptables/nft-shared.h | 1 |
4 files changed, 9 insertions, 4 deletions
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c index 105b1341..2d1bd10e 100644 --- a/iptables/nft-ipv4.c +++ b/iptables/nft-ipv4.c @@ -45,8 +45,7 @@ static int nft_ipv4_add(struct nftnl_rule *r, void *data) if (cs->fw.ip.proto != 0) { op = nft_invflags2cmp(cs->fw.ip.invflags, XT_INV_PROTO); - add_proto(r, offsetof(struct iphdr, protocol), 1, - cs->fw.ip.proto, op); + add_l4proto(r, cs->fw.ip.proto, op); } if (cs->fw.ip.src.s_addr != 0) { diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c index dd23557c..48a7cefe 100644 --- a/iptables/nft-ipv6.c +++ b/iptables/nft-ipv6.c @@ -44,8 +44,7 @@ static int nft_ipv6_add(struct nftnl_rule *r, void *data) if (cs->fw6.ipv6.proto != 0) { op = nft_invflags2cmp(cs->fw6.ipv6.invflags, XT_INV_PROTO); - add_proto(r, offsetof(struct ip6_hdr, ip6_nxt), 1, - cs->fw6.ipv6.proto, op); + add_l4proto(r, cs->fw6.ipv6.proto, op); } if (!IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.src)) { diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index b31234ee..62a57dd5 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -188,6 +188,12 @@ void add_proto(struct nftnl_rule *r, int offset, size_t len, add_cmp_u8(r, proto, op); } +void add_l4proto(struct nftnl_rule *r, uint8_t proto, uint32_t op) +{ + add_meta(r, NFT_META_L4PROTO); + add_cmp_u8(r, proto, op); +} + bool is_same_interfaces(const char *a_iniface, const char *a_outiface, unsigned const char *a_iniface_mask, unsigned const char *a_outiface_mask, diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index 80750784..59e1062a 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -122,6 +122,7 @@ void add_addr(struct nftnl_rule *r, int offset, void *data, void *mask, size_t len, uint32_t op); void add_proto(struct nftnl_rule *r, int offset, size_t len, uint8_t proto, uint32_t op); +void add_l4proto(struct nftnl_rule *r, uint8_t proto, uint32_t op); void add_compat(struct nftnl_rule *r, uint32_t proto, bool inv); bool is_same_interfaces(const char *a_iniface, const char *a_outiface, |