From patchwork Wed Nov 5 18:06:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Herbert X-Patchwork-Id: 407117 X-Patchwork-Delegate: shemminger@vyatta.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id CA9F6140098 for ; Thu, 6 Nov 2014 05:06:58 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751208AbaKESGy (ORCPT ); Wed, 5 Nov 2014 13:06:54 -0500 Received: from mail-ig0-f176.google.com ([209.85.213.176]:56616 "EHLO mail-ig0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751173AbaKESGw (ORCPT ); Wed, 5 Nov 2014 13:06:52 -0500 Received: by mail-ig0-f176.google.com with SMTP id l13so9988382iga.15 for ; Wed, 05 Nov 2014 10:06:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references; bh=veuO55dso9dwI0qxHn6IRLDJeQZMq/FUyk3v/Fa7EXs=; b=EyMsiTTM0xmGmvyjGPINzhP7NDElmt1+oPBNZV8fxVBvM1HOTeQ1WyrqV87NTh/s6o NG2ZDcRf/CgBkE6p/gvqNSo6DQuwXOIaT1i+GfrhUeeaNRSnXz+sIba6it6hn2fCuCbX F8ML+0hHFOX0b60p119KZ940EaefZKRjV3tl86S4HolhsKvClpvcY8EXovTc8a/Y39N/ bkPdHU8jh27L4P0nvqSqN1icqQGJIuyv2H8s6DCLN+khs9B5tWm9w76QmoqTmNIcV8Um MK0DTfO8kChFqXUUii7owFU+vDJXz0s8UyNulVUOwn5/GpMnBGoWCIijRZ4OAMvPptmf ufWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=veuO55dso9dwI0qxHn6IRLDJeQZMq/FUyk3v/Fa7EXs=; b=lrXKW+Y4oKRXl8lr5snlw3uOQbvWuCNWNVGlMrv0NeTi1vUg3UikoxZ/hquo4wHYt3 zaAeetNxaLFJnb7K7EjqlF6YF1yVxatk1yY5wZrRYiZ8QPUWgfpdYie9yGE8cI87Y236 TphkBrvakmyI87zZDZhmKLm+zuKc+KNyjgvf6SmRg3hU7NEEkqGS3JcR992+H3kdzhoH YTOANOAnu+9U2Q447hANkvpgpz0d/i1IsrsCbNa4M2j+GujD4Flp/gCN+CksTq+3nSqh 1i59A2v1CssbJ05ko/+liyVsMc8Hs7bKopbO/07OUHrKYuvLEvq2uX9oto9PqFHEhkvy z57Q== X-Gm-Message-State: ALoCoQki4uUtcxEADeNYlAVTtdqomhlVqSmIK3B7K4JqZBZv1iVLrApRb8GKs2s41CIuawuPxpHd X-Received: by 10.107.12.79 with SMTP id w76mr66299445ioi.3.1415210812105; Wed, 05 Nov 2014 10:06:52 -0800 (PST) Received: from tomh.mtv.corp.google.com ([172.18.117.126]) by mx.google.com with ESMTPSA id ro6sm1974041igb.3.2014.11.05.10.06.49 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Nov 2014 10:06:50 -0800 (PST) From: Tom Herbert To: stephen@networkplumber.org, davem@davemloft.net, netdev@vger.kernel.org Subject: [PATCH v2 iproute2 2/5] ip link ipip: Add support to configure FOU and GUE Date: Wed, 5 Nov 2014 10:06:25 -0800 Message-Id: <1415210788-8058-3-git-send-email-therbert@google.com> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1415210788-8058-1-git-send-email-therbert@google.com> References: <1415210788-8058-1-git-send-email-therbert@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 --- 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,