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@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>
This commit is contained in:
Eyal Birger 2024-09-02 17:07:10 -07:00 committed by Ksawlii
parent 981c319d7f
commit face97635f
4 changed files with 22 additions and 0 deletions

View file

@ -323,6 +323,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;

View 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))

View 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;

View file

@ -301,6 +301,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);