Skip to contentSkip to conversation

iproute2: Add FOU and GUE configuration in ip

PATCH In review Tom Herbert 2 participants 9 messages Nov 5, 2014 – Nov 7, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v2 cover iproute2: Add FOU and GUE configuration in ip

This patch set adds support in iproute2 to configure FOU and GUE ports for receive, and using FOU or GUE with ip tunnels (IPIP, GRE, sit) on transmit.

A new ip subcommand "fou" has been added to configure FOU/GUE ports. For example:

ip fou add port 5555 gue
ip fou add port 9999 ipproto 4

The first command creates a GUE port, the second creates a direct FOU port for IPIP (receive payload is a assumed to be an IP packet).

fou.8 and gue.8 man pages were added to describe this command.

To configure an IP tunnel to use FOU or GUE encap parameters have been added. For example:

  ip link add name tun1 type ipip remote 192.168.1.1 local 192.168.1.2 \
     ttl 225 encap gue encap-sport auto encap-dport 7777 encap-csum
  ip link add name tun2 type gre remote 192.168.1.1 local 192.168.1.2 \
     ttl 225 encap fou encap-sport auto encap-dport 8888 encap-csum

The first command configures an IPIP tunnel to use GUE on transmit. The peer might be configured to receive GUE packets with the
"ip fou add port 7777 gue" command.

The second configures a GRE tunnel to use FOU encapsulation. The peer might be configured to receive these packets with the "ip fou add port 8888 ipproto 47" command.

v2:
- Add man pages fou.8 and gue.8
- Add ntohs for print ports in configuration
- Add support for remote checksum offload

Tom Herbert (5):
ip fou: Support to configure foo-over-udp RX ip link ipip: Add support to configure FOU and GUE ip link gre: Add support to configure FOU and GUE ip link: Add support for remote checksum offload
iproute2: Man pages for fou and gue

 include/linux/fou.h       |  41 ++++++++++++
 include/linux/if_tunnel.h |   1 +
 ip/Makefile               |   2 +-
 ip/ip.c                   |   3 +-
 ip/ip_common.h            |   1 +
 ip/ipfou.c                | 159 ++++++++++++++++++++++++++++++++++++++++++++++
 ip/link_gre.c             |  98 ++++++++++++++++++++++++++++
 ip/link_iptnl.c           |  98 ++++++++++++++++++++++++++++
 man/man8/ip-fou.8         |  76 ++++++++++++++++++++++
 man/man8/ip-gue.8         |   1 +
 10 files changed, 478 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/fou.h
 create mode 100644 ip/ipfou.c
 create mode 100644 man/man8/ip-fou.8
 create mode 100644 man/man8/ip-gue.8
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#1 lore raw

PATCH v2 1/5 ip fou: Support to configure foo-over-udp RX

Added 'ip fou...' commands to enable/disable UDP ports for doing foo-over-udp and Generic UDP Encapsulation variant. Arguments are port number to bind to and IP protocol to map to port (for direct FOU).

Examples:

ip fou add port 7777 gue
ip fou add port 8888 ipproto 4

The first command creates a GUE port, the second creates a direct FOU port for IPIP (receive payload is a assumed to be an IPv4 packet).

---
 include/linux/fou.h |  41 ++++++++++++++
 ip/Makefile         |   2 +-
 ip/ip.c             |   3 +-
 ip/ip_common.h      |   1 +
 ip/ipfou.c          | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 204 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/fou.h
 create mode 100644 ip/ipfou.c
