diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
| -rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
| -rw-r--r-- | net/ipv6/datagram.c | 5 | ||||
| -rw-r--r-- | net/ipv6/exthdrs.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ip6_input.c | 9 | ||||
| -rw-r--r-- | net/ipv6/ipv6_sockglue.c | 23 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6table_mangle.c | 2 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 3 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 4 | ||||
| -rw-r--r-- | net/ipv6/reassembly.c | 2 | ||||
| -rw-r--r-- | net/ipv6/route.c | 14 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 44 | ||||
| -rw-r--r-- | net/ipv6/syncookies.c | 1 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 7 |
14 files changed, 76 insertions, 46 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 147588f4c7c0..ff61a5cdb0b3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -749,12 +749,12 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
| 749 | } | 749 | } |
| 750 | write_unlock_bh(&idev->lock); | 750 | write_unlock_bh(&idev->lock); |
| 751 | 751 | ||
| 752 | addrconf_del_timer(ifp); | ||
| 753 | |||
| 752 | ipv6_ifa_notify(RTM_DELADDR, ifp); | 754 | ipv6_ifa_notify(RTM_DELADDR, ifp); |
| 753 | 755 | ||
| 754 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); | 756 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); |
| 755 | 757 | ||
| 756 | addrconf_del_timer(ifp); | ||
| 757 | |||
| 758 | /* | 758 | /* |
| 759 | * Purge or update corresponding prefix | 759 | * Purge or update corresponding prefix |
| 760 | * | 760 | * |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3c6aafb02183..e84b3fd17fb4 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -191,7 +191,7 @@ lookup_protocol: | |||
| 191 | np->mcast_hops = -1; | 191 | np->mcast_hops = -1; |
| 192 | np->mc_loop = 1; | 192 | np->mc_loop = 1; |
| 193 | np->pmtudisc = IPV6_PMTUDISC_WANT; | 193 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
| 194 | np->ipv6only = init_net.ipv6.sysctl.bindv6only; | 194 | np->ipv6only = net->ipv6.sysctl.bindv6only; |
| 195 | 195 | ||
| 196 | /* Init the ipv4 part of the socket since we can have sockets | 196 | /* Init the ipv4 part of the socket since we can have sockets |
| 197 | * using v6 API for ipv4. | 197 | * using v6 API for ipv4. |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index b9c2de84a8a2..0f0f94a40335 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -705,6 +705,11 @@ int datagram_send_ctl(struct net *net, | |||
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | *hlimit = *(int *)CMSG_DATA(cmsg); | 707 | *hlimit = *(int *)CMSG_DATA(cmsg); |
| 708 | if (*hlimit < -1 || *hlimit > 0xff) { | ||
| 709 | err = -EINVAL; | ||
| 710 | goto exit_f; | ||
| 711 | } | ||
| 712 | |||
| 708 | break; | 713 | break; |
| 709 | 714 | ||
| 710 | case IPV6_TCLASS: | 715 | case IPV6_TCLASS: |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 3cd1c993d52b..dcf94fdfb863 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
| @@ -445,7 +445,7 @@ looped_back: | |||
| 445 | kfree_skb(skb); | 445 | kfree_skb(skb); |
| 446 | return -1; | 446 | return -1; |
| 447 | } | 447 | } |
| 448 | if (!ipv6_chk_home_addr(&init_net, addr)) { | 448 | if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) { |
| 449 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 449 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), |
| 450 | IPSTATS_MIB_INADDRERRORS); | 450 | IPSTATS_MIB_INADDRERRORS); |
| 451 | kfree_skb(skb); | 451 | kfree_skb(skb); |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 4e5c8615832c..17eb48b8e329 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
| @@ -102,6 +102,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
| 102 | if (hdr->version != 6) | 102 | if (hdr->version != 6) |
| 103 | goto err; | 103 | goto err; |
| 104 | 104 | ||
| 105 | /* | ||
| 106 | * RFC4291 2.5.3 | ||
| 107 | * A packet received on an interface with a destination address | ||
| 108 | * of loopback must be dropped. | ||
| 109 | */ | ||
| 110 | if (!(dev->flags & IFF_LOOPBACK) && | ||
| 111 | ipv6_addr_loopback(&hdr->daddr)) | ||
| 112 | goto err; | ||
| 113 | |||
| 105 | skb->transport_header = skb->network_header + sizeof(*hdr); | 114 | skb->transport_header = skb->network_header + sizeof(*hdr); |
| 106 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); | 115 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); |
| 107 | 116 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 26b83e512a09..86e28a75267f 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -67,7 +67,7 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) | |||
| 67 | 67 | ||
| 68 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ | 68 | /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ |
| 69 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) | 69 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) |
| 70 | return -EINVAL; | 70 | return -ENOPROTOOPT; |
| 71 | 71 | ||
| 72 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 72 | new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
| 73 | 73 | ||
| @@ -345,18 +345,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
| 345 | case IPV6_DSTOPTS: | 345 | case IPV6_DSTOPTS: |
| 346 | { | 346 | { |
| 347 | struct ipv6_txoptions *opt; | 347 | struct ipv6_txoptions *opt; |
| 348 | |||
| 349 | /* remove any sticky options header with a zero option | ||
| 350 | * length, per RFC3542. | ||
| 351 | */ | ||
| 348 | if (optlen == 0) | 352 | if (optlen == 0) |
| 349 | optval = NULL; | 353 | optval = NULL; |
| 354 | else if (optlen < sizeof(struct ipv6_opt_hdr) || | ||
| 355 | optlen & 0x7 || optlen > 8 * 255) | ||
| 356 | goto e_inval; | ||
| 350 | 357 | ||
| 351 | /* hop-by-hop / destination options are privileged option */ | 358 | /* hop-by-hop / destination options are privileged option */ |
| 352 | retv = -EPERM; | 359 | retv = -EPERM; |
| 353 | if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) | 360 | if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) |
| 354 | break; | 361 | break; |
| 355 | 362 | ||
| 356 | if (optlen < sizeof(struct ipv6_opt_hdr) || | ||
| 357 | optlen & 0x7 || optlen > 8 * 255) | ||
| 358 | goto e_inval; | ||
| 359 | |||
| 360 | opt = ipv6_renew_options(sk, np->opt, optname, | 363 | opt = ipv6_renew_options(sk, np->opt, optname, |
| 361 | (struct ipv6_opt_hdr __user *)optval, | 364 | (struct ipv6_opt_hdr __user *)optval, |
| 362 | optlen); | 365 | optlen); |
| @@ -446,7 +449,7 @@ done: | |||
| 446 | 449 | ||
| 447 | case IPV6_MULTICAST_HOPS: | 450 | case IPV6_MULTICAST_HOPS: |
| 448 | if (sk->sk_type == SOCK_STREAM) | 451 | if (sk->sk_type == SOCK_STREAM) |
| 449 | goto e_inval; | 452 | break; |
| 450 | if (optlen < sizeof(int)) | 453 | if (optlen < sizeof(int)) |
| 451 | goto e_inval; | 454 | goto e_inval; |
| 452 | if (val > 255 || val < -1) | 455 | if (val > 255 || val < -1) |
| @@ -458,13 +461,15 @@ done: | |||
| 458 | case IPV6_MULTICAST_LOOP: | 461 | case IPV6_MULTICAST_LOOP: |
| 459 | if (optlen < sizeof(int)) | 462 | if (optlen < sizeof(int)) |
| 460 | goto e_inval; | 463 | goto e_inval; |
| 464 | if (val != valbool) | ||
| 465 | goto e_inval; | ||
| 461 | np->mc_loop = valbool; | 466 | np->mc_loop = valbool; |
| 462 | retv = 0; | 467 | retv = 0; |
| 463 | break; | 468 | break; |
| 464 | 469 | ||
| 465 | case IPV6_MULTICAST_IF: | 470 | case IPV6_MULTICAST_IF: |
| 466 | if (sk->sk_type == SOCK_STREAM) | 471 | if (sk->sk_type == SOCK_STREAM) |
| 467 | goto e_inval; | 472 | break; |
| 468 | if (optlen < sizeof(int)) | 473 | if (optlen < sizeof(int)) |
| 469 | goto e_inval; | 474 | goto e_inval; |
| 470 | 475 | ||
| @@ -860,7 +865,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
| 860 | if (sk->sk_protocol != IPPROTO_UDP && | 865 | if (sk->sk_protocol != IPPROTO_UDP && |
| 861 | sk->sk_protocol != IPPROTO_UDPLITE && | 866 | sk->sk_protocol != IPPROTO_UDPLITE && |
| 862 | sk->sk_protocol != IPPROTO_TCP) | 867 | sk->sk_protocol != IPPROTO_TCP) |
| 863 | return -EINVAL; | 868 | return -ENOPROTOOPT; |
| 864 | if (sk->sk_state != TCP_ESTABLISHED) | 869 | if (sk->sk_state != TCP_ESTABLISHED) |
| 865 | return -ENOTCONN; | 870 | return -ENOTCONN; |
| 866 | val = sk->sk_family; | 871 | val = sk->sk_family; |
| @@ -874,6 +879,8 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
| 874 | return -EINVAL; | 879 | return -EINVAL; |
| 875 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) | 880 | if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) |
| 876 | return -EFAULT; | 881 | return -EFAULT; |
| 882 | if (gsf.gf_group.ss_family != AF_INET6) | ||
| 883 | return -EADDRNOTAVAIL; | ||
| 877 | lock_sock(sk); | 884 | lock_sock(sk); |
| 878 | err = ip6_mc_msfget(sk, &gsf, | 885 | err = ip6_mc_msfget(sk, &gsf, |
| 879 | (struct group_filter __user *)optval, optlen); | 886 | (struct group_filter __user *)optval, optlen); |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 27a5e8b48d93..f405cea21a8b 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
| @@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = { | |||
| 129 | .priority = NF_IP6_PRI_MANGLE, | 129 | .priority = NF_IP6_PRI_MANGLE, |
| 130 | }, | 130 | }, |
| 131 | { | 131 | { |
| 132 | .hook = ip6t_local_hook, | 132 | .hook = ip6t_route_hook, |
| 133 | .owner = THIS_MODULE, | 133 | .owner = THIS_MODULE, |
| 134 | .pf = PF_INET6, | 134 | .pf = PF_INET6, |
| 135 | .hooknum = NF_INET_LOCAL_IN, | 135 | .hooknum = NF_INET_LOCAL_IN, |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index e65e26e210ee..cf20bc4fd60d 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -207,9 +207,10 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) | |||
| 207 | arg.id = id; | 207 | arg.id = id; |
| 208 | arg.src = src; | 208 | arg.src = src; |
| 209 | arg.dst = dst; | 209 | arg.dst = dst; |
| 210 | |||
| 211 | read_lock_bh(&nf_frags.lock); | ||
| 210 | hash = ip6qhashfn(id, src, dst); | 212 | hash = ip6qhashfn(id, src, dst); |
| 211 | 213 | ||
| 212 | local_bh_disable(); | ||
| 213 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); | 214 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); |
| 214 | local_bh_enable(); | 215 | local_bh_enable(); |
| 215 | if (q == NULL) | 216 | if (q == NULL) |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 8fee9a15b2d3..3aee12310d94 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -1169,7 +1169,8 @@ static int raw6_destroy(struct sock *sk) | |||
| 1169 | lock_sock(sk); | 1169 | lock_sock(sk); |
| 1170 | ip6_flush_pending_frames(sk); | 1170 | ip6_flush_pending_frames(sk); |
| 1171 | release_sock(sk); | 1171 | release_sock(sk); |
| 1172 | return 0; | 1172 | |
| 1173 | return inet6_destroy_sock(sk); | ||
| 1173 | } | 1174 | } |
| 1174 | 1175 | ||
| 1175 | static int rawv6_init_sk(struct sock *sk) | 1176 | static int rawv6_init_sk(struct sock *sk) |
| @@ -1200,7 +1201,6 @@ struct proto rawv6_prot = { | |||
| 1200 | .disconnect = udp_disconnect, | 1201 | .disconnect = udp_disconnect, |
| 1201 | .ioctl = rawv6_ioctl, | 1202 | .ioctl = rawv6_ioctl, |
| 1202 | .init = rawv6_init_sk, | 1203 | .init = rawv6_init_sk, |
| 1203 | .destroy = inet6_destroy_sock, | ||
| 1204 | .setsockopt = rawv6_setsockopt, | 1204 | .setsockopt = rawv6_setsockopt, |
| 1205 | .getsockopt = rawv6_getsockopt, | 1205 | .getsockopt = rawv6_getsockopt, |
| 1206 | .sendmsg = rawv6_sendmsg, | 1206 | .sendmsg = rawv6_sendmsg, |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 798cabc7535b..a60d7d129713 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
| @@ -247,6 +247,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, | |||
| 247 | arg.id = id; | 247 | arg.id = id; |
| 248 | arg.src = src; | 248 | arg.src = src; |
| 249 | arg.dst = dst; | 249 | arg.dst = dst; |
| 250 | |||
| 251 | read_lock(&ip6_frags.lock); | ||
| 250 | hash = ip6qhashfn(id, src, dst); | 252 | hash = ip6qhashfn(id, src, dst); |
| 251 | 253 | ||
| 252 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); | 254 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 220cffe9e63b..7ff687020fa9 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -240,7 +240,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr) | |||
| 240 | static inline struct rt6_info *rt6_device_match(struct net *net, | 240 | static inline struct rt6_info *rt6_device_match(struct net *net, |
| 241 | struct rt6_info *rt, | 241 | struct rt6_info *rt, |
| 242 | int oif, | 242 | int oif, |
| 243 | int strict) | 243 | int flags) |
| 244 | { | 244 | { |
| 245 | struct rt6_info *local = NULL; | 245 | struct rt6_info *local = NULL; |
| 246 | struct rt6_info *sprt; | 246 | struct rt6_info *sprt; |
| @@ -253,7 +253,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
| 253 | if (dev->flags & IFF_LOOPBACK) { | 253 | if (dev->flags & IFF_LOOPBACK) { |
| 254 | if (sprt->rt6i_idev == NULL || | 254 | if (sprt->rt6i_idev == NULL || |
| 255 | sprt->rt6i_idev->dev->ifindex != oif) { | 255 | sprt->rt6i_idev->dev->ifindex != oif) { |
| 256 | if (strict && oif) | 256 | if (flags & RT6_LOOKUP_F_IFACE && oif) |
| 257 | continue; | 257 | continue; |
| 258 | if (local && (!oif || | 258 | if (local && (!oif || |
| 259 | local->rt6i_idev->dev->ifindex == oif)) | 259 | local->rt6i_idev->dev->ifindex == oif)) |
| @@ -266,7 +266,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
| 266 | if (local) | 266 | if (local) |
| 267 | return local; | 267 | return local; |
| 268 | 268 | ||
| 269 | if (strict) | 269 | if (flags & RT6_LOOKUP_F_IFACE) |
| 270 | return net->ipv6.ip6_null_entry; | 270 | return net->ipv6.ip6_null_entry; |
| 271 | } | 271 | } |
| 272 | return rt; | 272 | return rt; |
| @@ -2196,8 +2196,12 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
| 2196 | 2196 | ||
| 2197 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); | 2197 | NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); |
| 2198 | 2198 | ||
| 2199 | expires = (rt->rt6i_flags & RTF_EXPIRES) ? | 2199 | if (!(rt->rt6i_flags & RTF_EXPIRES)) |
| 2200 | rt->rt6i_expires - jiffies : 0; | 2200 | expires = 0; |
| 2201 | else if (rt->rt6i_expires - jiffies < INT_MAX) | ||
| 2202 | expires = rt->rt6i_expires - jiffies; | ||
| 2203 | else | ||
| 2204 | expires = INT_MAX; | ||
| 2201 | 2205 | ||
| 2202 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, | 2206 | if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, |
| 2203 | expires, rt->u.dst.error) < 0) | 2207 | expires, rt->u.dst.error) < 0) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 3de6ffdaedf2..32e871a6c25a 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -222,15 +222,18 @@ __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) | |||
| 222 | 222 | ||
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | static int ipip6_tunnel_get_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) | 225 | static int ipip6_tunnel_get_prl(struct ip_tunnel *t, |
| 226 | struct ip_tunnel_prl __user *a) | ||
| 226 | { | 227 | { |
| 227 | struct ip_tunnel_prl *kp; | 228 | struct ip_tunnel_prl kprl, *kp; |
| 228 | struct ip_tunnel_prl_entry *prl; | 229 | struct ip_tunnel_prl_entry *prl; |
| 229 | unsigned int cmax, c = 0, ca, len; | 230 | unsigned int cmax, c = 0, ca, len; |
| 230 | int ret = 0; | 231 | int ret = 0; |
| 231 | 232 | ||
| 232 | cmax = a->datalen / sizeof(*a); | 233 | if (copy_from_user(&kprl, a, sizeof(kprl))) |
| 233 | if (cmax > 1 && a->addr != htonl(INADDR_ANY)) | 234 | return -EFAULT; |
| 235 | cmax = kprl.datalen / sizeof(kprl); | ||
| 236 | if (cmax > 1 && kprl.addr != htonl(INADDR_ANY)) | ||
| 234 | cmax = 1; | 237 | cmax = 1; |
| 235 | 238 | ||
| 236 | /* For simple GET or for root users, | 239 | /* For simple GET or for root users, |
| @@ -261,26 +264,25 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) | |||
| 261 | for (prl = t->prl; prl; prl = prl->next) { | 264 | for (prl = t->prl; prl; prl = prl->next) { |
| 262 | if (c > cmax) | 265 | if (c > cmax) |
| 263 | break; | 266 | break; |
| 264 | if (a->addr != htonl(INADDR_ANY) && prl->addr != a->addr) | 267 | if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) |
| 265 | continue; | 268 | continue; |
| 266 | kp[c].addr = prl->addr; | 269 | kp[c].addr = prl->addr; |
| 267 | kp[c].flags = prl->flags; | 270 | kp[c].flags = prl->flags; |
| 268 | c++; | 271 | c++; |
| 269 | if (a->addr != htonl(INADDR_ANY)) | 272 | if (kprl.addr != htonl(INADDR_ANY)) |
| 270 | break; | 273 | break; |
| 271 | } | 274 | } |
| 272 | out: | 275 | out: |
| 273 | read_unlock(&ipip6_lock); | 276 | read_unlock(&ipip6_lock); |
| 274 | 277 | ||
| 275 | len = sizeof(*kp) * c; | 278 | len = sizeof(*kp) * c; |
| 276 | ret = len ? copy_to_user(a->data, kp, len) : 0; | 279 | ret = 0; |
| 280 | if ((len && copy_to_user(a + 1, kp, len)) || put_user(len, &a->datalen)) | ||
| 281 | ret = -EFAULT; | ||
| 277 | 282 | ||
| 278 | kfree(kp); | 283 | kfree(kp); |
| 279 | if (ret) | ||
| 280 | return -EFAULT; | ||
| 281 | 284 | ||
| 282 | a->datalen = len; | 285 | return ret; |
| 283 | return 0; | ||
| 284 | } | 286 | } |
| 285 | 287 | ||
| 286 | static int | 288 | static int |
| @@ -873,11 +875,20 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 873 | break; | 875 | break; |
| 874 | 876 | ||
| 875 | case SIOCGETPRL: | 877 | case SIOCGETPRL: |
| 878 | err = -EINVAL; | ||
| 879 | if (dev == sitn->fb_tunnel_dev) | ||
| 880 | goto done; | ||
| 881 | err = -ENOENT; | ||
| 882 | if (!(t = netdev_priv(dev))) | ||
| 883 | goto done; | ||
| 884 | err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); | ||
| 885 | break; | ||
| 886 | |||
| 876 | case SIOCADDPRL: | 887 | case SIOCADDPRL: |
| 877 | case SIOCDELPRL: | 888 | case SIOCDELPRL: |
| 878 | case SIOCCHGPRL: | 889 | case SIOCCHGPRL: |
| 879 | err = -EPERM; | 890 | err = -EPERM; |
| 880 | if (cmd != SIOCGETPRL && !capable(CAP_NET_ADMIN)) | 891 | if (!capable(CAP_NET_ADMIN)) |
| 881 | goto done; | 892 | goto done; |
| 882 | err = -EINVAL; | 893 | err = -EINVAL; |
| 883 | if (dev == sitn->fb_tunnel_dev) | 894 | if (dev == sitn->fb_tunnel_dev) |
| @@ -890,12 +901,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 890 | goto done; | 901 | goto done; |
| 891 | 902 | ||
| 892 | switch (cmd) { | 903 | switch (cmd) { |
| 893 | case SIOCGETPRL: | ||
| 894 | err = ipip6_tunnel_get_prl(t, &prl); | ||
| 895 | if (!err && copy_to_user(ifr->ifr_ifru.ifru_data, | ||
| 896 | &prl, sizeof(prl))) | ||
| 897 | err = -EFAULT; | ||
| 898 | break; | ||
| 899 | case SIOCDELPRL: | 904 | case SIOCDELPRL: |
| 900 | err = ipip6_tunnel_del_prl(t, &prl); | 905 | err = ipip6_tunnel_del_prl(t, &prl); |
| 901 | break; | 906 | break; |
| @@ -904,8 +909,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 904 | err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); | 909 | err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); |
| 905 | break; | 910 | break; |
| 906 | } | 911 | } |
| 907 | if (cmd != SIOCGETPRL) | 912 | netdev_state_change(dev); |
| 908 | netdev_state_change(dev); | ||
| 909 | break; | 913 | break; |
| 910 | 914 | ||
| 911 | default: | 915 | default: |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 938ce4ecde55..3ecc1157994e 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
| @@ -198,7 +198,6 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
| 198 | ireq = inet_rsk(req); | 198 | ireq = inet_rsk(req); |
| 199 | ireq6 = inet6_rsk(req); | 199 | ireq6 = inet6_rsk(req); |
| 200 | treq = tcp_rsk(req); | 200 | treq = tcp_rsk(req); |
| 201 | ireq6->pktopts = NULL; | ||
| 202 | 201 | ||
| 203 | if (security_inet_conn_request(sk, skb, req)) { | 202 | if (security_inet_conn_request(sk, skb, req)) { |
| 204 | reqsk_free(req); | 203 | reqsk_free(req); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 715965f0fac0..40ea9c36d24b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1299,7 +1299,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
| 1299 | treq = inet6_rsk(req); | 1299 | treq = inet6_rsk(req); |
| 1300 | ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); | 1300 | ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); |
| 1301 | ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); | 1301 | ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); |
| 1302 | treq->pktopts = NULL; | ||
| 1303 | if (!want_cookie) | 1302 | if (!want_cookie) |
| 1304 | TCP_ECN_create_request(req, tcp_hdr(skb)); | 1303 | TCP_ECN_create_request(req, tcp_hdr(skb)); |
| 1305 | 1304 | ||
| @@ -2037,7 +2036,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
| 2037 | 2036 | ||
| 2038 | seq_printf(seq, | 2037 | seq_printf(seq, |
| 2039 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " | 2038 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
| 2040 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n", | 2039 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n", |
| 2041 | i, | 2040 | i, |
| 2042 | src->s6_addr32[0], src->s6_addr32[1], | 2041 | src->s6_addr32[0], src->s6_addr32[1], |
| 2043 | src->s6_addr32[2], src->s6_addr32[3], srcp, | 2042 | src->s6_addr32[2], src->s6_addr32[3], srcp, |
| @@ -2053,8 +2052,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
| 2053 | icsk->icsk_probes_out, | 2052 | icsk->icsk_probes_out, |
| 2054 | sock_i_ino(sp), | 2053 | sock_i_ino(sp), |
| 2055 | atomic_read(&sp->sk_refcnt), sp, | 2054 | atomic_read(&sp->sk_refcnt), sp, |
| 2056 | icsk->icsk_rto, | 2055 | jiffies_to_clock_t(icsk->icsk_rto), |
| 2057 | icsk->icsk_ack.ato, | 2056 | jiffies_to_clock_t(icsk->icsk_ack.ato), |
| 2058 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, | 2057 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, |
| 2059 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh | 2058 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh |
| 2060 | ); | 2059 | ); |
