From patchwork Thu Sep 21 09:25:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amine Kherbouche X-Patchwork-Id: 816778 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=6wind-com.20150623.gappssmtp.com header.i=@6wind-com.20150623.gappssmtp.com header.b="p9yUWXLi"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xyWSb1gMCz9t43 for ; Thu, 21 Sep 2017 19:26:07 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751903AbdIUJ0D (ORCPT ); Thu, 21 Sep 2017 05:26:03 -0400 Received: from mail-wm0-f44.google.com ([74.125.82.44]:45074 "EHLO mail-wm0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751887AbdIUJ0A (ORCPT ); Thu, 21 Sep 2017 05:26:00 -0400 Received: by mail-wm0-f44.google.com with SMTP id q124so22245wmb.0 for ; Thu, 21 Sep 2017 02:26:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3e2hbwcjbjd21DNEiOzWCzEgpNenmnoink4dl9Giz/A=; b=p9yUWXLiIiiixDDVstoxjZoH7L88z71uOt2/UxSDaIsBQHtl6MPSyeUwUTnCBgzoGm rhBr6T+99dXUH0QP/JASXsv9bFeTk8lwjJBXgvgH+tpoXIEwKpuh40CwAbBDulxEqitv BgP05+effB/7w+qhrNAISrqAkPPFrieMLdxRBu4DOvjeedsCG1zqb6IXNKuQosmW5LZ/ T5Ff/hcWx+68mD9d4k4YYQyn+wqU4FvqHa5z5qA1qoxOKfDWl8+RgNB9Ml0H2BFCRQs+ aL+Jb5fuBaqaTB40wNg4vHrIsdZosk608FxYbux6edlaJOthfop7brs3ZbtouNJpNcII zjUA== 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:in-reply-to :references; bh=3e2hbwcjbjd21DNEiOzWCzEgpNenmnoink4dl9Giz/A=; b=oG6SX0fmNM3Fk6WFSuH3DVVCTfxLMwulhEg+EVMWgAnGuwB2Ww26Fh4afizQlhvTHq NyXSj2t0AO65a1SDUDHGYMPKwdmSYKAXrTXKzjyyGGovlzhJ0SvIWDN8YaptntntA7b2 Xlp0KhCaWyeEyWlasAp8/etqemEyEHvWJnCT8sL4ELVFsaenN+/HVhYL/FwhlPt1QU87 w61AOrL57sIo+GZoszO1YJMBUJjZU13DC2gdo8iJ8VSIGF6HO2O+VAKVhQ8Xmlk8+YED 7RD28SCFrkDuzRfSr64jAYDQoqFDVe7Ql7SBh26XmbRisQK2LlP+jRwE6nwNGw4aesQi rMaQ== X-Gm-Message-State: AHPjjUixBOoxgnvZ3le4LLHdFOuXCYyFWzKs0rn1Y9/8WGZ+/IuMrl0v kBYezxO9RkIR/X1LwCONtSb2X6IM X-Google-Smtp-Source: AOwi7QCAPu8CNRedNuXXY9pwfexreBB64jwd5WbyEWJ7SCsxBfKV3D69XKnCufsOndblpk2+Po9XqA== X-Received: by 10.28.107.17 with SMTP id g17mr435672wmc.58.1505985959223; Thu, 21 Sep 2017 02:25:59 -0700 (PDT) Received: from griffon.dev.6wind.com. (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id t15sm748591wrb.41.2017.09.21.02.25.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Sep 2017 02:25:58 -0700 (PDT) From: Amine Kherbouche To: netdev@vger.kernel.org, xeb@mail.ru, roopa@cumulusnetworks.com Cc: amine.kherbouche@6wind.com, equinox@diac24.net Subject: [PATCH 2/2] ip_tunnel: add mpls over gre encapsulation Date: Thu, 21 Sep 2017 11:25:24 +0200 Message-Id: <1505985924-12479-3-git-send-email-amine.kherbouche@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1505985924-12479-1-git-send-email-amine.kherbouche@6wind.com> References: <1505985924-12479-1-git-send-email-amine.kherbouche@6wind.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This commit introduces the MPLSoGRE support (RFC 4023), using ip tunnel API. Encap: - Add a new iptunnel type mpls. Decap: - pull gre hdr and call mpls_forward(). Signed-off-by: Amine Kherbouche --- include/net/gre.h | 3 +++ include/uapi/linux/if_tunnel.h | 1 + net/ipv4/gre_demux.c | 22 ++++++++++++++++++++++ net/ipv4/ip_gre.c | 9 +++++++++ net/ipv6/ip6_gre.c | 7 +++++++ net/mpls/af_mpls.c | 37 +++++++++++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+) diff --git a/include/net/gre.h b/include/net/gre.h index d25d836..88a8343 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -35,6 +35,9 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name, u8 name_assign_type); int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, bool *csum_err, __be16 proto, int nhs); +#if IS_ENABLED(CONFIG_MPLS) +int mpls_gre_rcv(struct sk_buff *skb, int gre_hdr_len); +#endif static inline int gre_calc_hlen(__be16 o_flags) { diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index 2e52088..a2f48c0 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h @@ -84,6 +84,7 @@ enum tunnel_encap_types { TUNNEL_ENCAP_NONE, TUNNEL_ENCAP_FOU, TUNNEL_ENCAP_GUE, + TUNNEL_ENCAP_MPLS, }; #define TUNNEL_ENCAP_FLAG_CSUM (1<<0) diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index b798862..a6a937e 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c @@ -23,6 +23,9 @@ #include #include #include +#if IS_ENABLED(CONFIG_MPLS) +#include +#endif #include #include @@ -122,6 +125,25 @@ int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, } EXPORT_SYMBOL(gre_parse_header); +#if IS_ENABLED(CONFIG_MPLS) +int mpls_gre_rcv(struct sk_buff *skb, int gre_hdr_len) +{ + if (unlikely(!pskb_may_pull(skb, gre_hdr_len))) + goto drop; + + /* Pop GRE hdr and reset the skb */ + skb_pull(skb, gre_hdr_len); + skb_reset_network_header(skb); + + mpls_forward(skb, skb->dev, NULL, NULL); + + return 0; +drop: + return NET_RX_DROP; +} +EXPORT_SYMBOL(mpls_gre_rcv); +#endif + static int gre_rcv(struct sk_buff *skb) { const struct gre_protocol *proto; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 9cee986..dd4431c 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -412,10 +412,19 @@ static int gre_rcv(struct sk_buff *skb) return 0; } +#if IS_ENABLED(CONFIG_MPLS) + if (unlikely(tpi.proto == htons(ETH_P_MPLS_UC))) { + if (mpls_gre_rcv(skb, hdr_len)) + goto drop; + return 0; + } +#endif + if (ipgre_rcv(skb, &tpi, hdr_len) == PACKET_RCVD) return 0; icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + drop: kfree_skb(skb); return 0; diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index c82d41e..e52396d 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -476,6 +476,13 @@ static int gre_rcv(struct sk_buff *skb) if (hdr_len < 0) goto drop; +#if IS_ENABLED(CONFIG_MPLS) + if (unlikely(tpi.proto == htons(ETH_P_MPLS_UC))) { + if (mpls_gre_rcv(skb, hdr_len)) + goto drop; + return 0; + } +#endif if (iptunnel_pull_header(skb, hdr_len, tpi.proto, false)) goto drop; diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 36ea2ad..060ed07 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #if IS_ENABLED(CONFIG_IPV6) #include @@ -39,6 +40,40 @@ static int one = 1; static int label_limit = (1 << 20) - 1; static int ttl_max = 255; +size_t ipgre_mpls_encap_hlen(struct ip_tunnel_encap *e) +{ + return sizeof(struct mpls_shim_hdr); +} + +int ipgre_mpls_build_header(struct sk_buff *skb, struct ip_tunnel_encap *e, + u8 *protocol, struct flowi4 *fl4) +{ + return 0; +} + +static const struct ip_tunnel_encap_ops mpls_iptun_ops = { + .encap_hlen = ipgre_mpls_encap_hlen, + .build_header = ipgre_mpls_build_header, +}; + +int ipgre_tunnel_encap_add_mpls_ops(void) +{ + int ret; + + ret = ip_tunnel_encap_add_ops(&mpls_iptun_ops, TUNNEL_ENCAP_MPLS); + if (ret < 0) { + pr_err("can't add mplsgre ops\n"); + return ret; + } + + return 0; +} + +static void ipgre_tunnel_encap_del_mpls_ops(void) +{ + ip_tunnel_encap_del_ops(&mpls_iptun_ops, TUNNEL_ENCAP_MPLS); +} + static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt, struct nlmsghdr *nlh, struct net *net, u32 portid, unsigned int nlm_flags); @@ -2486,6 +2521,7 @@ static int __init mpls_init(void) 0); rtnl_register(PF_MPLS, RTM_GETNETCONF, mpls_netconf_get_devconf, mpls_netconf_dump_devconf, 0); + ipgre_tunnel_encap_add_mpls_ops(); err = 0; out: return err; @@ -2503,6 +2539,7 @@ static void __exit mpls_exit(void) dev_remove_pack(&mpls_packet_type); unregister_netdevice_notifier(&mpls_dev_notifier); unregister_pernet_subsys(&mpls_net_ops); + ipgre_tunnel_encap_del_mpls_ops(); } module_exit(mpls_exit);