vxlan: Add support for remote checksum offload

This patch adds support to remote checksum checksum offload
to VXLAN. This patch adds remcsumtx and remcsumrx to ip vxlan
configuration to enable remote checksum offload for transmit
and receive on the VXLAN tunnel.

https://tools.ietf.org/html/draft-herbert-vxlan-rco-00

Example:

ip link add name vxlan0 type vxlan id 42 group 239.1.1.1 dev eth0 \
    udpcsum remcsumtx remcsumrx

Testing:

Ran single netperf over mlnx4 to illustrate the effest:

- Without RCO (UDP csum set to zero)
  4335.99 Mbps
- With RCO enabled
  7661.81 Mbps

Signed-off-by: Tom Herbert <tom@herbertland.com>
This commit is contained in:
Tom Herbert 2015-11-27 10:23:43 -08:00 committed by Stephen Hemminger
parent 61170fd88d
commit 35f59d862f
1 changed files with 21 additions and 0 deletions

View File

@ -30,6 +30,7 @@ static void print_explain(FILE *f)
fprintf(f, " [ [no]l2miss ] [ [no]l3miss ]\n");
fprintf(f, " [ ageing SECONDS ] [ maxaddress NUMBER ]\n");
fprintf(f, " [ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ]\n");
fprintf(f, " [ [no]remcsumtx ] [ [no]remcsumrx ]\n");
fprintf(f, " [ gbp ]\n");
fprintf(f, "\n");
fprintf(f, "Where: VNI := 0-16777215\n");
@ -69,6 +70,8 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
__u8 udpcsum = 0;
__u8 udp6zerocsumtx = 0;
__u8 udp6zerocsumrx = 0;
__u8 remcsumtx = 0;
__u8 remcsumrx = 0;
__u8 gbp = 0;
int dst_port_set = 0;
struct ifla_vxlan_port_range range = { 0, 0 };
@ -199,6 +202,14 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
udp6zerocsumrx = 1;
} else if (!matches(*argv, "noudp6zerocsumrx")) {
udp6zerocsumrx = 0;
} else if (!matches(*argv, "remcsumtx")) {
remcsumtx = 1;
} else if (!matches(*argv, "noremcsumtx")) {
remcsumtx = 0;
} else if (!matches(*argv, "remcsumrx")) {
remcsumrx = 1;
} else if (!matches(*argv, "noremcsumrx")) {
remcsumrx = 0;
} else if (!matches(*argv, "gbp")) {
gbp = 1;
} else if (matches(*argv, "help") == 0) {
@ -259,6 +270,8 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
addattr8(n, 1024, IFLA_VXLAN_UDP_CSUM, udpcsum);
addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, udp6zerocsumtx);
addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, udp6zerocsumrx);
addattr8(n, 1024, IFLA_VXLAN_REMCSUM_TX, remcsumtx);
addattr8(n, 1024, IFLA_VXLAN_REMCSUM_RX, remcsumrx);
if (noage)
addattr32(n, 1024, IFLA_VXLAN_AGEING, 0);
@ -407,6 +420,14 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
rta_getattr_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
fputs("udp6zerocsumrx ", f);
if (tb[IFLA_VXLAN_REMCSUM_TX] &&
rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_TX]))
fputs("remcsumtx ", f);
if (tb[IFLA_VXLAN_REMCSUM_RX] &&
rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_RX]))
fputs("remcsumrx ", f);
if (tb[IFLA_VXLAN_GBP])
fputs("gbp ", f);
}