diff options
Diffstat (limited to 'net/ipv4/udp.c')
| -rw-r--r-- | net/ipv4/udp.c | 22 | 
1 files changed, 15 insertions, 7 deletions
| diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 0cd6b857e7ec..464590ea922e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -74,6 +74,7 @@  #define pr_fmt(fmt) "UDP: " fmt +#include <linux/bpf-cgroup.h>  #include <linux/uaccess.h>  #include <asm/ioctls.h>  #include <linux/memblock.h> @@ -122,7 +123,7 @@ EXPORT_SYMBOL(udp_table);  long sysctl_udp_mem[3] __read_mostly;  EXPORT_SYMBOL(sysctl_udp_mem); -atomic_long_t udp_memory_allocated; +atomic_long_t udp_memory_allocated ____cacheline_aligned_in_smp;  EXPORT_SYMBOL(udp_memory_allocated);  #define MAX_UDP_PORTS 65536 @@ -459,7 +460,7 @@ static struct sock *udp4_lookup_run_bpf(struct net *net,  					struct udp_table *udptable,  					struct sk_buff *skb,  					__be32 saddr, __be16 sport, -					__be32 daddr, u16 hnum) +					__be32 daddr, u16 hnum, const int dif)  {  	struct sock *sk, *reuse_sk;  	bool no_reuseport; @@ -467,8 +468,8 @@ static struct sock *udp4_lookup_run_bpf(struct net *net,  	if (udptable != &udp_table)  		return NULL; /* only UDP is supported */ -	no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_UDP, -					    saddr, sport, daddr, hnum, &sk); +	no_reuseport = bpf_sk_lookup_run_v4(net, IPPROTO_UDP, saddr, sport, +					    daddr, hnum, dif, &sk);  	if (no_reuseport || IS_ERR_OR_NULL(sk))  		return sk; @@ -504,7 +505,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,  	/* Lookup redirect from BPF */  	if (static_branch_unlikely(&bpf_sk_lookup_enabled)) {  		sk = udp4_lookup_run_bpf(net, udptable, skb, -					 saddr, sport, daddr, hnum); +					 saddr, sport, daddr, hnum, dif);  		if (sk) {  			result = sk;  			goto done; @@ -2410,6 +2411,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,  	__be32 saddr, daddr;  	struct net *net = dev_net(skb->dev);  	bool refcounted; +	int drop_reason; + +	drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;  	/*  	 *  Validate the packet. @@ -2465,6 +2469,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,  	if (udp_lib_checksum_complete(skb))  		goto csum_error; +	drop_reason = SKB_DROP_REASON_NO_SOCKET;  	__UDP_INC_STATS(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);  	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); @@ -2472,10 +2477,11 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,  	 * Hmm.  We got an UDP packet to a port to which we  	 * don't wanna listen.  Ignore it.  	 */ -	kfree_skb(skb); +	kfree_skb_reason(skb, drop_reason);  	return 0;  short_packet: +	drop_reason = SKB_DROP_REASON_PKT_TOO_SMALL;  	net_dbg_ratelimited("UDP%s: short packet: From %pI4:%u %d/%d to %pI4:%u\n",  			    proto == IPPROTO_UDPLITE ? "Lite" : "",  			    &saddr, ntohs(uh->source), @@ -2488,6 +2494,7 @@ csum_error:  	 * RFC1122: OK.  Discards the bad packet silently (as far as  	 * the network is concerned, anyway) as per 4.1.3.4 (MUST).  	 */ +	drop_reason = SKB_DROP_REASON_UDP_CSUM;  	net_dbg_ratelimited("UDP%s: bad checksum. From %pI4:%u to %pI4:%u ulen %d\n",  			    proto == IPPROTO_UDPLITE ? "Lite" : "",  			    &saddr, ntohs(uh->source), &daddr, ntohs(uh->dest), @@ -2495,7 +2502,7 @@ csum_error:  	__UDP_INC_STATS(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);  drop:  	__UDP_INC_STATS(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); -	kfree_skb(skb); +	kfree_skb_reason(skb, drop_reason);  	return 0;  } @@ -2926,6 +2933,7 @@ struct proto udp_prot = {  	.unhash			= udp_lib_unhash,  	.rehash			= udp_v4_rehash,  	.get_port		= udp_v4_get_port, +	.put_port		= udp_lib_unhash,  #ifdef CONFIG_BPF_SYSCALL  	.psock_update_sk_prot	= udp_bpf_update_proto,  #endif |