aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r--net/ipv6/raw.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 203e069e7fe9..009a1047fc3f 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -152,7 +152,7 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
152 int delivered = 0; 152 int delivered = 0;
153 __u8 hash; 153 __u8 hash;
154 154
155 saddr = &skb->nh.ipv6h->saddr; 155 saddr = &ipv6_hdr(skb)->saddr;
156 daddr = saddr + 1; 156 daddr = saddr + 1;
157 157
158 hash = nexthdr & (MAX_INET_PROTOS - 1); 158 hash = nexthdr & (MAX_INET_PROTOS - 1);
@@ -361,17 +361,18 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
361 skb->ip_summed = CHECKSUM_UNNECESSARY; 361 skb->ip_summed = CHECKSUM_UNNECESSARY;
362 362
363 if (skb->ip_summed == CHECKSUM_COMPLETE) { 363 if (skb->ip_summed == CHECKSUM_COMPLETE) {
364 skb_postpull_rcsum(skb, skb->nh.raw, 364 skb_postpull_rcsum(skb, skb_network_header(skb),
365 skb->h.raw - skb->nh.raw); 365 skb_network_header_len(skb));
366 if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr, 366 if (!csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
367 &skb->nh.ipv6h->daddr, 367 &ipv6_hdr(skb)->daddr,
368 skb->len, inet->num, skb->csum)) 368 skb->len, inet->num, skb->csum))
369 skb->ip_summed = CHECKSUM_UNNECESSARY; 369 skb->ip_summed = CHECKSUM_UNNECESSARY;
370 } 370 }
371 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 371 if (!skb_csum_unnecessary(skb))
372 skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr, 372 skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
373 &skb->nh.ipv6h->daddr, 373 &ipv6_hdr(skb)->daddr,
374 skb->len, inet->num, 0)); 374 skb->len,
375 inet->num, 0));
375 376
376 if (inet->hdrincl) { 377 if (inet->hdrincl) {
377 if (skb_checksum_complete(skb)) { 378 if (skb_checksum_complete(skb)) {
@@ -420,7 +421,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
420 msg->msg_flags |= MSG_TRUNC; 421 msg->msg_flags |= MSG_TRUNC;
421 } 422 }
422 423
423 if (skb->ip_summed==CHECKSUM_UNNECESSARY) { 424 if (skb_csum_unnecessary(skb)) {
424 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 425 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
425 } else if (msg->msg_flags&MSG_TRUNC) { 426 } else if (msg->msg_flags&MSG_TRUNC) {
426 if (__skb_checksum_complete(skb)) 427 if (__skb_checksum_complete(skb))
@@ -438,7 +439,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
438 if (sin6) { 439 if (sin6) {
439 sin6->sin6_family = AF_INET6; 440 sin6->sin6_family = AF_INET6;
440 sin6->sin6_port = 0; 441 sin6->sin6_port = 0;
441 ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr); 442 ipv6_addr_copy(&sin6->sin6_addr, &ipv6_hdr(skb)->saddr);
442 sin6->sin6_flowinfo = 0; 443 sin6->sin6_flowinfo = 0;
443 sin6->sin6_scope_id = 0; 444 sin6->sin6_scope_id = 0;
444 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) 445 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
@@ -488,7 +489,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
488 goto out; 489 goto out;
489 490
490 offset = rp->offset; 491 offset = rp->offset;
491 total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data); 492 total_len = inet_sk(sk)->cork.length - (skb_network_header(skb) -
493 skb->data);
492 if (offset >= total_len - 1) { 494 if (offset >= total_len - 1) {
493 err = -EINVAL; 495 err = -EINVAL;
494 ip6_flush_pending_frames(sk); 496 ip6_flush_pending_frames(sk);
@@ -511,7 +513,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
511 if (csum_skb) 513 if (csum_skb)
512 continue; 514 continue;
513 515
514 len = skb->len - (skb->h.raw - skb->data); 516 len = skb->len - skb_transport_offset(skb);
515 if (offset >= len) { 517 if (offset >= len) {
516 offset -= len; 518 offset -= len;
517 continue; 519 continue;
@@ -523,7 +525,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
523 skb = csum_skb; 525 skb = csum_skb;
524 } 526 }
525 527
526 offset += skb->h.raw - skb->data; 528 offset += skb_transport_offset(skb);
527 if (skb_copy_bits(skb, offset, &csum, 2)) 529 if (skb_copy_bits(skb, offset, &csum, 2))
528 BUG(); 530 BUG();
529 531
@@ -575,11 +577,13 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
575 skb->priority = sk->sk_priority; 577 skb->priority = sk->sk_priority;
576 skb->dst = dst_clone(&rt->u.dst); 578 skb->dst = dst_clone(&rt->u.dst);
577 579
578 skb->nh.ipv6h = iph = (struct ipv6hdr *)skb_put(skb, length); 580 skb_put(skb, length);
581 skb_reset_network_header(skb);
582 iph = ipv6_hdr(skb);
579 583
580 skb->ip_summed = CHECKSUM_NONE; 584 skb->ip_summed = CHECKSUM_NONE;
581 585
582 skb->h.raw = skb->nh.raw; 586 skb->transport_header = skb->network_header;
583 err = memcpy_fromiovecend((void *)iph, from, 0, length); 587 err = memcpy_fromiovecend((void *)iph, from, 0, length);
584 if (err) 588 if (err)
585 goto error_fault; 589 goto error_fault;
@@ -878,7 +882,7 @@ static int rawv6_seticmpfilter(struct sock *sk, int level, int optname,
878 return 0; 882 return 0;
879 default: 883 default:
880 return -ENOPROTOOPT; 884 return -ENOPROTOOPT;
881 }; 885 }
882 886
883 return 0; 887 return 0;
884} 888}
@@ -903,7 +907,7 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname,
903 return 0; 907 return 0;
904 default: 908 default:
905 return -ENOPROTOOPT; 909 return -ENOPROTOOPT;
906 }; 910 }
907 911
908 return 0; 912 return 0;
909} 913}
@@ -957,7 +961,8 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
957 default: 961 default:
958 return ipv6_setsockopt(sk, level, optname, optval, 962 return ipv6_setsockopt(sk, level, optname, optval,
959 optlen); 963 optlen);
960 }; 964 }
965
961 return do_rawv6_setsockopt(sk, level, optname, optval, optlen); 966 return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
962} 967}
963 968
@@ -978,7 +983,7 @@ static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
978 default: 983 default:
979 return compat_ipv6_setsockopt(sk, level, optname, 984 return compat_ipv6_setsockopt(sk, level, optname,
980 optval, optlen); 985 optval, optlen);
981 }; 986 }
982 return do_rawv6_setsockopt(sk, level, optname, optval, optlen); 987 return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
983} 988}
984#endif 989#endif
@@ -1031,7 +1036,8 @@ static int rawv6_getsockopt(struct sock *sk, int level, int optname,
1031 default: 1036 default:
1032 return ipv6_getsockopt(sk, level, optname, optval, 1037 return ipv6_getsockopt(sk, level, optname, optval,
1033 optlen); 1038 optlen);
1034 }; 1039 }
1040
1035 return do_rawv6_getsockopt(sk, level, optname, optval, optlen); 1041 return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
1036} 1042}
1037 1043
@@ -1052,7 +1058,7 @@ static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname,
1052 default: 1058 default:
1053 return compat_ipv6_getsockopt(sk, level, optname, 1059 return compat_ipv6_getsockopt(sk, level, optname,
1054 optval, optlen); 1060 optval, optlen);
1055 }; 1061 }
1056 return do_rawv6_getsockopt(sk, level, optname, optval, optlen); 1062 return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
1057} 1063}
1058#endif 1064#endif
@@ -1073,7 +1079,7 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
1073 spin_lock_bh(&sk->sk_receive_queue.lock); 1079 spin_lock_bh(&sk->sk_receive_queue.lock);
1074 skb = skb_peek(&sk->sk_receive_queue); 1080 skb = skb_peek(&sk->sk_receive_queue);
1075 if (skb != NULL) 1081 if (skb != NULL)
1076 amount = skb->tail - skb->h.raw; 1082 amount = skb->tail - skb->transport_header;
1077 spin_unlock_bh(&sk->sk_receive_queue.lock); 1083 spin_unlock_bh(&sk->sk_receive_queue.lock);
1078 return put_user(amount, (int __user *)arg); 1084 return put_user(amount, (int __user *)arg);
1079 } 1085 }