include/linux/fou.h new file +41 -0
new file mode 100644
index 0000000..e1724ff
@@ -0,0 +1,41 @@
+/* fou.h - FOU Interface */
+
+#ifndef _LINUX_FOU_H
+#define _LINUX_FOU_H
+
+#include <linux/types.h>
+
+/* NETLINK_GENERIC related info
+ */
+#define FOU_GENL_NAME		"fou"
+#define FOU_GENL_VERSION	0x1
+
+enum {
+	FOU_ATTR_UNSPEC,
+	FOU_ATTR_PORT,				/* u16 */
+	FOU_ATTR_AF,				/* u8 */
+	FOU_ATTR_IPPROTO,			/* u8 */
+	FOU_ATTR_TYPE,				/* u8 */
+
+	__FOU_ATTR_MAX,
+};
+
+#define FOU_ATTR_MAX		(__FOU_ATTR_MAX - 1)
+
+enum {
+	FOU_CMD_UNSPEC,
+	FOU_CMD_ADD,
+	FOU_CMD_DEL,
+
+	__FOU_CMD_MAX,
+};
+
+enum {
+	FOU_ENCAP_UNSPEC,
+	FOU_ENCAP_DIRECT,
+	FOU_ENCAP_GUE,
+};
+
+#define FOU_CMD_MAX	(__FOU_CMD_MAX - 1)
+
+#endif /* _LINUX_FOU_H */
ip/Makefile +1 -1
index 5405ee7..1f50848 100644
@@ -6,7 +6,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \
     iplink_macvlan.o iplink_macvtap.o ipl2tp.o link_vti.o link_vti6.o \
     iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \
     link_iptnl.o link_gre6.o iplink_bond.o iplink_bond_slave.o iplink_hsr.o \
-    iplink_bridge.o iplink_bridge_slave.o
+    iplink_bridge.o iplink_bridge_slave.o ipfou.o
 
 RTMONOBJ=rtmon.o
 
ip/ip.c +2 -1
index e4b201f..5f759d5 100644
@@ -47,7 +47,7 @@ static void usage(void)
 "       ip [ -force ] -batch filename\n"
 "where  OBJECT := { link | addr | addrlabel | route | rule | neigh | ntable |\n"
 "                   tunnel | tuntap | maddr | mroute | mrule | monitor | xfrm |\n"
-"                   netns | l2tp | tcp_metrics | token | netconf }\n"
+"                   netns | l2tp | fou | tcp_metrics | token | netconf }\n"
 "       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
 "                    -h[uman-readable] | -iec |\n"
 "                    -f[amily] { inet | inet6 | ipx | dnet | bridge | link } |\n"
@@ -79,6 +79,7 @@ static const struct cmd {
 	{ "ntbl",	do_ipntable },
 	{ "link",	do_iplink },
 	{ "l2tp",	do_ipl2tp },
+	{ "fou",	do_ipfou },
 	{ "tunnel",	do_iptunnel },
 	{ "tunl",	do_iptunnel },
 	{ "tuntap",	do_iptuntap },
ip/ip_common.h +1 -0
index 8351463..095c92d 100644
@@ -48,6 +48,7 @@ extern int do_multirule(int argc, char **argv);
 extern int do_netns(int argc, char **argv);
 extern int do_xfrm(int argc, char **argv);
 extern int do_ipl2tp(int argc, char **argv);
+extern int do_ipfou(int argc, char **argv);
 extern int do_tcp_metrics(int argc, char **argv);
 extern int do_ipnetconf(int argc, char **argv);
 extern int do_iptoken(int argc, char **argv);
ip/ipfou.c new file +159 -0

159 lines not on this page · raw message

Signature · 1 line
2.1.0.rc2.206.gedb03e5
#2 lore raw

PATCH v2 2/5 ip link ipip: Add support to configure FOU and GUE

In reply to Tom Herbert

This patch adds support to configure foo-over-udp (FOU) and Generic UDP Encapsulation for IPIP and sit tunnels. This configuration allows selection of FOU or GUE for the tunnel, specification of the source and destination ports for UDP tunnel, and enabling TX checksum. This configuration only affects the transmit side of a tunnel.

Example:

ip link add name tun1 type ipip remote 192.168.1.1 local 192.168.1.2 \
ttl 225 encap gue encap-sport auto encap-dport 9999 encap-csum

This would create an IPIP tunnel in GUE encapsulation where the source port is automatically selected (based on hash of inner packet) and checksums in the encapsulating UDP header are enabled.

---
 ip/link_iptnl.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)
