diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/datagram.c | 44 | ||||
| -rw-r--r-- | net/core/devmem.c | 27 | ||||
| -rw-r--r-- | net/core/gro.c | 10 | ||||
| -rw-r--r-- | net/core/gro_cells.c | 5 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 3 | 
5 files changed, 68 insertions, 21 deletions
diff --git a/net/core/datagram.c b/net/core/datagram.c index cb4b9ef2e4e3..c285c6465923 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -920,21 +920,22 @@ fault:  EXPORT_SYMBOL(skb_copy_and_csum_datagram_msg);  /** - * 	datagram_poll - generic datagram poll + *	datagram_poll_queue - same as datagram_poll, but on a specific receive + *		queue   *	@file: file struct   *	@sock: socket   *	@wait: poll table + *	@rcv_queue: receive queue to poll   * - *	Datagram poll: Again totally generic. This also handles - *	sequenced packet sockets providing the socket receive queue - *	is only ever holding data ready to receive. + *	Performs polling on the given receive queue, handling shutdown, error, + *	and connection state. This is useful for protocols that deliver + *	userspace-bound packets through a custom queue instead of + *	sk->sk_receive_queue.   * - *	Note: when you *don't* use this routine for this protocol, - *	and you use a different write policy from sock_writeable() - *	then please supply your own write_space callback. + *	Return: poll bitmask indicating the socket's current state   */ -__poll_t datagram_poll(struct file *file, struct socket *sock, -			   poll_table *wait) +__poll_t datagram_poll_queue(struct file *file, struct socket *sock, +			     poll_table *wait, struct sk_buff_head *rcv_queue)  {  	struct sock *sk = sock->sk;  	__poll_t mask; @@ -956,7 +957,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,  		mask |= EPOLLHUP;  	/* readable? */ -	if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) +	if (!skb_queue_empty_lockless(rcv_queue))  		mask |= EPOLLIN | EPOLLRDNORM;  	/* Connection-based need to check for termination and startup */ @@ -978,4 +979,27 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,  	return mask;  } +EXPORT_SYMBOL(datagram_poll_queue); + +/** + *	datagram_poll - generic datagram poll + *	@file: file struct + *	@sock: socket + *	@wait: poll table + * + *	Datagram poll: Again totally generic. This also handles + *	sequenced packet sockets providing the socket receive queue + *	is only ever holding data ready to receive. + * + *	Note: when you *don't* use this routine for this protocol, + *	and you use a different write policy from sock_writeable() + *	then please supply your own write_space callback. + * + *	Return: poll bitmask indicating the socket's current state + */ +__poll_t datagram_poll(struct file *file, struct socket *sock, poll_table *wait) +{ +	return datagram_poll_queue(file, sock, wait, +				   &sock->sk->sk_receive_queue); +}  EXPORT_SYMBOL(datagram_poll); diff --git a/net/core/devmem.c b/net/core/devmem.c index d9de31a6cc7f..1d04754bc756 100644 --- a/net/core/devmem.c +++ b/net/core/devmem.c @@ -17,6 +17,7 @@  #include <net/page_pool/helpers.h>  #include <net/page_pool/memory_provider.h>  #include <net/sock.h> +#include <net/tcp.h>  #include <trace/events/page_pool.h>  #include "devmem.h" @@ -357,7 +358,8 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk,  							 unsigned int dmabuf_id)  {  	struct net_devmem_dmabuf_binding *binding; -	struct dst_entry *dst = __sk_dst_get(sk); +	struct net_device *dst_dev; +	struct dst_entry *dst;  	int err = 0;  	binding = net_devmem_lookup_dmabuf(dmabuf_id); @@ -366,16 +368,35 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk,  		goto out_err;  	} +	rcu_read_lock(); +	dst = __sk_dst_get(sk); +	/* If dst is NULL (route expired), attempt to rebuild it. */ +	if (unlikely(!dst)) { +		if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) { +			err = -EHOSTUNREACH; +			goto out_unlock; +		} +		dst = __sk_dst_get(sk); +		if (unlikely(!dst)) { +			err = -ENODEV; +			goto out_unlock; +		} +	} +  	/* The dma-addrs in this binding are only reachable to the corresponding  	 * net_device.  	 */ -	if (!dst || !dst->dev || dst->dev->ifindex != binding->dev->ifindex) { +	dst_dev = dst_dev_rcu(dst); +	if (unlikely(!dst_dev) || unlikely(dst_dev != binding->dev)) {  		err = -ENODEV; -		goto out_err; +		goto out_unlock;  	} +	rcu_read_unlock();  	return binding; +out_unlock: +	rcu_read_unlock();  out_err:  	if (binding)  		net_devmem_dmabuf_binding_put(binding); diff --git a/net/core/gro.c b/net/core/gro.c index 5ba4504cfd28..76f9c3712422 100644 --- a/net/core/gro.c +++ b/net/core/gro.c @@ -639,6 +639,8 @@ EXPORT_SYMBOL(gro_receive_skb);  static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)  { +	struct skb_shared_info *shinfo; +  	if (unlikely(skb->pfmemalloc)) {  		consume_skb(skb);  		return; @@ -655,8 +657,12 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)  	skb->encapsulation = 0;  	skb->ip_summed = CHECKSUM_NONE; -	skb_shinfo(skb)->gso_type = 0; -	skb_shinfo(skb)->gso_size = 0; + +	shinfo = skb_shinfo(skb); +	shinfo->gso_type = 0; +	shinfo->gso_size = 0; +	shinfo->hwtstamps.hwtstamp = 0; +  	if (unlikely(skb->slow_gro)) {  		skb_orphan(skb);  		skb_ext_reset(skb); diff --git a/net/core/gro_cells.c b/net/core/gro_cells.c index b43911562f4d..fd57b845de33 100644 --- a/net/core/gro_cells.c +++ b/net/core/gro_cells.c @@ -43,12 +43,11 @@ drop:  	if (skb_queue_len(&cell->napi_skbs) == 1)  		napi_schedule(&cell->napi); -	if (have_bh_lock) -		local_unlock_nested_bh(&gcells->cells->bh_lock); -  	res = NET_RX_SUCCESS;  unlock: +	if (have_bh_lock) +		local_unlock_nested_bh(&gcells->cells->bh_lock);  	rcu_read_unlock();  	return res;  } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 8040ff7c356e..576d5ec3bb36 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -4715,9 +4715,6 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,  	int err;  	u16 vid; -	if (!netlink_capable(skb, CAP_NET_ADMIN)) -		return -EPERM; -  	if (!del_bulk) {  		err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX,  					     NULL, extack);  | 
