From patchwork Wed Dec 20 01:08:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Tu X-Patchwork-Id: 851153 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="X+6NmA+E"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3z1c9L3gBNz9sBW for ; Wed, 20 Dec 2017 12:08:54 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752716AbdLTBIw (ORCPT ); Tue, 19 Dec 2017 20:08:52 -0500 Received: from mail-pg0-f65.google.com ([74.125.83.65]:33356 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751551AbdLTBIv (ORCPT ); Tue, 19 Dec 2017 20:08:51 -0500 Received: by mail-pg0-f65.google.com with SMTP id g7so11299198pgs.0 for ; Tue, 19 Dec 2017 17:08:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=ybUMslDV9iw9ranZCi22xH48qCcHGjUqzC06PZ0878k=; b=X+6NmA+ESjewylolq2JW/bwxem1H7A1rEdwB8DJO07Xa1Lik4p9/MYM9jTOSKn23OP SfULdU/F/7XATt+hDGnTMhxfEoKEDHW9B9w1JWF2eXqkuC7o0BoJHccUSUmOWkkmf6eD 6TVU7eVu6OQS5syfPtYwOw7zymTGwJ0ZCWCcD+ebBx51LrQRfHfrHKGkr/EhlrH0f4qi R/fW7ap39rfSt0E10jqYjXPO/ProoS1Zbi0LieCdKrIbkLpFyP4OdFjOVw+c1YGDZbR/ CbMPdJZyROJs8W+q1KcCw8nVU4/tat+ffb78O2WC3c3KrA5nTens1XaLxyTxM60RBmqg g+6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=ybUMslDV9iw9ranZCi22xH48qCcHGjUqzC06PZ0878k=; b=MPTGr+lMasl01XCB7wdtTIsqSrLNEvVSL8JPMDI2sS1ZFrfmZLfkcdZiz92I8K6y+U BauKkfkYMB62MfkRGXO2WvRDrhhD2p5+Ld4Z2yghPKIf+jE9o0bAQWHVGveJMAfDMioh MowasqGOaEojYwDDHjCSE4gIWCyyaspjppTiMrAn6ftfF3wsDSURUWxX+u8zJWTmTP8y 3PuZZ1O4WdrijTl0wzcKbfQiz66vKqdM1X/c/Prl4q/elxM8VcTImEwa1EzG+U0CCP++ WakCpinH8oqA8ACWKBwS7zQ0+dnh12QGaiCn8KaxDAahe/lvw6Cs76Zt6/Ks0W/bMGnu BD0A== X-Gm-Message-State: AKGB3mJUj+Cgu12Sd7GnAIU1x2T9lPN6UtOTkNSIvF8I9/eiESJmbYmz GcveAKFf7hsV0kk/QmF9e0jxD28z X-Google-Smtp-Source: ACJfBosgBlg8HtTwNzYcq724ggjPqdJybnexO2AKIMFcnY4xB9xoF5goBToups4adSE6ZyvDBQIPDQ== X-Received: by 10.99.163.25 with SMTP id s25mr4684877pge.447.1513732130111; Tue, 19 Dec 2017 17:08:50 -0800 (PST) Received: from sc9-mailhost3.vmware.com ([208.91.2.1]) by smtp.gmail.com with ESMTPSA id n65sm33013591pfa.83.2017.12.19.17.08.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 19 Dec 2017 17:08:49 -0800 (PST) From: William Tu To: netdev@vger.kernel.org Cc: dsahern@gmail.com Subject: [PATCH v3 iproute2 net-next] erspan: add erspan version II support Date: Tue, 19 Dec 2017 17:08:41 -0800 Message-Id: <1513732121-115044-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. As for manpage, the ERSPAN descriptions used to be under GRE, IPIP, SIT Type paragraph. Since IP6GRE/IP6GRETAP also supports ERSPAN, the patch removes the old one, creates a separate ERSPAN paragrah, and adds an example. Signed-off-by: William Tu --- change in v3: - change erspan_dir 0/1 to "in[gress]/e[gress]" - update manpage change in v2: - fix typo ETH_P_ERSPAN2 - fix space and indent --- include/uapi/linux/if_ether.h | 1 + include/uapi/linux/if_tunnel.h | 3 ++ ip/link_gre.c | 68 +++++++++++++++++++++++++++++-- ip/link_gre6.c | 69 +++++++++++++++++++++++++++++-- man/man8/ip-link.8.in | 92 ++++++++++++++++++++++++++++++++++++------ 5 files changed, 214 insertions(+), 19 deletions(-) diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 2eb529a90250..133567bf2e04 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..ecdc76669cfd 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..27c03121f7e3 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,26 @@ 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 (strcmp(*argv, "ingress") == 0 || + strcmp(*argv, "in") == 0) + erspan_dir = 0; + else if (strcmp(*argv, "egress") == 0 || + strcmp(*argv, "e") == 0) + erspan_dir = 1; + else + invarg("Invalid erspan direction.", *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 +406,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 +553,30 @@ 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]); + + if (erspan_dir == 0) + print_string(PRINT_ANY, "erspan_dir", + "erspan_dir ingress ", NULL); + else + print_string(PRINT_ANY, "erspan_dir", + "erspan_dir egress ", NULL); + } + + 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 0x%x ", erspan_hwid); } if (tb[IFLA_GRE_ENCAP_TYPE] && diff --git a/ip/link_gre6.c b/ip/link_gre6.c index 2cb46ca116d0..de6a38d50cd1 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,26 @@ 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 (strcmp(*argv, "ingress") == 0 || + strcmp(*argv, "in") == 0) + erspan_dir = 0; + else if (strcmp(*argv, "egress") == 0 || + strcmp(*argv, "e") == 0) + erspan_dir = 1; + else + invarg("Invalid erspan direction.", *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 +440,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,7 +625,30 @@ 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]); + + if (erspan_dir == 0) + print_string(PRINT_ANY, "erspan_dir", + "erspan_dir ingress ", NULL); + else + print_string(PRINT_ANY, "erspan_dir", + "erspan_dir egress ", NULL); + } + + 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 0x%x ", erspan_hwid); } if (tb[IFLA_GRE_ENCAP_TYPE] && diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 9e9a5f0d2cef..2b051ed7b5a0 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -665,13 +665,13 @@ keyword. .in -8 .TP -GRE, IPIP, SIT, ERSPAN Type Support +GRE, IPIP, SIT Type Support For a link of types -.I GRE/IPIP/SIT/ERSPAN +.I GRE/IPIP/SIT the following additional arguments are supported: .BI "ip link add " DEVICE -.BR type " { " gre " | " ipip " | " sit " | " erspan " }" +.BR type " { " gre " | " ipip " | " sit " }" .BI " remote " ADDR " local " ADDR [ .BR encap " { " fou " | " gue " | " none " }" @@ -685,8 +685,6 @@ the following additional arguments are supported: .I " [no]encap-remcsum " ] [ .I " mode " { ip6ip | ipip | mplsip | any } " -] [ -.BR erspan " \fIIDX " ] .in +8 @@ -731,13 +729,6 @@ MPLS-Over-IPv4, "any" indicates IPv6, IPv4 or MPLS Over IPv4. Supported for SIT where the default is "ip6ip" and IPIP where the default is "ipip". IPv6-Over-IPv4 is not supported for IPIP. -.sp -.BR erspan " \fIIDX " -- specifies the ERSPAN index field. -.IR IDX -indicates a 20 bit index/port number associated with the ERSPAN -traffic's source port and direction. - .in -8 .TP @@ -883,6 +874,76 @@ the following additional arguments are supported: - specifies the mode (datagram or connected) to use. .TP +ERSPAN Type Support +For a link of type +.I ERSPAN/IP6ERSPAN +the following additional arguments are supported: + +.BI "ip link add " DEVICE +.BR type " { " erspan " | " ip6erspan " }" +.BI remote " ADDR " local " ADDR " seq +.RB key +.I KEY +.BR erspan_ver " \fIversion " +[ +.BR erspan " \fIIDX " +] [ +.BR erspan_dir " { " \fIin[gress] " | " \fIe[gress] " }" +] [ +.BR erspan_hwid " \fIhwid " +] [ +.RB external +] + +.in +8 +.sp +.BI remote " ADDR " +- specifies the remote address of the tunnel. + +.sp +.BI local " ADDR " +- specifies the fixed local address for tunneled packets. +It must be an address on another interface on this host. + +.sp +.BR erspan_ver " \fIversion " +- specifies the ERSPAN version number. +.IR version +indicates the ERSPAN version to be created: 1 for version 1 (type II) +or 2 for version 2 (type III). + +.sp +.BR erspan " \fIIDX " +- specifies the ERSPAN v1 index field. +.IR IDX +indicates a 20 bit index/port number associated with the ERSPAN +traffic's source port and direction. + +.sp +.BR erspan_dir " { " \fIin[gress] " | " \fIe[gress] " }" +- specifies the ERSPAN v2 mirrored traffic's direction. + +.sp +.BR erspan_hwid " \fIhwid " +- an unique identifier of an ERSPAN v2 engine within a system. +.IR hwid +is a 6-bit value for users to configure. + +.sp +.BR external +- make this tunnel externally controlled (or not, which is the default). +In the kernel, this is referred to as collect metadata mode. This flag is +mutually exclusive with the +.BR remote , +.BR local , +.BR erspan_ver , +.BR erspan , +.BR erspan_dir " and " erspan_hwid +options. + +.in -8 + +.TP GENEVE Type Support For a link of type .I GENEVE @@ -2062,6 +2123,13 @@ ip link add link wpan0 lowpan0 type lowpan Creates a 6LoWPAN interface named lowpan0 on the underlying IEEE 802.15.4 device wpan0. .RE +.PP +ip link add dev ip6erspan11 type ip6erspan seq key 102 +local fc00:100::2 remote fc00:100::1 +erspan_ver 2 erspan_dir ingress erspan_hwid 17 +.RS 4 +Creates a IP6ERSPAN version 2 interface named ip6erspan00. +.RE .SH SEE ALSO .br