* [PATCH v2 iproute2 1/5] ip fou: Support to configure foo-over-udp RX
2014-11-05 18:06 [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Tom Herbert
@ 2014-11-05 18:06 ` Tom Herbert
2014-11-05 18:06 ` [PATCH v2 iproute2 2/5] ip link ipip: Add support to configure FOU and GUE Tom Herbert
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2014-11-05 18:06 UTC (permalink / raw)
To: stephen, davem, netdev
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).
Signed-off-by: Tom Herbert <therbert@google.com>
---
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
diff --git a/include/linux/fou.h b/include/linux/fou.h
new file mode 100644
index 0000000..e1724ff
--- /dev/null
+++ b/include/linux/fou.h
@@ -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 */
diff --git a/ip/Makefile b/ip/Makefile
index 5405ee7..1f50848 100644
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -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
diff --git a/ip/ip.c b/ip/ip.c
index e4b201f..5f759d5 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -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 },
diff --git a/ip/ip_common.h b/ip/ip_common.h
index 8351463..095c92d 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -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);
diff --git a/ip/ipfou.c b/ip/ipfou.c
new file mode 100644
index 0000000..2676045
--- /dev/null
+++ b/ip/ipfou.c
@@ -0,0 +1,159 @@
+/*
+ * ipfou.c FOU (foo over UDP) support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Tom Herbert <therbert@google.com>
+ */
+
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <net/if.h>
+#include <linux/fou.h>
+#include <linux/genetlink.h>
+#include <linux/ip.h>
+#include <arpa/inet.h>
+
+#include "libgenl.h"
+#include "utils.h"
+#include "ip_common.h"
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: ip fou add port PORT { ipproto PROTO | gue }\n");
+ fprintf(stderr, " ip fou del port PORT\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Where: PROTO { ipproto-name | 1..255 }\n");
+ fprintf(stderr, " PORT { 1..65535 }\n");
+
+ exit(-1);
+}
+
+/* netlink socket */
+static struct rtnl_handle genl_rth = { .fd = -1 };
+static int genl_family = -1;
+
+#define FOU_REQUEST(_req, _bufsiz, _cmd, _flags) \
+ GENL_REQUEST(_req, _bufsiz, genl_family, 0, \
+ FOU_GENL_VERSION, _cmd, _flags)
+
+static int fou_parse_opt(int argc, char **argv, struct nlmsghdr *n,
+ bool adding)
+{
+ __u16 port;
+ int port_set = 0;
+ __u8 ipproto, type;
+ bool gue_set = false;
+ int ipproto_set = 0;
+
+ while (argc > 0) {
+ if (!matches(*argv, "port")) {
+ NEXT_ARG();
+
+ if (get_u16(&port, *argv, 0) || port == 0)
+ invarg("invalid port", *argv);
+ port = htons(port);
+ port_set = 1;
+ } else if (!matches(*argv, "ipproto")) {
+ struct protoent *servptr;
+
+ NEXT_ARG();
+
+ servptr = getprotobyname(*argv);
+ if (servptr)
+ ipproto = servptr->p_proto;
+ else if (get_u8(&ipproto, *argv, 0) || ipproto == 0)
+ invarg("invalid ipproto", *argv);
+ ipproto_set = 1;
+ } else if (!matches(*argv, "gue")) {
+ gue_set = true;
+ } else {
+ fprintf(stderr, "fou: unknown command \"%s\"?\n", *argv);
+ usage();
+ return -1;
+ }
+ argc--, argv++;
+ }
+
+ if (!port_set) {
+ fprintf(stderr, "fou: missing port\n");
+ return -1;
+ }
+
+ if (!ipproto_set && !gue_set && adding) {
+ fprintf(stderr, "fou: must set ipproto or gue\n");
+ return -1;
+ }
+
+ if (ipproto_set && gue_set) {
+ fprintf(stderr, "fou: cannot set ipproto and gue\n");
+ return -1;
+ }
+
+ type = gue_set ? FOU_ENCAP_GUE : FOU_ENCAP_DIRECT;
+
+ addattr16(n, 1024, FOU_ATTR_PORT, port);
+ addattr8(n, 1024, FOU_ATTR_TYPE, type);
+
+ if (ipproto_set)
+ addattr8(n, 1024, FOU_ATTR_IPPROTO, ipproto);
+
+ return 0;
+}
+
+static int do_add(int argc, char **argv)
+{
+ FOU_REQUEST(req, 1024, FOU_CMD_ADD, NLM_F_REQUEST);
+
+ fou_parse_opt(argc, argv, &req.n, true);
+
+ if (rtnl_talk(&genl_rth, &req.n, 0, 0, NULL) < 0)
+ return -2;
+
+ return 0;
+}
+
+static int do_del(int argc, char **argv)
+{
+ FOU_REQUEST(req, 1024, FOU_CMD_DEL, NLM_F_REQUEST);
+
+ fou_parse_opt(argc, argv, &req.n, false);
+
+ if (rtnl_talk(&genl_rth, &req.n, 0, 0, NULL) < 0)
+ return -2;
+
+ return 0;
+}
+
+int do_ipfou(int argc, char **argv)
+{
+ if (genl_family < 0) {
+ if (rtnl_open_byproto(&genl_rth, 0, NETLINK_GENERIC) < 0) {
+ fprintf(stderr, "Cannot open generic netlink socket\n");
+ exit(1);
+ }
+
+ genl_family = genl_resolve_family(&genl_rth, FOU_GENL_NAME);
+ if (genl_family < 0)
+ exit(1);
+ }
+
+ if (argc < 1)
+ usage();
+
+ if (matches(*argv, "add") == 0)
+ return do_add(argc-1, argv+1);
+ if (matches(*argv, "delete") == 0)
+ return do_del(argc-1, argv+1);
+ if (matches(*argv, "help") == 0)
+ usage();
+
+ fprintf(stderr, "Command \"%s\" is unknown, try \"ip fou help\".\n", *argv);
+ exit(-1);
+}
+
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 iproute2 2/5] ip link ipip: Add support to configure FOU and GUE
2014-11-05 18:06 [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Tom Herbert
2014-11-05 18:06 ` [PATCH v2 iproute2 1/5] ip fou: Support to configure foo-over-udp RX Tom Herbert
@ 2014-11-05 18:06 ` Tom Herbert
2014-11-05 18:06 ` [PATCH v2 iproute2 3/5] ip link gre: " Tom Herbert
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2014-11-05 18:06 UTC (permalink / raw)
To: stephen, davem, netdev
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.
Signed-off-by: Tom Herbert <therbert@google.com>
---
ip/link_iptnl.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
index ea13ce9..9487117 100644
--- a/ip/link_iptnl.c
+++ b/ip/link_iptnl.c
@@ -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,
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 iproute2 3/5] ip link gre: Add support to configure FOU and GUE
2014-11-05 18:06 [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Tom Herbert
2014-11-05 18:06 ` [PATCH v2 iproute2 1/5] ip fou: Support to configure foo-over-udp RX Tom Herbert
2014-11-05 18:06 ` [PATCH v2 iproute2 2/5] ip link ipip: Add support to configure FOU and GUE Tom Herbert
@ 2014-11-05 18:06 ` Tom Herbert
2014-11-05 18:06 ` [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload Tom Herbert
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2014-11-05 18:06 UTC (permalink / raw)
To: stephen, davem, netdev
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.
Signed-off-by: Tom Herbert <therbert@google.com>
---
ip/link_gre.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/ip/link_gre.c b/ip/link_gre.c
index 83653d0..47b64cb 100644
--- a/ip/link_gre.c
+++ b/ip/link_gre.c
@@ -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,
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload
2014-11-05 18:06 [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Tom Herbert
` (2 preceding siblings ...)
2014-11-05 18:06 ` [PATCH v2 iproute2 3/5] ip link gre: " Tom Herbert
@ 2014-11-05 18:06 ` Tom Herbert
2014-11-07 0:14 ` Stephen Hemminger
2014-11-07 0:41 ` Stephen Hemminger
2014-11-05 18:06 ` [PATCH v2 iproute2 5/5] iproute2: Man pages for fou and gue Tom Herbert
2014-11-07 0:21 ` [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Stephen Hemminger
5 siblings, 2 replies; 9+ messages in thread
From: Tom Herbert @ 2014-11-05 18:06 UTC (permalink / raw)
To: stephen, davem, netdev
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).
Signed-off-by: Tom Herbert <therbert@google.com>
---
include/linux/if_tunnel.h | 1 +
ip/link_gre.c | 11 ++++++++++-
ip/link_iptnl.c | 11 ++++++++++-
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
index 8b04f32..102ce7a 100644
--- a/include/linux/if_tunnel.h
+++ b/include/linux/if_tunnel.h
@@ -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
diff --git a/ip/link_gre.c b/ip/link_gre.c
index 47b64cb..1d78387 100644
--- a/ip/link_gre.c
+++ b/ip/link_gre.c
@@ -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);
}
}
diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
index 9487117..cab174f 100644
--- a/ip/link_iptnl.c
+++ b/ip/link_iptnl.c
@@ -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);
}
}
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload
2014-11-05 18:06 ` [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload Tom Herbert
@ 2014-11-07 0:14 ` Stephen Hemminger
2014-11-07 0:41 ` Stephen Hemminger
1 sibling, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2014-11-07 0:14 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
On Wed, 5 Nov 2014 10:06:27 -0800
Tom Herbert <therbert@google.com> 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).
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> 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.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload
2014-11-05 18:06 ` [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload Tom Herbert
2014-11-07 0:14 ` Stephen Hemminger
@ 2014-11-07 0:41 ` Stephen Hemminger
1 sibling, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2014-11-07 0:41 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
On Wed, 5 Nov 2014 10:06:27 -0800
Tom Herbert <therbert@google.com> 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).
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> 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
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 iproute2 5/5] iproute2: Man pages for fou and gue
2014-11-05 18:06 [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Tom Herbert
` (3 preceding siblings ...)
2014-11-05 18:06 ` [PATCH v2 iproute2 4/5] ip link: Add support for remote checksum offload Tom Herbert
@ 2014-11-05 18:06 ` Tom Herbert
2014-11-07 0:21 ` [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Stephen Hemminger
5 siblings, 0 replies; 9+ messages in thread
From: Tom Herbert @ 2014-11-05 18:06 UTC (permalink / raw)
To: stephen, davem, netdev
Man pages for Foo-over-UDP and Generic UDP Encapsulation receive
port configuration. gue man page links to fou one.
Signed-off-by: Tom Herbert <therbert@google.com>
---
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
diff --git a/man/man8/ip-fou.8 b/man/man8/ip-fou.8
new file mode 100644
index 0000000..0fa22ee
--- /dev/null
+++ b/man/man8/ip-fou.8
@@ -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 <therbert@google.com>
diff --git a/man/man8/ip-gue.8 b/man/man8/ip-gue.8
new file mode 100644
index 0000000..4d2914c
--- /dev/null
+++ b/man/man8/ip-gue.8
@@ -0,0 +1 @@
+.so man8/ip-fou.8
--
2.1.0.rc2.206.gedb03e5
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip
2014-11-05 18:06 [PATCH v2 iproute2 0/5] iproute2: Add FOU and GUE configuration in ip Tom Herbert
` (4 preceding siblings ...)
2014-11-05 18:06 ` [PATCH v2 iproute2 5/5] iproute2: Man pages for fou and gue Tom Herbert
@ 2014-11-07 0:21 ` Stephen Hemminger
5 siblings, 0 replies; 9+ messages in thread
From: Stephen Hemminger @ 2014-11-07 0:21 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, netdev
On Wed, 5 Nov 2014 10:06:23 -0800
Tom Herbert <therbert@google.com> 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.
^ permalink raw reply [flat|nested] 9+ messages in thread