All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Anders K. Pedersen | Cohaesio" <akp@cohaesio.com>
To: "netfilter-devel@vger.kernel.org"
	<netfilter-devel@vger.kernel.org>,
	"pablo@netfilter.org" <pablo@netfilter.org>
Subject: [PATCH v2 nf-next 2/5] netfilter: nft: basic routing expression
Date: Wed, 19 Oct 2016 18:38:14 +0000	[thread overview]
Message-ID: <1476902293.1161.19.camel@cohaesio.com> (raw)
In-Reply-To: <1476902043.1161.14.camel@cohaesio.com>

From: Anders K. Pedersen <akp@cohaesio.com>

Introduce basic infrastructure for nftables rt expression for routing
related data. Initially "rt classid" is implemented identical to "meta
rtclassid", since it is more logical to have this match in the routing
expression going forward.

Signed-off-by: Anders K. Pedersen <akp@cohaesio.com>
---
v2
- remove nft_rt_select_ops

 include/net/netfilter/nft_rt.h           |  23 +++++
 net/netfilter/Kconfig                    |   6 ++
 net/netfilter/Makefile                   |   1 +
 net/netfilter/nft_rt.c                   | 137 +++++++++++++++++++++++++++++
 4 files changed, 167 insertions(+)

diff --git a/include/net/netfilter/nft_rt.h b/include/net/netfilter/nft_rt.h
new file mode 100644
index 0000000..e32e9e6
--- /dev/null
+++ b/include/net/netfilter/nft_rt.h
@@ -0,0 +1,23 @@
+#ifndef _NFT_RT_H_
+#define _NFT_RT_H_
+
+struct nft_rt {
+	enum nft_rt_keys	key:8;
+	enum nft_registers	dreg:8;
+	u8			family;
+};
+
+extern const struct nla_policy nft_rt_policy[];
+
+int nft_rt_get_init(const struct nft_ctx *ctx,
+		    const struct nft_expr *expr,
+		    const struct nlattr * const tb[]);
+
+int nft_rt_get_dump(struct sk_buff *skb,
+		    const struct nft_expr *expr);
+
+void nft_rt_get_eval(const struct nft_expr *expr,
+		     struct nft_regs *regs,
+		     const struct nft_pktinfo *pkt);
+
+#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index e8d56d9..40d6e0f 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -474,6 +474,12 @@ config NFT_META
 	  This option adds the "meta" expression that you can use to match and
 	  to set packet metainformation such as the packet mark.
 
+config NFT_RT
+	tristate "Netfilter nf_tables routing module"
+	help
+	  This option adds the "rt" expression that you can use to match
+	  packet routing information such as the packet nexthop.
+
 config NFT_NUMGEN
 	tristate "Netfilter nf_tables number generator module"
 	help
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index c23c3c8..f3a0c59 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_NF_TABLES_NETDEV)	+= nf_tables_netdev.o
 obj-$(CONFIG_NFT_COMPAT)	+= nft_compat.o
 obj-$(CONFIG_NFT_EXTHDR)	+= nft_exthdr.o
 obj-$(CONFIG_NFT_META)		+= nft_meta.o
+obj-$(CONFIG_NFT_RT)		+= nft_rt.o
 obj-$(CONFIG_NFT_NUMGEN)	+= nft_numgen.o
 obj-$(CONFIG_NFT_CT)		+= nft_ct.o
 obj-$(CONFIG_NFT_LIMIT)		+= nft_limit.o
