diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-09-03 09:28:30 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-09-03 09:34:51 -0400 |
commit | ace1fe1231bdfffd60b5e703aa5b7283fbf98dbd (patch) | |
tree | 06c7492a8f3cc65f916768616ca24c6bc7171761 /net/ipv6 | |
parent | ce9f3f31efb88841e4df98794b13dbac8c4901da (diff) | |
parent | a2dc375e12334b3d8f787a48b2fb6172ccfb80ae (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.c | 35 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 47 | ||||
-rw-r--r-- | net/ipv6/raw.c | 3 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 1 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 11 | ||||
-rw-r--r-- | net/ipv6/udp.c | 3 |
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 |
130 | static int __ipv6_regen_rndid(struct inet6_dev *idev); | 130 | static void __ipv6_regen_rndid(struct inet6_dev *idev); |
131 | static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); | 131 | static void __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); |
132 | static void ipv6_regen_rndid(unsigned long data); | 132 | static 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) */ |
1603 | static int __ipv6_regen_rndid(struct inet6_dev *idev) | 1594 | static void __ipv6_regen_rndid(struct inet6_dev *idev) |
1604 | { | 1595 | { |
1605 | regen: | 1596 | regen: |
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 | ||
1634 | static void ipv6_regen_rndid(unsigned long data) | 1623 | static 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 | ||
1667 | static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) | 1655 | static 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) | |||
91 | static void fl_free(struct ip6_flowlabel *fl) | 92 | static 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 | ||
622 | struct ip6fl_iter_state { | 628 | struct 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 | ||
700 | static int ip6fl_seq_show(struct seq_file *seq, void *v) | 707 | static 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 | ||
728 | static int ip6fl_seq_open(struct inode *inode, struct file *file) | 740 | static 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 | |||
759 | static 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 | ||
734 | static const struct file_operations ip6fl_seq_fops = { | 767 | static 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 | ||
742 | static int __net_init ip6_flowlabel_proc_init(struct net *net) | 775 | static 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. */ |
1830 | static void get_openreq6(struct seq_file *seq, | 1831 | static 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)); |