Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cebc209 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "udp: add support for UDP_GRO cmsg"

parents d7540678 149bddaa
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -49,7 +49,13 @@ struct udp_sock {
	unsigned int	 corkflag;	/* Cork is required */
	__u8		 encap_type;	/* Is this an Encapsulation socket? */
	unsigned char	 no_check6_tx:1,/* Send zero UDP6 checksums on TX? */
			 no_check6_rx:1;/* Allow zero UDP6 checksums on RX? */
			 no_check6_rx:1,/* Allow zero UDP6 checksums on RX? */
			 encap_enabled:1,/* This socket enabled encap
					  * processing; UDP tunnels and
					  * different encapsulation layers set
					  * this
					  */
			 gro_enabled:1; /* Can accept GRO packets */
	/*
	 * Following member retains the information to create a UDP header
	 * when the socket is uncorked.
@@ -115,6 +121,17 @@ static inline bool udp_get_no_check6_rx(struct sock *sk)
	return udp_sk(sk)->no_check6_rx;
}

static inline void udp_cmsg_recv(struct msghdr *msg, struct sock *sk,
				 struct sk_buff *skb)
{
	int gso_size;

	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
		gso_size = skb_shinfo(skb)->gso_size;
		put_cmsg(msg, SOL_UDP, UDP_GRO, sizeof(gso_size), &gso_size);
	}
}

#define udp_portaddr_for_each_entry(__sk, list) \
	hlist_for_each_entry(__sk, list, __sk_common.skc_portaddr_node)

+1 −2
Original line number Diff line number Diff line
@@ -175,8 +175,7 @@ struct sk_buff **udp_gro_receive(struct sk_buff **head, struct sk_buff *skb,
int udp_gro_complete(struct sk_buff *skb, int nhoff, udp_lookup_t lookup);

struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
				  netdev_features_t features,
				  unsigned int mss, __sum16 check);
				  netdev_features_t features);

static inline struct udphdr *udp_gro_udphdr(struct sk_buff *skb)
{
+6 −0
Original line number Diff line number Diff line
@@ -165,6 +165,12 @@ static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)

static inline void udp_tunnel_encap_enable(struct socket *sock)
{
	struct udp_sock *up = udp_sk(sock->sk);

	if (up->encap_enabled)
		return;

	up->encap_enabled = 1;
#if IS_ENABLED(CONFIG_IPV6)
	if (sock->sk->sk_family == PF_INET6)
		ipv6_stub->udpv6_encap_enable();
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ struct udphdr {
#define UDP_NO_CHECK6_TX 101	/* Disable sending checksum for UDP6X */
#define UDP_NO_CHECK6_RX 102	/* Disable accpeting checksum for UDP6 */
#define UDP_SEGMENT	103	/* Set GSO segmentation size */
#define UDP_GRO		104	/* This socket can receive UDP GRO packets */

/* UDP encapsulation types */
#define UDP_ENCAP_ESPINUDP_NON_IKE	1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
+25 −6
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@
#include "udp_impl.h"
#include <net/sock_reuseport.h>
#include <net/addrconf.h>
#include <net/udp_tunnel.h>

struct udp_table udp_table __read_mostly;
EXPORT_SYMBOL(udp_table);
@@ -1714,6 +1715,10 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
		*addr_len = sizeof(*sin);
	}

	if (udp_sk(sk)->gro_enabled)
		udp_cmsg_recv(msg, sk, skb);

	if (inet->cmsg_flags)
		ip_cmsg_recv_offset(msg, sk, skb, sizeof(struct udphdr), off);

@@ -2386,12 +2391,16 @@ void udp_destroy_sock(struct sock *sk)
	bool slow = lock_sock_fast(sk);
	udp_flush_pending_frames(sk);
	unlock_sock_fast(sk, slow);
	if (static_key_false(&udp_encap_needed) && up->encap_type) {
	if (static_key_false(&udp_encap_needed)) {
		if (up->encap_type) {
			void (*encap_destroy)(struct sock *sk);
			encap_destroy = ACCESS_ONCE(up->encap_destroy);
			if (encap_destroy)
				encap_destroy(sk);
		}
		if (up->encap_enabled)
			static_key_disable(&udp_encap_needed);
	}
}

/*
@@ -2435,7 +2444,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
			/* FALLTHROUGH */
		case UDP_ENCAP_L2TPINUDP:
			up->encap_type = val;
			udp_encap_enable();
			lock_sock(sk);
			udp_tunnel_encap_enable(sk->sk_socket);
			release_sock(sk);
			break;
		default:
			err = -ENOPROTOOPT;
@@ -2457,6 +2468,14 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
		up->gso_size = val;
		break;

	case UDP_GRO:
		lock_sock(sk);
		if (valbool)
			udp_tunnel_encap_enable(sk->sk_socket);
		up->gro_enabled = valbool;
		release_sock(sk);
		break;

	/*
	 * 	UDP-Lite's partial checksum coverage (RFC 3828).
	 */
Loading