ip/link_iptnl.c +89 -0
index ea13ce9..9487117 100644
@@ -29,6 +29,9 @@ static void print_usage(FILE *f, int sit)
 	fprintf(f, "          type { ipip | sit } [ remote ADDR ] [ local ADDR ]\n");
 	fprintf(f, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
 	fprintf(f, "          [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n");
+	fprintf(f, "          [ noencap ] [ encap { fou | gue | none } ]\n");
+	fprintf(f, "          [ encap-sport PORT ] [ encap-dport PORT ]\n");
+	fprintf(f, "          [ [no]encap-csum ] [ [no]encap-csum6 ]\n");
 	if (sit) {
 		fprintf(f, "          [ mode { ip6ip | ipip | any } ]\n");
 		fprintf(f, "          [ isatap ]\n");
@@ -72,6 +75,10 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u16 ip6rdprefixlen = 0;
 	__u32 ip6rdrelayprefix = 0;
 	__u16 ip6rdrelayprefixlen = 0;
+	__u16 encaptype = 0;
+	__u16 encapflags = 0;
+	__u16 encapsport = 0;
+	__u16 encapdport = 0;
 
 	memset(&ip6rdprefix, 0, sizeof(ip6rdprefix));
 
@@ -134,6 +141,14 @@ get_failed:
 		if (iptuninfo[IFLA_IPTUN_PROTO])
 			proto = rta_getattr_u8(iptuninfo[IFLA_IPTUN_PROTO]);
 
+		if (iptuninfo[IFLA_IPTUN_ENCAP_TYPE])
+			encaptype = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_TYPE]);
+		if (iptuninfo[IFLA_IPTUN_ENCAP_FLAGS])
+			encapflags = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_FLAGS]);
+		if (iptuninfo[IFLA_IPTUN_ENCAP_SPORT])
+			encapsport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_SPORT]);
+		if (iptuninfo[IFLA_IPTUN_ENCAP_DPORT])
+			encapdport = rta_getattr_u16(iptuninfo[IFLA_IPTUN_ENCAP_DPORT]);
 		if (iptuninfo[IFLA_IPTUN_6RD_PREFIX])
 			memcpy(&ip6rdprefix,
 			       RTA_DATA(iptuninfo[IFLA_IPTUN_6RD_PREFIX]),
@@ -211,6 +226,36 @@ get_failed:
 				proto = 0;
 			else
 				invarg("Cannot guess tunnel mode.", *argv);
+		} else if (strcmp(*argv, "noencap") == 0) {
+			encaptype = TUNNEL_ENCAP_NONE;
+		} else if (strcmp(*argv, "encap") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "fou") == 0)
+				encaptype = TUNNEL_ENCAP_FOU;
+			else if (strcmp(*argv, "gue") == 0)
+				encaptype = TUNNEL_ENCAP_GUE;
+			else if (strcmp(*argv, "none") == 0)
+				encaptype = TUNNEL_ENCAP_NONE;
+			else
+				invarg("Invalid encap type.", *argv);
+		} else if (strcmp(*argv, "encap-sport") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "auto") == 0)
+				encapsport = 0;
+			else if (get_u16(&encapsport, *argv, 0))
+				invarg("Invalid source port.", *argv);
+		} else if (strcmp(*argv, "encap-dport") == 0) {
+			NEXT_ARG();
+			if (get_u16(&encapdport, *argv, 0))
+				invarg("Invalid destination port.", *argv);
+		} else if (strcmp(*argv, "encap-csum") == 0) {
+			encapflags |= TUNNEL_ENCAP_FLAG_CSUM;
+		} else if (strcmp(*argv, "noencap-csum") == 0) {
+			encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM;
+		} else if (strcmp(*argv, "encap-udp6-csum") == 0) {
+			encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
+		} else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
+			encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM6;
 		} else if (strcmp(*argv, "6rd-prefix") == 0) {
 			inet_prefix prefix;
 			NEXT_ARG();
@@ -248,6 +293,12 @@ get_failed:
 	addattr8(n, 1024, IFLA_IPTUN_TTL, ttl);
 	addattr8(n, 1024, IFLA_IPTUN_TOS, tos);
 	addattr8(n, 1024, IFLA_IPTUN_PMTUDISC, pmtudisc);
+
+	addattr16(n, 1024, IFLA_IPTUN_ENCAP_TYPE, encaptype);
+	addattr16(n, 1024, IFLA_IPTUN_ENCAP_FLAGS, encapflags);
+	addattr16(n, 1024, IFLA_IPTUN_ENCAP_SPORT, htons(encapsport));
+	addattr16(n, 1024, IFLA_IPTUN_ENCAP_DPORT, htons(encapdport));
+
 	if (strcmp(lu->id, "sit") == 0) {
 		addattr16(n, 1024, IFLA_IPTUN_FLAGS, iflags);
 		addattr8(n, 1024, IFLA_IPTUN_PROTO, proto);
@@ -350,6 +401,44 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
 			       relayprefixlen);
 		}
 	}
