@@ -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;
@@ -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))
@@ -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;
@@ -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, ¶ms);