aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/icmp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-12 16:22:43 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-12 18:08:54 -0500
commit4c9483b2fb5d2548c3cc1fe03cdd4484ceeb5d1c (patch)
treec29c8070012cffb38fe249cf528589a675f622b1 /net/ipv6/icmp.c
parent9cce96df5b76691712dba22e83ff5efe900361e1 (diff)
ipv6: Convert to use flowi6 where applicable.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r--net/ipv6/icmp.c110
1 files changed, 55 insertions, 55 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 52ff7aa1f9fc..f7b9041f7845 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -158,7 +158,7 @@ static int is_ineligible(struct sk_buff *skb)
158 * Check the ICMP output rate limit 158 * Check the ICMP output rate limit
159 */ 159 */
160static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type, 160static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
161 struct flowi *fl) 161 struct flowi6 *fl6)
162{ 162{
163 struct dst_entry *dst; 163 struct dst_entry *dst;
164 struct net *net = sock_net(sk); 164 struct net *net = sock_net(sk);
@@ -177,7 +177,7 @@ static inline bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
177 * XXX: perhaps the expire for routing entries cloned by 177 * XXX: perhaps the expire for routing entries cloned by
178 * this lookup should be more aggressive (not longer than timeout). 178 * this lookup should be more aggressive (not longer than timeout).
179 */ 179 */
180 dst = ip6_route_output(net, sk, fl); 180 dst = ip6_route_output(net, sk, fl6);
181 if (dst->error) { 181 if (dst->error) {
182 IP6_INC_STATS(net, ip6_dst_idev(dst), 182 IP6_INC_STATS(net, ip6_dst_idev(dst),
183 IPSTATS_MIB_OUTNOROUTES); 183 IPSTATS_MIB_OUTNOROUTES);
@@ -217,7 +217,7 @@ static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset)
217 return (*op & 0xC0) == 0x80; 217 return (*op & 0xC0) == 0x80;
218} 218}
219 219
220static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct icmp6hdr *thdr, int len) 220static int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6, struct icmp6hdr *thdr, int len)
221{ 221{
222 struct sk_buff *skb; 222 struct sk_buff *skb;
223 struct icmp6hdr *icmp6h; 223 struct icmp6hdr *icmp6h;
@@ -233,9 +233,9 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
233 if (skb_queue_len(&sk->sk_write_queue) == 1) { 233 if (skb_queue_len(&sk->sk_write_queue) == 1) {
234 skb->csum = csum_partial(icmp6h, 234 skb->csum = csum_partial(icmp6h,
235 sizeof(struct icmp6hdr), skb->csum); 235 sizeof(struct icmp6hdr), skb->csum);
236 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, 236 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
237 &fl->fl6_dst, 237 &fl6->daddr,
238 len, fl->flowi_proto, 238 len, fl6->flowi6_proto,
239 skb->csum); 239 skb->csum);
240 } else { 240 } else {
241 __wsum tmp_csum = 0; 241 __wsum tmp_csum = 0;
@@ -246,9 +246,9 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
246 246
247 tmp_csum = csum_partial(icmp6h, 247 tmp_csum = csum_partial(icmp6h,
248 sizeof(struct icmp6hdr), tmp_csum); 248 sizeof(struct icmp6hdr), tmp_csum);
249 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src, 249 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl6->saddr,
250 &fl->fl6_dst, 250 &fl6->daddr,
251 len, fl->flowi_proto, 251 len, fl6->flowi6_proto,
252 tmp_csum); 252 tmp_csum);
253 } 253 }
254 ip6_push_pending_frames(sk); 254 ip6_push_pending_frames(sk);
@@ -301,13 +301,13 @@ static inline void mip6_addr_swap(struct sk_buff *skb) {}
301#endif 301#endif
302 302
303static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb, 303static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *skb,
304 struct sock *sk, struct flowi *fl) 304 struct sock *sk, struct flowi6 *fl6)
305{ 305{
306 struct dst_entry *dst, *dst2; 306 struct dst_entry *dst, *dst2;
307 struct flowi fl2; 307 struct flowi6 fl2;
308 int err; 308 int err;
309 309
310 err = ip6_dst_lookup(sk, &dst, fl); 310 err = ip6_dst_lookup(sk, &dst, fl6);
311 if (err) 311 if (err)
312 return ERR_PTR(err); 312 return ERR_PTR(err);
313 313
@@ -324,7 +324,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk
324 /* No need to clone since we're just using its address. */ 324 /* No need to clone since we're just using its address. */
325 dst2 = dst; 325 dst2 = dst;
326 326
327 dst = xfrm_lookup(net, dst, fl, sk, 0); 327 dst = xfrm_lookup(net, dst, flowi6_to_flowi(fl6), sk, 0);
328 if (!IS_ERR(dst)) { 328 if (!IS_ERR(dst)) {
329 if (dst != dst2) 329 if (dst != dst2)
330 return dst; 330 return dst;
@@ -335,7 +335,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk
335 return dst; 335 return dst;
336 } 336 }
337 337
338 err = xfrm_decode_session_reverse(skb, &fl2, AF_INET6); 338 err = xfrm_decode_session_reverse(skb, flowi6_to_flowi(&fl2), AF_INET6);
339 if (err) 339 if (err)
340 goto relookup_failed; 340 goto relookup_failed;
341 341
@@ -343,7 +343,7 @@ static struct dst_entry *icmpv6_route_lookup(struct net *net, struct sk_buff *sk
343 if (err) 343 if (err)
344 goto relookup_failed; 344 goto relookup_failed;
345 345
346 dst2 = xfrm_lookup(net, dst2, &fl2, sk, XFRM_LOOKUP_ICMP); 346 dst2 = xfrm_lookup(net, dst2, flowi6_to_flowi(&fl2), sk, XFRM_LOOKUP_ICMP);
347 if (!IS_ERR(dst2)) { 347 if (!IS_ERR(dst2)) {
348 dst_release(dst); 348 dst_release(dst);
349 dst = dst2; 349 dst = dst2;
@@ -375,7 +375,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
375 struct in6_addr *saddr = NULL; 375 struct in6_addr *saddr = NULL;
376 struct dst_entry *dst; 376 struct dst_entry *dst;
377 struct icmp6hdr tmp_hdr; 377 struct icmp6hdr tmp_hdr;
378 struct flowi fl; 378 struct flowi6 fl6;
379 struct icmpv6_msg msg; 379 struct icmpv6_msg msg;
380 int iif = 0; 380 int iif = 0;
381 int addr_type = 0; 381 int addr_type = 0;
@@ -442,22 +442,22 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
442 442
443 mip6_addr_swap(skb); 443 mip6_addr_swap(skb);
444 444
445 memset(&fl, 0, sizeof(fl)); 445 memset(&fl6, 0, sizeof(fl6));
446 fl.flowi_proto = IPPROTO_ICMPV6; 446 fl6.flowi6_proto = IPPROTO_ICMPV6;
447 ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr); 447 ipv6_addr_copy(&fl6.daddr, &hdr->saddr);
448 if (saddr) 448 if (saddr)
449 ipv6_addr_copy(&fl.fl6_src, saddr); 449 ipv6_addr_copy(&fl6.saddr, saddr);
450 fl.flowi_oif = iif; 450 fl6.flowi6_oif = iif;
451 fl.fl6_icmp_type = type; 451 fl6.uli.icmpt.type = type;
452 fl.fl6_icmp_code = code; 452 fl6.uli.icmpt.code = code;
453 security_skb_classify_flow(skb, &fl); 453 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
454 454
455 sk = icmpv6_xmit_lock(net); 455 sk = icmpv6_xmit_lock(net);
456 if (sk == NULL) 456 if (sk == NULL)
457 return; 457 return;
458 np = inet6_sk(sk); 458 np = inet6_sk(sk);
459 459
460 if (!icmpv6_xrlim_allow(sk, type, &fl)) 460 if (!icmpv6_xrlim_allow(sk, type, &fl6))
461 goto out; 461 goto out;
462 462
463 tmp_hdr.icmp6_type = type; 463 tmp_hdr.icmp6_type = type;
@@ -465,14 +465,14 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
465 tmp_hdr.icmp6_cksum = 0; 465 tmp_hdr.icmp6_cksum = 0;
466 tmp_hdr.icmp6_pointer = htonl(info); 466 tmp_hdr.icmp6_pointer = htonl(info);
467 467
468 if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) 468 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
469 fl.flowi_oif = np->mcast_oif; 469 fl6.flowi6_oif = np->mcast_oif;
470 470
471 dst = icmpv6_route_lookup(net, skb, sk, &fl); 471 dst = icmpv6_route_lookup(net, skb, sk, &fl6);
472 if (IS_ERR(dst)) 472 if (IS_ERR(dst))
473 goto out; 473 goto out;
474 474
475 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 475 if (ipv6_addr_is_multicast(&fl6.daddr))
476 hlimit = np->mcast_hops; 476 hlimit = np->mcast_hops;
477 else 477 else
478 hlimit = np->hop_limit; 478 hlimit = np->hop_limit;
@@ -495,14 +495,14 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
495 err = ip6_append_data(sk, icmpv6_getfrag, &msg, 495 err = ip6_append_data(sk, icmpv6_getfrag, &msg,
496 len + sizeof(struct icmp6hdr), 496 len + sizeof(struct icmp6hdr),
497 sizeof(struct icmp6hdr), hlimit, 497 sizeof(struct icmp6hdr), hlimit,
498 np->tclass, NULL, &fl, (struct rt6_info*)dst, 498 np->tclass, NULL, &fl6, (struct rt6_info*)dst,
499 MSG_DONTWAIT, np->dontfrag); 499 MSG_DONTWAIT, np->dontfrag);
500 if (err) { 500 if (err) {
501 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS); 501 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
502 ip6_flush_pending_frames(sk); 502 ip6_flush_pending_frames(sk);
503 goto out_put; 503 goto out_put;
504 } 504 }
505 err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr)); 505 err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr));
506 506
507out_put: 507out_put:
508 if (likely(idev != NULL)) 508 if (likely(idev != NULL))
@@ -524,7 +524,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
524 struct in6_addr *saddr = NULL; 524 struct in6_addr *saddr = NULL;
525 struct icmp6hdr *icmph = icmp6_hdr(skb); 525 struct icmp6hdr *icmph = icmp6_hdr(skb);
526 struct icmp6hdr tmp_hdr; 526 struct icmp6hdr tmp_hdr;
527 struct flowi fl; 527 struct flowi6 fl6;
528 struct icmpv6_msg msg; 528 struct icmpv6_msg msg;
529 struct dst_entry *dst; 529 struct dst_entry *dst;
530 int err = 0; 530 int err = 0;
@@ -538,31 +538,31 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
538 memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr)); 538 memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
539 tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY; 539 tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
540 540
541 memset(&fl, 0, sizeof(fl)); 541 memset(&fl6, 0, sizeof(fl6));
542 fl.flowi_proto = IPPROTO_ICMPV6; 542 fl6.flowi6_proto = IPPROTO_ICMPV6;
543 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); 543 ipv6_addr_copy(&fl6.daddr, &ipv6_hdr(skb)->saddr);
544 if (saddr) 544 if (saddr)
545 ipv6_addr_copy(&fl.fl6_src, saddr); 545 ipv6_addr_copy(&fl6.saddr, saddr);
546 fl.flowi_oif = skb->dev->ifindex; 546 fl6.flowi6_oif = skb->dev->ifindex;
547 fl.fl6_icmp_type = ICMPV6_ECHO_REPLY; 547 fl6.uli.icmpt.type = ICMPV6_ECHO_REPLY;
548 security_skb_classify_flow(skb, &fl); 548 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
549 549
550 sk = icmpv6_xmit_lock(net); 550 sk = icmpv6_xmit_lock(net);
551 if (sk == NULL) 551 if (sk == NULL)
552 return; 552 return;
553 np = inet6_sk(sk); 553 np = inet6_sk(sk);
554 554
555 if (!fl.flowi_oif && ipv6_addr_is_multicast(&fl.fl6_dst)) 555 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
556 fl.flowi_oif = np->mcast_oif; 556 fl6.flowi6_oif = np->mcast_oif;
557 557
558 err = ip6_dst_lookup(sk, &dst, &fl); 558 err = ip6_dst_lookup(sk, &dst, &fl6);
559 if (err) 559 if (err)
560 goto out; 560 goto out;
561 dst = xfrm_lookup(net, dst, &fl, sk, 0); 561 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), sk, 0);
562 if (IS_ERR(dst)) 562 if (IS_ERR(dst))
563 goto out; 563 goto out;
564 564
565 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 565 if (ipv6_addr_is_multicast(&fl6.daddr))
566 hlimit = np->mcast_hops; 566 hlimit = np->mcast_hops;
567 else 567 else
568 hlimit = np->hop_limit; 568 hlimit = np->hop_limit;
@@ -576,7 +576,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
576 msg.type = ICMPV6_ECHO_REPLY; 576 msg.type = ICMPV6_ECHO_REPLY;
577 577
578 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), 578 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
579 sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl, 579 sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl6,
580 (struct rt6_info*)dst, MSG_DONTWAIT, 580 (struct rt6_info*)dst, MSG_DONTWAIT,
581 np->dontfrag); 581 np->dontfrag);
582 582
@@ -585,7 +585,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
585 ip6_flush_pending_frames(sk); 585 ip6_flush_pending_frames(sk);
586 goto out_put; 586 goto out_put;
587 } 587 }
588 err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); 588 err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
589 589
590out_put: 590out_put:
591 if (likely(idev != NULL)) 591 if (likely(idev != NULL))
@@ -784,20 +784,20 @@ drop_no_count:
784 return 0; 784 return 0;
785} 785}
786 786
787void icmpv6_flow_init(struct sock *sk, struct flowi *fl, 787void icmpv6_flow_init(struct sock *sk, struct flowi6 *fl6,
788 u8 type, 788 u8 type,
789 const struct in6_addr *saddr, 789 const struct in6_addr *saddr,
790 const struct in6_addr *daddr, 790 const struct in6_addr *daddr,
791 int oif) 791 int oif)
792{ 792{
793 memset(fl, 0, sizeof(*fl)); 793 memset(fl6, 0, sizeof(*fl6));
794 ipv6_addr_copy(&fl->fl6_src, saddr); 794 ipv6_addr_copy(&fl6->saddr, saddr);
795 ipv6_addr_copy(&fl->fl6_dst, daddr); 795 ipv6_addr_copy(&fl6->daddr, daddr);
796 fl->flowi_proto = IPPROTO_ICMPV6; 796 fl6->flowi6_proto = IPPROTO_ICMPV6;
797 fl->fl6_icmp_type = type; 797 fl6->uli.icmpt.type = type;
798 fl->fl6_icmp_code = 0; 798 fl6->uli.icmpt.code = 0;
799 fl->flowi_oif = oif; 799 fl6->flowi6_oif = oif;
800 security_sk_classify_flow(sk, fl); 800 security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
801} 801}
802 802
803/* 803/*