+
+	if (tb[IFLA_IPTUN_ENCAP_TYPE] &&
+	    *(__u16 *)RTA_DATA(tb[IFLA_IPTUN_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) {
+		__u16 type = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_TYPE]);
+		__u16 flags = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_FLAGS]);
+		__u16 sport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_SPORT]);
+		__u16 dport = rta_getattr_u16(tb[IFLA_IPTUN_ENCAP_DPORT]);
+
+		fputs("encap ", f);
+		switch (type) {
+		case TUNNEL_ENCAP_FOU:
+			fputs("fou ", f);
+			break;
+		case TUNNEL_ENCAP_GUE:
+			fputs("gue ", f);
+			break;
+		default:
+			fputs("unknown ", f);
+			break;
+		}
+
+		if (sport == 0)
+			fputs("encap-sport auto ", f);
+		else
+			fprintf(f, "encap-sport %u", ntohs(sport));
+
+		fprintf(f, "encap-dport %u ", ntohs(dport));
+
+		if (flags & TUNNEL_ENCAP_FLAG_CSUM)
+			fputs("encap-csum ", f);
+		else
+			fputs("noencap-csum ", f);
+
+		if (flags & TUNNEL_ENCAP_FLAG_CSUM6)
+			fputs("encap-csum6 ", f);
+		else
+			fputs("noencap-csum6 ", f);
+	}
 }
 
 static void iptunnel_print_help(struct link_util *lu, int argc, char **argv,
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#3 lore raw

PATCH v2 3/5 ip link gre: Add support to configure FOU and GUE

In reply to Tom Herbert

This patch adds support to configure foo-over-udp (FOU) and Generic UDP Encapsulation for GRE tunnels. This configuration allows selection of FOU or GUE for the tunnel, specification of the source and destination ports for UDP tunnel, and enabling TX checksum. This configuration only affects the transmit side of a tunnel.

Example:

ip link add name tun1 type gre remote 192.168.1.1 local 192.168.1.2 \
ttl 225 encap fou encap-sport auto encap-dport 7777 encap-csum

This would create an GRE tunnel in GUE encapsulation where the source port is automatically selected (based on hash of inner packet) and checksums in the encapsulating UDP header are enabled.

---
 ip/link_gre.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)
ip/link_gre.c +89 -0
index 83653d0..47b64cb 100644
@@ -29,6 +29,9 @@ static void print_usage(FILE *f)
 	fprintf(f, "          type { gre | gretap } [ remote ADDR ] [ local ADDR ]\n");
 	fprintf(f, "          [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n");
 	fprintf(f, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
+	fprintf(f, "          [ noencap ] [ encap { fou | gue | none } ]\n");
+	fprintf(f, "          [ encap-sport PORT ] [ encap-dport PORT ]\n");
+	fprintf(f, "          [ [no]encap-csum ] [ [no]encap-csum6 ]\n");
 	fprintf(f, "\n");
 	fprintf(f, "Where: NAME := STRING\n");
 	fprintf(f, "       ADDR := { IP_ADDRESS | any }\n");
@@ -67,6 +70,10 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv,
 	__u8 ttl = 0;
 	__u8 tos = 0;
 	int len;
+	__u16 encaptype = 0;
+	__u16 encapflags = 0;
+	__u16 encapsport = 0;
+	__u16 encapdport = 0;
 
 	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
 		memset(&req, 0, sizeof(req));
@@ -132,6 +139,15 @@ get_failed:
 
 		if (greinfo[IFLA_GRE_LINK])
 			link = rta_getattr_u8(greinfo[IFLA_GRE_LINK]);
+
+		if (greinfo[IFLA_GRE_ENCAP_TYPE])
+			encaptype = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_TYPE]);
+		if (greinfo[IFLA_GRE_ENCAP_FLAGS])
+			encapflags = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_FLAGS]);
+		if (greinfo[IFLA_GRE_ENCAP_SPORT])
+			encapsport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_SPORT]);
+		if (greinfo[IFLA_GRE_ENCAP_DPORT])
+			encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]);
 	}
 
 	while (argc > 0) {
@@ -241,6 +257,36 @@ get_failed:
 				tos = uval;
 			} else
 				tos = 1;
+		} else if (strcmp(*argv, "noencap") == 0) {
+			encaptype = TUNNEL_ENCAP_NONE;
+		} else if (strcmp(*argv, "encap") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "fou") == 0)
+				encaptype = TUNNEL_ENCAP_FOU;
+			else if (strcmp(*argv, "gue") == 0)
+				encaptype = TUNNEL_ENCAP_GUE;
+			else if (strcmp(*argv, "none") == 0)
+				encaptype = TUNNEL_ENCAP_NONE;
+			else
+				invarg("Invalid encap type.", *argv);
+		} else if (strcmp(*argv, "encap-sport") == 0) {
+			NEXT_ARG();
+			if (strcmp(*argv, "auto") == 0)
+				encapsport = 0;
+			else if (get_u16(&encapsport, *argv, 0))
+				invarg("Invalid source port.", *argv);
+		} else if (strcmp(*argv, "encap-dport") == 0) {
+			NEXT_ARG();
+			if (get_u16(&encapdport, *argv, 0))
+				invarg("Invalid destination port.", *argv);
+		} else if (strcmp(*argv, "encap-csum") == 0) {
+			encapflags |= TUNNEL_ENCAP_FLAG_CSUM;
+		} else if (strcmp(*argv, "noencap-csum") == 0) {
+			encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM;
+		} else if (strcmp(*argv, "encap-udp6-csum") == 0) {
+			encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
+		} else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
+			encapflags |= ~TUNNEL_ENCAP_FLAG_CSUM6;
 		} else
 			usage();
 		argc--; argv++;
@@ -271,6 +317,11 @@ get_failed:
 	addattr_l(n, 1024, IFLA_GRE_TTL, &ttl, 1);
 	addattr_l(n, 1024, IFLA_GRE_TOS, &tos, 1);
 
+	addattr16(n, 1024, IFLA_GRE_ENCAP_TYPE, encaptype);
+	addattr16(n, 1024, IFLA_GRE_ENCAP_FLAGS, encapflags);
+	addattr16(n, 1024, IFLA_GRE_ENCAP_SPORT, htons(encapsport));
+	addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport));
+
 	return 0;
 }
 
@@ -357,6 +408,44 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 		fputs("icsum ", f);
 	if (oflags & GRE_CSUM)
 		fputs("ocsum ", f);
