From patchwork Thu Aug 10 20:28:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amine Kherbouche X-Patchwork-Id: 800331 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="NVpcQRyQ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xT08x6bFmz9sPk for ; Fri, 11 Aug 2017 06:29:05 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753318AbdHJU3C (ORCPT ); Thu, 10 Aug 2017 16:29:02 -0400 Received: from mail-wm0-f52.google.com ([74.125.82.52]:35838 "EHLO mail-wm0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752889AbdHJU3A (ORCPT ); Thu, 10 Aug 2017 16:29:00 -0400 Received: by mail-wm0-f52.google.com with SMTP id m85so28246578wma.0 for ; Thu, 10 Aug 2017 13:28:59 -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=vKn/Sdes9CHAYFdryq+1i9gbx17NSuatjYx1R6qzD4Q=; b=NVpcQRyQDfDaAtKup4SlPXyl42Dyr8fmFpPRIPTvx1uLHsTdtVRypLImOteCx+ljn4 ShJSyApMaeAlb7WlmJzoXRnOAgeNRsTgiFaQc4k9GxScEpyoH0vJBvyEAbscnk+WbZP6 VjBdIXMBV7V2CUkWPz6oSYhh8idIER4iDIdVg8jXPqgxdEJlfbkbkwHsyUIeytNmVRQz 10e5dSX6oKKFnX8544e/nkmtunWXnY/bOJNx8Q1st5QLZvfIsPnyT8Y/cHqXykC2pXz0 dPpNlB8hpta/R0PdlOpYM+zYh9q1NhA9pcR/6ZnGnLD2KINxhkE0t5CGi6b9DqocU+J9 b4NA== 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=vKn/Sdes9CHAYFdryq+1i9gbx17NSuatjYx1R6qzD4Q=; b=t+0lLPgtbIC5Z99xgJLklSysc9xVBkrOpeDY6xD/t8k7GhEbsNMynncJmB3fcgQ7lr cHJ2NwxN1qZn1YrL355PgQNHDtFUZUBiVwP20lv0DSSjm/LV3Ml84aAHmIGBAQBVa89N T2xg/HWeLfVcitx9T4u+/5R/7x6oltyi0+lwek9Z0EkpZgm++5BMtLMnBn1cOLmr9QRK s7pdXktknXiT/5ApYi1Nqu60LMaCFv91ctVH3F7ZZJ3aaDl7ami1gFPKu74ffGKjl9Yb GyZOHreo90M8KhHT3fiuKayn4kf/cTMjCAy3b+gGdqcU/1kB+zEMJZ1Aew+xfDMQC1Rz k/4Q== X-Gm-Message-State: AHYfb5jIPWxgNM7Qjn/EoyEhg9Kmaf8Hu/l9pdYv7zkB5zaMakcSU6bo 79eFuvWjWg5NjX7Qy+0= X-Received: by 10.28.169.70 with SMTP id s67mr9698207wme.47.1502396938918; Thu, 10 Aug 2017 13:28:58 -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 y30sm9221465wrc.51.2017.08.10.13.28.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 10 Aug 2017 13:28:58 -0700 (PDT) From: Amine Kherbouche To: netdev@vger.kernel.org Cc: amine.kherbouche@6wind.com, roopa@cumulusnetworks.com, David Lamparter Subject: [PATCH 1/2] mpls: add handlers Date: Thu, 10 Aug 2017 22:28:36 +0200 Message-Id: <1502396917-14848-2-git-send-email-amine.kherbouche@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1502396917-14848-1-git-send-email-amine.kherbouche@6wind.com> References: <1502396917-14848-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 Mpls handler allows creation/deletion of mpls routes without using rtnetlink. When an incoming mpls packet matches this route, the saved function handler is called. Signed-off-by: Amine Kherbouche Signed-off-by: David Lamparter --- include/net/mpls.h | 10 +++++++ net/mpls/af_mpls.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ net/mpls/internal.h | 3 +++ 3 files changed, 88 insertions(+) diff --git a/include/net/mpls.h b/include/net/mpls.h index 1dbc669..0ff51b6 100644 --- a/include/net/mpls.h +++ b/include/net/mpls.h @@ -33,4 +33,14 @@ static inline struct mpls_shim_hdr *mpls_hdr(const struct sk_buff *skb) { return (struct mpls_shim_hdr *)skb_network_header(skb); } + +typedef int (*mpls_handler)(void *arg, struct sk_buff *skb, + struct net_device *dev, u32 index, u8 bos); + +extern int mpls_handler_add(struct net *net, u32 index, u8 via_table, u8 via[], + mpls_handler handler, void *handler_arg, + struct netlink_ext_ack *extack); +extern int mpls_handler_del(struct net *net, u32 index, + struct netlink_ext_ack *extack); + #endif diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index c5b9ce4..82d2126 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -299,6 +300,7 @@ static bool mpls_egress(struct net *net, struct mpls_route *rt, success = true; break; } + case MPT_HANDLER: case MPT_UNSPEC: /* Should have decided which protocol it is by now */ break; @@ -356,6 +358,10 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev, goto drop; } + if (rt->rt_payload_type == MPT_HANDLER) + return rt->rt_handler(rt->rt_harg, skb, dev, + dec.label, dec.bos); + nh = mpls_select_multipath(rt, skb); if (!nh) goto err; @@ -457,6 +463,8 @@ static const struct nla_policy rtm_mpls_policy[RTA_MAX+1] = { struct mpls_route_config { u32 rc_protocol; u32 rc_ifindex; + mpls_handler rc_handler; + void *rc_harg; u8 rc_via_table; u8 rc_via_alen; u8 rc_via[MAX_VIA_ALEN]; @@ -995,6 +1003,11 @@ static int mpls_route_add(struct mpls_route_config *cfg, rt->rt_payload_type = cfg->rc_payload_type; rt->rt_ttl_propagate = cfg->rc_ttl_propagate; + if (cfg->rc_handler) { + rt->rt_handler = cfg->rc_handler; + rt->rt_harg = cfg->rc_harg; + } + if (cfg->rc_mp) err = mpls_nh_build_multi(cfg, rt, max_labels, extack); else @@ -1271,6 +1284,68 @@ static int mpls_netconf_dump_devconf(struct sk_buff *skb, return skb->len; } +int mpls_handler_add(struct net *net, u32 label, u8 via_table, u8 via[], + mpls_handler handler, void *handler_arg, + struct netlink_ext_ack *extack) +{ + struct net_device *dev = handler_arg; + struct mpls_route_config *cfg; + u8 alen = 0; + int err; + + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + + memset(cfg, 0, sizeof(*cfg)); + if (via_table == NEIGH_ARP_TABLE) + alen = sizeof(struct in_addr); + else if (via_table == NEIGH_ND_TABLE) + alen = sizeof(struct in6_addr); + + cfg->rc_ttl_propagate = MPLS_TTL_PROP_DEFAULT; + cfg->rc_protocol = RTPROT_KERNEL; + cfg->rc_nlflags |= NLM_F_CREATE; + cfg->rc_payload_type = MPT_HANDLER; + cfg->rc_via_table = via_table; + cfg->rc_label = label; + cfg->rc_via_alen = alen; + memcpy(&cfg->rc_via, via, alen); + cfg->rc_ifindex = dev->ifindex; + cfg->rc_nlinfo.nl_net = net; + cfg->rc_harg = handler_arg; + cfg->rc_handler = handler; + cfg->rc_output_labels = 0; + + err = mpls_route_add(cfg, extack); + kfree(cfg); + + return err; +} +EXPORT_SYMBOL(mpls_handler_add); + +int mpls_handler_del(struct net *net, u32 index, + struct netlink_ext_ack *extack) +{ + struct mpls_route_config *cfg; + int err = 0; + + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + + memset(cfg, 0, sizeof(*cfg)); + cfg->rc_protocol = RTPROT_KERNEL; + cfg->rc_label = index; + cfg->rc_nlinfo.nl_net = net; + + err = mpls_route_del(cfg, extack); + kfree(cfg); + + return err; +} +EXPORT_SYMBOL(mpls_handler_del); + #define MPLS_PERDEV_SYSCTL_OFFSET(field) \ (&((struct mpls_dev *)0)->field) diff --git a/net/mpls/internal.h b/net/mpls/internal.h index cf65aec..2cd73eb 100644 --- a/net/mpls/internal.h +++ b/net/mpls/internal.h @@ -78,6 +78,7 @@ enum mpls_payload_type { MPT_UNSPEC, /* IPv4 or IPv6 */ MPT_IPV4 = 4, MPT_IPV6 = 6, + MPT_HANDLER = 255, /* Other types not implemented: * - Pseudo-wire with or without control word (RFC4385) @@ -141,6 +142,8 @@ enum mpls_ttl_propagation { */ struct mpls_route { /* next hop label forwarding entry */ struct rcu_head rt_rcu; + mpls_handler rt_handler; + void *rt_harg; u8 rt_protocol; u8 rt_payload_type; u8 rt_max_alen;