aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/raw.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/ipv6/raw.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r--net/ipv6/raw.c159
1 files changed, 84 insertions, 75 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index e677937a07fc..cc7313b8f7ea 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -31,6 +31,7 @@
31#include <linux/netfilter.h> 31#include <linux/netfilter.h>
32#include <linux/netfilter_ipv6.h> 32#include <linux/netfilter_ipv6.h>
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <linux/compat.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35#include <asm/ioctls.h> 36#include <asm/ioctls.h>
36 37
@@ -66,8 +67,8 @@ static struct raw_hashinfo raw_v6_hashinfo = {
66}; 67};
67 68
68static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, 69static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
69 unsigned short num, struct in6_addr *loc_addr, 70 unsigned short num, const struct in6_addr *loc_addr,
70 struct in6_addr *rmt_addr, int dif) 71 const struct in6_addr *rmt_addr, int dif)
71{ 72{
72 struct hlist_node *node; 73 struct hlist_node *node;
73 int is_multicast = ipv6_addr_is_multicast(loc_addr); 74 int is_multicast = ipv6_addr_is_multicast(loc_addr);
@@ -123,18 +124,18 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
123} 124}
124 125
125#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 126#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
126static int (*mh_filter)(struct sock *sock, struct sk_buff *skb); 127typedef int mh_filter_t(struct sock *sock, struct sk_buff *skb);
127 128
128int rawv6_mh_filter_register(int (*filter)(struct sock *sock, 129static mh_filter_t __rcu *mh_filter __read_mostly;
129 struct sk_buff *skb)) 130
131int rawv6_mh_filter_register(mh_filter_t filter)
130{ 132{
131 rcu_assign_pointer(mh_filter, filter); 133 rcu_assign_pointer(mh_filter, filter);
132 return 0; 134 return 0;
133} 135}
134EXPORT_SYMBOL(rawv6_mh_filter_register); 136EXPORT_SYMBOL(rawv6_mh_filter_register);
135 137
136int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock, 138int rawv6_mh_filter_unregister(mh_filter_t filter)
137 struct sk_buff *skb))
138{ 139{
139 rcu_assign_pointer(mh_filter, NULL); 140 rcu_assign_pointer(mh_filter, NULL);
140 synchronize_rcu(); 141 synchronize_rcu();
@@ -153,8 +154,8 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister);
153 */ 154 */
154static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) 155static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
155{ 156{
156 struct in6_addr *saddr; 157 const struct in6_addr *saddr;
157 struct in6_addr *daddr; 158 const struct in6_addr *daddr;
158 struct sock *sk; 159 struct sock *sk;
159 int delivered = 0; 160 int delivered = 0;
160 __u8 hash; 161 __u8 hash;
@@ -192,10 +193,10 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
192 * policy is placed in rawv6_rcv() because it is 193 * policy is placed in rawv6_rcv() because it is
193 * required for each socket. 194 * required for each socket.
194 */ 195 */
195 int (*filter)(struct sock *sock, struct sk_buff *skb); 196 mh_filter_t *filter;
196 197
197 filter = rcu_dereference(mh_filter); 198 filter = rcu_dereference(mh_filter);
198 filtered = filter ? filter(sk, skb) : 0; 199 filtered = filter ? (*filter)(sk, skb) : 0;
199 break; 200 break;
200 } 201 }
201#endif 202#endif
@@ -347,7 +348,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
347{ 348{
348 struct sock *sk; 349 struct sock *sk;
349 int hash; 350 int hash;
350 struct in6_addr *saddr, *daddr; 351 const struct in6_addr *saddr, *daddr;
351 struct net *net; 352 struct net *net;
352 353
353 hash = nexthdr & (RAW_HTABLE_SIZE - 1); 354 hash = nexthdr & (RAW_HTABLE_SIZE - 1);
@@ -356,7 +357,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
356 sk = sk_head(&raw_v6_hashinfo.ht[hash]); 357 sk = sk_head(&raw_v6_hashinfo.ht[hash]);
357 if (sk != NULL) { 358 if (sk != NULL) {
358 /* Note: ipv6_hdr(skb) != skb->data */ 359 /* Note: ipv6_hdr(skb) != skb->data */
359 struct ipv6hdr *ip6h = (struct ipv6hdr *)skb->data; 360 const struct ipv6hdr *ip6h = (const struct ipv6hdr *)skb->data;
360 saddr = &ip6h->saddr; 361 saddr = &ip6h->saddr;
361 daddr = &ip6h->daddr; 362 daddr = &ip6h->daddr;
362 net = dev_net(skb->dev); 363 net = dev_net(skb->dev);
@@ -373,7 +374,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
373 374
374static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) 375static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
375{ 376{
376 if ((raw6_sk(sk)->checksum || sk->sk_filter) && 377 if ((raw6_sk(sk)->checksum || rcu_dereference_raw(sk->sk_filter)) &&
377 skb_checksum_complete(skb)) { 378 skb_checksum_complete(skb)) {
378 atomic_inc(&sk->sk_drops); 379 atomic_inc(&sk->sk_drops);
379 kfree_skb(skb); 380 kfree_skb(skb);
@@ -523,7 +524,7 @@ csum_copy_err:
523 goto out; 524 goto out;
524} 525}
525 526
526static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, 527static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
527 struct raw6_sock *rp) 528 struct raw6_sock *rp)
528{ 529{
529 struct sk_buff *skb; 530 struct sk_buff *skb;
@@ -541,8 +542,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
541 goto out; 542 goto out;
542 543
543 offset = rp->offset; 544 offset = rp->offset;
544 total_len = inet_sk(sk)->cork.length - (skb_network_header(skb) - 545 total_len = inet_sk(sk)->cork.base.length - (skb_network_header(skb) -
545 skb->data); 546 skb->data);
546 if (offset >= total_len - 1) { 547 if (offset >= total_len - 1) {
547 err = -EINVAL; 548 err = -EINVAL;
548 ip6_flush_pending_frames(sk); 549 ip6_flush_pending_frames(sk);
@@ -585,11 +586,10 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
585 if (unlikely(csum)) 586 if (unlikely(csum))
586 tmp_csum = csum_sub(tmp_csum, csum_unfold(csum)); 587 tmp_csum = csum_sub(tmp_csum, csum_unfold(csum));
587 588
588 csum = csum_ipv6_magic(&fl->fl6_src, 589 csum = csum_ipv6_magic(&fl6->saddr, &fl6->daddr,
589 &fl->fl6_dst, 590 total_len, fl6->flowi6_proto, tmp_csum);
590 total_len, fl->proto, tmp_csum);
591 591
592 if (csum == 0 && fl->proto == IPPROTO_UDP) 592 if (csum == 0 && fl6->flowi6_proto == IPPROTO_UDP)
593 csum = CSUM_MANGLED_0; 593 csum = CSUM_MANGLED_0;
594 594
595 if (skb_store_bits(skb, offset, &csum, 2)) 595 if (skb_store_bits(skb, offset, &csum, 2))
@@ -602,7 +602,7 @@ out:
602} 602}
603 603
604static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, 604static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
605 struct flowi *fl, struct dst_entry **dstp, 605 struct flowi6 *fl6, struct dst_entry **dstp,
606 unsigned int flags) 606 unsigned int flags)
607{ 607{
608 struct ipv6_pinfo *np = inet6_sk(sk); 608 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -612,7 +612,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
612 struct rt6_info *rt = (struct rt6_info *)*dstp; 612 struct rt6_info *rt = (struct rt6_info *)*dstp;
613 613
614 if (length > rt->dst.dev->mtu) { 614 if (length > rt->dst.dev->mtu) {
615 ipv6_local_error(sk, EMSGSIZE, fl, rt->dst.dev->mtu); 615 ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
616 return -EMSGSIZE; 616 return -EMSGSIZE;
617 } 617 }
618 if (flags&MSG_PROBE) 618 if (flags&MSG_PROBE)
@@ -661,7 +661,7 @@ error:
661 return err; 661 return err;
662} 662}
663 663
664static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 664static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg)
665{ 665{
666 struct iovec *iov; 666 struct iovec *iov;
667 u8 __user *type = NULL; 667 u8 __user *type = NULL;
@@ -678,7 +678,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
678 if (!iov) 678 if (!iov)
679 continue; 679 continue;
680 680
681 switch (fl->proto) { 681 switch (fl6->flowi6_proto) {
682 case IPPROTO_ICMPV6: 682 case IPPROTO_ICMPV6:
683 /* check if one-byte field is readable or not. */ 683 /* check if one-byte field is readable or not. */
684 if (iov->iov_base && iov->iov_len < 1) 684 if (iov->iov_base && iov->iov_len < 1)
@@ -693,8 +693,8 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
693 code = iov->iov_base; 693 code = iov->iov_base;
694 694
695 if (type && code) { 695 if (type && code) {
696 if (get_user(fl->fl_icmp_type, type) || 696 if (get_user(fl6->fl6_icmp_type, type) ||
697 get_user(fl->fl_icmp_code, code)) 697 get_user(fl6->fl6_icmp_code, code))
698 return -EFAULT; 698 return -EFAULT;
699 probed = 1; 699 probed = 1;
700 } 700 }
@@ -705,7 +705,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
705 /* check if type field is readable or not. */ 705 /* check if type field is readable or not. */
706 if (iov->iov_len > 2 - len) { 706 if (iov->iov_len > 2 - len) {
707 u8 __user *p = iov->iov_base; 707 u8 __user *p = iov->iov_base;
708 if (get_user(fl->fl_mh_type, &p[2 - len])) 708 if (get_user(fl6->fl6_mh_type, &p[2 - len]))
709 return -EFAULT; 709 return -EFAULT;
710 probed = 1; 710 probed = 1;
711 } else 711 } else
@@ -734,7 +734,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
734 struct ipv6_txoptions *opt = NULL; 734 struct ipv6_txoptions *opt = NULL;
735 struct ip6_flowlabel *flowlabel = NULL; 735 struct ip6_flowlabel *flowlabel = NULL;
736 struct dst_entry *dst = NULL; 736 struct dst_entry *dst = NULL;
737 struct flowi fl; 737 struct flowi6 fl6;
738 int addr_len = msg->msg_namelen; 738 int addr_len = msg->msg_namelen;
739 int hlimit = -1; 739 int hlimit = -1;
740 int tclass = -1; 740 int tclass = -1;
@@ -755,16 +755,16 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
755 /* 755 /*
756 * Get and verify the address. 756 * Get and verify the address.
757 */ 757 */
758 memset(&fl, 0, sizeof(fl)); 758 memset(&fl6, 0, sizeof(fl6));
759 759
760 fl.mark = sk->sk_mark; 760 fl6.flowi6_mark = sk->sk_mark;
761 761
762 if (sin6) { 762 if (sin6) {
763 if (addr_len < SIN6_LEN_RFC2133) 763 if (addr_len < SIN6_LEN_RFC2133)
764 return -EINVAL; 764 return -EINVAL;
765 765
766 if (sin6->sin6_family && sin6->sin6_family != AF_INET6) 766 if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
767 return(-EAFNOSUPPORT); 767 return -EAFNOSUPPORT;
768 768
769 /* port is the proto value [0..255] carried in nexthdr */ 769 /* port is the proto value [0..255] carried in nexthdr */
770 proto = ntohs(sin6->sin6_port); 770 proto = ntohs(sin6->sin6_port);
@@ -772,16 +772,16 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
772 if (!proto) 772 if (!proto)
773 proto = inet->inet_num; 773 proto = inet->inet_num;
774 else if (proto != inet->inet_num) 774 else if (proto != inet->inet_num)
775 return(-EINVAL); 775 return -EINVAL;
776 776
777 if (proto > 255) 777 if (proto > 255)
778 return(-EINVAL); 778 return -EINVAL;
779 779
780 daddr = &sin6->sin6_addr; 780 daddr = &sin6->sin6_addr;
781 if (np->sndflow) { 781 if (np->sndflow) {
782 fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; 782 fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
783 if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) { 783 if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
784 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); 784 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
785 if (flowlabel == NULL) 785 if (flowlabel == NULL)
786 return -EINVAL; 786 return -EINVAL;
787 daddr = &flowlabel->dst; 787 daddr = &flowlabel->dst;
@@ -799,32 +799,32 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
799 if (addr_len >= sizeof(struct sockaddr_in6) && 799 if (addr_len >= sizeof(struct sockaddr_in6) &&
800 sin6->sin6_scope_id && 800 sin6->sin6_scope_id &&
801 ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) 801 ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
802 fl.oif = sin6->sin6_scope_id; 802 fl6.flowi6_oif = sin6->sin6_scope_id;
803 } else { 803 } else {
804 if (sk->sk_state != TCP_ESTABLISHED) 804 if (sk->sk_state != TCP_ESTABLISHED)
805 return -EDESTADDRREQ; 805 return -EDESTADDRREQ;
806 806
807 proto = inet->inet_num; 807 proto = inet->inet_num;
808 daddr = &np->daddr; 808 daddr = &np->daddr;
809 fl.fl6_flowlabel = np->flow_label; 809 fl6.flowlabel = np->flow_label;
810 } 810 }
811 811
812 if (fl.oif == 0) 812 if (fl6.flowi6_oif == 0)
813 fl.oif = sk->sk_bound_dev_if; 813 fl6.flowi6_oif = sk->sk_bound_dev_if;
814 814
815 if (msg->msg_controllen) { 815 if (msg->msg_controllen) {
816 opt = &opt_space; 816 opt = &opt_space;
817 memset(opt, 0, sizeof(struct ipv6_txoptions)); 817 memset(opt, 0, sizeof(struct ipv6_txoptions));
818 opt->tot_len = sizeof(struct ipv6_txoptions); 818 opt->tot_len = sizeof(struct ipv6_txoptions);
819 819
820 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, 820 err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit,
821 &tclass, &dontfrag); 821 &tclass, &dontfrag);
822 if (err < 0) { 822 if (err < 0) {
823 fl6_sock_release(flowlabel); 823 fl6_sock_release(flowlabel);
824 return err; 824 return err;
825 } 825 }
826 if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { 826 if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
827 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); 827 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
828 if (flowlabel == NULL) 828 if (flowlabel == NULL)
829 return -EINVAL; 829 return -EINVAL;
830 } 830 }
@@ -837,40 +837,31 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
837 opt = fl6_merge_options(&opt_space, flowlabel, opt); 837 opt = fl6_merge_options(&opt_space, flowlabel, opt);
838 opt = ipv6_fixup_options(&opt_space, opt); 838 opt = ipv6_fixup_options(&opt_space, opt);
839 839
840 fl.proto = proto; 840 fl6.flowi6_proto = proto;
841 err = rawv6_probe_proto_opt(&fl, msg); 841 err = rawv6_probe_proto_opt(&fl6, msg);
842 if (err) 842 if (err)
843 goto out; 843 goto out;
844 844
845 if (!ipv6_addr_any(daddr)) 845 if (!ipv6_addr_any(daddr))
846 ipv6_addr_copy(&fl.fl6_dst, daddr); 846 ipv6_addr_copy(&fl6.daddr, daddr);
847 else 847 else
848 fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ 848 fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
849 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 849 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
850 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 850 ipv6_addr_copy(&fl6.saddr, &np->saddr);
851 851
852 final_p = fl6_update_dst(&fl, opt, &final); 852 final_p = fl6_update_dst(&fl6, opt, &final);
853 853
854 if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) 854 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
855 fl.oif = np->mcast_oif; 855 fl6.flowi6_oif = np->mcast_oif;
856 security_sk_classify_flow(sk, &fl); 856 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
857 857
858 err = ip6_dst_lookup(sk, &dst, &fl); 858 dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
859 if (err) 859 if (IS_ERR(dst)) {
860 err = PTR_ERR(dst);
860 goto out; 861 goto out;
861 if (final_p)
862 ipv6_addr_copy(&fl.fl6_dst, final_p);
863
864 err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
865 if (err < 0) {
866 if (err == -EREMOTE)
867 err = ip6_dst_blackhole(sk, &dst, &fl);
868 if (err < 0)
869 goto out;
870 } 862 }
871
872 if (hlimit < 0) { 863 if (hlimit < 0) {
873 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 864 if (ipv6_addr_is_multicast(&fl6.daddr))
874 hlimit = np->mcast_hops; 865 hlimit = np->mcast_hops;
875 else 866 else
876 hlimit = np->hop_limit; 867 hlimit = np->hop_limit;
@@ -889,17 +880,17 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
889 880
890back_from_confirm: 881back_from_confirm:
891 if (inet->hdrincl) 882 if (inet->hdrincl)
892 err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl, &dst, msg->msg_flags); 883 err = rawv6_send_hdrinc(sk, msg->msg_iov, len, &fl6, &dst, msg->msg_flags);
893 else { 884 else {
894 lock_sock(sk); 885 lock_sock(sk);
895 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, 886 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov,
896 len, 0, hlimit, tclass, opt, &fl, (struct rt6_info*)dst, 887 len, 0, hlimit, tclass, opt, &fl6, (struct rt6_info*)dst,
897 msg->msg_flags, dontfrag); 888 msg->msg_flags, dontfrag);
898 889
899 if (err) 890 if (err)
900 ip6_flush_pending_frames(sk); 891 ip6_flush_pending_frames(sk);
901 else if (!(msg->msg_flags & MSG_MORE)) 892 else if (!(msg->msg_flags & MSG_MORE))
902 err = rawv6_push_pending_frames(sk, &fl, rp); 893 err = rawv6_push_pending_frames(sk, &fl6, rp);
903 release_sock(sk); 894 release_sock(sk);
904 } 895 }
905done: 896done:
@@ -985,7 +976,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
985 /* You may get strange result with a positive odd offset; 976 /* You may get strange result with a positive odd offset;
986 RFC2292bis agrees with me. */ 977 RFC2292bis agrees with me. */
987 if (val > 0 && (val&1)) 978 if (val > 0 && (val&1))
988 return(-EINVAL); 979 return -EINVAL;
989 if (val < 0) { 980 if (val < 0) {
990 rp->checksum = 0; 981 rp->checksum = 0;
991 } else { 982 } else {
@@ -997,7 +988,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
997 break; 988 break;
998 989
999 default: 990 default:
1000 return(-ENOPROTOOPT); 991 return -ENOPROTOOPT;
1001 } 992 }
1002} 993}
1003 994
@@ -1157,6 +1148,23 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
1157 } 1148 }
1158} 1149}
1159 1150
1151#ifdef CONFIG_COMPAT
1152static int compat_rawv6_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
1153{
1154 switch (cmd) {
1155 case SIOCOUTQ:
1156 case SIOCINQ:
1157 return -ENOIOCTLCMD;
1158 default:
1159#ifdef CONFIG_IPV6_MROUTE
1160 return ip6mr_compat_ioctl(sk, cmd, compat_ptr(arg));
1161#else
1162 return -ENOIOCTLCMD;
1163#endif
1164 }
1165}
1166#endif
1167
1160static void rawv6_close(struct sock *sk, long timeout) 1168static void rawv6_close(struct sock *sk, long timeout)
1161{ 1169{
1162 if (inet_sk(sk)->inet_num == IPPROTO_RAW) 1170 if (inet_sk(sk)->inet_num == IPPROTO_RAW)
@@ -1190,7 +1198,7 @@ static int rawv6_init_sk(struct sock *sk)
1190 default: 1198 default:
1191 break; 1199 break;
1192 } 1200 }
1193 return(0); 1201 return 0;
1194} 1202}
1195 1203
1196struct proto rawv6_prot = { 1204struct proto rawv6_prot = {
@@ -1215,6 +1223,7 @@ struct proto rawv6_prot = {
1215#ifdef CONFIG_COMPAT 1223#ifdef CONFIG_COMPAT
1216 .compat_setsockopt = compat_rawv6_setsockopt, 1224 .compat_setsockopt = compat_rawv6_setsockopt,
1217 .compat_getsockopt = compat_rawv6_getsockopt, 1225 .compat_getsockopt = compat_rawv6_getsockopt,
1226 .compat_ioctl = compat_rawv6_ioctl,
1218#endif 1227#endif
1219}; 1228};
1220 1229
@@ -1222,7 +1231,7 @@ struct proto rawv6_prot = {
1222static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) 1231static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
1223{ 1232{
1224 struct ipv6_pinfo *np = inet6_sk(sp); 1233 struct ipv6_pinfo *np = inet6_sk(sp);
1225 struct in6_addr *dest, *src; 1234 const struct in6_addr *dest, *src;
1226 __u16 destp, srcp; 1235 __u16 destp, srcp;
1227 1236
1228 dest = &np->daddr; 1237 dest = &np->daddr;
@@ -1231,7 +1240,7 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
1231 srcp = inet_sk(sp)->inet_num; 1240 srcp = inet_sk(sp)->inet_num;
1232 seq_printf(seq, 1241 seq_printf(seq,
1233 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " 1242 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1234 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", 1243 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
1235 i, 1244 i,
1236 src->s6_addr32[0], src->s6_addr32[1], 1245 src->s6_addr32[0], src->s6_addr32[1],
1237 src->s6_addr32[2], src->s6_addr32[3], srcp, 1246 src->s6_addr32[2], src->s6_addr32[3], srcp,