Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c539f017 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: add connlabel conntrack extension



similar to connmarks, except labels are bit-based; i.e.
all labels may be attached to a flow at the same time.

Up to 128 labels are supported.  Supporting more labels
is possible, but requires increasing the ct offset delta
from u8 to u16 type due to increased extension sizes.

Mapping of bit-identifier to label name is done in userspace.

The extension is enabled at run-time once "-m connlabel" netfilter
rules are added.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 7266507d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ enum nf_ct_ext_id {
#endif
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
	NF_CT_EXT_TIMEOUT,
#endif
#ifdef CONFIG_NF_CONNTRACK_LABELS
	NF_CT_EXT_LABELS,
#endif
	NF_CT_EXT_NUM,
};
@@ -33,6 +36,7 @@ enum nf_ct_ext_id {
#define NF_CT_EXT_ZONE_TYPE struct nf_conntrack_zone
#define NF_CT_EXT_TSTAMP_TYPE struct nf_conn_tstamp
#define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout
#define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels

/* Extensions: optional stuff which isn't permanently in struct. */
struct nf_ct_ext {
+55 −0
Original line number Diff line number Diff line
#include <linux/types.h>
#include <net/net_namespace.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_extend.h>

#include <uapi/linux/netfilter/xt_connlabel.h>

struct nf_conn_labels {
	u8 words;
	unsigned long bits[];
};

static inline struct nf_conn_labels *nf_ct_labels_find(const struct nf_conn *ct)
{
#ifdef CONFIG_NF_CONNTRACK_LABELS
	return nf_ct_ext_find(ct, NF_CT_EXT_LABELS);
#else
	return NULL;
#endif
}

static inline struct nf_conn_labels *nf_ct_labels_ext_add(struct nf_conn *ct)
{
#ifdef CONFIG_NF_CONNTRACK_LABELS
	struct nf_conn_labels *cl_ext;
	struct net *net = nf_ct_net(ct);
	u8 words;

	words = ACCESS_ONCE(net->ct.label_words);
	if (words == 0 || WARN_ON_ONCE(words > 8))
		return NULL;

	cl_ext = nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS,
				      words * sizeof(long), GFP_ATOMIC);
	if (cl_ext != NULL)
		cl_ext->words = words;

	return cl_ext;
#else
	return NULL;
#endif
}

bool nf_connlabel_match(const struct nf_conn *ct, u16 bit);
int nf_connlabel_set(struct nf_conn *ct, u16 bit);

#ifdef CONFIG_NF_CONNTRACK_LABELS
int nf_conntrack_labels_init(struct net *net);
void nf_conntrack_labels_fini(struct net *net);
#else
static inline int nf_conntrack_labels_init(struct net *n) { return 0; }
static inline void nf_conntrack_labels_fini(struct net *net) {}
#endif
+4 −0
Original line number Diff line number Diff line
@@ -84,6 +84,10 @@ struct netns_ct {
	int			sysctl_auto_assign_helper;
	bool			auto_assign_helper_warned;
	struct nf_ip_net	nf_ct_proto;
#if defined(CONFIG_NF_CONNTRACK_LABELS)
	unsigned int		labels_used;
	u8			label_words;
#endif
#ifdef CONFIG_NF_NAT_NEEDED
	struct hlist_head	*nat_bysource;
	unsigned int		nat_htable_size;
+12 −0
Original line number Diff line number Diff line
#include <linux/types.h>

#define XT_CONNLABEL_MAXBIT 127
enum xt_connlabel_mtopts {
	XT_CONNLABEL_OP_INVERT = 1 << 0,
	XT_CONNLABEL_OP_SET    = 1 << 1,
};

struct xt_connlabel_mtinfo {
	__u16 bit;
	__u16 options;
};
+18 −0
Original line number Diff line number Diff line
@@ -124,6 +124,12 @@ config NF_CONNTRACK_TIMESTAMP

	  If unsure, say `N'.

config NF_CONNTRACK_LABELS
	bool
	help
	  This option enables support for assigning user-defined flag bits
	  to connection tracking entries.  It selected by the connlabel match.

config NF_CT_PROTO_DCCP
	tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
	depends on EXPERIMENTAL
@@ -842,6 +848,18 @@ config NETFILTER_XT_MATCH_CONNBYTES
	  If you want to compile it as a module, say M here and read
	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.

config NETFILTER_XT_MATCH_CONNLABEL
	tristate '"connlabel" match support'
	select NF_CONNTRACK_LABELS
	depends on NETFILTER_ADVANCED
	---help---
	  This match allows you to test and assign userspace-defined labels names
	  to a connection.  The kernel only stores bit values - mapping
	  names to bits is done by userspace.

	  Unlike connmark, more than 32 flag bits may be assigned to a
	  connection simultaneously.

config NETFILTER_XT_MATCH_CONNLIMIT
	tristate '"connlimit" match support"'
	depends on NF_CONNTRACK
Loading