aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-09-03 09:28:30 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-09-03 09:34:51 -0400
commitace1fe1231bdfffd60b5e703aa5b7283fbf98dbd (patch)
tree06c7492a8f3cc65f916768616ca24c6bc7171761 /net/ipv6
parentce9f3f31efb88841e4df98794b13dbac8c4901da (diff)
parenta2dc375e12334b3d8f787a48b2fb6172ccfb80ae (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
This merges (3f509c6 netfilter: nf_nat_sip: fix incorrect handling of EBUSY for RTCP expectation) to Patrick McHardy's IPv6 NAT changes.
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c35
-rw-r--r--net/ipv6/ip6_flowlabel.c47
-rw-r--r--net/ipv6/raw.c3
-rw-r--r--net/ipv6/syncookies.c1
-rw-r--r--net/ipv6/tcp_ipv6.c11
-rw-r--r--net/ipv6/udp.c3
6 files changed, 59 insertions, 41 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 19d4bffda9d7..572cb660837b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -127,8 +127,8 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
127#endif 127#endif
128 128
129#ifdef CONFIG_IPV6_PRIVACY 129#ifdef CONFIG_IPV6_PRIVACY
130static int __ipv6_regen_rndid(struct inet6_dev *idev); 130static void __ipv6_regen_rndid(struct inet6_dev *idev);
131static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); 131static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr);
132static void ipv6_regen_rndid(unsigned long data); 132static void ipv6_regen_rndid(unsigned long data);
133#endif 133#endif
134 134
@@ -852,16 +852,7 @@ retry:
852 } 852 }
853 in6_ifa_hold(ifp); 853 in6_ifa_hold(ifp);
854 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8); 854 memcpy(addr.s6_addr, ifp->addr.s6_addr, 8);
855 if (__ipv6_try_regen_rndid(idev, tmpaddr) < 0) { 855 __ipv6_try_regen_rndid(idev, tmpaddr);
856 spin_unlock_bh(&ifp->lock);
857 write_unlock(&idev->lock);
858 pr_warn("%s: regeneration of randomized interface id failed\n",
859 __func__);
860 in6_ifa_put(ifp);
861 in6_dev_put(idev);
862 ret = -1;
863 goto out;
864 }
865 memcpy(&addr.s6_addr[8], idev->rndid, 8); 856 memcpy(&addr.s6_addr[8], idev->rndid, 8);
866 age = (now - ifp->tstamp) / HZ; 857 age = (now - ifp->tstamp) / HZ;
867 tmp_valid_lft = min_t(__u32, 858 tmp_valid_lft = min_t(__u32,
@@ -1600,7 +1591,7 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
1600 1591
1601#ifdef CONFIG_IPV6_PRIVACY 1592#ifdef CONFIG_IPV6_PRIVACY
1602/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */ 1593/* (re)generation of randomized interface identifier (RFC 3041 3.2, 3.5) */
1603static int __ipv6_regen_rndid(struct inet6_dev *idev) 1594static void __ipv6_regen_rndid(struct inet6_dev *idev)
1604{ 1595{
1605regen: 1596regen:
1606 get_random_bytes(idev->rndid, sizeof(idev->rndid)); 1597 get_random_bytes(idev->rndid, sizeof(idev->rndid));
@@ -1627,8 +1618,6 @@ regen:
1627 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00) 1618 if ((idev->rndid[2]|idev->rndid[3]|idev->rndid[4]|idev->rndid[5]|idev->rndid[6]|idev->rndid[7]) == 0x00)
1628 goto regen; 1619 goto regen;
1629 } 1620 }
1630
1631 return 0;
1632} 1621}
1633 1622
1634static void ipv6_regen_rndid(unsigned long data) 1623static void ipv6_regen_rndid(unsigned long data)
@@ -1642,8 +1631,7 @@ static void ipv6_regen_rndid(unsigned long data)
1642 if (idev->dead) 1631 if (idev->dead)
1643 goto out; 1632 goto out;
1644 1633
1645 if (__ipv6_regen_rndid(idev) < 0) 1634 __ipv6_regen_rndid(idev);
1646 goto out;
1647 1635
1648 expires = jiffies + 1636 expires = jiffies +
1649 idev->cnf.temp_prefered_lft * HZ - 1637 idev->cnf.temp_prefered_lft * HZ -
@@ -1664,13 +1652,10 @@ out:
1664 in6_dev_put(idev); 1652 in6_dev_put(idev);
1665} 1653}
1666 1654
1667static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) 1655static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr)
1668{ 1656{
1669 int ret = 0;
1670
1671 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0) 1657 if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
1672 ret = __ipv6_regen_rndid(idev); 1658 __ipv6_regen_rndid(idev);
1673 return ret;
1674} 1659}
1675#endif 1660#endif
1676 1661
@@ -2566,14 +2551,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2566 void *data) 2551 void *data)
2567{ 2552{
2568 struct net_device *dev = (struct net_device *) data; 2553 struct net_device *dev = (struct net_device *) data;
2569 struct inet6_dev *idev; 2554 struct inet6_dev *idev = __in6_dev_get(dev);
2570 int run_pending = 0; 2555 int run_pending = 0;
2571 int err; 2556 int err;
2572 2557
2573 if (event == NETDEV_UNREGISTER_FINAL)
2574 return NOTIFY_DONE;
2575
2576 idev = __in6_dev_get(dev);
2577 switch (event) { 2558 switch (event) {
2578 case NETDEV_REGISTER: 2559 case NETDEV_REGISTER:
2579 if (!idev && dev->mtu >= IPV6_MIN_MTU) { 2560 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 9772fbd8a3f5..90bbefb57943 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -22,6 +22,7 @@
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/pid_namespace.h>
25 26
26#include <net/net_namespace.h> 27#include <net/net_namespace.h>
27#include <net/sock.h> 28#include <net/sock.h>
@@ -91,6 +92,8 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label)
91static void fl_free(struct ip6_flowlabel *fl) 92static void fl_free(struct ip6_flowlabel *fl)
92{ 93{
93 if (fl) { 94 if (fl) {
95 if (fl->share == IPV6_FL_S_PROCESS)
96 put_pid(fl->owner.pid);
94 release_net(fl->fl_net); 97 release_net(fl->fl_net);
95 kfree(fl->opt); 98 kfree(fl->opt);
96 } 99 }
@@ -394,10 +397,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
394 case IPV6_FL_S_ANY: 397 case IPV6_FL_S_ANY:
395 break; 398 break;
396 case IPV6_FL_S_PROCESS: 399 case IPV6_FL_S_PROCESS:
397 fl->owner = current->pid; 400 fl->owner.pid = get_task_pid(current, PIDTYPE_PID);
398 break; 401 break;
399 case IPV6_FL_S_USER: 402 case IPV6_FL_S_USER:
400 fl->owner = current_euid(); 403 fl->owner.uid = current_euid();
401 break; 404 break;
402 default: 405 default:
403 err = -EINVAL; 406 err = -EINVAL;
@@ -561,7 +564,10 @@ recheck:
561 err = -EPERM; 564 err = -EPERM;
562 if (fl1->share == IPV6_FL_S_EXCL || 565 if (fl1->share == IPV6_FL_S_EXCL ||
563 fl1->share != fl->share || 566 fl1->share != fl->share ||
564 fl1->owner != fl->owner) 567 ((fl1->share == IPV6_FL_S_PROCESS) &&
568 (fl1->owner.pid == fl->owner.pid)) ||
569 ((fl1->share == IPV6_FL_S_USER) &&
570 uid_eq(fl1->owner.uid, fl->owner.uid)))
565 goto release; 571 goto release;
566 572
567 err = -EINVAL; 573 err = -EINVAL;
@@ -621,6 +627,7 @@ done:
621 627
622struct ip6fl_iter_state { 628struct ip6fl_iter_state {
623 struct seq_net_private p; 629 struct seq_net_private p;
630 struct pid_namespace *pid_ns;
624 int bucket; 631 int bucket;
625}; 632};
626 633
@@ -699,6 +706,7 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v)
699 706
700static int ip6fl_seq_show(struct seq_file *seq, void *v) 707static int ip6fl_seq_show(struct seq_file *seq, void *v)
701{ 708{
709 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
702 if (v == SEQ_START_TOKEN) 710 if (v == SEQ_START_TOKEN)
703 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", 711 seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
704 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); 712 "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
@@ -708,7 +716,11 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
708 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", 716 "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n",
709 (unsigned int)ntohl(fl->label), 717 (unsigned int)ntohl(fl->label),
710 fl->share, 718 fl->share,
711 (int)fl->owner, 719 ((fl->share == IPV6_FL_S_PROCESS) ?
720 pid_nr_ns(fl->owner.pid, state->pid_ns) :
721 ((fl->share == IPV6_FL_S_USER) ?
722 from_kuid_munged(seq_user_ns(seq), fl->owner.uid) :
723 0)),
712 atomic_read(&fl->users), 724 atomic_read(&fl->users),
713 fl->linger/HZ, 725 fl->linger/HZ,
714 (long)(fl->expires - jiffies)/HZ, 726 (long)(fl->expires - jiffies)/HZ,
@@ -727,8 +739,29 @@ static const struct seq_operations ip6fl_seq_ops = {
727 739
728static int ip6fl_seq_open(struct inode *inode, struct file *file) 740static int ip6fl_seq_open(struct inode *inode, struct file *file)
729{ 741{
730 return seq_open_net(inode, file, &ip6fl_seq_ops, 742 struct seq_file *seq;
731 sizeof(struct ip6fl_iter_state)); 743 struct ip6fl_iter_state *state;
744 int err;
745
746 err = seq_open_net(inode, file, &ip6fl_seq_ops,
747 sizeof(struct ip6fl_iter_state));
748
749 if (!err) {
750 seq = file->private_data;
751 state = ip6fl_seq_private(seq);
752 rcu_read_lock();
753 state->pid_ns = get_pid_ns(task_active_pid_ns(current));
754 rcu_read_unlock();
755 }
756 return err;
757}
758
759static int ip6fl_seq_release(struct inode *inode, struct file *file)
760{
761 struct seq_file *seq = file->private_data;
762 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
763 put_pid_ns(state->pid_ns);
764 return seq_release_net(inode, file);
732} 765}
733 766
734static const struct file_operations ip6fl_seq_fops = { 767static const struct file_operations ip6fl_seq_fops = {
@@ -736,7 +769,7 @@ static const struct file_operations ip6fl_seq_fops = {
736 .open = ip6fl_seq_open, 769 .open = ip6fl_seq_open,
737 .read = seq_read, 770 .read = seq_read,
738 .llseek = seq_lseek, 771 .llseek = seq_lseek,
739 .release = seq_release_net, 772 .release = ip6fl_seq_release,
740}; 773};
741 774
742static int __net_init ip6_flowlabel_proc_init(struct net *net) 775static int __net_init ip6_flowlabel_proc_init(struct net *net)
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ef0579d5bca6..7af88ef01657 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1251,7 +1251,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
1251 sk_wmem_alloc_get(sp), 1251 sk_wmem_alloc_get(sp),
1252 sk_rmem_alloc_get(sp), 1252 sk_rmem_alloc_get(sp),
1253 0, 0L, 0, 1253 0, 0L, 0,
1254 sock_i_uid(sp), 0, 1254 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1255 0,
1255 sock_i_ino(sp), 1256 sock_i_ino(sp),
1256 atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); 1257 atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
1257} 1258}
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index bb46061c813a..182ab9a85d6c 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -190,6 +190,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
190 ireq = inet_rsk(req); 190 ireq = inet_rsk(req);
191 ireq6 = inet6_rsk(req); 191 ireq6 = inet6_rsk(req);
192 treq = tcp_rsk(req); 192 treq = tcp_rsk(req);
193 treq->listener = NULL;
193 194
194 if (security_inet_conn_request(sk, skb, req)) 195 if (security_inet_conn_request(sk, skb, req))
195 goto out_free; 196 goto out_free;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index cd49de3678fb..09078b9bc6f6 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -475,7 +475,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
475 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL) 475 if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
476 goto done; 476 goto done;
477 477
478 skb = tcp_make_synack(sk, dst, req, rvp); 478 skb = tcp_make_synack(sk, dst, req, rvp, NULL);
479 479
480 if (skb) { 480 if (skb) {
481 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); 481 __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
@@ -987,7 +987,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
987 &ipv6_hdr(skb)->saddr, 987 &ipv6_hdr(skb)->saddr,
988 &ipv6_hdr(skb)->daddr, inet6_iif(skb)); 988 &ipv6_hdr(skb)->daddr, inet6_iif(skb));
989 if (req) 989 if (req)
990 return tcp_check_req(sk, skb, req, prev); 990 return tcp_check_req(sk, skb, req, prev, false);
991 991
992 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo, 992 nsk = __inet6_lookup_established(sock_net(sk), &tcp_hashinfo,
993 &ipv6_hdr(skb)->saddr, th->source, 993 &ipv6_hdr(skb)->saddr, th->source,
@@ -1179,6 +1179,7 @@ have_isn:
1179 want_cookie) 1179 want_cookie)
1180 goto drop_and_free; 1180 goto drop_and_free;
1181 1181
1182 tcp_rsk(req)->listener = NULL;
1182 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT); 1183 inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
1183 return 0; 1184 return 0;
1184 1185
@@ -1828,7 +1829,7 @@ static void tcp_v6_destroy_sock(struct sock *sk)
1828#ifdef CONFIG_PROC_FS 1829#ifdef CONFIG_PROC_FS
1829/* Proc filesystem TCPv6 sock list dumping. */ 1830/* Proc filesystem TCPv6 sock list dumping. */
1830static void get_openreq6(struct seq_file *seq, 1831static void get_openreq6(struct seq_file *seq,
1831 const struct sock *sk, struct request_sock *req, int i, int uid) 1832 const struct sock *sk, struct request_sock *req, int i, kuid_t uid)
1832{ 1833{
1833 int ttd = req->expires - jiffies; 1834 int ttd = req->expires - jiffies;
1834 const struct in6_addr *src = &inet6_rsk(req)->loc_addr; 1835 const struct in6_addr *src = &inet6_rsk(req)->loc_addr;
@@ -1852,7 +1853,7 @@ static void get_openreq6(struct seq_file *seq,
1852 1, /* timers active (only the expire timer) */ 1853 1, /* timers active (only the expire timer) */
1853 jiffies_to_clock_t(ttd), 1854 jiffies_to_clock_t(ttd),
1854 req->retrans, 1855 req->retrans,
1855 uid, 1856 from_kuid_munged(seq_user_ns(seq), uid),
1856 0, /* non standard timer */ 1857 0, /* non standard timer */
1857 0, /* open_requests have no inode */ 1858 0, /* open_requests have no inode */
1858 0, req); 1859 0, req);
@@ -1902,7 +1903,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1902 timer_active, 1903 timer_active,
1903 jiffies_delta_to_clock_t(timer_expires - jiffies), 1904 jiffies_delta_to_clock_t(timer_expires - jiffies),
1904 icsk->icsk_retransmits, 1905 icsk->icsk_retransmits,
1905 sock_i_uid(sp), 1906 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1906 icsk->icsk_probes_out, 1907 icsk->icsk_probes_out,
1907 sock_i_ino(sp), 1908 sock_i_ino(sp),
1908 atomic_read(&sp->sk_refcnt), sp, 1909 atomic_read(&sp->sk_refcnt), sp,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 99d0077b56b8..bbdff07eebe1 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1458,7 +1458,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
1458 sk_wmem_alloc_get(sp), 1458 sk_wmem_alloc_get(sp),
1459 sk_rmem_alloc_get(sp), 1459 sk_rmem_alloc_get(sp),
1460 0, 0L, 0, 1460 0, 0L, 0,
1461 sock_i_uid(sp), 0, 1461 from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
1462 0,
1462 sock_i_ino(sp), 1463 sock_i_ino(sp),
1463 atomic_read(&sp->sk_refcnt), sp, 1464 atomic_read(&sp->sk_refcnt), sp,
1464 atomic_read(&sp->sk_drops)); 1465 atomic_read(&sp->sk_drops));