Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfrm: respect ip protocols rules criteria when performing dst lookups

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>

authored by

Eyal Birger and committed by
Steffen Klassert
b8469721 e509996b

+22
+2
include/net/xfrm.h
··· 356 356 xfrm_address_t *saddr; 357 357 xfrm_address_t *daddr; 358 358 u32 mark; 359 + __u8 ipproto; 360 + union flowi_uli uli; 359 361 }; 360 362 361 363 struct net_device;
+2
net/ipv4/xfrm4_policy.c
··· 30 30 fl4->flowi4_mark = params->mark; 31 31 if (params->saddr) 32 32 fl4->saddr = params->saddr->a4; 33 + fl4->flowi4_proto = params->ipproto; 34 + fl4->uli = params->uli; 33 35 34 36 rt = __ip_route_output_key(params->net, fl4); 35 37 if (!IS_ERR(rt))
+3
net/ipv6/xfrm6_policy.c
··· 37 37 if (params->saddr) 38 38 memcpy(&fl6.saddr, params->saddr, sizeof(fl6.saddr)); 39 39 40 + fl6.flowi4_proto = params->ipproto; 41 + fl6.uli = params->uli; 42 + 40 43 dst = ip6_route_output(params->net, NULL, &fl6); 41 44 42 45 err = dst->error;
+15
net/xfrm/xfrm_policy.c
··· 315 315 params.tos = tos; 316 316 params.oif = oif; 317 317 params.mark = mark; 318 + params.ipproto = x->id.proto; 319 + if (x->encap) { 320 + switch (x->encap->encap_type) { 321 + case UDP_ENCAP_ESPINUDP: 322 + params.ipproto = IPPROTO_UDP; 323 + params.uli.ports.sport = x->encap->encap_sport; 324 + params.uli.ports.dport = x->encap->encap_dport; 325 + break; 326 + case TCP_ENCAP_ESPINTCP: 327 + params.ipproto = IPPROTO_TCP; 328 + params.uli.ports.sport = x->encap->encap_sport; 329 + params.uli.ports.dport = x->encap->encap_dport; 330 + break; 331 + } 332 + } 318 333 319 334 dst = __xfrm_dst_lookup(family, &params); 320 335