diff mbox series

[net-next,v2,09/12] gtp: support GRO

Message ID 20201211122612.869225-10-jonas@norrbonn.se
State Superseded
Headers show
Series gtp: IPv6 support | expand

Commit Message

Jonas Bonn Dec. 11, 2020, 12:26 p.m. UTC
This patch implements GRO callbacks for UDP-tunneled GTP traffic.

iperf3 numbers

Without GRO for GTP tunnels:

Accepted connection from 172.99.2.1, port 48783
[  5] local 172.99.0.1 port 5201 connected to 172.99.2.1 port 46095
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   563 MBytes  576306 KBytes/sec
[  5]   1.00-2.00   sec   681 MBytes  697814 KBytes/sec
[  5]   2.00-3.00   sec   677 MBytes  693612 KBytes/sec
[  5]   3.00-4.00   sec   679 MBytes  695690 KBytes/sec
[  5]   4.00-5.00   sec   683 MBytes  699521 KBytes/sec
[  5]   5.00-6.00   sec   682 MBytes  698922 KBytes/sec
[  5]   6.00-7.00   sec   683 MBytes  699820 KBytes/sec
[  5]   7.00-8.00   sec   682 MBytes  698052 KBytes/sec
[  5]   8.00-9.00   sec   683 MBytes  699245 KBytes/sec
[  5]   9.00-10.00  sec   683 MBytes  699554 KBytes/sec
[  5]  10.00-10.00  sec   616 KBytes  687914 KBytes/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  6.54 GBytes  685853 KBytes/sec                  receiver

With GRO for GTP tunnels:

Accepted connection from 172.99.2.1, port 40847
[  5] local 172.99.0.1 port 5201 connected to 172.99.2.1 port 55053
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   989 MBytes  1012640 KBytes/sec
[  5]   1.00-2.00   sec  1.23 GBytes  1291408 KBytes/sec
[  5]   2.00-3.00   sec  1.26 GBytes  1320197 KBytes/sec
[  5]   3.00-4.00   sec  1.29 GBytes  1350097 KBytes/sec
[  5]   4.00-5.00   sec  1.23 GBytes  1284512 KBytes/sec
[  5]   5.00-6.00   sec  1.26 GBytes  1326329 KBytes/sec
[  5]   6.00-7.00   sec  1.28 GBytes  1338620 KBytes/sec
[  5]   7.00-8.00   sec  1.28 GBytes  1346391 KBytes/sec
[  5]   8.00-9.00   sec  1.30 GBytes  1366394 KBytes/sec
[  5]   9.00-10.00  sec  1.26 GBytes  1323848 KBytes/sec
[  5]  10.00-10.00  sec   384 KBytes  1113043 KBytes/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  12.4 GBytes  1296036 KBytes/sec                  receiver

Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
---
 drivers/net/gtp.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

Comments

kernel test robot Dec. 11, 2020, 3:43 p.m. UTC | #1
Hi Jonas,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Jonas-Bonn/gtp-IPv6-support/20201211-203639
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 91163f82143630a9629a8bf0227d49173697c69c
config: mips-randconfig-r026-20201209 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 5ff35356f1af2bb92785b38c657463924d9ec386)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install mips cross compiling tool for clang build
        # apt-get install binutils-mips-linux-gnu
        # https://github.com/0day-ci/linux/commit/de5669628a8f684dd7ed378aaf2a997221d243fa
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jonas-Bonn/gtp-IPv6-support/20201211-203639
        git checkout de5669628a8f684dd7ed378aaf2a997221d243fa
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/gtp.c:402:2: warning: variable 'err' is used uninitialized whenever 'if' condition is true
   if (!ptype)
   ^~~~~~~~~~~
   include/linux/compiler.h:56:28: note: expanded from macro 'if'
   #define if(cond, ...) if ( __trace_if_var( , ## __VA_ARGS__) ) )
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler.h:58:30: note: expanded from macro '__trace_if_var'
   #define __trace_if_var(cond) (__builtin_constant_p(cond) (cond) : __trace_if_value(cond))
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/gtp.c:413:9: note: uninitialized use occurs here
   return err;
   ^~~
   drivers/net/gtp.c:402:2: note: remove the 'if' if its condition is always false
   if (!ptype)
   ^~~~~~~~~~~
   include/linux/compiler.h:56:23: note: expanded from macro 'if'
   #define if(cond, ...) if ( __trace_if_var( , ## __VA_ARGS__) ) )
   ^
