diff options
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 78 |
1 files changed, 39 insertions, 39 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index c2d8059e754e..16d4c63ff554 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * RAW sockets for IPv6 | 2 | * RAW sockets for IPv6 |
3 | * Linux INET6 implementation | 3 | * Linux INET6 implementation |
4 | * | 4 | * |
5 | * Authors: | 5 | * Authors: |
6 | * Pedro Roque <roque@di.fc.ul.pt> | 6 | * Pedro Roque <roque@di.fc.ul.pt> |
7 | * | 7 | * |
8 | * Adapted from linux/net/ipv4/raw.c | 8 | * Adapted from linux/net/ipv4/raw.c |
9 | * | 9 | * |
@@ -11,7 +11,7 @@ | |||
11 | * | 11 | * |
12 | * Fixes: | 12 | * Fixes: |
13 | * Hideaki YOSHIFUJI : sin6_scope_id support | 13 | * Hideaki YOSHIFUJI : sin6_scope_id support |
14 | * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance) | 14 | * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance) |
15 | * Kazunori MIYAZAWA @USAGI: change process style to use ip6_append_data | 15 | * Kazunori MIYAZAWA @USAGI: change process style to use ip6_append_data |
16 | * | 16 | * |
17 | * This program is free software; you can redistribute it and/or | 17 | * This program is free software; you can redistribute it and/or |
@@ -71,12 +71,12 @@ static void raw_v6_hash(struct sock *sk) | |||
71 | write_lock_bh(&raw_v6_lock); | 71 | write_lock_bh(&raw_v6_lock); |
72 | sk_add_node(sk, list); | 72 | sk_add_node(sk, list); |
73 | sock_prot_inc_use(sk->sk_prot); | 73 | sock_prot_inc_use(sk->sk_prot); |
74 | write_unlock_bh(&raw_v6_lock); | 74 | write_unlock_bh(&raw_v6_lock); |
75 | } | 75 | } |
76 | 76 | ||
77 | static void raw_v6_unhash(struct sock *sk) | 77 | static void raw_v6_unhash(struct sock *sk) |
78 | { | 78 | { |
79 | write_lock_bh(&raw_v6_lock); | 79 | write_lock_bh(&raw_v6_lock); |
80 | if (sk_del_node_init(sk)) | 80 | if (sk_del_node_init(sk)) |
81 | sock_prot_dec_use(sk->sk_prot); | 81 | sock_prot_dec_use(sk->sk_prot); |
82 | write_unlock_bh(&raw_v6_lock); | 82 | write_unlock_bh(&raw_v6_lock); |
@@ -250,7 +250,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
250 | */ | 250 | */ |
251 | sk->sk_bound_dev_if = addr->sin6_scope_id; | 251 | sk->sk_bound_dev_if = addr->sin6_scope_id; |
252 | } | 252 | } |
253 | 253 | ||
254 | /* Binding to link-local address requires an interface */ | 254 | /* Binding to link-local address requires an interface */ |
255 | if (!sk->sk_bound_dev_if) | 255 | if (!sk->sk_bound_dev_if) |
256 | goto out; | 256 | goto out; |
@@ -261,7 +261,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
261 | goto out; | 261 | goto out; |
262 | } | 262 | } |
263 | } | 263 | } |
264 | 264 | ||
265 | /* ipv4 addr of the socket is invalid. Only the | 265 | /* ipv4 addr of the socket is invalid. Only the |
266 | * unspecified and mapped address have a v4 equivalent. | 266 | * unspecified and mapped address have a v4 equivalent. |
267 | */ | 267 | */ |
@@ -324,7 +324,7 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb, | |||
324 | 324 | ||
325 | static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) | 325 | static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) |
326 | { | 326 | { |
327 | if ((raw6_sk(sk)->checksum || sk->sk_filter) && | 327 | if ((raw6_sk(sk)->checksum || sk->sk_filter) && |
328 | skb_checksum_complete(skb)) { | 328 | skb_checksum_complete(skb)) { |
329 | /* FIXME: increment a raw6 drops counter here */ | 329 | /* FIXME: increment a raw6 drops counter here */ |
330 | kfree_skb(skb); | 330 | kfree_skb(skb); |
@@ -342,10 +342,10 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) | |||
342 | } | 342 | } |
343 | 343 | ||
344 | /* | 344 | /* |
345 | * This is next to useless... | 345 | * This is next to useless... |
346 | * if we demultiplex in network layer we don't need the extra call | 346 | * if we demultiplex in network layer we don't need the extra call |
347 | * just to queue the skb... | 347 | * just to queue the skb... |
348 | * maybe we could have the network decide upon a hint if it | 348 | * maybe we could have the network decide upon a hint if it |
349 | * should call raw_rcv for demultiplexing | 349 | * should call raw_rcv for demultiplexing |
350 | */ | 350 | */ |
351 | int rawv6_rcv(struct sock *sk, struct sk_buff *skb) | 351 | int rawv6_rcv(struct sock *sk, struct sk_buff *skb) |
@@ -353,17 +353,17 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb) | |||
353 | struct inet_sock *inet = inet_sk(sk); | 353 | struct inet_sock *inet = inet_sk(sk); |
354 | struct raw6_sock *rp = raw6_sk(sk); | 354 | struct raw6_sock *rp = raw6_sk(sk); |
355 | 355 | ||
356 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { | 356 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { |
357 | kfree_skb(skb); | 357 | kfree_skb(skb); |
358 | return NET_RX_DROP; | 358 | return NET_RX_DROP; |
359 | } | 359 | } |
360 | 360 | ||
361 | if (!rp->checksum) | 361 | if (!rp->checksum) |
362 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 362 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
363 | 363 | ||
364 | if (skb->ip_summed == CHECKSUM_COMPLETE) { | 364 | if (skb->ip_summed == CHECKSUM_COMPLETE) { |
365 | skb_postpull_rcsum(skb, skb->nh.raw, | 365 | skb_postpull_rcsum(skb, skb->nh.raw, |
366 | skb->h.raw - skb->nh.raw); | 366 | skb->h.raw - skb->nh.raw); |
367 | if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr, | 367 | if (!csum_ipv6_magic(&skb->nh.ipv6h->saddr, |
368 | &skb->nh.ipv6h->daddr, | 368 | &skb->nh.ipv6h->daddr, |
369 | skb->len, inet->num, skb->csum)) | 369 | skb->len, inet->num, skb->csum)) |
@@ -404,8 +404,8 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
404 | 404 | ||
405 | if (flags & MSG_OOB) | 405 | if (flags & MSG_OOB) |
406 | return -EOPNOTSUPP; | 406 | return -EOPNOTSUPP; |
407 | 407 | ||
408 | if (addr_len) | 408 | if (addr_len) |
409 | *addr_len=sizeof(*sin6); | 409 | *addr_len=sizeof(*sin6); |
410 | 410 | ||
411 | if (flags & MSG_ERRQUEUE) | 411 | if (flags & MSG_ERRQUEUE) |
@@ -416,10 +416,10 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
416 | goto out; | 416 | goto out; |
417 | 417 | ||
418 | copied = skb->len; | 418 | copied = skb->len; |
419 | if (copied > len) { | 419 | if (copied > len) { |
420 | copied = len; | 420 | copied = len; |
421 | msg->msg_flags |= MSG_TRUNC; | 421 | msg->msg_flags |= MSG_TRUNC; |
422 | } | 422 | } |
423 | 423 | ||
424 | if (skb->ip_summed==CHECKSUM_UNNECESSARY) { | 424 | if (skb->ip_summed==CHECKSUM_UNNECESSARY) { |
425 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 425 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); |
@@ -549,7 +549,7 @@ out: | |||
549 | } | 549 | } |
550 | 550 | ||
551 | static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, | 551 | static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, |
552 | struct flowi *fl, struct rt6_info *rt, | 552 | struct flowi *fl, struct rt6_info *rt, |
553 | unsigned int flags) | 553 | unsigned int flags) |
554 | { | 554 | { |
555 | struct ipv6_pinfo *np = inet6_sk(sk); | 555 | struct ipv6_pinfo *np = inet6_sk(sk); |
@@ -570,7 +570,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, | |||
570 | skb = sock_alloc_send_skb(sk, length+hh_len+15, | 570 | skb = sock_alloc_send_skb(sk, length+hh_len+15, |
571 | flags&MSG_DONTWAIT, &err); | 571 | flags&MSG_DONTWAIT, &err); |
572 | if (skb == NULL) | 572 | if (skb == NULL) |
573 | goto error; | 573 | goto error; |
574 | skb_reserve(skb, hh_len); | 574 | skb_reserve(skb, hh_len); |
575 | 575 | ||
576 | skb->priority = sk->sk_priority; | 576 | skb->priority = sk->sk_priority; |
@@ -600,7 +600,7 @@ error_fault: | |||
600 | kfree_skb(skb); | 600 | kfree_skb(skb); |
601 | error: | 601 | error: |
602 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); | 602 | IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); |
603 | return err; | 603 | return err; |
604 | } | 604 | } |
605 | 605 | ||
606 | static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | 606 | static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) |
@@ -694,19 +694,19 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
694 | return -EMSGSIZE; | 694 | return -EMSGSIZE; |
695 | 695 | ||
696 | /* Mirror BSD error message compatibility */ | 696 | /* Mirror BSD error message compatibility */ |
697 | if (msg->msg_flags & MSG_OOB) | 697 | if (msg->msg_flags & MSG_OOB) |
698 | return -EOPNOTSUPP; | 698 | return -EOPNOTSUPP; |
699 | 699 | ||
700 | /* | 700 | /* |
701 | * Get and verify the address. | 701 | * Get and verify the address. |
702 | */ | 702 | */ |
703 | memset(&fl, 0, sizeof(fl)); | 703 | memset(&fl, 0, sizeof(fl)); |
704 | 704 | ||
705 | if (sin6) { | 705 | if (sin6) { |
706 | if (addr_len < SIN6_LEN_RFC2133) | 706 | if (addr_len < SIN6_LEN_RFC2133) |
707 | return -EINVAL; | 707 | return -EINVAL; |
708 | 708 | ||
709 | if (sin6->sin6_family && sin6->sin6_family != AF_INET6) | 709 | if (sin6->sin6_family && sin6->sin6_family != AF_INET6) |
710 | return(-EAFNOSUPPORT); | 710 | return(-EAFNOSUPPORT); |
711 | 711 | ||
712 | /* port is the proto value [0..255] carried in nexthdr */ | 712 | /* port is the proto value [0..255] carried in nexthdr */ |
@@ -744,17 +744,17 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
744 | ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) | 744 | ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) |
745 | fl.oif = sin6->sin6_scope_id; | 745 | fl.oif = sin6->sin6_scope_id; |
746 | } else { | 746 | } else { |
747 | if (sk->sk_state != TCP_ESTABLISHED) | 747 | if (sk->sk_state != TCP_ESTABLISHED) |
748 | return -EDESTADDRREQ; | 748 | return -EDESTADDRREQ; |
749 | 749 | ||
750 | proto = inet->num; | 750 | proto = inet->num; |
751 | daddr = &np->daddr; | 751 | daddr = &np->daddr; |
752 | fl.fl6_flowlabel = np->flow_label; | 752 | fl.fl6_flowlabel = np->flow_label; |
753 | } | 753 | } |
754 | 754 | ||
755 | if (ipv6_addr_any(daddr)) { | 755 | if (ipv6_addr_any(daddr)) { |
756 | /* | 756 | /* |
757 | * unspecified destination address | 757 | * unspecified destination address |
758 | * treated as error... is this correct ? | 758 | * treated as error... is this correct ? |
759 | */ | 759 | */ |
760 | fl6_sock_release(flowlabel); | 760 | fl6_sock_release(flowlabel); |
@@ -792,7 +792,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
792 | err = rawv6_probe_proto_opt(&fl, msg); | 792 | err = rawv6_probe_proto_opt(&fl, msg); |
793 | if (err) | 793 | if (err) |
794 | goto out; | 794 | goto out; |
795 | 795 | ||
796 | ipv6_addr_copy(&fl.fl6_dst, daddr); | 796 | ipv6_addr_copy(&fl.fl6_dst, daddr); |
797 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) | 797 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) |
798 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | 798 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); |
@@ -856,7 +856,7 @@ done: | |||
856 | dst_release(dst); | 856 | dst_release(dst); |
857 | if (!inet->hdrincl) | 857 | if (!inet->hdrincl) |
858 | release_sock(sk); | 858 | release_sock(sk); |
859 | out: | 859 | out: |
860 | fl6_sock_release(flowlabel); | 860 | fl6_sock_release(flowlabel); |
861 | return err<0?err:len; | 861 | return err<0?err:len; |
862 | do_confirm: | 862 | do_confirm: |
@@ -867,7 +867,7 @@ do_confirm: | |||
867 | goto done; | 867 | goto done; |
868 | } | 868 | } |
869 | 869 | ||
870 | static int rawv6_seticmpfilter(struct sock *sk, int level, int optname, | 870 | static int rawv6_seticmpfilter(struct sock *sk, int level, int optname, |
871 | char __user *optval, int optlen) | 871 | char __user *optval, int optlen) |
872 | { | 872 | { |
873 | switch (optname) { | 873 | switch (optname) { |
@@ -884,7 +884,7 @@ static int rawv6_seticmpfilter(struct sock *sk, int level, int optname, | |||
884 | return 0; | 884 | return 0; |
885 | } | 885 | } |
886 | 886 | ||
887 | static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, | 887 | static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, |
888 | char __user *optval, int __user *optlen) | 888 | char __user *optval, int __user *optlen) |
889 | { | 889 | { |
890 | int len; | 890 | int len; |
@@ -916,7 +916,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, | |||
916 | struct raw6_sock *rp = raw6_sk(sk); | 916 | struct raw6_sock *rp = raw6_sk(sk); |
917 | int val; | 917 | int val; |
918 | 918 | ||
919 | if (get_user(val, (int __user *)optval)) | 919 | if (get_user(val, (int __user *)optval)) |
920 | return -EFAULT; | 920 | return -EFAULT; |
921 | 921 | ||
922 | switch (optname) { | 922 | switch (optname) { |
@@ -1224,7 +1224,7 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | |||
1224 | src->s6_addr32[2], src->s6_addr32[3], srcp, | 1224 | src->s6_addr32[2], src->s6_addr32[3], srcp, |
1225 | dest->s6_addr32[0], dest->s6_addr32[1], | 1225 | dest->s6_addr32[0], dest->s6_addr32[1], |
1226 | dest->s6_addr32[2], dest->s6_addr32[3], destp, | 1226 | dest->s6_addr32[2], dest->s6_addr32[3], destp, |
1227 | sp->sk_state, | 1227 | sp->sk_state, |
1228 | atomic_read(&sp->sk_wmem_alloc), | 1228 | atomic_read(&sp->sk_wmem_alloc), |
1229 | atomic_read(&sp->sk_rmem_alloc), | 1229 | atomic_read(&sp->sk_rmem_alloc), |
1230 | 0, 0L, 0, | 1230 | 0, 0L, 0, |