summaryrefslogtreecommitdiff
path: root/net/ipv6
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@nvidia.com>2021-04-14 11:20:32 +0300
committerPablo Neira Ayuso <pablo@netfilter.org>2021-04-18 22:04:16 +0200
commit812fa71f0d967dea7616810f27e98135d410b27e (patch)
tree5c7385ce12cf10921f289c7e65ca809904208f99 /net/ipv6
parent783003f3bb8a565326e89d18bbd948ad8ffc816a (diff)
netfilter: Dissect flow after packet mangling
Netfilter tries to reroute mangled packets as a different route might need to be used following the mangling. When this happens, netfilter does not populate the IP protocol, the source port and the destination port in the flow key. Therefore, FIB rules that match on these fields are ignored and packets can be misrouted. Solve this by dissecting the outer flow and populating the flow key before rerouting the packet. Note that flow dissection only happens when FIB rules that match on these fields are installed, so in the common case there should not be a penalty. Reported-by: Michal Soltys <msoltyspl@yandex.pl> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/netfilter.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index ab9a279dd6d4..6ab710b5a1a8 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -24,6 +24,7 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
{
const struct ipv6hdr *iph = ipv6_hdr(skb);
struct sock *sk = sk_to_full_sk(sk_partial);
+ struct flow_keys flkeys;
unsigned int hh_len;
struct dst_entry *dst;
int strict = (ipv6_addr_type(&iph->daddr) &
@@ -38,6 +39,7 @@ int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff
};
int err;
+ fib6_rules_early_flow_dissect(net, skb, &fl6, &flkeys);
dst = ip6_route_output(net, sk, &fl6);
err = dst->error;
if (err) {