aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-10-20 09:08:27 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-20 09:08:27 -0400
commit26440c835f8b1a491e2704118ac55bf87334366c (patch)
tree3c2d23b59fd49b252fdbf6c09efc41b354933fc6 /net/netlink
parent371f1c7e0d854796adc622cc3bacfcc5fc638db1 (diff)
parent1099f86044111e9a7807f09523e42d4c9d0fb781 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/usb/asix_common.c net/ipv4/inet_connection_sock.c net/switchdev/switchdev.c In the inet_connection_sock.c case the request socket hashing scheme is completely different in net-next. The other two conflicts were overlapping changes. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 8f060d7f9a0e..0a49a8c7c564 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2785,6 +2785,7 @@ static int netlink_dump(struct sock *sk)
2785 struct sk_buff *skb = NULL; 2785 struct sk_buff *skb = NULL;
2786 struct nlmsghdr *nlh; 2786 struct nlmsghdr *nlh;
2787 int len, err = -ENOBUFS; 2787 int len, err = -ENOBUFS;
2788 int alloc_min_size;
2788 int alloc_size; 2789 int alloc_size;
2789 2790
2790 mutex_lock(nlk->cb_mutex); 2791 mutex_lock(nlk->cb_mutex);
@@ -2793,9 +2794,6 @@ static int netlink_dump(struct sock *sk)
2793 goto errout_skb; 2794 goto errout_skb;
2794 } 2795 }
2795 2796
2796 cb = &nlk->cb;
2797 alloc_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
2798
2799 if (!netlink_rx_is_mmaped(sk) && 2797 if (!netlink_rx_is_mmaped(sk) &&
2800 atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) 2798 atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
2801 goto errout_skb; 2799 goto errout_skb;
@@ -2805,23 +2803,35 @@ static int netlink_dump(struct sock *sk)
2805 * to reduce number of system calls on dump operations, if user 2803 * to reduce number of system calls on dump operations, if user
2806 * ever provided a big enough buffer. 2804 * ever provided a big enough buffer.
2807 */ 2805 */
2808 if (alloc_size < nlk->max_recvmsg_len) { 2806 cb = &nlk->cb;
2809 skb = netlink_alloc_skb(sk, 2807 alloc_min_size = max_t(int, cb->min_dump_alloc, NLMSG_GOODSIZE);
2810 nlk->max_recvmsg_len, 2808
2811 nlk->portid, 2809 if (alloc_min_size < nlk->max_recvmsg_len) {
2810 alloc_size = nlk->max_recvmsg_len;
2811 skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
2812 GFP_KERNEL | 2812 GFP_KERNEL |
2813 __GFP_NOWARN | 2813 __GFP_NOWARN |
2814 __GFP_NORETRY); 2814 __GFP_NORETRY);
2815 /* available room should be exact amount to avoid MSG_TRUNC */
2816 if (skb)
2817 skb_reserve(skb, skb_tailroom(skb) -
2818 nlk->max_recvmsg_len);
2819 } 2815 }
2820 if (!skb) 2816 if (!skb) {
2817 alloc_size = alloc_min_size;
2821 skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, 2818 skb = netlink_alloc_skb(sk, alloc_size, nlk->portid,
2822 GFP_KERNEL); 2819 GFP_KERNEL);
2820 }
2823 if (!skb) 2821 if (!skb)
2824 goto errout_skb; 2822 goto errout_skb;
2823
2824 /* Trim skb to allocated size. User is expected to provide buffer as
2825 * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at
2826 * netlink_recvmsg())). dump will pack as many smaller messages as
2827 * could fit within the allocated skb. skb is typically allocated
2828 * with larger space than required (could be as much as near 2x the
2829 * requested size with align to next power of 2 approach). Allowing
2830 * dump to use the excess space makes it difficult for a user to have a
2831 * reasonable static buffer based on the expected largest dump of a
2832 * single netdev. The outcome is MSG_TRUNC error.
2833 */
2834 skb_reserve(skb, skb_tailroom(skb) - alloc_size);
2825 netlink_skb_set_owner_r(skb, sk); 2835 netlink_skb_set_owner_r(skb, sk);
2826 2836
2827 len = cb->dump(skb, cb); 2837 len = cb->dump(skb, cb);