diff options
Diffstat (limited to 'net/ipv6/xfrm6_policy.c')
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index da87428681cc..05e34c8ec913 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -27,18 +27,19 @@ | |||
27 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; | 27 | static struct xfrm_policy_afinfo xfrm6_policy_afinfo; |
28 | 28 | ||
29 | static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, | 29 | static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, |
30 | xfrm_address_t *saddr, | 30 | const xfrm_address_t *saddr, |
31 | xfrm_address_t *daddr) | 31 | const xfrm_address_t *daddr) |
32 | { | 32 | { |
33 | struct flowi fl = {}; | 33 | struct flowi6 fl6; |
34 | struct dst_entry *dst; | 34 | struct dst_entry *dst; |
35 | int err; | 35 | int err; |
36 | 36 | ||
37 | memcpy(&fl.fl6_dst, daddr, sizeof(fl.fl6_dst)); | 37 | memset(&fl6, 0, sizeof(fl6)); |
38 | memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr)); | ||
38 | if (saddr) | 39 | if (saddr) |
39 | memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src)); | 40 | memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr)); |
40 | 41 | ||
41 | dst = ip6_route_output(net, NULL, &fl); | 42 | dst = ip6_route_output(net, NULL, &fl6); |
42 | 43 | ||
43 | err = dst->error; | 44 | err = dst->error; |
44 | if (dst->error) { | 45 | if (dst->error) { |
@@ -67,7 +68,7 @@ static int xfrm6_get_saddr(struct net *net, | |||
67 | return 0; | 68 | return 0; |
68 | } | 69 | } |
69 | 70 | ||
70 | static int xfrm6_get_tos(struct flowi *fl) | 71 | static int xfrm6_get_tos(const struct flowi *fl) |
71 | { | 72 | { |
72 | return 0; | 73 | return 0; |
73 | } | 74 | } |
@@ -87,7 +88,7 @@ static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst, | |||
87 | } | 88 | } |
88 | 89 | ||
89 | static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | 90 | static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, |
90 | struct flowi *fl) | 91 | const struct flowi *fl) |
91 | { | 92 | { |
92 | struct rt6_info *rt = (struct rt6_info*)xdst->route; | 93 | struct rt6_info *rt = (struct rt6_info*)xdst->route; |
93 | 94 | ||
@@ -120,6 +121,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
120 | static inline void | 121 | static inline void |
121 | _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | 122 | _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) |
122 | { | 123 | { |
124 | struct flowi6 *fl6 = &fl->u.ip6; | ||
123 | int onlyproto = 0; | 125 | int onlyproto = 0; |
124 | u16 offset = skb_network_header_len(skb); | 126 | u16 offset = skb_network_header_len(skb); |
125 | struct ipv6hdr *hdr = ipv6_hdr(skb); | 127 | struct ipv6hdr *hdr = ipv6_hdr(skb); |
@@ -127,11 +129,11 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
127 | const unsigned char *nh = skb_network_header(skb); | 129 | const unsigned char *nh = skb_network_header(skb); |
128 | u8 nexthdr = nh[IP6CB(skb)->nhoff]; | 130 | u8 nexthdr = nh[IP6CB(skb)->nhoff]; |
129 | 131 | ||
130 | memset(fl, 0, sizeof(struct flowi)); | 132 | memset(fl6, 0, sizeof(struct flowi6)); |
131 | fl->mark = skb->mark; | 133 | fl6->flowi6_mark = skb->mark; |
132 | 134 | ||
133 | ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); | 135 | ipv6_addr_copy(&fl6->daddr, reverse ? &hdr->saddr : &hdr->daddr); |
134 | ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); | 136 | ipv6_addr_copy(&fl6->saddr, reverse ? &hdr->daddr : &hdr->saddr); |
135 | 137 | ||
136 | while (nh + offset + 1 < skb->data || | 138 | while (nh + offset + 1 < skb->data || |
137 | pskb_may_pull(skb, nh + offset + 1 - skb->data)) { | 139 | pskb_may_pull(skb, nh + offset + 1 - skb->data)) { |
@@ -158,20 +160,20 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
158 | pskb_may_pull(skb, nh + offset + 4 - skb->data))) { | 160 | pskb_may_pull(skb, nh + offset + 4 - skb->data))) { |
159 | __be16 *ports = (__be16 *)exthdr; | 161 | __be16 *ports = (__be16 *)exthdr; |
160 | 162 | ||
161 | fl->fl_ip_sport = ports[!!reverse]; | 163 | fl6->fl6_sport = ports[!!reverse]; |
162 | fl->fl_ip_dport = ports[!reverse]; | 164 | fl6->fl6_dport = ports[!reverse]; |
163 | } | 165 | } |
164 | fl->proto = nexthdr; | 166 | fl6->flowi6_proto = nexthdr; |
165 | return; | 167 | return; |
166 | 168 | ||
167 | case IPPROTO_ICMPV6: | 169 | case IPPROTO_ICMPV6: |
168 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) { | 170 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) { |
169 | u8 *icmp = (u8 *)exthdr; | 171 | u8 *icmp = (u8 *)exthdr; |
170 | 172 | ||
171 | fl->fl_icmp_type = icmp[0]; | 173 | fl6->fl6_icmp_type = icmp[0]; |
172 | fl->fl_icmp_code = icmp[1]; | 174 | fl6->fl6_icmp_code = icmp[1]; |
173 | } | 175 | } |
174 | fl->proto = nexthdr; | 176 | fl6->flowi6_proto = nexthdr; |
175 | return; | 177 | return; |
176 | 178 | ||
177 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 179 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
@@ -180,9 +182,9 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
180 | struct ip6_mh *mh; | 182 | struct ip6_mh *mh; |
181 | mh = (struct ip6_mh *)exthdr; | 183 | mh = (struct ip6_mh *)exthdr; |
182 | 184 | ||
183 | fl->fl_mh_type = mh->ip6mh_type; | 185 | fl6->fl6_mh_type = mh->ip6mh_type; |
184 | } | 186 | } |
185 | fl->proto = nexthdr; | 187 | fl6->flowi6_proto = nexthdr; |
186 | return; | 188 | return; |
187 | #endif | 189 | #endif |
188 | 190 | ||
@@ -191,8 +193,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
191 | case IPPROTO_ESP: | 193 | case IPPROTO_ESP: |
192 | case IPPROTO_COMP: | 194 | case IPPROTO_COMP: |
193 | default: | 195 | default: |
194 | fl->fl_ipsec_spi = 0; | 196 | fl6->fl6_ipsec_spi = 0; |
195 | fl->proto = nexthdr; | 197 | fl6->flowi6_proto = nexthdr; |
196 | return; | 198 | return; |
197 | } | 199 | } |
198 | } | 200 | } |
@@ -220,6 +222,7 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) | |||
220 | 222 | ||
221 | if (likely(xdst->u.rt6.rt6i_idev)) | 223 | if (likely(xdst->u.rt6.rt6i_idev)) |
222 | in6_dev_put(xdst->u.rt6.rt6i_idev); | 224 | in6_dev_put(xdst->u.rt6.rt6i_idev); |
225 | dst_destroy_metrics_generic(dst); | ||
223 | if (likely(xdst->u.rt6.rt6i_peer)) | 226 | if (likely(xdst->u.rt6.rt6i_peer)) |
224 | inet_putpeer(xdst->u.rt6.rt6i_peer); | 227 | inet_putpeer(xdst->u.rt6.rt6i_peer); |
225 | xfrm_dst_destroy(xdst); | 228 | xfrm_dst_destroy(xdst); |
@@ -257,6 +260,7 @@ static struct dst_ops xfrm6_dst_ops = { | |||
257 | .protocol = cpu_to_be16(ETH_P_IPV6), | 260 | .protocol = cpu_to_be16(ETH_P_IPV6), |
258 | .gc = xfrm6_garbage_collect, | 261 | .gc = xfrm6_garbage_collect, |
259 | .update_pmtu = xfrm6_update_pmtu, | 262 | .update_pmtu = xfrm6_update_pmtu, |
263 | .cow_metrics = dst_cow_metrics_generic, | ||
260 | .destroy = xfrm6_dst_destroy, | 264 | .destroy = xfrm6_dst_destroy, |
261 | .ifdown = xfrm6_dst_ifdown, | 265 | .ifdown = xfrm6_dst_ifdown, |
262 | .local_out = __ip6_local_out, | 266 | .local_out = __ip6_local_out, |
@@ -272,6 +276,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { | |||
272 | .get_tos = xfrm6_get_tos, | 276 | .get_tos = xfrm6_get_tos, |
273 | .init_path = xfrm6_init_path, | 277 | .init_path = xfrm6_init_path, |
274 | .fill_dst = xfrm6_fill_dst, | 278 | .fill_dst = xfrm6_fill_dst, |
279 | .blackhole_route = ip6_blackhole_route, | ||
275 | }; | 280 | }; |
276 | 281 | ||
277 | static int __init xfrm6_policy_init(void) | 282 | static int __init xfrm6_policy_init(void) |