+
+	if (tb[IFLA_GRE_ENCAP_TYPE] &&
+	    *(__u16 *)RTA_DATA(tb[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) {
+		__u16 type = rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]);
+		__u16 flags = rta_getattr_u16(tb[IFLA_GRE_ENCAP_FLAGS]);
+		__u16 sport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_SPORT]);
+		__u16 dport = rta_getattr_u16(tb[IFLA_GRE_ENCAP_DPORT]);
+
+		fputs("encap ", f);
+		switch (type) {
+		case TUNNEL_ENCAP_FOU:
+			fputs("fou ", f);
+			break;
+		case TUNNEL_ENCAP_GUE:
+			fputs("gue ", f);
+			break;
+		default:
+			fputs("unknown ", f);
+			break;
+		}
+
+		if (sport == 0)
+			fputs("encap-sport auto ", f);
+		else
+			fprintf(f, "encap-sport %u", ntohs(sport));
+
+		fprintf(f, "encap-dport %u ", ntohs(dport));
+
+		if (flags & TUNNEL_ENCAP_FLAG_CSUM)
+			fputs("encap-csum ", f);
+		else
+			fputs("noencap-csum ", f);
+
+		if (flags & TUNNEL_ENCAP_FLAG_CSUM6)
+			fputs("encap-csum6 ", f);
+		else
+			fputs("noencap-csum6 ", f);
+	}
 }
 
 static void gre_print_help(struct link_util *lu, int argc, char **argv,
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#4 lore raw

PATCH v2 4/5 ip link: Add support for remote checksum offload

In reply to Tom Herbert

This patch adds support to remote checksum checksum offload confinguration for IPIP, SIT, and GRE tunnels. This patch adds a [no]encap-remcsum to ip link command which applicable when configured tunnels that use GUE.

http://tools.ietf.org/html/draft-herbert-remotecsumoffload-00

Example:

ip link add name tun1 type gre remote 192.168.1.1 local 192.168.1.2 \
ttl 225 encap fou encap-sport auto encap-dport 7777 encap-csum \
encap-remcsum

This would create an GRE tunnel in GUE encapsulation where the source port is automatically selected (based on hash of inner packet), checksums in the encapsulating UDP header are enabled (needed.for remote checksum offload), and remote checksum is configured to be used on the tunnel (affects TX side).

---
 include/linux/if_tunnel.h |  1 +
 ip/link_gre.c             | 11 ++++++++++-
 ip/link_iptnl.c           | 11 ++++++++++-
 3 files changed, 21 insertions(+), 2 deletions(-)
include/linux/if_tunnel.h +1 -0
index 8b04f32..102ce7a 100644
@@ -69,6 +69,7 @@ enum tunnel_encap_types {
 
 #define TUNNEL_ENCAP_FLAG_CSUM		(1<<0)
 #define TUNNEL_ENCAP_FLAG_CSUM6		(1<<1)
+#define TUNNEL_ENCAP_FLAG_REMCSUM	(1<<2)
 
 /* SIT-mode i_flags */
 #define	SIT_ISATAP	0x0001
ip/link_gre.c +10 -1
index 47b64cb..1d78387 100644
@@ -31,7 +31,7 @@ static void print_usage(FILE *f)
 	fprintf(f, "          [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n");
 	fprintf(f, "          [ noencap ] [ encap { fou | gue | none } ]\n");
 	fprintf(f, "          [ encap-sport PORT ] [ encap-dport PORT ]\n");
-	fprintf(f, "          [ [no]encap-csum ] [ [no]encap-csum6 ]\n");
+	fprintf(f, "          [ [no]encap-csum ] [ [no]encap-csum6 ] [ [no]encap-remcsum ]\n");
 	fprintf(f, "\n");
 	fprintf(f, "Where: NAME := STRING\n");
 	fprintf(f, "       ADDR := { IP_ADDRESS | any }\n");
@@ -287,6 +287,10 @@ get_failed:
 			encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
 		} else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
 			encapflags |= ~TUNNEL_ENCAP_FLAG_CSUM6;
+		} else if (strcmp(*argv, "encap-remcsum") == 0) {
+			encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
+		} else if (strcmp(*argv, "noencap-remcsum") == 0) {
+			encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM;
 		} else
 			usage();
 		argc--; argv++;
@@ -445,6 +449,11 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 			fputs("encap-csum6 ", f);
 		else
 			fputs("noencap-csum6 ", f);