>> drivers/net/gtp.c:396:2: warning: variable 'err' is used uninitialized whenever switch default is taken
   default:
   ^~~~~~~
   drivers/net/gtp.c:413:9: note: uninitialized use occurs here
   return err;
   ^~~
   drivers/net/gtp.c:372:9: note: initialize the variable 'err' to silence this warning
   int err;
   ^
   = 0
   fatal error: error in backend: Nested variants found in inline asm string: ' .set push
   .set mips64r2
   .if ( 0x00 ) != -1)) 0x00 ) != -1)) : ($( static struct ftrace_branch_data __attribute__((__aligned__(4))) __attribute__((__section__("_ftrace_branch"))) __if_trace = $( .func = __func__, .file = "arch/mips/include/asm/atomic.h", .line = 153, $); 0x00 ) != -1)) : $))) ) && ( 0 ); .set push; .set mips64r2; .rept 1; sync 0x00; .endr; .set pop; .else; ; .endif
   1: ll $1, $2 # atomic_fetch_add
   addu $0, $1, $3
   sc $0, $2
   beqz $0, 1b
   .set pop
   move $0, $1
   '
   clang-12: error: clang frontend command failed with exit code 70 (use -v to see invocation)
   clang version 12.0.0 (git://gitmirror/llvm_project 5ff35356f1af2bb92785b38c657463924d9ec386)
   Target: mipsel-unknown-linux-gnu
   Thread model: posix
   InstalledDir: /opt/cross/clang-5ff35356f1/bin
   clang-12: note: diagnostic msg:
   Makefile arch drivers include kernel scripts source usr

vim +402 drivers/net/gtp.c

   363	
   364	static int gtp_gro_complete(struct sock *sk, struct sk_buff * skb, int nhoff)
   365	{
   366		size_t hdrlen;
   367		char* gtphdr = skb->data + nhoff;
   368		u8 version;
   369		__be16 type;
   370		struct packet_offload *ptype;
   371		uint8_t ipver;
   372		int err;
   373	
   374		version = *gtphdr >> 5;
   375		switch (version) {
   376		case GTP_V0:
   377			hdrlen = sizeof(struct gtp0_header);
   378			break;
   379		case GTP_V1:
   380			hdrlen = sizeof(struct gtp1_header);
   381			if (*gtphdr & GTP1_F_MASK)
   382				hdrlen += 4;
   383			break;
   384		}
   385	
   386		skb_set_inner_network_header(skb, nhoff + hdrlen);
   387	
   388		ipver = inner_ip_hdr(skb)->version;
   389		switch (ipver) {
   390		case 4:
   391			type = cpu_to_be16(ETH_P_IP);
   392			break;
   393		case 6:
   394			type = cpu_to_be16(ETH_P_IPV6);
   395			break;
 > 396		default:
   397			goto out;
   398		}
   399	
   400		rcu_read_lock();
   401		ptype = gro_find_complete_by_type(type);
 > 402		if (!ptype)
   403			goto out_unlock;
   404	
   405		err = ptype->callbacks.gro_complete(skb, nhoff + hdrlen);
   406	
   407		skb_set_inner_mac_header(skb, nhoff + hdrlen);
   408	
   409	out_unlock:
   410		rcu_read_unlock();
   411	out:
   412	
   413		return err;
   414	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 7bbeec173113..86639fae8d45 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -361,6 +361,128 @@  static int gtp_encap_recv(struct sock *sk, struct sk_buff *skb)
 	return ret;
 }
 
+static int gtp_gro_complete(struct sock *sk, struct sk_buff * skb, int nhoff)
+{
+	size_t hdrlen;
+	char* gtphdr = skb->data + nhoff;
+	u8 version;
+	__be16 type;
+	struct packet_offload *ptype;
+	uint8_t ipver;
+	int err;
+
+	version = *gtphdr >> 5;
+	switch (version) {
+	case GTP_V0:
+		hdrlen = sizeof(struct gtp0_header);
+		break;
+	case GTP_V1:
+		hdrlen = sizeof(struct gtp1_header);
+		if (*gtphdr & GTP1_F_MASK)
+			hdrlen += 4;
+		break;
+	}
+
+	skb_set_inner_network_header(skb, nhoff + hdrlen);
+
+	ipver = inner_ip_hdr(skb)->version;
+	switch (ipver) {
+	case 4:
+		type = cpu_to_be16(ETH_P_IP);
+		break;
+	case 6:
+		type = cpu_to_be16(ETH_P_IPV6);
+		break;
+	default:
+		goto out;
+	}
+
+	rcu_read_lock();
+	ptype = gro_find_complete_by_type(type);
+	if (!ptype)
+		goto out_unlock;
+
+	err = ptype->callbacks.gro_complete(skb, nhoff + hdrlen);
+
+	skb_set_inner_mac_header(skb, nhoff + hdrlen);
+
+out_unlock:
+	rcu_read_unlock();
+out:
+
+	return err;
+
+}
+
+static struct sk_buff *gtp_gro_receive(struct sock *sk,
+				       struct list_head *head,
+				       struct sk_buff *skb)
+{
+	size_t off, hdrlen;
+	char* gtphdr;
+	u8 version;
+	struct sk_buff *pp = NULL;
+	__be16 type;
+	struct packet_offload *ptype;
+
+	off = skb_gro_offset(skb);
+
+	gtphdr = skb_gro_header_fast(skb, off);
+	if (skb_gro_header_hard(skb, off+1)) {
+		gtphdr = skb_gro_header_slow(skb, off+1, off);
+		if (unlikely(!gtphdr))
+			goto out;
+	}
+
+	version = *gtphdr >> 5;
+	switch (version) {
+	case GTP_V0:
+		hdrlen = sizeof(struct gtp0_header);
+		break;
+	case GTP_V1:
+		hdrlen = sizeof(struct gtp1_header);
+		if (*gtphdr & GTP1_F_MASK)
+			hdrlen += 4;
+		break;
+	}
+
+	gtphdr = skb_gro_header_fast(skb, off);
+	if (skb_gro_header_hard(skb, off+hdrlen)) {
+		gtphdr = skb_gro_header_slow(skb, off+hdrlen, off);
+		if (unlikely(!gtphdr))
+			goto out;
+	}
+
+	skb_set_inner_network_header(skb, off + hdrlen);
+
+	switch(inner_ip_hdr(skb)->version) {
+	case 4:
+		type = cpu_to_be16(ETH_P_IP);
+		break;
+	case 6:
+		type = cpu_to_be16(ETH_P_IPV6);
+		break;
+	default:
+		goto out;
+	}
+
+	rcu_read_lock();
+	ptype = gro_find_receive_by_type(type);
+	if (!ptype)
+		goto out_unlock;
+
+	skb_gro_pull(skb, hdrlen);
+	skb_gro_postpull_rcsum(skb, gtphdr, hdrlen);
+
+	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
+
+out_unlock:
+	rcu_read_unlock();
+out:
+
+	return pp;
+}
+
 static int gtp_dev_init(struct net_device *dev)
 {
 	struct gtp_dev *gtp = netdev_priv(dev);
@@ -622,7 +744,9 @@  static void gtp_link_setup(struct net_device *dev)
 
 	dev->priv_flags	|= IFF_NO_QUEUE;
 	dev->features	|= NETIF_F_LLTX;
+	dev->hw_features |= NETIF_F_RXCSUM;
 	dev->hw_features |= NETIF_F_SG | NETIF_F_GSO_SOFTWARE | NETIF_F_HW_CSUM;
+	dev->features	|= NETIF_F_RXCSUM;
 	dev->features	|= NETIF_F_SG | NETIF_F_GSO_SOFTWARE | NETIF_F_HW_CSUM;
 	netif_keep_dst(dev);
 
@@ -818,6 +942,8 @@  static struct sock *gtp_encap_enable_socket(int fd, int type,
 	tuncfg.encap_type = type;
 	tuncfg.encap_rcv = gtp_encap_recv;
 	tuncfg.encap_destroy = gtp_encap_destroy;
+	tuncfg.gro_receive = gtp_gro_receive;
+	tuncfg.gro_complete = gtp_gro_complete;
 
 	setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg);