From patchwork Thu Dec 14 00:38:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Tu X-Patchwork-Id: 848332 X-Patchwork-Delegate: davem@davemloft.net 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="qc5C75+P"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yxvp71dcfz9sRg for ; Thu, 14 Dec 2017 11:39:27 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751577AbdLNAjZ (ORCPT ); Wed, 13 Dec 2017 19:39:25 -0500 Received: from mail-pf0-f195.google.com ([209.85.192.195]:38743 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751101AbdLNAjR (ORCPT ); Wed, 13 Dec 2017 19:39:17 -0500 Received: by mail-pf0-f195.google.com with SMTP id u25so2399630pfg.5 for ; Wed, 13 Dec 2017 16:39:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=JG0C5XBK3bIEEP92SDOBKRLHHdwOjO5byIGqEZTZaBw=; b=qc5C75+PkoQo7vKg13LRcZ/Drf4f3h4L23FO49R+yl5/9uj0UmBYk2TRP9U3MSSkFA LoEjXidk7fSepGysMtDoEc3b7KZ8rVUhsTB9YSTujaMcketFYlz7igEwWCD6PKkdDjH2 kw3dKOAS2xBIArHkX3uYfkrvdW+0uS3nIUlHSyH1UFgtnlX89/cnrqmgpnUPiBl9f/2j 2ftUakhUU2nD7a5dQjw7mP06V+/hUO6euN5OxtQC0UFROlA2Iw7VkNa1EiCqYIHplOfO BP9IwecAZXMa66Jz02gFOrNS3onPavNxg7sRMtXw2kuX4k2KMH2yO9gMukzfeM0iWEBR L2OQ== 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:in-reply-to :references; bh=JG0C5XBK3bIEEP92SDOBKRLHHdwOjO5byIGqEZTZaBw=; b=q7qexU6FkQxcQzml4afCyvNLEnUrpkgJWj8JIV0n07SmWUsi0nxn9zvggcMdpnsWhx ISOh8pRlDeYHE0r+7geUakfbTO7D1bIJOpMVEtoiuvteQbjiEfJnODLofDafUDSEHqL8 nTaWc3EUXVaDfeKhUoRTWxNFfLtf5hZp6QP2w0pIwCEwmR1a/vBPUf+uCMnBLCCCsJn5 Q1lTLQu8bHTO0KR6a0OypEUnWuWo+Yz2KhjmilsJ5wMV4o7/wUcywwH9mMnmcM6Cphed izV12tEHIo1ZwR6cKJeYk1nLUpUcoP8m8fYISRfAtm/ss9P/OrZwKQCAEjqwNmDvtxvz RTiw== X-Gm-Message-State: AKGB3mLCopM4AhSZJWXjhjsIchZA4XO3SJFBgpHhuzE9t0GAXEn/0e7E NyvfRj1getyOLYMyIxvHStaYPxlw X-Google-Smtp-Source: ACJfBouaDLDkqiJVTb3ydWAiqGFOIzJDQvty9G9iieZTGY+CU1JUKCn+INu99DS67jA8kD+qoz85WA== X-Received: by 10.99.165.75 with SMTP id r11mr6900914pgu.331.1513211956311; Wed, 13 Dec 2017 16:39:16 -0800 (PST) Received: from sc9-mailhost3.vmware.com ([208.91.2.1]) by smtp.gmail.com with ESMTPSA id e7sm5349938pfj.44.2017.12.13.16.39.14 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 13 Dec 2017 16:39:14 -0800 (PST) From: William Tu To: netdev@vger.kernel.org Subject: [PATCH net-next 3/4] ip6_gre: add erspan v2 support Date: Wed, 13 Dec 2017 16:38:57 -0800 Message-Id: <1513211938-8749-4-git-send-email-u9012063@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513211938-8749-1-git-send-email-u9012063@gmail.com> References: <1513211938-8749-1-git-send-email-u9012063@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Similar to support for ipv4 erspan, this patch adds erspan v2 to ip6erspan tunnel. Signed-off-by: William Tu --- include/net/ip6_tunnel.h | 3 ++ net/ipv6/ip6_gre.c | 120 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 107 insertions(+), 16 deletions(-) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index 109a5a8877ef..236e40ba06bf 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -37,6 +37,9 @@ struct __ip6_tnl_parm { __u32 fwmark; __u32 index; /* ERSPAN type II index */ + __u8 erspan_ver; /* ERSPAN version */ + __u8 dir; /* direction */ + __u16 hwid; /* hwid */ }; /* IPv6 tunnel */ diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 1303d0c44c36..5c9c65f1d5c2 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -553,13 +553,28 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len, return PACKET_REJECT; memcpy(md, pkt_md, sizeof(*md)); + md->version = ver; info->key.tun_flags |= TUNNEL_ERSPAN_OPT; info->options_len = sizeof(*md); ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error); } else { - tunnel->parms.index = ntohl(pkt_md->u.index); + tunnel->parms.erspan_ver = ver; + + if (ver == 1) { + tunnel->parms.index = ntohl(pkt_md->u.index); + } else { + u16 md2_flags; + u16 dir, hwid; + + md2_flags = ntohs(pkt_md->u.md2.flags); + dir = (md2_flags & DIR_MASK) >> DIR_OFFSET; + hwid = (md2_flags & HWID_MASK) >> HWID_OFFSET; + tunnel->parms.dir = dir; + tunnel->parms.hwid = hwid; + } + ip6_tnl_rcv(tunnel, skb, tpi, NULL, log_ecn_error); } @@ -582,7 +597,8 @@ static int gre_rcv(struct sk_buff *skb) if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) goto drop; - if (unlikely(tpi.proto == htons(ETH_P_ERSPAN))) { + if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) || + tpi.proto == htons(ETH_P_ERSPAN2))) { if (ip6erspan_rcv(skb, hdr_len, &tpi) == PACKET_RCVD) return 0; goto drop; @@ -927,9 +943,24 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, if (!md) goto tx_err; - erspan_build_header(skb, tunnel_id_to_key32(key->tun_id), - ntohl(md->u.index), truncate, false); - + if (md->version == 1) { + erspan_build_header(skb, + tunnel_id_to_key32(key->tun_id), + ntohl(md->u.index), truncate, + false); + } else if (md->version == 2) { + u16 md2_flags; + u16 dir, hwid; + + md2_flags = ntohs(md->u.md2.flags); + dir = (md2_flags & DIR_MASK) >> DIR_OFFSET; + hwid = (md2_flags & HWID_MASK) >> HWID_OFFSET; + + erspan_build_header_v2(skb, + tunnel_id_to_key32(key->tun_id), + dir, hwid, truncate, + false); + } } else { switch (skb->protocol) { case htons(ETH_P_IP): @@ -949,8 +980,15 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, break; } - erspan_build_header(skb, t->parms.o_key, t->parms.index, - truncate, false); + if (t->parms.erspan_ver == 1) + erspan_build_header(skb, t->parms.o_key, + t->parms.index, + truncate, false); + else + erspan_build_header_v2(skb, t->parms.o_key, + t->parms.dir, + t->parms.hwid, + truncate, false); fl6.daddr = t->parms.raddr; } @@ -1514,7 +1552,7 @@ static int ip6erspan_tap_validate(struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { __be16 flags = 0; - int ret; + int ret, ver = 0; if (!data) return 0; @@ -1543,12 +1581,35 @@ static int ip6erspan_tap_validate(struct nlattr *tb[], struct nlattr *data[], (ntohl(nla_get_be32(data[IFLA_GRE_OKEY])) & ~ID_MASK)) return -EINVAL; - if (data[IFLA_GRE_ERSPAN_INDEX]) { - u32 index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); - - if (index & ~INDEX_MASK) + if (data[IFLA_GRE_ERSPAN_VER]) { + ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]); + if (ver != 1 && ver != 2) return -EINVAL; } + + if (ver == 1) { + if (data[IFLA_GRE_ERSPAN_INDEX]) { + u32 index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); + + if (index & ~INDEX_MASK) + return -EINVAL; + } + } else if (ver == 2) { + if (data[IFLA_GRE_ERSPAN_DIR]) { + u16 dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]); + + if (dir & ~(DIR_MASK >> DIR_OFFSET)) + return -EINVAL; + } + + if (data[IFLA_GRE_ERSPAN_HWID]) { + u16 hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]); + + if (hwid & ~(HWID_MASK >> HWID_OFFSET)) + return -EINVAL; + } + } + return 0; } @@ -1598,11 +1659,21 @@ static void ip6gre_netlink_parms(struct nlattr *data[], if (data[IFLA_GRE_FWMARK]) parms->fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]); - if (data[IFLA_GRE_ERSPAN_INDEX]) - parms->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); - if (data[IFLA_GRE_COLLECT_METADATA]) parms->collect_md = true; + + if (data[IFLA_GRE_ERSPAN_VER]) + parms->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]); + + if (parms->erspan_ver == 1) { + if (data[IFLA_GRE_ERSPAN_INDEX]) + parms->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); + } else if (parms->erspan_ver == 2) { + if (data[IFLA_GRE_ERSPAN_DIR]) + parms->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]); + if (data[IFLA_GRE_ERSPAN_HWID]) + parms->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]); + } } static int ip6gre_tap_init(struct net_device *dev) @@ -1664,7 +1735,7 @@ static int ip6erspan_tap_init(struct net_device *dev) tunnel->tun_hlen = 8; tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen + - sizeof(struct erspan_base_hdr) + ERSPAN_V1_MDSIZE; + erspan_hdr_len(tunnel->parms.erspan_ver); t_hlen = tunnel->hlen + sizeof(struct ipv6hdr); dev->hard_header_len = LL_MAX_HEADER + t_hlen; @@ -1932,6 +2003,19 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) goto nla_put_failure; } + if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, p->erspan_ver)) + goto nla_put_failure; + + if (p->erspan_ver == 1) { + if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, p->index)) + goto nla_put_failure; + } else if (p->erspan_ver == 2) { + if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, p->dir)) + goto nla_put_failure; + if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, p->hwid)) + goto nla_put_failure; + } + return 0; nla_put_failure: @@ -1957,6 +2041,9 @@ static const struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = { [IFLA_GRE_COLLECT_METADATA] = { .type = NLA_FLAG }, [IFLA_GRE_FWMARK] = { .type = NLA_U32 }, [IFLA_GRE_ERSPAN_INDEX] = { .type = NLA_U32 }, + [IFLA_GRE_ERSPAN_VER] = { .type = NLA_U8 }, + [IFLA_GRE_ERSPAN_DIR] = { .type = NLA_U8 }, + [IFLA_GRE_ERSPAN_HWID] = { .type = NLA_U16 }, }; static void ip6erspan_tap_setup(struct net_device *dev) @@ -2078,4 +2165,5 @@ MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); MODULE_DESCRIPTION("GRE over IPv6 tunneling device"); MODULE_ALIAS_RTNL_LINK("ip6gre"); MODULE_ALIAS_RTNL_LINK("ip6gretap"); +MODULE_ALIAS_RTNL_LINK("ip6erspan"); MODULE_ALIAS_NETDEV("ip6gre0");