+
+		if (flags & TUNNEL_ENCAP_FLAG_REMCSUM)
+			fputs("encap-remcsum ", f);
+		else
+			fputs("noencap-remcsum ", f);
 	}
 }
 
ip/link_iptnl.c +10 -1
index 9487117..cab174f 100644
@@ -31,7 +31,7 @@ static void print_usage(FILE *f, int sit)
 	fprintf(f, "          [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n");
 	fprintf(f, "          [ noencap ] [ encap { fou | gue | none } ]\n");
 	fprintf(f, "          [ encap-sport PORT ] [ encap-dport PORT ]\n");
-	fprintf(f, "          [ [no]encap-csum ] [ [no]encap-csum6 ]\n");
+	fprintf(f, "          [ [no]encap-csum ] [ [no]encap-csum6 ] [ [no]encap-remcsum ]\n");
 	if (sit) {
 		fprintf(f, "          [ mode { ip6ip | ipip | any } ]\n");
 		fprintf(f, "          [ isatap ]\n");
@@ -256,6 +256,10 @@ get_failed:
 			encapflags |= TUNNEL_ENCAP_FLAG_CSUM6;
 		} else if (strcmp(*argv, "noencap-udp6-csum") == 0) {
 			encapflags &= ~TUNNEL_ENCAP_FLAG_CSUM6;
+		} else if (strcmp(*argv, "encap-remcsum") == 0) {
+			encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM;
+		} else if (strcmp(*argv, "noencap-remcsum") == 0) {
+			encapflags &= ~TUNNEL_ENCAP_FLAG_REMCSUM;
 		} else if (strcmp(*argv, "6rd-prefix") == 0) {
 			inet_prefix prefix;
 			NEXT_ARG();
@@ -438,6 +442,11 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
 			fputs("encap-csum6 ", f);
 		else
 			fputs("noencap-csum6 ", f);
+
+		if (flags & TUNNEL_ENCAP_FLAG_REMCSUM)
+			fputs("encap-remcsum ", f);
+		else
+			fputs("noencap-remcsum ", f);
 	}
 }
 
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#5 lore raw

