[PATCH 2/2 WIP nf-next] nft: implement the nf_tables_api changes to add osf signatures in nft

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Added _ADD and _REMOVE commands to nf_tables_api.c in order to use the
nf_tables interface to add 'osf' signatures in nft.

Signed-off-by: Fernando Fernandez Mancera <ffmancera@xxxxxxxxxx>
---
 include/net/netfilter/nf_tables_core.h   |   2 +
 include/uapi/linux/netfilter/nf_osf.h    |   8 ++
 include/uapi/linux/netfilter/nf_tables.h |  14 +++
 include/uapi/linux/netfilter/xt_osf.h    |   7 +-
 net/netfilter/nf_tables_api.c            | 110 +++++++++++++++++++++++
 net/netfilter/nft_osf.c                  |   1 +
 6 files changed, 136 insertions(+), 6 deletions(-)

diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h
index e0c0c2558ec4..ee7eabc8d3e1 100644
--- a/include/net/netfilter/nf_tables_core.h
+++ b/include/net/netfilter/nf_tables_core.h
@@ -65,4 +65,6 @@ extern const struct nft_expr_ops nft_payload_fast_ops;
 extern struct static_key_false nft_counters_enabled;
 extern struct static_key_false nft_trace_enabled;
 
+extern struct list_head nft_osf_fingers[2];
+
 #endif /* _NET_NF_TABLES_CORE_H */
diff --git a/include/uapi/linux/netfilter/nf_osf.h b/include/uapi/linux/netfilter/nf_osf.h
index 79882b2f7f8e..35352c1cd994 100644
--- a/include/uapi/linux/netfilter/nf_osf.h
+++ b/include/uapi/linux/netfilter/nf_osf.h
@@ -2,6 +2,8 @@
 #define _NF_OSF_H
 
 #include <linux/types.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
 
 #define MAXGENRELEN	32
 
@@ -90,4 +92,10 @@ enum iana_options {
 	OSFOPT_EMPTY = 255,
 };
 
+enum nf_osf_attr_type {
+	OSF_ATTR_UNSPEC,
+	OSF_ATTR_FINGER,
+	OSF_ATTR_MAX,
+};
+
 #endif /* _NF_OSF_H */
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index c9bf74b94f37..beffa2010b20 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -9,6 +9,8 @@
 #define NFT_OBJ_MAXNAMELEN	NFT_NAME_MAXLEN
 #define NFT_USERDATA_MAXLEN	256
 
+#define OSF_GENRE_SIZE		32
+
 /**
  * enum nft_registers - nf_tables registers
  *
@@ -122,6 +124,8 @@ enum nf_tables_msg_types {
 	NFT_MSG_NEWFLOWTABLE,
 	NFT_MSG_GETFLOWTABLE,
 	NFT_MSG_DELFLOWTABLE,
+	NFT_MSG_NEWOSF,
+	NFT_MSG_DELOSF,
 	NFT_MSG_MAX,
 };
 
@@ -1461,6 +1465,16 @@ enum nft_flowtable_hook_attributes {
 };
 #define NFTA_FLOWTABLE_HOOK_MAX	(__NFTA_FLOWTABLE_HOOK_MAX - 1)
 
+enum nft_osf_attributes {
+	NFTA_OSF_UNSPEC,
+	NFTA_OSF_GENRE,
+	NFTA_OSF_FLAGS,
+	NFTA_OSF_LOGLEVEL,
+	NFTA_OSF_TTL,
+	__NFTA_OSF_MAX,
+};
+#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
+
 /**
  * enum nft_device_attributes - nf_tables device netlink attributes
  *
diff --git a/include/uapi/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h
index 2f5d4e6d0434..b7c0f93fe9d4 100644
--- a/include/uapi/linux/netfilter/xt_osf.h
+++ b/include/uapi/linux/netfilter/xt_osf.h
@@ -51,6 +51,7 @@
 #define xt_osf_finger		nf_osf_finger
 #define xt_osf_nlmsg		nf_osf_nlmsg
 
+#define xt_osf_attr_type	nf_osf_attr_type
 /*
  * Add/remove fingerprint from the kernel.
  */
@@ -60,10 +61,4 @@ enum xt_osf_msg_types {
 	OSF_MSG_MAX,
 };
 
-enum xt_osf_attr_type {
-	OSF_ATTR_UNSPEC,
-	OSF_ATTR_FINGER,
-	OSF_ATTR_MAX,
-};
-
 #endif				/* _XT_OSF_H */
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index ca4c4d994ddb..1783d8ef658c 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -17,6 +17,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netfilter/nf_tables.h>
+#include <linux/netfilter/nf_osf.h>
 #include <net/netfilter/nf_flow_table.h>
 #include <net/netfilter/nf_tables_core.h>
 #include <net/netfilter/nf_tables.h>
