From patchwork Wed Jul 6 18:22:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 645435 X-Patchwork-Delegate: davem@davemloft.net 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 3rl8JR5XFmz9sDC for ; Thu, 7 Jul 2016 04:23:19 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b=suNbs2Lb; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755253AbcGFSW4 (ORCPT ); Wed, 6 Jul 2016 14:22:56 -0400 Received: from mail-wm0-f54.google.com ([74.125.82.54]:35973 "EHLO mail-wm0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751793AbcGFSWx (ORCPT ); Wed, 6 Jul 2016 14:22:53 -0400 Received: by mail-wm0-f54.google.com with SMTP id f126so183583887wma.1 for ; Wed, 06 Jul 2016 11:22:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=NsbIixFdZPuC/VMH4NhS5z1FOBmL34480HiMgkO380o=; b=suNbs2Lb2EkM5IDLaWoxQlDBf0J/1IS7fr6sMl57cvYbCQ73MPR09hO3rX+OmtVVmS 0lfHs8O0o7JZgPKtXmg7Tl9ZsCL62Pbs6sjj6Kmw7ZzMtCIK2Ikwnbjwz8nCkSz3lUqq R8IzJ2VS4kmyS5zcOK0JfF7CafWSohbL9bADkdC8CKFAyoXAKWrti4mXmQtppk8AnW11 24LGkySDb5lJ1J11VHVrN+8jP2qZzATKvpOLL+jorzVEh5gZj04d715WAmj7Up6uTSAo B7e5oUX88tQ10BixzDPTYY2WswM5ygkR2Qo/bcovM6IDJPh9bhWzOTATTpShXfa/RnmF SyJQ== 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=NsbIixFdZPuC/VMH4NhS5z1FOBmL34480HiMgkO380o=; b=M+WJEQueZo4VWhg0G4ifzsczpRxcfHZgiaHTY3iz0fjGPpKXADsVbPA78vCT1pJjYC wP05wTypAVUvZmwNi82vQN9t8lpPQIm3NqIjUSqPjy5QZsy6xmt3i8gabibIMfWF+mBd pxTwFKacSqecCT/jXBYccLyy9PO/+WvpAwJURZdCpNr5maZEy+bxnjhlzACJP2WKXYWb todM68ZYcwqxrkZ5uva3JogpAeG6O3F5hMqOdJ79hPSO4eAWxl8N9qQ0AZ89Goy3izdU fH37gg9NfeIdlVNvW2YzbV/I+bUL/azm8HQhWr6m7mLaSkBS8znyhkO2J+PHzNo4rWoX 19HQ== X-Gm-Message-State: ALyK8tJfWvYCfBxmmKueh6w8k3ANrjfXz7d/47CO5OOU3qQFW8lt3z7R4fDgp9scQ9aB3XrC X-Received: by 10.28.18.199 with SMTP id 190mr23491403wms.66.1467829371733; Wed, 06 Jul 2016 11:22:51 -0700 (PDT) Received: from penelope.isobedori.kobe.vergenet.net (dhcp-077-251-078-056.chello.nl. [77.251.78.56]) by smtp.gmail.com with ESMTPSA id m5sm629757wmm.10.2016.07.06.11.22.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Jul 2016 11:22:50 -0700 (PDT) From: Simon Horman To: netdev@vger.kernel.org Subject: [PATCH/RFC net-next 1/4] tunnels: support MPLS over IPv4 tunnels Date: Wed, 6 Jul 2016 20:22:32 +0200 Message-Id: <1467829355-4498-2-git-send-email-simon.horman@netronome.com> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 In-Reply-To: <1467829355-4498-1-git-send-email-simon.horman@netronome.com> References: <1467829355-4498-1-git-send-email-simon.horman@netronome.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Extend tunnel support to MPLS over IPv4. The implementation extends the existing differentiation between IPIP and IPv6 over IPv4 to also cover MPLS over IPv4. Signed-off-by: Simon Horman Reviewed-by: Dinan Gunawardena --- net/ipv4/tunnel4.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index 0d0171830620..45cd4253583a 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -16,11 +17,14 @@ static struct xfrm_tunnel __rcu *tunnel4_handlers __read_mostly; static struct xfrm_tunnel __rcu *tunnel64_handlers __read_mostly; +static struct xfrm_tunnel __rcu *tunnelmpls4_handlers __read_mostly; static DEFINE_MUTEX(tunnel4_mutex); static inline struct xfrm_tunnel __rcu **fam_handlers(unsigned short family) { - return (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers; + return (family == AF_INET) ? &tunnel4_handlers : + (family == AF_INET6) ? &tunnel64_handlers : + &tunnelmpls4_handlers; } int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) @@ -125,6 +129,26 @@ drop: } #endif +#if IS_ENABLED(CONFIG_MPLS) +static int tunnelmpls4_rcv(struct sk_buff *skb) +{ + struct xfrm_tunnel *handler; + + if (!pskb_may_pull(skb, sizeof(struct mpls_label))) + goto drop; + + for_each_tunnel_rcu(tunnelmpls4_handlers, handler) + if (!handler->handler(skb)) + return 0; + + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + +drop: + kfree_skb(skb); + return 0; +} +#endif + static void tunnel4_err(struct sk_buff *skb, u32 info) { struct xfrm_tunnel *handler; @@ -145,6 +169,17 @@ static void tunnel64_err(struct sk_buff *skb, u32 info) } #endif +#if IS_ENABLED(CONFIG_MPLS) +static void tunnelmpls4_err(struct sk_buff *skb, u32 info) +{ + struct xfrm_tunnel *handler; + + for_each_tunnel_rcu(tunnelmpls4_handlers, handler) + if (!handler->err_handler(skb, info)) + break; +} +#endif + static const struct net_protocol tunnel4_protocol = { .handler = tunnel4_rcv, .err_handler = tunnel4_err, @@ -161,24 +196,46 @@ static const struct net_protocol tunnel64_protocol = { }; #endif +#if IS_ENABLED(CONFIG_MPLS) +static const struct net_protocol tunnelmpls4_protocol = { + .handler = tunnelmpls4_rcv, + .err_handler = tunnelmpls4_err, + .no_policy = 1, + .netns_ok = 1, +}; +#endif + static int __init tunnel4_init(void) { - if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) { - pr_err("%s: can't add protocol\n", __func__); - return -EAGAIN; - } + if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) + goto err_ipip; #if IS_ENABLED(CONFIG_IPV6) - if (inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)) { - pr_err("tunnel64 init: can't add protocol\n"); - inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP); - return -EAGAIN; - } + if (inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)) + goto err_ipv6; +#endif +#if IS_ENABLED(CONFIG_MPLS) + if (inet_add_protocol(&tunnelmpls4_protocol, IPPROTO_MPLS)) + goto err_mpls; #endif return 0; + +#if IS_ENABLED(CONFIG_IPV6) +err_mpls: + inet_del_protocol(&tunnel4_protocol, IPPROTO_IPV6); +#endif +err_ipv6: + inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP); +err_ipip: + pr_err("%s: can't add protocol\n", __func__); + return -EAGAIN; } static void __exit tunnel4_fini(void) { +#if IS_ENABLED(CONFIG_MPLS) + if (inet_del_protocol(&tunnelmpls4_protocol, IPPROTO_MPLS)) + pr_err("tunnelmpls4 close: can't remove protocol\n"); +#endif #if IS_ENABLED(CONFIG_IPV6) if (inet_del_protocol(&tunnel64_protocol, IPPROTO_IPV6)) pr_err("tunnel64 close: can't remove protocol\n");