From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
To: netdev@vger.kernel.org
Cc: pabeni@redhat.com, steffen.klassert@secunet.com,
davem@davemloft.net, Willem de Bruijn <willemb@google.com>
Subject: [PATCH net-next RFC 8/8] udp: add gro
Date: Fri, 14 Sep 2018 13:59:41 -0400 [thread overview]
Message-ID: <20180914175941.213950-9-willemdebruijn.kernel@gmail.com> (raw)
In-Reply-To: <20180914175941.213950-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemb@google.com>
Very rough initial version of udp gro, for discussion purpose only at
this point.
Among others it
- lacks the cmsg UDP_SEGMENT to return gso_size
- probably breaks udp tunnels
- hard breaks at 40 segments
- does not allow a last segment of unequal size
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
include/uapi/linux/udp.h | 1 +
net/ipv4/udp.c | 71 ++++++++++++++++++++++++++++++++++++++++
net/ipv4/udp_offload.c | 11 +++----
3 files changed, 76 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/udp.h b/include/uapi/linux/udp.h
index 09d00f8c442b..7fda3e8c7fcf 100644
--- a/include/uapi/linux/udp.h
+++ b/include/uapi/linux/udp.h
@@ -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 /* Enable GRO */
/* UDP encapsulation types */
#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index bd873a5b8a86..ae49c08e6225 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2387,6 +2387,51 @@ void udp_destroy_sock(struct sock *sk)
}
}
+static struct sk_buff *udp_gro_receive_cb(struct sock *sk,
+ struct list_head *head,
+ struct sk_buff *skb)
+{
+ struct sk_buff *p;
+ unsigned int off;
+
+ off = skb_gro_offset(skb) - sizeof(struct udphdr);
+
+ list_for_each_entry(p, head, list) {
+ if (!NAPI_GRO_CB(p)->same_flow)
+ continue;
+
+ /* TODO: for UDP_GRO: match size unless last segment */
+ if (NAPI_GRO_CB(p)->flush)
+ break;
+
+ /* TODO: look into ip id check */
+ if (skb_gro_receive(p, skb)) {
+ NAPI_GRO_CB(skb)->flush = 1;
+ break;
+ }
+
+ if (NAPI_GRO_CB(skb)->count >= 40) {
+ return p;
+ }
+
+ return NULL;
+ }
+
+ return NULL;
+}
+
+static int udp_gro_complete_cb(struct sock *sk, struct sk_buff *skb,
+ int nhoff)
+{
+ skb->csum_start = (unsigned char *)udp_hdr(skb) - skb->head;
+ skb->csum_offset = offsetof(struct udphdr, check);
+ skb->ip_summed = CHECKSUM_PARTIAL;
+
+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count;
+
+ return 0;
+}
+
/*
* Socket option code for UDP
*/
@@ -2450,6 +2495,32 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
up->gso_size = val;
break;
+ case UDP_GRO:
+ {
+ if (val < 0 || val > 1)
+ return -EINVAL;
+
+ lock_sock(sk);
+ if (val) {
+
+ if (!udp_sk(sk)->gro_receive) {
+ udp_sk(sk)->gro_complete = udp_gro_complete_cb;
+ udp_sk(sk)->gro_receive = udp_gro_receive_cb;
+ } else {
+ err = -EALREADY;
+ }
+ } else {
+ if (udp_sk(sk)->gro_receive) {
+ udp_sk(sk)->gro_receive = NULL;
+ udp_sk(sk)->gro_complete = NULL;
+ } else {
+ err = -ENOENT;
+ }
+ }
+ release_sock(sk);
+ break;
+ }
+
/*
* UDP-Lite's partial checksum coverage (RFC 3828).
*/
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index f44fe328aa0f..6dd3f0a28b5e 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -386,6 +386,8 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
+
+ /* TODO: for UDP_GRO: match size */
}
skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
@@ -437,11 +439,6 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff,
uh->len = newlen;
- /* Set encapsulation before calling into inner gro_complete() functions
- * to make them set up the inner offsets.
- */
- skb->encapsulation = 1;
-
rcu_read_lock();
sk = (*lookup)(skb, uh->source, uh->dest);
if (sk && udp_sk(sk)->gro_complete)
@@ -462,11 +459,11 @@ static int udp4_gro_complete(struct sk_buff *skb, int nhoff)
struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
if (uh->check) {
- skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM;
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_L4;
uh->check = ~udp_v4_check(skb->len - nhoff, iph->saddr,
iph->daddr, 0);
} else {
- skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_L4;
}
return udp_gro_complete(skb, nhoff, udp4_lib_lookup_skb);
--
2.19.0.397.gdd90340f6a-goog
next prev parent reply other threads:[~2018-09-14 23:15 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-14 17:59 [PATCH net-next RFC 0/8] udp and configurable gro Willem de Bruijn
2018-09-14 17:59 ` [PATCH net-next RFC 1/8] gro: convert device offloads to net_offload Willem de Bruijn
2018-09-14 17:59 ` [PATCH net-next RFC 2/8] gro: deduplicate gro_complete Willem de Bruijn
2018-09-14 17:59 ` [PATCH net-next RFC 3/8] gro: add net_gro_receive Willem de Bruijn
2018-09-14 17:59 ` [PATCH net-next RFC 4/8] ipv6: remove offload exception for hopopts Willem de Bruijn
2018-09-14 17:59 ` [PATCH net-next RFC 5/8] net: deconstify net_offload Willem de Bruijn
2018-09-15 3:30 ` Subash Abhinov Kasiviswanathan
2018-09-16 18:12 ` Willem de Bruijn
2018-09-14 17:59 ` [PATCH net-next RFC 6/8] net: make gro configurable Willem de Bruijn
2018-09-14 18:38 ` Stephen Hemminger
2018-09-14 22:50 ` Willem de Bruijn
2018-09-14 23:09 ` Willem de Bruijn
2018-09-14 23:14 ` Willem de Bruijn
2018-09-14 17:59 ` [PATCH net-next RFC 7/8] udp: gro behind static key Willem de Bruijn
2018-09-15 3:37 ` Subash Abhinov Kasiviswanathan
2018-09-16 18:10 ` Willem de Bruijn
2018-09-17 9:03 ` Steffen Klassert
2018-09-17 14:10 ` Willem de Bruijn
2018-09-17 10:24 ` Paolo Abeni
2018-09-17 14:12 ` Willem de Bruijn
2018-09-17 10:37 ` Steffen Klassert
2018-09-17 14:19 ` Willem de Bruijn
2018-09-18 10:59 ` Steffen Klassert
2018-09-14 17:59 ` Willem de Bruijn [this message]
2018-10-05 13:53 ` [PATCH net-next RFC 0/8] udp and configurable gro Paolo Abeni
2018-10-05 14:41 ` Willem de Bruijn
2018-10-05 15:30 ` Paolo Abeni
2018-10-05 15:45 ` Willem de Bruijn
2018-10-05 16:05 ` Paolo Abeni
2018-10-05 16:12 ` Willem de Bruijn
2018-10-08 11:27 ` Steffen Klassert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180914175941.213950-9-willemdebruijn.kernel@gmail.com \
--to=willemdebruijn.kernel@gmail.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=steffen.klassert@secunet.com \
--cc=willemb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.