]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfrm: respect ip protocols rules criteria when performing dst lookups
authorEyal Birger <eyal.birger@gmail.com>
Tue, 3 Sep 2024 00:07:10 +0000 (17:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Nov 2024 01:02:35 +0000 (02:02 +0100)
[ Upstream commit b8469721034300bbb6dec5b4bf32492c95e16a0c ]

The series in the "fixes" tag added the ability to consider L4 attributes
in routing rules.

The dst lookup on the outer packet of encapsulated traffic in the xfrm
code was not adapted to this change, thus routing behavior that relies
on L4 information is not respected.

Pass the ip protocol information when performing dst lookups.

Fixes: a25724b05af0 ("Merge branch 'fib_rules-support-sport-dport-and-proto-match'")
Signed-off-by: Eyal Birger <eyal.birger@gmail.com>
Tested-by: Antony Antony <antony.antony@secunet.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/net/xfrm.h
net/ipv4/xfrm4_policy.c
net/ipv6/xfrm6_policy.c
net/xfrm/xfrm_policy.c

index 0f49f70dfd141050627e00babdedcf04b11eed67..2a98d14b036fab15b9e68b33474f7755427867b7 100644 (file)
@@ -356,6 +356,8 @@ struct xfrm_dst_lookup_params {
        xfrm_address_t *saddr;
        xfrm_address_t *daddr;
        u32 mark;
+       __u8 ipproto;
+       union flowi_uli uli;
 };
 
 struct net_device;
index ac1a28ef0c56085674c3436e42862ccb96ff0695..7e1c2faed1ff9931b599107955fa24a7d284d734 100644 (file)
@@ -30,6 +30,8 @@ static struct dst_entry *__xfrm4_dst_lookup(struct flowi4 *fl4,
        fl4->flowi4_mark = params->mark;
        if (params->saddr)
                fl4->saddr = params->saddr->a4;
+       fl4->flowi4_proto = params->ipproto;
+       fl4->uli = params->uli;
 
        rt = __ip_route_output_key(params->net, fl4);
        if (!IS_ERR(rt))
index fc3f5eec6898576d546e01a336fce1ea414bdad9..1f19b6f14484c6fd74fccb67ecb8f18da038a55a 100644 (file)
@@ -37,6 +37,9 @@ static struct dst_entry *xfrm6_dst_lookup(const struct xfrm_dst_lookup_params *p
        if (params->saddr)
                memcpy(&fl6.saddr, params->saddr, sizeof(fl6.saddr));
 
+       fl6.flowi4_proto = params->ipproto;
+       fl6.uli = params->uli;
+
        dst = ip6_route_output(params->net, NULL, &fl6);
 
        err = dst->error;
index 1025b5b3a1dd631be17c82b45aa6620c96aca680..d30a22cd5c621dfd5a4c76106d8a3b38ceb50edd 100644 (file)
@@ -312,6 +312,21 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x,
        params.tos = tos;
        params.oif = oif;
        params.mark = mark;
+       params.ipproto = x->id.proto;
+       if (x->encap) {
+               switch (x->encap->encap_type) {
+               case UDP_ENCAP_ESPINUDP:
+                       params.ipproto = IPPROTO_UDP;
+                       params.uli.ports.sport = x->encap->encap_sport;
+                       params.uli.ports.dport = x->encap->encap_dport;
+                       break;
+               case TCP_ENCAP_ESPINTCP:
+                       params.ipproto = IPPROTO_TCP;
+                       params.uli.ports.sport = x->encap->encap_sport;
+                       params.uli.ports.dport = x->encap->encap_dport;
+                       break;
+               }
+       }
 
        dst = __xfrm_dst_lookup(family, &params);