@@ -26,6 +27,7 @@
 static LIST_HEAD(nf_tables_expressions);
 static LIST_HEAD(nf_tables_objects);
 static LIST_HEAD(nf_tables_flowtables);
+
 static u64 table_handle;
 
 enum {
@@ -5851,6 +5853,8 @@ static int nf_tables_flowtable_event(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
+
+
 static struct notifier_block nf_tables_flowtable_notifier = {
 	.notifier_call	= nf_tables_flowtable_event,
 };
@@ -5908,6 +5912,102 @@ static int nf_tables_getgen(struct net *net, struct sock *nlsk,
 	return err;
 }
 
+struct list_head nft_osf_fingers[2];
+EXPORT_SYMBOL_GPL(nft_osf_fingers);
+
+static int nf_tables_newosf(struct net *net, struct sock *ctnl,
+			    struct sk_buff *skb, const struct nlmsghdr *nlh,
+			    const struct nlattr * const osf_attrs[],
+			    struct netlink_ext_ack *extack)
+{
+	struct nf_osf_user_finger *f;
+	struct nf_osf_finger *kf = NULL, *sf;
+	int err = 0;
+	int i = 0;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (!osf_attrs[OSF_ATTR_FINGER])
+		return -EINVAL;
+
+	if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+		return -EINVAL;
+
+	f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+	kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL);
+	if (!kf)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(nft_osf_fingers); ++i)
+		INIT_LIST_HEAD(&nft_osf_fingers[i]);
+
+	memcpy(&kf->finger, f, sizeof(struct nf_osf_user_finger));
+
+	list_for_each_entry(sf, &nft_osf_fingers[!!f->df], finger_entry) {
+		if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger)))
+			continue;
+
+		kfree(kf);
+		kf = NULL;
+
+		if (nlh->nlmsg_flags & NLM_F_EXCL)
+			err = -EEXIST;
+		break;
+	}
+
+	/*
+	 * We are protected by nfnl mutex.
+	 */
+	if (kf)
+		list_add_tail_rcu(&kf->finger_entry, &nft_osf_fingers[!!f->df]);
+
+	return err;
+}
+
+static int nf_tables_delosf(struct net *net, struct sock *ctnl,
+			    struct sk_buff *skb,
+			    const struct nlmsghdr *nlh,
+			    const struct nlattr * const osf_attrs[],
+			    struct netlink_ext_ack *extack)
+{
+	struct nf_osf_user_finger *f;
+	struct nf_osf_finger *sf;
+	int err = -ENOENT;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (!osf_attrs[OSF_ATTR_FINGER])
+		return -EINVAL;
+
+	f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+	list_for_each_entry(sf, &nft_osf_fingers[!!f->df], finger_entry) {
+		if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger)))
+			continue;
+
+		/*
+		 * We are protected by nfnl mutex.
+		 */
+		list_del_rcu(&sf->finger_entry);
+		kfree_rcu(sf, rcu_head);
+
+		err = 0;
+		break;
+	}
+
+	return err;
+}
+
+static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
+	[NFTA_OSF_GENRE]	= { .type = NLA_STRING, .len = OSF_GENRE_SIZE },
+	[NFTA_OSF_FLAGS]	= { .type = NLA_U32 },
+	[NFTA_OSF_LOGLEVEL]	= { .type = NLA_U32 },
+	[NFTA_OSF_TTL]		= { .type = NLA_U32 },
+};
+
 static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
 	[NFT_MSG_NEWTABLE] = {
 		.call_batch	= nf_tables_newtable,
@@ -6022,6 +6122,16 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
 		.attr_count	= NFTA_FLOWTABLE_MAX,
 		.policy		= nft_flowtable_policy,
 	},
+	[NFT_MSG_NEWOSF] = {
+		.call_batch	= nf_tables_newosf,
+		.attr_count	= NFTA_OSF_MAX,
+		.policy		= nft_osf_policy,
+	},
+	[NFT_MSG_DELOSF] = {
+		.call_batch	= nf_tables_delosf,
+		.attr_count	= NFTA_OSF_MAX,
+		.policy		= nft_osf_policy,
+	},
 };
 
 static int nf_tables_validate(struct net *net)
diff --git a/net/netfilter/nft_osf.c b/net/netfilter/nft_osf.c
index 30c503f2bf53..cf8a38b052ad 100644
--- a/net/netfilter/nft_osf.c
+++ b/net/netfilter/nft_osf.c
@@ -54,6 +54,7 @@ static int nft_osf_init(const struct nft_ctx *ctx,
 		return -EINVAL;
 	priv->ttl	= ntohl(nla_get_be32(tb[NFTA_OSF_TTL]));
 	priv->len = strlen(priv->genre);
+
 	return 0;
 }
 
-- 
2.18.0

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux