From patchwork Thu Jul 7 05:56:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 645761 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 3rlRhQ1jKPz9s9x for ; Thu, 7 Jul 2016 15:56:38 +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=r/31k0cf; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756127AbcGGF43 (ORCPT ); Thu, 7 Jul 2016 01:56:29 -0400 Received: from mail-wm0-f48.google.com ([74.125.82.48]:36720 "EHLO mail-wm0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751399AbcGGF42 (ORCPT ); Thu, 7 Jul 2016 01:56:28 -0400 Received: by mail-wm0-f48.google.com with SMTP id f126so196754686wma.1 for ; Wed, 06 Jul 2016 22:56:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=NsbIixFdZPuC/VMH4NhS5z1FOBmL34480HiMgkO380o=; b=r/31k0cfM2NUx7ffej9NqGNPYZ5ONAdZ8WiBhwluGI+tGTDEMKFj8xD/I0lqQlVpVI tjd1Ot5oEMlfMNpaXec8yZ5Ce+OAdt1mp3jyTmmzUED5VDXGO4WCUzKiFx3CdT5Xiera Hk74PnDBmxI+5wULNPLWLdI8cI35dlfvlTW/sOMXIegO1GFLqUreicbG0vQIm1Q/sRxR usbkSgrBCdEetNEAWL3CrIctlVsZAIkIy6K0Mow4XGoQFhsKNHPFJujgGsyQYgnyuu7L P4IxOTJhyj5+dvK2sVvqatQkft0QvknUiCMg09uMSk80Mw3FVCHa1dj1I8q63P/oZula pEbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=NsbIixFdZPuC/VMH4NhS5z1FOBmL34480HiMgkO380o=; b=h0vTtiEI4UY/X+jXFDWZLxXnNxz/S80cnysiFLNGjvEgooSWFVEMVvtp6xYfc1h9/e ujvQSVCJeePpaICZAEARUnpTxgOsV6aGrRc8btxlzGsVSB/7FsjuN9mcxiYPQClsB1Km Ts8mJtIDWYvXFQtN7q0QmJR+SaGpxhmyhYtU61M4iVfUEi2TAf8OSSL2mmibsBsSatsk ztJE9ZFomu5tED0B0qvFG/i0DZ7hGuNvKvXEDZV1/e1RWA4ubHgb/REhurRCIrCupqtm xfJF/nUcTsi+OTCbVERXTpG/WOdWd4gLrQJa5YJkm34yfMRLR/Ps8SCQhFt1iOs0jvUF 5o9w== X-Gm-Message-State: ALyK8tICMT73uLhFA7Avj0Z1C5sgJknDuuvwYxzhOdVta11Yi3s9ubYQ/ZurujK/iadmoSCT X-Received: by 10.194.209.201 with SMTP id mo9mr6508633wjc.120.1467870987082; Wed, 06 Jul 2016 22:56:27 -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 a191sm4488035wme.5.2016.07.06.22.56.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Jul 2016 22:56:26 -0700 (PDT) From: Simon Horman To: David Miller Cc: Tom Herbert , netdev@vger.kernel.org, Simon Horman Subject: [PATCH net-next v2 1/4] tunnels: support MPLS over IPv4 tunnels Date: Thu, 7 Jul 2016 07:56:12 +0200 Message-Id: <1467870975-28003-2-git-send-email-simon.horman@netronome.com> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 In-Reply-To: <1467870975-28003-1-git-send-email-simon.horman@netronome.com> References: <1467870975-28003-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");