net: Generic UDP Encapsulation
Subsystems (3)
v2 cover net: Generic UDP Encapsulation
Generic UDP Encapsulation (GUE) is UDP encapsulation protocol which encapsulates packets of various IP protocols. The GUE protocol is described in http://tools.ietf.org/html/draft-herbert-gue-01.
The receive path of GUE is implemented in the FOU over UDP module (FOU). This includes a UDP encap receive function for GUE as well as GUE specific GRO functions. Management and configuration of GUE ports shares most of the same code with FOU.
For the transmit path, the previous FOU support for IPIP, sit, and GRE was simply extended for GUE (when GUE is enabled insert the GUE header on transmit in addition to UDP header inserted for FOU).
Semantically GUE is the same as FOU in that the encapsulation (UDP and GUE headers) that are inserted on transmission and removed on reception so that IP packet is processed with the inner header.
This patch set includes:
- Some fixes to FOU, removal of IPv4,v6 specific GRO functions
- Support to configure a GUE receive port
- Implementation of GUE receive path (normal and GRO)
- Additions to ip_tunnel netlink to configure GUE
- GUE header inserion in ip_tunnel transmit path
v2:
- Include net/gue.h in patch set
Testing:
I ran performance numbers using netperf TCP_RR with 200 streams, comparing encapsulation without GUE, encapsulation with GUE, and encapsulation with FOU.
GRE
TCP_STREAM
IPv4, FOU, UDP checksum enabled
14.04% TX CPU utilization
13.17% RX CPU utilization
9211 Mbps
IPv4, GUE, UDP checksum enabled
14.99% TX CPU utilization
13.79% RX CPU utilization
9185 Mbps
IPv4, FOU, UDP checksum disabled
13.14% TX CPU utilization
23.18% RX CPU utilization
9277 Mbps
IPv4, GUE, UDP checksum disabled
13.66% TX CPU utilization
23.57% RX CPU utilization
9184 Mbps
TCP_RR
IPv4, FOU, UDP checksum enabled
94.2% CPU utilization
155/249/460 90/95/99% latencies
1.17018e+06 tps
IPv4, GUE, UDP checksum enabled
93.9% CPU utilization
158/253/472 90/95/99% latencies
1.15045e+06 tps
IPIP
TCP_STREAM
FOU, UDP checksum enabled
15.28% TX CPU utilization
13.92% RX CPU utilization
9342 Mbps
GUE, UDP checksum enabled
13.99% TX CPU utilization
13.34% RX CPU utilization
9210 Mbps
FOU, UDP checksum disabled
15.08% TX CPU utilization
24.64% RX CPU utilization
9226 Mbps
GUE, UDP checksum disabled
15.90% TX CPU utilization
24.77% RX CPU utilization
9197 Mbps
TCP_RR
FOU, UDP checksum enabled
94.23% CPU utilization
149/237/429 90/95/99% latencies
1.19553e+06 tps
GUE, UDP checksum enabled
93.75% CPU utilization
152/243/442 90/95/99% latencies
1.17027e+06 tps
SIT
TCP_STREAM
FOU, UDP checksum enabled
14.47% TX CPU utilization
14.58% RX CPU utilization
9106 Mbps
GUE, UDP checksum enabled
15.09% TX CPU utilization
14.84% RX CPU utilization
9080 Mbps
FOU, UDP checksum disabled
15.70% TX CPU utilization
27.93% RX CPU utilization
9097 Mbps
GUE, UDP checksum disabled
15.04% TX CPU utilization
27.54% RX CPU utilization
9073 Mbps
TCP_RR
FOU, UDP checksum enabled
96.9% CPU utilization
170/281/581 90/95/99% latencies
1.03372e+06 tps
GUE, UDP checksum enabled
97.16% CPU utilization
172/286/576 90/95/99% latencies
1.00469e+06 tps
Tom Herbert (4):
ip_tunnel: Account for secondary encapsulation header in max_headroom
fou: eliminate IPv4,v6 specific GRO functions
gue: Receive side for Generic UDP Encapsulation
ip_tunnel: Add GUE support
include/linux/netdevice.h | 3 + include/net/gue.h | 23 +++++ include/uapi/linux/fou.h | 7 ++ include/uapi/linux/if_tunnel.h | 1 + net/ipv4/fou.c | 224 ++++++++++++++++++++++++++++++++++------- net/ipv4/ip_tunnel.c | 15 ++- net/ipv4/udp_offload.c | 1 + net/ipv6/udp_offload.c | 1 + 8 files changed, 235 insertions(+), 40 deletions(-) create mode 100644 include/net/gue.h
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 1/4 ip_tunnel: Account for secondary encapsulation header in max_headroom
When adjusting max_header for the tunnel interface based on egress device we need to account for any extra bytes in secondary encapsulation (e.g. FOU).
--- net/ipv4/ip_tunnel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/ip_tunnel.c +1 -1
@@ -759,7 +759,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, df |= (inner_iph->frag_off&htons (IP_DF )); max_headroom =LL_RESERVED_SPACE (rt->dst.dev) +sizeof (struct iphdr ) - + rt->dst.header_len; + + rt->dst.header_len +ip_encap_hlen (&tunnel->encap);if (max_headroom > dev->needed_headroom) dev->needed_headroom = max_headroom;
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 2/4 fou: eliminate IPv4,v6 specific GRO functions
In reply to Tom HerbertThis patch removes fou[46]_gro_receive and fou[46]_gro_complete functions. The v4 or v6 variants were chosen for the UDP offloads based on the address family of the socket this is not necessary or correct. Alternatively, this patch adds is_ipv6 to napi_gro_skb. This is set in udp6_gro_receive and unset in udp4_gro_receive. In fou_gro_receive the value is used to select the correct inet_offloads for the protocol of the outer IP header.
--- include/linux/netdevice.h | 3 +++ net/ipv4/fou.c | 48 ++++++++--------------------------------------- net/ipv4/udp_offload.c | 1 + net/ipv6/udp_offload.c | 1 + 4 files changed, 13 insertions(+), 40 deletions(-)
include/linux/netdevice.h +3 -0
@@ -1886,6 +1886,9 @@ struct napi_gro_cb {/* Number of checksums via CHECKSUM_UNNECESSARY */ u8 csum_cnt:3; +/* Used in foo-over-udp, set in udp[46]_gro_receive */ + u8 is_ipv6:1; +/* used to support CHECKSUM_COMPLETE for tunneling protocols */ __wsum csum;
net/ipv4/fou.c +8 -40
84 lines not on this page · raw message
net/ipv4/udp_offload.c +1 -0
@@ -334,6 +334,7 @@ static struct sk_buff **udp4_gro_receive(struct sk_buff **head,skb_gro_checksum_try_convert (skb,IPPROTO_UDP , uh->check, inet_gro_compute_pseudo); skip: +NAPI_GRO_CB (skb)->is_ipv6 =0 ;return udp_gro_receive (head, skb, uh); flush:
net/ipv6/udp_offload.c +1 -0
@@ -140,6 +140,7 @@ static struct sk_buff **udp6_gro_receive(struct sk_buff **head, ip6_gro_compute_pseudo); skip: +NAPI_GRO_CB (skb)->is_ipv6 =1 ;return udp_gro_receive (head, skb, uh); flush:
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 3/4 gue: Receive side for Generic UDP Encapsulation
In reply to Tom HerbertThis patch adds support receiving for GUE packets in the fou module. The fou module now supports direct foo-over-udp (no encapsulation header) and GUE. To support this a type parameter is added to the fou netlink parameters.
For a GUE socket we define gue_udp_recv, gue_gro_receive, and gue_gro_complete to handle the specifics of the GUE protocol. Most of the code to manage and configure sockets is common with the fou.
--- include/net/gue.h | 23 ++++++ include/uapi/linux/fou.h | 7 ++ net/ipv4/fou.c | 196 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 217 insertions(+), 9 deletions(-) create mode 100644 include/net/gue.h
include/net/gue.h new file +23 -0
@@ -0,0 +1,23 @@ +#ifndef __NET_GUE_H +#define __NET_GUE_H + +struct guehdr { +union { +struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) +__u8 hlen:4 , + version:4 ; +#elif defined (__BIG_ENDIAN_BITFIELD) +__u8 version:4 , + hlen:4 ; +#else +#error "Please fix <asm/byteorder.h>" +#endif +__u8 next_hdr; +__u16 flags; + }; +__u32 word; + }; +}; + +#endif
include/uapi/linux/fou.h +7 -0
@@ -13,6 +13,7 @@ enum {FOU_ATTR_PORT ,/* u16 */ FOU_ATTR_AF ,/* u8 */ FOU_ATTR_IPPROTO ,/* u8 */ +FOU_ATTR_TYPE ,/* u8 */ __FOU_ATTR_MAX, };
@@ -27,6 +28,12 @@ enum { __FOU_CMD_MAX, }; +enum { +FOU_ENCAP_UNSPEC , +FOU_ENCAP_DIRECT , +FOU_ENCAP_GUE , +}; +#define FOU_CMD_MAX (__FOU_CMD_MAX - 1)#endif /* _UAPI_LINUX_FOU_H */
net/ipv4/fou.c +187 -9
250 lines not on this page · raw message
Signature · 1 line
2.1.0.rc2.206.gedb03e5
PATCH v2 4/4 ip_tunnel: Add GUE support
In reply to Tom HerbertThis patch allows configuring IPIP, sit, and GRE tunnels to use GUE. This is very similar to fou excpet that we need to insert the GUE header in addition to the UDP header on transmit.
--- include/uapi/linux/if_tunnel.h | 1 + net/ipv4/ip_tunnel.c | 13 +++++++++++++ 2 files changed, 14 insertions(+)
include/uapi/linux/if_tunnel.h +1 -0
@@ -64,6 +64,7 @@ enum {enum tunnel_encap_types {TUNNEL_ENCAP_NONE ,TUNNEL_ENCAP_FOU , +TUNNEL_ENCAP_GUE , };#define TUNNEL_ENCAP_FLAG_CSUM (1<<0)
net/ipv4/ip_tunnel.c +13 -0
@@ -56,6 +56,7 @@#include <net/netns/generic.h> #include <net/rtnetlink.h> #include <net/udp.h> +#include <net/gue.h> #if IS_ENABLED (CONFIG_IPV6 )#include <net/ipv6.h>
@@ -495,6 +496,8 @@ static int ip_encap_hlen(struct ip_tunnel_encap *e)return 0 ;case TUNNEL_ENCAP_FOU :return sizeof (struct udphdr ); +case TUNNEL_ENCAP_GUE : +return sizeof (struct udphdr ) +sizeof (struct guehdr );default :return -EINVAL ; }
@@ -546,6 +549,15 @@ static int fou_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e,skb_reset_transport_header (skb); uh =udp_hdr (skb); +if (e->type ==TUNNEL_ENCAP_GUE ) { +struct guehdr *guehdr = (struct guehdr *)&uh[1 ]; + + guehdr->version =0 ; + guehdr->hlen =0 ; + guehdr->flags =0 ; + guehdr->next_hdr = *protocol; + } + uh->dest = e->dport; uh->source = sport; uh->len =htons (skb->len);
@@ -565,6 +577,7 @@ int ip_tunnel_encap(struct sk_buff *skb, struct ip_tunnel *t,case TUNNEL_ENCAP_NONE :return 0 ;case TUNNEL_ENCAP_FOU : +case TUNNEL_ENCAP_GUE :return fou_build_header (skb, &t->encap, t->encap_hlen, protocol, fl4);default :
Signature · 1 line
2.1.0.rc2.206.gedb03e5
David Miller
maintainerFrom: Tom Herbert <[email protected]>
Date: Fri, 3 Oct 2014 15:48:06 -0700
Quoted 3 lines
Generic UDP Encapsulation (GUE) is UDP encapsulation protocol which encapsulates packets of various IP protocols. The GUE protocol is described in http://tools.ietf.org/html/draft-herbert-gue-01.
This looks better, applied, thanks Tom.