This is a note to let you know that I've just added the patch titled xfrm: respect ip protocols rules criteria when performing dst lookups to the 5.10-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: xfrm-respect-ip-protocols-rules-criteria-when-perfor.patch and it can be found in the queue-5.10 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 5faadc7886a4de0de7f8fe278160d9f4c83cd8a9 Author: Eyal Birger <eyal.birger@xxxxxxxxx> Date: Mon Sep 2 17:07:10 2024 -0700 xfrm: respect ip protocols rules criteria when performing dst lookups [ 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@xxxxxxxxx> Tested-by: Antony Antony <antony.antony@xxxxxxxxxxx> Signed-off-by: Steffen Klassert <steffen.klassert@xxxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 142967e456b18..798df30c2d253 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -328,6 +328,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; diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index d1c2619e03740..5d8e38f4ecc07 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -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)) diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 40183fdf7da0e..f5ef5e4c88df1 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -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; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index a7f8da5241ae5..a1a662a55c2ae 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -296,6 +296,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, ¶ms);