]> git.ipfire.org Git - thirdparty/kernel/linux.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)
committerSteffen Klassert <steffen.klassert@secunet.com>
Mon, 23 Sep 2024 05:02:07 +0000 (07:02 +0200)
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>
include/net/xfrm.h
net/ipv4/xfrm4_policy.c
net/ipv6/xfrm6_policy.c
net/xfrm/xfrm_policy.c

index f3ae5037270715fce33ea011ae2ca261c8fdfed2..a0bdd58f401c0f7ac15191e8c56878707cb98566 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 ec8f2fe13a515ec0b4a403cbd1a8a77ad1b2259b..55cc9f4cb42ba2a300bc2c2b8cf4a7c8644ba481 100644 (file)
@@ -315,6 +315,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);