diff options
Diffstat (limited to 'net/ipv4/xfrm4_policy.c')
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index d20a05e970d8..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 | } |
@@ -73,7 +81,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
73 | 81 | ||
74 | rt->rt_key_dst = fl4->daddr; | 82 | rt->rt_key_dst = fl4->daddr; |
75 | rt->rt_key_src = fl4->saddr; | 83 | rt->rt_key_src = fl4->saddr; |
76 | rt->rt_tos = fl4->flowi4_tos; | 84 | rt->rt_key_tos = fl4->flowi4_tos; |
77 | rt->rt_route_iif = fl4->flowi4_iif; | 85 | rt->rt_route_iif = fl4->flowi4_iif; |
78 | rt->rt_iif = fl4->flowi4_iif; | 86 | rt->rt_iif = fl4->flowi4_iif; |
79 | rt->rt_oif = fl4->flowi4_oif; | 87 | rt->rt_oif = fl4->flowi4_oif; |
@@ -102,7 +110,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
102 | static void | 110 | static void |
103 | _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | 111 | _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) |
104 | { | 112 | { |
105 | struct iphdr *iph = ip_hdr(skb); | 113 | const struct iphdr *iph = ip_hdr(skb); |
106 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; | 114 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; |
107 | struct flowi4 *fl4 = &fl->u.ip4; | 115 | struct flowi4 *fl4 = &fl->u.ip4; |
108 | 116 | ||