diff --git a/net/netfilter/nft_rt.c b/net/netfilter/nft_rt.c
new file mode 100644
index 0000000..775c283
--- /dev/null
+++ b/net/netfilter/nft_rt.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Anders K. Pedersen <akp@cohaesio.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netlink.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <net/dst.h>
+#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_core.h>
+#include <net/netfilter/nft_rt.h>
+
+void nft_rt_get_eval(const struct nft_expr *expr,
+		     struct nft_regs *regs,
+		     const struct nft_pktinfo *pkt)
+{
+	const struct nft_rt *priv = nft_expr_priv(expr);
+	const struct sk_buff *skb = pkt->skb;
+	u32 *dest = &regs->data[priv->dreg];
+
+	switch (priv->key) {
+#ifdef CONFIG_IP_ROUTE_CLASSID
+	case NFT_RT_CLASSID: {
+		const struct dst_entry *dst = skb_dst(skb);
+
+		if (dst == NULL)
+			goto err;
+		*dest = dst->tclassid;
+		break;
+	}
+#endif
+	default:
+		WARN_ON(1);
+		goto err;
+	}
+	return;
+
+err:
+	regs->verdict.code = NFT_BREAK;
+}
+EXPORT_SYMBOL_GPL(nft_rt_get_eval);
+
+const struct nla_policy nft_rt_policy[NFTA_RT_MAX + 1] = {
+	[NFTA_RT_DREG]		= { .type = NLA_U32 },
+	[NFTA_RT_KEY]		= { .type = NLA_U32 },
+	[NFTA_RT_FAMILY]	= { .type = NLA_U32 },
+};
+EXPORT_SYMBOL_GPL(nft_rt_policy);
+
+int nft_rt_get_init(const struct nft_ctx *ctx,
+		    const struct nft_expr *expr,
+		    const struct nlattr * const tb[])
+{
+	struct nft_rt *priv = nft_expr_priv(expr);
+	unsigned int len;
+
+	if (tb[NFTA_RT_KEY] == NULL ||
+	    tb[NFTA_RT_DREG] == NULL ||
+	    tb[NFTA_RT_FAMILY] == NULL)
+		return -EINVAL;
+
+	priv->key = ntohl(nla_get_be32(tb[NFTA_RT_KEY]));
+	switch (priv->key) {
+#ifdef CONFIG_IP_ROUTE_CLASSID
+	case NFT_RT_CLASSID:
+		len = sizeof(u32);
+		break;
+#endif
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	priv->family = ntohl(nla_get_be32(tb[NFTA_RT_FAMILY]));
+	priv->dreg = nft_parse_register(tb[NFTA_RT_DREG]);
+	return nft_validate_register_store(ctx, priv->dreg, NULL,
+					   NFT_DATA_VALUE, len);
+}
+EXPORT_SYMBOL_GPL(nft_rt_get_init);
+
+int nft_rt_get_dump(struct sk_buff *skb,
+		    const struct nft_expr *expr)
+{
+	const struct nft_rt *priv = nft_expr_priv(expr);
+
+	if (nla_put_be32(skb, NFTA_RT_KEY, htonl(priv->key)))
+		goto nla_put_failure;
+	if (nft_dump_register(skb, NFTA_RT_DREG, priv->dreg))
+		goto nla_put_failure;
+	if (nla_put_be32(skb, NFTA_RT_FAMILY, htonl(priv->family)))
+		goto nla_put_failure;
+	return 0;
+
+nla_put_failure:
+	return -1;
+}
+EXPORT_SYMBOL_GPL(nft_rt_get_dump);
+
+static struct nft_expr_type nft_rt_type;
+static const struct nft_expr_ops nft_rt_get_ops = {
+	.type		= &nft_rt_type,
+	.size		= NFT_EXPR_SIZE(sizeof(struct nft_rt)),
+	.eval		= nft_rt_get_eval,
+	.init		= nft_rt_get_init,
+	.dump		= nft_rt_get_dump,
+};
+
+static struct nft_expr_type nft_rt_type __read_mostly = {
+	.name		= "rt",
+	.ops		= &nft_rt_get_ops,
+	.policy		= nft_rt_policy,
+	.maxattr	= NFTA_RT_MAX,
+	.owner		= THIS_MODULE,
+};
+
+static int __init nft_rt_module_init(void)
+{
+	return nft_register_expr(&nft_rt_type);
+}
+
+static void __exit nft_rt_module_exit(void)
+{
+	nft_unregister_expr(&nft_rt_type);
+}
+
+module_init(nft_rt_module_init);
+module_exit(nft_rt_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anders K. Pedersen <akp@cohaesio.com>");
+MODULE_ALIAS_NFT_EXPR("rt");

  parent reply	other threads:[~2016-10-19 18:38 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-19 18:34 [PATCH v2 nf-next 0/5] netfilter: nft: introduce routing expression Anders K. Pedersen | Cohaesio
2016-10-19 18:35 ` [PATCH v2 nf-next 1/5] netfilter: nft: UAPI headers for " Anders K. Pedersen | Cohaesio
2016-10-19 18:38 ` Anders K. Pedersen | Cohaesio [this message]
2016-10-19 18:39 ` [PATCH v2 nf-next 3/5] netfilter: nft: rt nexthop for IPv4 family Anders K. Pedersen | Cohaesio
2016-10-19 18:40 ` [PATCH v2 nf-next 4/5] netfilter: nft: rt nexthop for IPv6 family Anders K. Pedersen | Cohaesio
2016-10-19 18:41 ` [PATCH v2 nf-next 5/5] netfilter: nft: rt nexthop for inet family Anders K. Pedersen | Cohaesio
2016-10-20  9:13   ` Liping Zhang
2016-10-20 12:36     ` Anders K. Pedersen | Cohaesio
2016-10-20 13:27       ` Liping Zhang
2016-10-20 13:52         ` Anders K. Pedersen | Cohaesio
2016-10-21  2:06           ` Liping Zhang
2016-10-21  4:16             ` Anders K. Pedersen | Cohaesio
2016-10-21  6:17               ` Liping Zhang
2016-10-21  8:26                 ` Anders K. Pedersen | Cohaesio
2016-10-21 12:42                   ` Liping Zhang
2016-10-22 15:25                     ` Anders K. Pedersen | Cohaesio
2016-10-21  9:21                 ` Pablo Neira Ayuso
2016-10-21 13:22                   ` Liping Zhang
2016-10-21 16:58                     ` Pablo Neira Ayuso
2016-10-22  1:44                       ` Liping Zhang
2016-10-22 16:08                         ` Anders K. Pedersen | Cohaesio
2016-10-23  5:01                           ` Liping Zhang
2016-10-27 17:50                             ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1476902293.1161.19.camel@cohaesio.com \
    --to=akp@cohaesio.com \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.