]> git.hungrycats.org Git - linux/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, 8 Nov 2024 15:21:59 +0000 (16:21 +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 142967e456b18e333b95484be5d94526beed4571..798df30c2d253e2b9fdbce2d47d26bf8eb648cd9 100644 (file)
@@ -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;
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 a7f8da5241ae5f6eb13b3451d35fe19dd75d843b..a1a662a55c2ae4a3b0e9834448c223f53337011b 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);