diff options
| -rw-r--r-- | net/ipv4/xfrm4_policy.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 7ff973bd02dd..981e43eaf704 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -18,38 +18,46 @@ | |||
| 18 | 18 | ||
| 19 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo; | 19 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo; |
| 20 | 20 | ||
| 21 | static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, | 21 | static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, |
| 22 | const xfrm_address_t *saddr, | 22 | int tos, |
| 23 | const xfrm_address_t *daddr) | 23 | const xfrm_address_t *saddr, |
| 24 | const xfrm_address_t *daddr) | ||
| 24 | { | 25 | { |
| 25 | struct flowi4 fl4 = { | ||
| 26 | .daddr = daddr->a4, | ||
| 27 | .flowi4_tos = tos, | ||
| 28 | }; | ||
| 29 | struct rtable *rt; | 26 | struct rtable *rt; |
| 30 | 27 | ||
| 28 | memset(fl4, 0, sizeof(*fl4)); | ||
| 29 | fl4->daddr = daddr->a4; | ||
| 30 | fl4->flowi4_tos = tos; | ||
| 31 | if (saddr) | 31 | if (saddr) |
| 32 | fl4.saddr = saddr->a4; | 32 | fl4->saddr = saddr->a4; |
| 33 | 33 | ||
| 34 | rt = __ip_route_output_key(net, &fl4); | 34 | rt = __ip_route_output_key(net, fl4); |
| 35 | if (!IS_ERR(rt)) | 35 | if (!IS_ERR(rt)) |
| 36 | return &rt->dst; | 36 | return &rt->dst; |
| 37 | 37 | ||
| 38 | return ERR_CAST(rt); | 38 | return ERR_CAST(rt); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, | ||
| 42 | const xfrm_address_t *saddr, | ||
| 43 | const xfrm_address_t *daddr) | ||
| 44 | { | ||
| 45 | struct flowi4 fl4; | ||
| 46 | |||
| 47 | return __xfrm4_dst_lookup(net, &fl4, tos, saddr, daddr); | ||
| 48 | } | ||
| 49 | |||
| 41 | static int xfrm4_get_saddr(struct net *net, | 50 | static int xfrm4_get_saddr(struct net *net, |
| 42 | xfrm_address_t *saddr, xfrm_address_t *daddr) | 51 | xfrm_address_t *saddr, xfrm_address_t *daddr) |
| 43 | { | 52 | { |
| 44 | struct dst_entry *dst; | 53 | struct dst_entry *dst; |
| 45 | struct rtable *rt; | 54 | struct flowi4 fl4; |
| 46 | 55 | ||
| 47 | dst = xfrm4_dst_lookup(net, 0, NULL, daddr); | 56 | dst = __xfrm4_dst_lookup(net, &fl4, 0, NULL, daddr); |
| 48 | if (IS_ERR(dst)) | 57 | if (IS_ERR(dst)) |
| 49 | return -EHOSTUNREACH; | 58 | return -EHOSTUNREACH; |
| 50 | 59 | ||
| 51 | rt = (struct rtable *)dst; | 60 | saddr->a4 = fl4.saddr; |
| 52 | saddr->a4 = rt->rt_src; | ||
| 53 | dst_release(dst); | 61 | dst_release(dst); |
| 54 | return 0; | 62 | return 0; |
| 55 | } | 63 | } |
