X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv6%2Fraw.c;fp=net%2Fipv6%2Fraw.c;h=ae20a0ec9bd8254f2e85d43fad57ac7ebafdd30a;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=15b862d8acabc621edde195034cb2b9e72737bfd;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 15b862d8a..ae20a0ec9 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -411,7 +411,6 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, /* Copy the address. */ if (sin6) { sin6->sin6_family = AF_INET6; - sin6->sin6_port = 0; ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr); sin6->sin6_flowinfo = 0; sin6->sin6_scope_id = 0; @@ -781,7 +780,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, } if (tclass < 0) { - tclass = np->tclass; + tclass = np->cork.tclass; if (tclass < 0) tclass = 0; } @@ -860,12 +859,29 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname, } -static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, +static int rawv6_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen) { struct raw6_sock *rp = raw6_sk(sk); int val; + switch(level) { + case SOL_RAW: + break; + + case SOL_ICMPV6: + if (inet_sk(sk)->num != IPPROTO_ICMPV6) + return -EOPNOTSUPP; + return rawv6_seticmpfilter(sk, level, optname, optval, + optlen); + case SOL_IPV6: + if (optname == IPV6_CHECKSUM) + break; + default: + return ipv6_setsockopt(sk, level, optname, optval, + optlen); + }; + if (get_user(val, (int __user *)optval)) return -EFAULT; @@ -890,9 +906,12 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, } } -static int rawv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) +static int rawv6_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *optlen) { + struct raw6_sock *rp = raw6_sk(sk); + int val, len; + switch(level) { case SOL_RAW: break; @@ -900,45 +919,15 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname, case SOL_ICMPV6: if (inet_sk(sk)->num != IPPROTO_ICMPV6) return -EOPNOTSUPP; - return rawv6_seticmpfilter(sk, level, optname, optval, + return rawv6_geticmpfilter(sk, level, optname, optval, optlen); case SOL_IPV6: if (optname == IPV6_CHECKSUM) break; default: - return ipv6_setsockopt(sk, level, optname, optval, + return ipv6_getsockopt(sk, level, optname, optval, optlen); }; - return do_rawv6_setsockopt(sk, level, optname, optval, optlen); -} - -#ifdef CONFIG_COMPAT -static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname, - char __user *optval, int optlen) -{ - switch (level) { - case SOL_RAW: - break; - case SOL_ICMPV6: - if (inet_sk(sk)->num != IPPROTO_ICMPV6) - return -EOPNOTSUPP; - return rawv6_seticmpfilter(sk, level, optname, optval, optlen); - case SOL_IPV6: - if (optname == IPV6_CHECKSUM) - break; - default: - return compat_ipv6_setsockopt(sk, level, optname, - optval, optlen); - }; - return do_rawv6_setsockopt(sk, level, optname, optval, optlen); -} -#endif - -static int do_rawv6_getsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user *optlen) -{ - struct raw6_sock *rp = raw6_sk(sk); - int val, len; if (get_user(len,optlen)) return -EFAULT; @@ -964,50 +953,6 @@ static int do_rawv6_getsockopt(struct sock *sk, int level, int optname, return 0; } -static int rawv6_getsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user *optlen) -{ - switch(level) { - case SOL_RAW: - break; - - case SOL_ICMPV6: - if (inet_sk(sk)->num != IPPROTO_ICMPV6) - return -EOPNOTSUPP; - return rawv6_geticmpfilter(sk, level, optname, optval, - optlen); - case SOL_IPV6: - if (optname == IPV6_CHECKSUM) - break; - default: - return ipv6_getsockopt(sk, level, optname, optval, - optlen); - }; - return do_rawv6_getsockopt(sk, level, optname, optval, optlen); -} - -#ifdef CONFIG_COMPAT -static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user *optlen) -{ - switch (level) { - case SOL_RAW: - break; - case SOL_ICMPV6: - if (inet_sk(sk)->num != IPPROTO_ICMPV6) - return -EOPNOTSUPP; - return rawv6_geticmpfilter(sk, level, optname, optval, optlen); - case SOL_IPV6: - if (optname == IPV6_CHECKSUM) - break; - default: - return compat_ipv6_getsockopt(sk, level, optname, - optval, optlen); - }; - return do_rawv6_getsockopt(sk, level, optname, optval, optlen); -} -#endif - static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) { switch(cmd) { @@ -1053,27 +998,23 @@ static int rawv6_init_sk(struct sock *sk) } struct proto rawv6_prot = { - .name = "RAWv6", - .owner = THIS_MODULE, - .close = rawv6_close, - .connect = ip6_datagram_connect, - .disconnect = udp_disconnect, - .ioctl = rawv6_ioctl, - .init = rawv6_init_sk, - .destroy = inet6_destroy_sock, - .setsockopt = rawv6_setsockopt, - .getsockopt = rawv6_getsockopt, - .sendmsg = rawv6_sendmsg, - .recvmsg = rawv6_recvmsg, - .bind = rawv6_bind, - .backlog_rcv = rawv6_rcv_skb, - .hash = raw_v6_hash, - .unhash = raw_v6_unhash, - .obj_size = sizeof(struct raw6_sock), -#ifdef CONFIG_COMPAT - .compat_setsockopt = compat_rawv6_setsockopt, - .compat_getsockopt = compat_rawv6_getsockopt, -#endif + .name = "RAWv6", + .owner = THIS_MODULE, + .close = rawv6_close, + .connect = ip6_datagram_connect, + .disconnect = udp_disconnect, + .ioctl = rawv6_ioctl, + .init = rawv6_init_sk, + .destroy = inet6_destroy_sock, + .setsockopt = rawv6_setsockopt, + .getsockopt = rawv6_getsockopt, + .sendmsg = rawv6_sendmsg, + .recvmsg = rawv6_recvmsg, + .bind = rawv6_bind, + .backlog_rcv = rawv6_rcv_skb, + .hash = raw_v6_hash, + .unhash = raw_v6_unhash, + .obj_size = sizeof(struct raw6_sock), }; #ifdef CONFIG_PROC_FS @@ -1199,7 +1140,7 @@ static int raw6_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct raw6_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct raw6_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; rc = seq_open(file, &raw6_seq_ops); @@ -1207,6 +1148,7 @@ static int raw6_seq_open(struct inode *inode, struct file *file) goto out_kfree; seq = file->private_data; seq->private = s; + memset(s, 0, sizeof(*s)); out: return rc; out_kfree: