From patchwork Thu Dec 14 00:29:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Tu X-Patchwork-Id: 848328 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="p4mb6XYE"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yxvbX0XC9z9sRg for ; Thu, 14 Dec 2017 11:30:16 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751026AbdLNAaL (ORCPT ); Wed, 13 Dec 2017 19:30:11 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:46237 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750737AbdLNAaK (ORCPT ); Wed, 13 Dec 2017 19:30:10 -0500 Received: by mail-pg0-f68.google.com with SMTP id b11so2225337pgu.13 for ; Wed, 13 Dec 2017 16:30:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=xhnCzJUkLv7w6/jj/1v0sREBEyB5tq2SgEFTSpNspoE=; b=p4mb6XYEZOHKIPYsO4AsZJ0ezuwoaYGsO8IzSQZthBkDlszQAHH90YwQmkRdXHU8lF lBfhAlsO31oDiBf/5qhlS6LlFPN9b/RVk9W1WgD+T/+uxmbp2Q8B8EpOgW2gCksjx7ZE aLT9Xl6DsxH4uxexEG4Bx3KHLuU6YKLiqL537DArIpD/4Gu+TJ2Y50pbXJBzIqrE3T85 TbdK6oQjNPGOTPzzF7fXyuP5Hhijygg3ADBXb/ha52cUanbb8c4zZ7nmcSgNxlP0fk4Y Fb3WrASqi2GV1dtEJSGPPxGPI/IolXi/rlPCmeLcFPj8WsBeQuwrBX0UqREUEP07KYke jgKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=xhnCzJUkLv7w6/jj/1v0sREBEyB5tq2SgEFTSpNspoE=; b=qt0BBJ/U/nW4T0voZNvvrRKTR1UQ6sWuZiezn8w5caAGerXRKCwP5qGbDcFV8IzAuS mKUPchNBe/O1KjTJDzbFfegqrVQhLH5tw3CO3t6zyHN3ZKYiVAOJCJONOl7dB9QYfHU4 WAuZbpKXAunz97hvtQrQeV1T51PfKLoGzWeuE07P5m8lqj/NcJGlW9u9USIlJsTQBeb3 PrTHe7oA+18rVf4vAM6hnUCNeGElv5x1cja93nhdQGIzHLSJL5ghKj/UzyU+mWKo1N7Y V5GcnBlptE9+GQeZaH4N+z0d436oTvOpwvMZBBsAoyFDZCR1btXT+4MUex4yFIptOQ4q +BYw== X-Gm-Message-State: AKGB3mLBA+JRpb1B57bJhhQF8fpMNaYrzNgAnkS57TTt/YDei4L0YYcR S/SXBxj3PYptgpCwZSMo7KVr95jq X-Google-Smtp-Source: ACJfBou9/7aaLWIaGkAD0FRxFhiwMU14sdqeaxBBsDhElQs4KbJktby+0jMRMMwAAcygDjYhdgYUCQ== X-Received: by 10.99.188.2 with SMTP id q2mr6879222pge.332.1513211409831; Wed, 13 Dec 2017 16:30:09 -0800 (PST) Received: from sc9-mailhost3.vmware.com ([208.91.2.1]) by smtp.gmail.com with ESMTPSA id y7sm5344781pfy.96.2017.12.13.16.30.08 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 13 Dec 2017 16:30:09 -0800 (PST) From: William Tu To: netdev@vger.kernel.org Subject: [PATCH iproute2 net-next] erspan: add erspan version II support Date: Wed, 13 Dec 2017 16:29:59 -0800 Message-Id: <1513211399-8593-1-git-send-email-u9012063@gmail.com> X-Mailer: git-send-email 2.7.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The patch adds support for configuring the erspan v2, for both ipv4 and ipv6 erspan implementation. Three additional fields are added: 'erspan_ver' for distinguishing v1 or v2, 'erspan_dir' for specifying direction of the mirrored traffic, and 'erspan_hwid' for users to set ERSPAN engine ID within a system. For details of version II, see https://tools.ietf.org/html/draft-foschiano-erspan-03 Signed-off-by: William Tu --- include/uapi/linux/if_ether.h | 1 + include/uapi/linux/if_tunnel.h | 3 +++ ip/link_gre.c | 59 +++++++++++++++++++++++++++++++++++++--- ip/link_gre6.c | 61 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 117 insertions(+), 7 deletions(-) diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 2eb529a90250..5fd5c12ef8e9 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h @@ -47,6 +47,7 @@ #define ETH_P_PUP 0x0200 /* Xerox PUP packet */ #define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ #define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */ +#define ETH_P_ERsPAN2 0x22EB /* ERSPAN version 2 (type III) */ #define ETH_P_IP 0x0800 /* Internet Protocol packet */ #define ETH_P_X25 0x0805 /* CCITT X.25 */ #define ETH_P_ARP 0x0806 /* Address Resolution packet */ diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index 38cdf90692f8..29602df037e9 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h @@ -137,6 +137,9 @@ enum { IFLA_GRE_IGNORE_DF, IFLA_GRE_FWMARK, IFLA_GRE_ERSPAN_INDEX, + IFLA_GRE_ERSPAN_VER, + IFLA_GRE_ERSPAN_DIR, + IFLA_GRE_ERSPAN_HWID, __IFLA_GRE_MAX, }; diff --git a/ip/link_gre.c b/ip/link_gre.c index 43cb1af6196a..924a05530f5c 100644 --- a/ip/link_gre.c +++ b/ip/link_gre.c @@ -98,6 +98,9 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, __u8 ignore_df = 0; __u32 fwmark = 0; __u32 erspan_idx = 0; + __u8 erspan_ver = 0; + __u8 erspan_dir = 0; + __u16 erspan_hwid = 0; if (!(n->nlmsg_flags & NLM_F_CREATE)) { if (rtnl_talk(&rth, &req.n, &answer) < 0) { @@ -179,6 +182,15 @@ get_failed: if (greinfo[IFLA_GRE_ERSPAN_INDEX]) erspan_idx = rta_getattr_u32(greinfo[IFLA_GRE_ERSPAN_INDEX]); + if (greinfo[IFLA_GRE_ERSPAN_VER]) + erspan_ver = rta_getattr_u8(greinfo[IFLA_GRE_ERSPAN_VER]); + + if (greinfo[IFLA_GRE_ERSPAN_DIR]) + erspan_dir = rta_getattr_u8(greinfo[IFLA_GRE_ERSPAN_DIR]); + + if (greinfo[IFLA_GRE_ERSPAN_HWID]) + erspan_hwid = rta_getattr_u16(greinfo[IFLA_GRE_ERSPAN_HWID]); + free(answer); } @@ -343,6 +355,22 @@ get_failed: invarg("invalid erspan index\n", *argv); if (erspan_idx & ~((1<<20) - 1) || erspan_idx == 0) invarg("erspan index must be > 0 and <= 20-bit\n", *argv); + } else if (strcmp(*argv, "erspan_ver") == 0) { + NEXT_ARG(); + if (get_u8(&erspan_ver, *argv, 0)) + invarg("invalid erspan version\n", *argv); + if (erspan_ver != 1 && erspan_ver != 2) + invarg("erspan version must be 1 or 2\n", *argv); + } else if (strcmp(*argv, "erspan_dir") == 0) { + NEXT_ARG(); + if (get_u8(&erspan_dir, *argv, 0)) + invarg("invalid erspan direction\n", *argv); + if (erspan_dir != 0 && erspan_dir != 1) + invarg("erspan direction must be 0(Ingress) or 1(Egress)\n", *argv); + } else if (strcmp(*argv, "erspan_hwid") == 0) { + NEXT_ARG(); + if (get_u16(&erspan_hwid, *argv, 0)) + invarg("invalid erspan hwid\n", *argv); } else usage(); argc--; argv++; @@ -374,8 +402,15 @@ get_failed: addattr_l(n, 1024, IFLA_GRE_TTL, &ttl, 1); addattr_l(n, 1024, IFLA_GRE_TOS, &tos, 1); addattr32(n, 1024, IFLA_GRE_FWMARK, fwmark); - if (erspan_idx != 0) - addattr32(n, 1024, IFLA_GRE_ERSPAN_INDEX, erspan_idx); + if (erspan_ver) { + addattr8(n, 1024, IFLA_GRE_ERSPAN_VER, erspan_ver); + if (erspan_ver == 1 && erspan_idx != 0) { + addattr32(n, 1024, IFLA_GRE_ERSPAN_INDEX, erspan_idx); + } else if (erspan_ver == 2) { + addattr8(n, 1024, IFLA_GRE_ERSPAN_DIR, erspan_dir); + addattr16(n, 1024, IFLA_GRE_ERSPAN_HWID, erspan_hwid); + } + } } else { addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0); } @@ -514,7 +549,25 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (tb[IFLA_GRE_ERSPAN_INDEX]) { __u32 erspan_idx = rta_getattr_u32(tb[IFLA_GRE_ERSPAN_INDEX]); - fprintf(f, "erspan_index %u ", erspan_idx); + print_uint(PRINT_ANY, "erspan_index", "erspan_index %u", erspan_idx); + } + + if (tb[IFLA_GRE_ERSPAN_VER]) { + __u8 erspan_ver = rta_getattr_u8(tb[IFLA_GRE_ERSPAN_VER]); + + print_uint(PRINT_ANY, "erspan_ver", "erspan_ver %u", erspan_ver); + } + + if (tb[IFLA_GRE_ERSPAN_DIR]) { + __u8 erspan_dir = rta_getattr_u8(tb[IFLA_GRE_ERSPAN_DIR]); + + print_uint(PRINT_ANY, "erspan_dir", "erspan_dir %u", erspan_dir); + } + + if (tb[IFLA_GRE_ERSPAN_HWID]) { + __u16 erspan_hwid = rta_getattr_u16(tb[IFLA_GRE_ERSPAN_HWID]); + + print_hex(PRINT_ANY, "erspan_hwid", "erspan_hwid %x", erspan_hwid); } if (tb[IFLA_GRE_ENCAP_TYPE] && diff --git a/ip/link_gre6.c b/ip/link_gre6.c index 2cb46ca116d0..71181af91bc8 100644 --- a/ip/link_gre6.c +++ b/ip/link_gre6.c @@ -109,6 +109,9 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, int len; __u32 fwmark = 0; __u32 erspan_idx = 0; + __u8 erspan_ver = 0; + __u8 erspan_dir = 0; + __u16 erspan_hwid = 0; if (!(n->nlmsg_flags & NLM_F_CREATE)) { if (rtnl_talk(&rth, &req.n, &answer) < 0) { @@ -191,6 +194,15 @@ get_failed: if (greinfo[IFLA_GRE_ERSPAN_INDEX]) erspan_idx = rta_getattr_u32(greinfo[IFLA_GRE_ERSPAN_INDEX]); + if (greinfo[IFLA_GRE_ERSPAN_VER]) + erspan_ver = rta_getattr_u8(greinfo[IFLA_GRE_ERSPAN_VER]); + + if (greinfo[IFLA_GRE_ERSPAN_DIR]) + erspan_dir = rta_getattr_u8(greinfo[IFLA_GRE_ERSPAN_DIR]); + + if (greinfo[IFLA_GRE_ERSPAN_HWID]) + erspan_hwid = rta_getattr_u16(greinfo[IFLA_GRE_ERSPAN_HWID]); + free(answer); } @@ -389,6 +401,22 @@ get_failed: invarg("invalid erspan index\n", *argv); if (erspan_idx & ~((1<<20) - 1) || erspan_idx == 0) invarg("erspan index must be > 0 and <= 20-bit\n", *argv); + } else if (strcmp(*argv, "erspan_ver") == 0) { + NEXT_ARG(); + if (get_u8(&erspan_ver, *argv, 0)) + invarg("invalid erspan version\n", *argv); + if (erspan_ver != 1 && erspan_ver != 2) + invarg("erspan version must be 1 or 2\n", *argv); + } else if (strcmp(*argv, "erspan_dir") == 0) { + NEXT_ARG(); + if (get_u8(&erspan_dir, *argv, 0)) + invarg("invalid erspan direction\n", *argv); + if (erspan_dir != 0 && erspan_dir != 1) + invarg("erspan direction must be 0(Ingress) or 1(Egress)\n", *argv); + } else if (strcmp(*argv, "erspan_hwid") == 0) { + NEXT_ARG(); + if (get_u16(&erspan_hwid, *argv, 0)) + invarg("invalid erspan hwid\n", *argv); } else usage(); argc--; argv++; @@ -408,9 +436,15 @@ get_failed: addattr_l(n, 1024, IFLA_GRE_FLOWINFO, &flowinfo, 4); addattr32(n, 1024, IFLA_GRE_FLAGS, flags); addattr32(n, 1024, IFLA_GRE_FWMARK, fwmark); - if (erspan_idx != 0) - addattr32(n, 1024, IFLA_GRE_ERSPAN_INDEX, erspan_idx); - + if (erspan_ver) { + addattr8(n, 1024, IFLA_GRE_ERSPAN_VER, erspan_ver); + if (erspan_ver == 1 && erspan_idx != 0) { + addattr32(n, 1024, IFLA_GRE_ERSPAN_INDEX, erspan_idx); + } else { + addattr8(n, 1024, IFLA_GRE_ERSPAN_DIR, erspan_dir); + addattr16(n, 1024, IFLA_GRE_ERSPAN_HWID, erspan_hwid); + } + } 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)); @@ -587,9 +621,28 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (tb[IFLA_GRE_ERSPAN_INDEX]) { __u32 erspan_idx = rta_getattr_u32(tb[IFLA_GRE_ERSPAN_INDEX]); - fprintf(f, "erspan_index %u ", erspan_idx); + print_uint(PRINT_ANY, "erspan_index", "erspan_index %u ", erspan_idx); } + if (tb[IFLA_GRE_ERSPAN_VER]) { + __u8 erspan_ver = rta_getattr_u8(tb[IFLA_GRE_ERSPAN_VER]); + + print_uint(PRINT_ANY, "erspan_ver", "erspan_ver %u", erspan_ver); + } + + if (tb[IFLA_GRE_ERSPAN_DIR]) { + __u8 erspan_dir = rta_getattr_u8(tb[IFLA_GRE_ERSPAN_DIR]); + + print_uint(PRINT_ANY, "erspan_dir", "erspan_dir %u", erspan_dir); + } + + if (tb[IFLA_GRE_ERSPAN_HWID]) { + __u16 erspan_hwid = rta_getattr_u16(tb[IFLA_GRE_ERSPAN_HWID]); + + print_hex(PRINT_ANY, "erspan_hwid", "erspan_hwid %x", erspan_hwid); + } + + if (tb[IFLA_GRE_ENCAP_TYPE] && rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) { __u16 type = rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]);