diff mbox

[netfilter:,nft] Add the connmark meta_key

Message ID 1389027476-16837-1-git-send-email-kristian.evensen@gmail.com
State Not Applicable
Headers show

Commit Message

Kristian Evensen Jan. 6, 2014, 4:57 p.m. UTC
From: Kristian Evensen <kristian.evensen@gmail.com>

This patch enables connmark to be set/retrieved using meta
expressions/statements.

Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_meta.c                 | 34 ++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

Comments

Patrick McHardy Jan. 6, 2014, 5:04 p.m. UTC | #1
On Mon, Jan 06, 2014 at 05:57:56PM +0100, Kristian Evensen wrote:
> From: Kristian Evensen <kristian.evensen@gmail.com>
> 
> This patch enables connmark to be set/retrieved using meta
> expressions/statements.

Why would we add this to the meta expression instead of the ct expression?
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Florian Westphal Jan. 6, 2014, 5:05 p.m. UTC | #2
Kristian Evensen <kristian.evensen@gmail.com> wrote:
> From: Kristian Evensen <kristian.evensen@gmail.com>
> 
> This patch enables connmark to be set/retrieved using meta
> expressions/statements.
> 
> Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
> ---
>  include/uapi/linux/netfilter/nf_tables.h |  2 ++
>  net/netfilter/nft_meta.c                 | 34 ++++++++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+)
> 
> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index aa86a152..05eaeb9 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -531,6 +531,7 @@ enum nft_exthdr_attributes {
>   * @NFT_META_NFTRACE: packet nftrace bit
>   * @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
>   * @NFT_META_SECMARK: packet secmark (skb->secmark)
> + * @NFT_META_CONNMARK: used to get/set the connection mark
>   */
>  enum nft_meta_keys {
>  	NFT_META_LEN,
> @@ -548,6 +549,7 @@ enum nft_meta_keys {
>  	NFT_META_NFTRACE,
>  	NFT_META_RTCLASSID,
>  	NFT_META_SECMARK,
> +	NFT_META_CONNMARK,
>  };

This looks wrong, meta is for packet properties.
You should probably use NFT_CT_MARK from nft_ct_keys enum.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Patrick McHardy Jan. 6, 2014, 5:15 p.m. UTC | #3
On Mon, Jan 06, 2014 at 06:05:23PM +0100, Florian Westphal wrote:
> Kristian Evensen <kristian.evensen@gmail.com> wrote:
> > From: Kristian Evensen <kristian.evensen@gmail.com>
> > 
> > This patch enables connmark to be set/retrieved using meta
> > expressions/statements.
> > 
> > Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
> > ---
> >  include/uapi/linux/netfilter/nf_tables.h |  2 ++
> >  net/netfilter/nft_meta.c                 | 34 ++++++++++++++++++++++++++++++++
> >  2 files changed, 36 insertions(+)
> > 
> > diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> > index aa86a152..05eaeb9 100644
> > --- a/include/uapi/linux/netfilter/nf_tables.h
> > +++ b/include/uapi/linux/netfilter/nf_tables.h
> > @@ -531,6 +531,7 @@ enum nft_exthdr_attributes {
> >   * @NFT_META_NFTRACE: packet nftrace bit
> >   * @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
> >   * @NFT_META_SECMARK: packet secmark (skb->secmark)
> > + * @NFT_META_CONNMARK: used to get/set the connection mark
> >   */
> >  enum nft_meta_keys {
> >  	NFT_META_LEN,
> > @@ -548,6 +549,7 @@ enum nft_meta_keys {
> >  	NFT_META_NFTRACE,
> >  	NFT_META_RTCLASSID,
> >  	NFT_META_SECMARK,
> > +	NFT_META_CONNMARK,
> >  };
> 
> This looks wrong, meta is for packet properties.
> You should probably use NFT_CT_MARK from nft_ct_keys enum.

Well, actually the ct expression already supports connmark, as does userspace.

#ifdef CONFIG_NF_CONNTRACK_MARK
        case NFT_CT_MARK:
                dest->data[0] = ct->mark;
                return;
#endif
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kristian Evensen Jan. 6, 2014, 6:09 p.m. UTC | #4
Hello,

On Mon, Jan 6, 2014 at 6:15 PM, Patrick McHardy <kaber@trash.net> wrote:
> Well, actually the ct expression already supports connmark, as does userspace.
>
> #ifdef CONFIG_NF_CONNTRACK_MARK
>         case NFT_CT_MARK:
>                 dest->data[0] = ct->mark;
>                 return;
> #endif

Thank you very much for pointing this out. I will change my approach
and add a set command in ct (similar to what was recently added to
meta). Or is someone already working on this?

-Kristian
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Patrick McHardy Jan. 6, 2014, 6:19 p.m. UTC | #5
On Mon, Jan 06, 2014 at 07:09:58PM +0100, Kristian Evensen wrote:
> Hello,
> 
> On Mon, Jan 6, 2014 at 6:15 PM, Patrick McHardy <kaber@trash.net> wrote:
> > Well, actually the ct expression already supports connmark, as does userspace.
> >
> > #ifdef CONFIG_NF_CONNTRACK_MARK
> >         case NFT_CT_MARK:
> >                 dest->data[0] = ct->mark;
> >                 return;
> > #endif
> 
> Thank you very much for pointing this out. I will change my approach
> and add a set command in ct (similar to what was recently added to
> meta). Or is someone already working on this?

Not sure what you're trying to achieve, we already support the connmark
in the ct expression:

nft filter output ct mark 0x1 ...
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kristian Evensen Jan. 6, 2014, 7:25 p.m. UTC | #6
On Mon, Jan 6, 2014 at 7:19 PM, Patrick McHardy <kaber@trash.net> wrote:
>
> Not sure what you're trying to achieve, we already support the connmark
> in the ct expression:
>
> nft filter output ct mark 0x1 ...

What I want to achieve is to have functionality similar to connmark
--save-mark, so that we can also set the connmark.

-Kristian
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Patrick McHardy Jan. 6, 2014, 8:54 p.m. UTC | #7
On Mon, Jan 06, 2014 at 08:25:39PM +0100, Kristian Evensen wrote:
> On Mon, Jan 6, 2014 at 7:19 PM, Patrick McHardy <kaber@trash.net> wrote:
> >
> > Not sure what you're trying to achieve, we already support the connmark
> > in the ct expression:
> >
> > nft filter output ct mark 0x1 ...
> 
> What I want to achieve is to have functionality similar to connmark
> --save-mark, so that we can also set the connmark.

I see. We need a meta statement for this in userspace and corresponding
support for the kernel. I thought we'd had an example how to do this in
the meta expression, but apparently this is wrong. I'll add it for the
meta expression during the next days so you have a reference.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kristian Evensen Jan. 6, 2014, 9 p.m. UTC | #8
Hi,

On Mon, Jan 6, 2014 at 9:54 PM, Patrick McHardy <kaber@trash.net> wrote:
> I see. We need a meta statement for this in userspace and corresponding
> support for the kernel. I thought we'd had an example how to do this in
> the meta expression, but apparently this is wrong. I'll add it for the
> meta expression during the next days so you have a reference.

I am not sure if I understand you correctly, but meta set is already
there. My plan was to use nft_meta (and the related parts in
nftables/libnftables) as a reference for how to add set and add
support for something like:

nft filter postrouting ct mark set "meta mark"

Or is there something I dont see/understand?

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

Patch

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index aa86a152..05eaeb9 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -531,6 +531,7 @@  enum nft_exthdr_attributes {
  * @NFT_META_NFTRACE: packet nftrace bit
  * @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
  * @NFT_META_SECMARK: packet secmark (skb->secmark)
+ * @NFT_META_CONNMARK: used to get/set the connection mark
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -548,6 +549,7 @@  enum nft_meta_keys {
 	NFT_META_NFTRACE,
 	NFT_META_RTCLASSID,
 	NFT_META_SECMARK,
+	NFT_META_CONNMARK,
 };
 
 /**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 1ceaaa6..07ae212 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -18,6 +18,8 @@ 
 #include <net/sock.h>
 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
 #include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
 
 struct nft_meta {
 	enum nft_meta_keys	key:8;
@@ -35,6 +37,10 @@  static void nft_meta_get_eval(const struct nft_expr *expr,
 	const struct sk_buff *skb = pkt->skb;
 	const struct net_device *in = pkt->in, *out = pkt->out;
 	struct nft_data *dest = &data[priv->dreg];
+#ifdef CONFIG_NF_CONNTRACK_MARK
+	enum ip_conntrack_info ctinfo;
+	struct nf_conn *ct;
+#endif
 
 	switch (priv->key) {
 	case NFT_META_LEN:
@@ -125,6 +131,15 @@  static void nft_meta_get_eval(const struct nft_expr *expr,
 		dest->data[0] = skb->secmark;
 		break;
 #endif
+#ifdef CONFIG_NF_CONNTRACK_MARK
+	case NFT_META_CONNMARK:
+		ct = nf_ct_get(skb, &ctinfo);
+		if (ct != NULL)
+			dest->data[0] = ct->mark;
+		else
+			dest->data[0] = 0;
+		break;
+#endif
 	default:
 		WARN_ON(1);
 		goto err;
@@ -142,6 +157,10 @@  static void nft_meta_set_eval(const struct nft_expr *expr,
 	const struct nft_meta *meta = nft_expr_priv(expr);
 	struct sk_buff *skb = pkt->skb;
 	u32 value = data[meta->sreg].data[0];
+#ifdef CONFIG_NF_CONNTRACK_MARK
+	enum ip_conntrack_info ctinfo;
+	struct nf_conn *ct;
+#endif
 
 	switch (meta->key) {
 	case NFT_META_MARK:
@@ -153,6 +172,15 @@  static void nft_meta_set_eval(const struct nft_expr *expr,
 	case NFT_META_NFTRACE:
 		skb->nf_trace = 1;
 		break;
+#ifdef CONFIG_NF_CONNTRACK_MARK
+	case NFT_META_CONNMARK:
+		ct = nf_ct_get(skb, &ctinfo);
+		if (ct != NULL && ct->mark != value) {
+			ct->mark = value;
+			nf_conntrack_event_cache(IPCT_MARK, ct);
+		}
+		break;
+#endif
 	default:
 		WARN_ON(1);
 	}
@@ -170,6 +198,9 @@  static int nft_meta_init_validate_set(uint32_t key)
 	case NFT_META_MARK:
 	case NFT_META_PRIORITY:
 	case NFT_META_NFTRACE:
+#ifdef CONFIG_NF_CONNTRACK_MARK
+	case NFT_META_CONNMARK:
+#endif
 		return 0;
 	default:
 		return -EOPNOTSUPP;
@@ -197,6 +228,9 @@  static int nft_meta_init_validate_get(uint32_t key)
 #ifdef CONFIG_NETWORK_SECMARK
 	case NFT_META_SECMARK:
 #endif
+#ifdef CONFIG_NF_CONNTRACK_MARK
+	case NFT_META_CONNMARK:
+#endif
 		return 0;
 	default:
 		return -EOPNOTSUPP;