]> 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 00:52:36 +0000 (01:52 +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 642e0b60130d844e589f040edf95e0b6a6363012..20ce2e1b3f61ec20b5eeabb7b167658bb0fc6aff 100644 (file)
@@ -322,6 +322,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 d1c2619e0374056df7af3de1a9ca9b4f8532d2f8..5d8e38f4ecc0706e92543b0f69a7b72377e40c6e 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 40183fdf7da0e1728d4ea85921cfd813f19921ae..f5ef5e4c88df1f2c31bb32e4178fca7e4e68453e 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 ab6f5955aa9cf06d8b1a6cb91a8844979f3d0392..55ef8e83292439b25e6a8406bff0ba705c743f23 100644 (file)
@@ -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, &params);