Re: [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload

Quoted 19 lines · On Wed, 5 Nov 2014 10:06:27 -0800 Tom Herbert <[email protected]> wrote:

This patch adds support to remote checksum checksum offload confinguration for IPIP, SIT, and GRE tunnels. This patch adds a [no]encap-remcsum to ip link command which applicable when configured tunnels that use GUE.

http://tools.ietf.org/html/draft-herbert-remotecsumoffload-00

Example:

ip link add name tun1 type gre remote 192.168.1.1 local 192.168.1.2 \
ttl 225 encap fou encap-sport auto encap-dport 7777 encap-csum \
encap-remcsum

This would create an GRE tunnel in GUE encapsulation where the source port is automatically selected (based on hash of inner packet), checksums in the encapsulating UDP header are enabled (needed.for remote checksum offload), and remote checksum is configured to be used on the tunnel (affects TX side).

Quoted 3 lines
---
 include/linux/if_tunnel.h |  1 +

This patch is for net-next not current release
Remote checksum offload flag does not exist in upstream tree (net or linus).

Please don't mix patches for current and future releases together.

#6 lore raw

Re: [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload

In reply to Tom Herbert
Quoted 19 lines · On Wed, 5 Nov 2014 10:06:27 -0800 Tom Herbert <[email protected]> wrote:

This patch adds support to remote checksum checksum offload confinguration for IPIP, SIT, and GRE tunnels. This patch adds a [no]encap-remcsum to ip link command which applicable when configured tunnels that use GUE.

http://tools.ietf.org/html/draft-herbert-remotecsumoffload-00

Example:

ip link add name tun1 type gre remote 192.168.1.1 local 192.168.1.2 \
ttl 225 encap fou encap-sport auto encap-dport 7777 encap-csum \
encap-remcsum

This would create an GRE tunnel in GUE encapsulation where the source port is automatically selected (based on hash of inner packet), checksums in the encapsulating UDP header are enabled (needed.for remote checksum offload), and remote checksum is configured to be used on the tunnel (affects TX side).

Quoted 3 lines
---
 include/linux/if_tunnel.h |  1 +

This patch is for net-next not current release
Remote checksum offload flag does not exist in upstream tree (net or linus).

Please don't mix patches for current and future releases together

#7 lore raw

PATCH v2 5/5 iproute2: Man pages for fou and gue

In reply to Tom Herbert

Man pages for Foo-over-UDP and Generic UDP Encapsulation receive port configuration. gue man page links to fou one.

---
 man/man8/ip-fou.8 | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/ip-gue.8 |  1 +
 2 files changed, 77 insertions(+)
 create mode 100644 man/man8/ip-fou.8
 create mode 100644 man/man8/ip-gue.8
man/man8/ip-fou.8 new file +76 -0
new file mode 100644
index 0000000..0fa22ee
@@ -0,0 +1,76 @@
+.TH IP\-FOU 8 "2 Nov 2014" "iproute2" "Linux"
+.SH "NAME"
+ip-fou \- Foo-over-UDP receive port configuration
+.P
+ip-gue \- Generic UDP Encapsulation receive port configuration
+.SH "SYNOPSIS"
+.sp
+.ad l
+.in +8
+.ti -8
+.B ip
+.RI "[ " OPTIONS " ]"
+.B fou
+.RI " { " COMMAND " | "
+.BR help " }"
+.sp
+.ti -8
+.BR "ip fou add"
+.B port
+.IR PORT
+.RB "{ "
+.B gue
+.RI "|"
+.B ipproto
+.IR PROTO
+.RB " }"
+.br
+.ti -8
+.BR "ip fou del"
+.B port
+.IR PORT
+.SH DESCRIPTION
+The
+.B ip fou
+commands are used to create and delete receive ports for Foo-over-UDP
+(FOU) as well as Generic UDP Encapsulation (GUE).
+.PP
+Foo-over-UDP allows encapsulating packets of an IP protocol directly
+over UDP. The receiver infers the protocol of a packet received on
+a FOU UDP port to be the protocol configured for the port.
+.PP
+Generic UDP Encapsulation (GUE) encapsulates packets of an IP protocol
+within UDP and an encapsulation header. The encapsulation header contains the
+IP protocol number for the encapsulated packet.
+.PP
+When creating a FOU or GUE receive port, the port number is specified in
+.I PORT
+argument. If FOU is used, the IP protocol number associated with the port is specified in
+.I PROTO
+argument.
+.PP
+A FOU or GUE receive port is deleted by specifying
+.I PORT
+in the delete command.
+.SH EXAMPLES
+.PP
+.SS Configure a FOU receive port for GRE bound to 7777
+.nf
+# ip fou add port 8888 ipproto 47
+.PP
+.SS Configure a FOU receive port for IPIP bound to 8888
+.nf
+# ip fou add port 8888 ipproto 4
+.PP
+.SS Configure a GUE receive port bound to 9999
+.nf
+# ip fou add port 9999 gue
+.PP
+.SS Delete the GUE receive port bound to 9999
+.nf
+# ip fou del port 9999
+.SH SEE ALSO
+.br
+.BR ip (8)
+.SH AUTHOR
+Tom Herbert <[email protected]>
man/man8/ip-gue.8 new file +1 -0
new file mode 100644
index 0000000..4d2914c
@@ -0,0 +1 @@
+.so man8/ip-fou.8
Signature · 1 line
2.1.0.rc2.206.gedb03e5
#8 lore raw
In reply to Tom Herbert
Quoted 3 lines · On Wed, 5 Nov 2014 10:06:23 -0800 Tom Herbert <[email protected]> wrote:

This patch set adds support in iproute2 to configure FOU and GUE ports for receive, and using FOU or GUE with ip tunnels (IPIP, GRE, sit) on transmit.

Applied 1-3 and 5 (ie not part 4) because those are the only ones that apply to the current linux release.