forked from mirrors/linux
		
	udp: Implement ->read_sock() for sockmap
This is similar to tcp_read_sock(), except we do not need to worry about connections, we just need to retrieve skb from UDP receive queue. Note, the return value of ->read_sock() is unused in sk_psock_verdict_data_ready(), and UDP still does not support splice() due to lack of ->splice_read(), so users can not reach udp_read_sock() directly. Signed-off-by: Cong Wang <cong.wang@bytedance.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: John Fastabend <john.fastabend@gmail.com> Link: https://lore.kernel.org/bpf/20210331023237.41094-12-xiyou.wangcong@gmail.com
This commit is contained in:
		
							parent
							
								
									8a59f9d1e3
								
							
						
					
					
						commit
						d7f571188e
					
				
					 4 changed files with 33 additions and 0 deletions
				
			
		|  | @ -329,6 +329,8 @@ struct sock *__udp6_lib_lookup(struct net *net, | ||||||
| 			       struct sk_buff *skb); | 			       struct sk_buff *skb); | ||||||
| struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb, | struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb, | ||||||
| 				 __be16 sport, __be16 dport); | 				 __be16 sport, __be16 dport); | ||||||
|  | int udp_read_sock(struct sock *sk, read_descriptor_t *desc, | ||||||
|  | 		  sk_read_actor_t recv_actor); | ||||||
| 
 | 
 | ||||||
| /* UDP uses skb->dev_scratch to cache as much information as possible and avoid
 | /* UDP uses skb->dev_scratch to cache as much information as possible and avoid
 | ||||||
|  * possibly multiple cache miss on dequeue() |  * possibly multiple cache miss on dequeue() | ||||||
|  |  | ||||||
|  | @ -1070,6 +1070,7 @@ const struct proto_ops inet_dgram_ops = { | ||||||
| 	.setsockopt	   = sock_common_setsockopt, | 	.setsockopt	   = sock_common_setsockopt, | ||||||
| 	.getsockopt	   = sock_common_getsockopt, | 	.getsockopt	   = sock_common_getsockopt, | ||||||
| 	.sendmsg	   = inet_sendmsg, | 	.sendmsg	   = inet_sendmsg, | ||||||
|  | 	.read_sock	   = udp_read_sock, | ||||||
| 	.recvmsg	   = inet_recvmsg, | 	.recvmsg	   = inet_recvmsg, | ||||||
| 	.mmap		   = sock_no_mmap, | 	.mmap		   = sock_no_mmap, | ||||||
| 	.sendpage	   = inet_sendpage, | 	.sendpage	   = inet_sendpage, | ||||||
|  |  | ||||||
|  | @ -1782,6 +1782,35 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags, | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(__skb_recv_udp); | EXPORT_SYMBOL(__skb_recv_udp); | ||||||
| 
 | 
 | ||||||
|  | int udp_read_sock(struct sock *sk, read_descriptor_t *desc, | ||||||
|  | 		  sk_read_actor_t recv_actor) | ||||||
|  | { | ||||||
|  | 	int copied = 0; | ||||||
|  | 
 | ||||||
|  | 	while (1) { | ||||||
|  | 		struct sk_buff *skb; | ||||||
|  | 		int err, used; | ||||||
|  | 
 | ||||||
|  | 		skb = skb_recv_udp(sk, 0, 1, &err); | ||||||
|  | 		if (!skb) | ||||||
|  | 			return err; | ||||||
|  | 		used = recv_actor(desc, skb, 0, skb->len); | ||||||
|  | 		if (used <= 0) { | ||||||
|  | 			if (!copied) | ||||||
|  | 				copied = used; | ||||||
|  | 			break; | ||||||
|  | 		} else if (used <= skb->len) { | ||||||
|  | 			copied += used; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!desc->count) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return copied; | ||||||
|  | } | ||||||
|  | EXPORT_SYMBOL(udp_read_sock); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * 	This should be easy, if there is something there we |  * 	This should be easy, if there is something there we | ||||||
|  * 	return it, otherwise we block. |  * 	return it, otherwise we block. | ||||||
|  |  | ||||||
|  | @ -714,6 +714,7 @@ const struct proto_ops inet6_dgram_ops = { | ||||||
| 	.getsockopt	   = sock_common_getsockopt,	/* ok		*/ | 	.getsockopt	   = sock_common_getsockopt,	/* ok		*/ | ||||||
| 	.sendmsg	   = inet6_sendmsg,		/* retpoline's sake */ | 	.sendmsg	   = inet6_sendmsg,		/* retpoline's sake */ | ||||||
| 	.recvmsg	   = inet6_recvmsg,		/* retpoline's sake */ | 	.recvmsg	   = inet6_recvmsg,		/* retpoline's sake */ | ||||||
|  | 	.read_sock	   = udp_read_sock, | ||||||
| 	.mmap		   = sock_no_mmap, | 	.mmap		   = sock_no_mmap, | ||||||
| 	.sendpage	   = sock_no_sendpage, | 	.sendpage	   = sock_no_sendpage, | ||||||
| 	.set_peek_off	   = sk_set_peek_off, | 	.set_peek_off	   = sk_set_peek_off, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Cong Wang
						Cong Wang