If layer 4 protocol has no ports, then return false. Otherwise, users like the conntrack utility filtering does not properly work with layer 4 protocol such as ICMP and ICMPv6. Fixes: 93c459d603cc ("objopt: use indirect calls instead of switch") Reported-by: Jan Kasprzak Signed-off-by: Pablo Neira Ayuso --- src/conntrack/objopt.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/conntrack/objopt.c b/src/conntrack/objopt.c index 1581480667e5..6024d15e2602 100644 --- a/src/conntrack/objopt.c +++ b/src/conntrack/objopt.c @@ -182,8 +182,27 @@ static int getobjopt_is_dnat(const struct nf_conntrack *ct) } } +static bool l4proto_has_ports(const struct nf_conntrack *ct) +{ + switch (ct->head.orig.l3protonum) { + case IPPROTO_UDP: + case IPPROTO_UDPLITE: + case IPPROTO_SCTP: + case IPPROTO_TCP: + case IPPROTO_DCCP: + break; + default: + return false; + } + + return true; +} + static int getobjopt_is_spat(const struct nf_conntrack *ct) { + if (!l4proto_has_ports(ct)) + return 0; + return ((test_bit(ATTR_STATUS, ct->head.set) ? ct->status & IPS_SRC_NAT_DONE : 1) && ct->repl.l4dst.tcp.port != @@ -192,6 +211,9 @@ static int getobjopt_is_spat(const struct nf_conntrack *ct) static int getobjopt_is_dpat(const struct nf_conntrack *ct) { + if (!l4proto_has_ports(ct)) + return 0; + return ((test_bit(ATTR_STATUS, ct->head.set) ? ct->status & IPS_DST_NAT_DONE : 1) && ct->repl.l4src.tcp.port != -- 2.47.3