* [PATCH] netfilter: nft_ct: add ct expectations support
@ 2019-05-04 17:35 Stéphane Veyret
2019-05-05 13:24 ` Jeremy Sowden
0 siblings, 1 reply; 10+ messages in thread
From: Stéphane Veyret @ 2019-05-04 17:35 UTC (permalink / raw)
To: netfilter-devel
This patch allows to add, list and delete expectations via nft objref
infrastructure and assigning these expectations via nft rule.
Signed-off-by: Stéphane Veyret <sveyret@gmail.com>
---
include/uapi/linux/netfilter/nf_tables.h | 15 ++-
net/netfilter/nft_ct.c | 124 ++++++++++++++++++++++-
2 files changed, 136 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/netfilter/nf_tables.h
b/include/uapi/linux/netfilter/nf_tables.h
index f0cf7b0f4f35..0a3452ca684c 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -968,6 +968,7 @@ enum nft_socket_keys {
* @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
* @NFT_CT_TIMEOUT: connection tracking timeout policy assigned to conntrack
* @NFT_CT_ID: conntrack id
+ * @NFT_CT_EXPECT: connection tracking expectation
*/
enum nft_ct_keys {
NFT_CT_STATE,
@@ -995,6 +996,7 @@ enum nft_ct_keys {
NFT_CT_DST_IP6,
NFT_CT_TIMEOUT,
NFT_CT_ID,
+ NFT_CT_EXPECT,
__NFT_CT_MAX
};
#define NFT_CT_MAX (__NFT_CT_MAX - 1)
@@ -1447,6 +1449,16 @@ enum nft_ct_timeout_timeout_attributes {
};
#define NFTA_CT_TIMEOUT_MAX (__NFTA_CT_TIMEOUT_MAX - 1)
+enum nft_ct_expectation_attributes {
+ NFTA_CT_EXPECT_UNSPEC,
+ NFTA_CT_EXPECT_L3PROTO,
+ NFTA_CT_EXPECT_L4PROTO,
+ NFTA_CT_EXPECT_DPORT,
+ NFTA_CT_EXPECT_TIMEOUT,
+ __NFTA_CT_EXPECT_MAX,
+};
+#define NFTA_CT_EXPECT_MAX (__NFTA_CT_EXPECT_MAX - 1)
+
#define NFT_OBJECT_UNSPEC 0
#define NFT_OBJECT_COUNTER 1
#define NFT_OBJECT_QUOTA 2
@@ -1456,7 +1468,8 @@ enum nft_ct_timeout_timeout_attributes {
#define NFT_OBJECT_TUNNEL 6
#define NFT_OBJECT_CT_TIMEOUT 7
#define NFT_OBJECT_SECMARK 8
-#define __NFT_OBJECT_MAX 9
+#define NFT_OBJECT_CT_EXPECT 9
+#define __NFT_OBJECT_MAX 10
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
/**
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index f043936763f3..06c13b2dfb78 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -24,6 +24,7 @@
#include <net/netfilter/nf_conntrack_labels.h>
#include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_expect.h>
struct nft_ct {
enum nft_ct_keys key:8;
@@ -790,6 +791,117 @@ static struct nft_expr_type nft_notrack_type
__read_mostly = {
.owner = THIS_MODULE,
};
+struct nft_ct_expect_obj {
+ int l3num;
+ u8 l4proto;
+ __be16 dport;
+ u32 timeout;
+};
+
+static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
+ const struct nlattr * const tb[],
+ struct nft_object *obj)
+{
+ struct nft_ct_expect_obj *priv = nft_obj_data(obj);
+ int ret;
+
+ if (!tb[NFTA_CT_EXPECT_L4PROTO] ||
+ !tb[NFTA_CT_EXPECT_DPORT])
+ return -EINVAL;
+
+ priv->l3num = ctx->family;
+ if (tb[NFTA_CT_EXPECT_L3PROTO])
+ priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO]));
+ priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]);
+
+ priv->dportmin = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT_MIN]);
+
+ priv->timeout = 0;
+ if (tb[NFTA_CT_EXPECT_TIMEOUT])
+ priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]);
+
+ ret = nf_ct_netns_get(ctx->net, ctx->family);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void nft_ct_expect_obj_destroy(const struct nft_ctx *ctx,
+ struct nft_object *obj)
+{
+ nf_ct_netns_put(ctx->net, ctx->family);
+}
+
+static int nft_ct_expect_obj_dump(struct sk_buff *skb,
+ struct nft_object *obj, bool reset)
+{
+ const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
+
+ if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) ||
+ nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) ||
+ nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) ||
+ nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout))
+ return -1
+
+ return 0;
+}
+
+static void nft_ct_expect_obj_eval(struct nft_object *obj,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+{
+ const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = nf_ct_get(pkt->skb, ctinfo);
+ int dir = CTINFO2DIR(ctinfo);
+ struct nf_conntrack_expect *exp;
+
+ exp = nf_ct_expect_alloc(ct);
+ if (exp == NULL) {
+ nf_ct_helper_log(skb, ct, "cannot allocate expectation");
+ regs->verdict.code = NF_DROP;
+ return;
+ }
+
+ nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, priv->l3num,
+ &ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3,
+ priv->l4proto, NULL, &priv->dport);
+ if (priv->timeout)
+ exp->timeout.expires = jiffies + priv->timeout * HZ;
+
+ if (nf_ct_expect_related(exp) != 0) {
+ nf_ct_helper_log(skb, ct, "cannot add expectation");
+ regs->verdict.code = NF_DROP;
+ }
+}
+
+static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX
+ 1] = {
+ [NFTA_CT_EXPECT_L3PROTO] = {.type = NLA_U16 },
+ [NFTA_CT_EXPECT_L4PROTO] = {.type = NLA_U8 },
+ [NFTA_CT_EXPECT_DPORT] = {.type = NLA_U16 },
+ [NFTA_CT_EXPECT_TIMEOUT] = {.type = NLA_U32 },
+};
+
+static struct nft_object_type nft_ct_expect_obj_type;
+
+static const struct nft_object_ops nft_ct_expect_obj_ops = {
+ .type = &nft_ct_expect_obj_type,
+ .size = sizeof(struct nft_ct_expect_obj),
+ .eval = nft_ct_expect_obj_eval,
+ .init = nft_ct_expect_obj_init,
+ .destroy = nft_ct_expect_obj_destroy,
+ .dump = nft_ct_expect_obj_dump,
+};
+
+static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {
+ .type = NFT_OBJECT_CT_EXPECT,
+ .ops = &nft_ct_expect_obj_ops,
+ .maxattr = NFTA_CT_EXPECT_MAX,
+ .policy = nft_ct_expect_policy,
+ .owner = THIS_MODULE,
+};
+
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
static int
nft_ct_timeout_parse_policy(void *timeouts,
@@ -1173,17 +1285,23 @@ static int __init nft_ct_module_init(void)
err = nft_register_obj(&nft_ct_helper_obj_type);
if (err < 0)
goto err2;
+
+ err = nft_register_obj(&nft_ct_expect_obj_type);
+ if (err < 0)
+ goto err3;
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
err = nft_register_obj(&nft_ct_timeout_obj_type);
if (err < 0)
- goto err3;
+ goto err4;
#endif
return 0;
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+err4:
+ nft_unregister_obj(&nft_ct_expect_obj_type);
+#endif
err3:
nft_unregister_obj(&nft_ct_helper_obj_type);
-#endif
err2:
nft_unregister_expr(&nft_notrack_type);
err1:
@@ -1196,6 +1314,7 @@ static void __exit nft_ct_module_exit(void)
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
nft_unregister_obj(&nft_ct_timeout_obj_type);
#endif
+ nft_unregister_obj(&nft_ct_expect_obj_type);
nft_unregister_obj(&nft_ct_helper_obj_type);
nft_unregister_expr(&nft_notrack_type);
nft_unregister_expr(&nft_ct_type);
@@ -1210,3 +1329,4 @@ MODULE_ALIAS_NFT_EXPR("ct");
MODULE_ALIAS_NFT_EXPR("notrack");
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER);
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT);
+MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_EXPECT);
--
2.21.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-04 17:35 [PATCH] netfilter: nft_ct: add ct expectations support Stéphane Veyret
@ 2019-05-05 13:24 ` Jeremy Sowden
2019-05-05 15:38 ` Stéphane Veyret
0 siblings, 1 reply; 10+ messages in thread
From: Jeremy Sowden @ 2019-05-05 13:24 UTC (permalink / raw)
To: Stéphane Veyret; +Cc: netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 1220 bytes --]
On 2019-05-04, at 19:35:41 +0200, Stéphane Veyret wrote:
> This patch allows to add, list and delete expectations via nft objref
> infrastructure and assigning these expectations via nft rule.
>
> Signed-off-by: Stéphane Veyret <sveyret@gmail.com>
> ---
> include/uapi/linux/netfilter/nf_tables.h | 15 ++-
> net/netfilter/nft_ct.c | 124 ++++++++++++++++++++++-
> 2 files changed, 136 insertions(+), 3 deletions(-)
>
> diff --git a/include/uapi/linux/netfilter/nf_tables.h
> b/include/uapi/linux/netfilter/nf_tables.h
> index f0cf7b0f4f35..0a3452ca684c 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -968,6 +968,7 @@ enum nft_socket_keys {
> * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
> * @NFT_CT_TIMEOUT: connection tracking timeout policy assigned to conntrack
> * @NFT_CT_ID: conntrack id
> + * @NFT_CT_EXPECT: connection tracking expectation
> */
> enum nft_ct_keys {
> NFT_CT_STATE,
> @@ -995,6 +996,7 @@ enum nft_ct_keys {
> NFT_CT_DST_IP6,
> NFT_CT_TIMEOUT,
> NFT_CT_ID,
> + NFT_CT_EXPECT,
> __NFT_CT_MAX
> };
> #define NFT_CT_MAX (__NFT_CT_MAX - 1)
Your patch has been mangled.
J.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-05 13:24 ` Jeremy Sowden
@ 2019-05-05 15:38 ` Stéphane Veyret
0 siblings, 0 replies; 10+ messages in thread
From: Stéphane Veyret @ 2019-05-05 15:38 UTC (permalink / raw)
To: netfilter-devel
Le dim. 5 mai 2019 à 15:24, Jeremy Sowden <jeremy@azazel.net> a écrit :
> Your patch has been mangled.
Thank you for warning me. A problem with git and GMail which seem not
to be good friend, but I think I managed to configure everything
correctly now. I will send it again in a few minutes.
Stéphane.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] netfilter: nft_ct: add ct expectations support
@ 2019-05-05 15:40 Stéphane Veyret
2019-05-05 15:58 ` Florian Westphal
2019-05-05 22:51 ` Pablo Neira Ayuso
0 siblings, 2 replies; 10+ messages in thread
From: Stéphane Veyret @ 2019-05-05 15:40 UTC (permalink / raw)
To: netfilter-devel; +Cc: Stéphane Veyret
This patch allows to add, list and delete expectations via nft objref
infrastructure and assigning these expectations via nft rule.
Signed-off-by: Stéphane Veyret <sveyret@gmail.com>
---
include/uapi/linux/netfilter/nf_tables.h | 15 ++-
net/netfilter/nft_ct.c | 124 ++++++++++++++++++++++-
2 files changed, 136 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index f0cf7b0f4f35..0a3452ca684c 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -968,6 +968,7 @@ enum nft_socket_keys {
* @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
* @NFT_CT_TIMEOUT: connection tracking timeout policy assigned to conntrack
* @NFT_CT_ID: conntrack id
+ * @NFT_CT_EXPECT: connection tracking expectation
*/
enum nft_ct_keys {
NFT_CT_STATE,
@@ -995,6 +996,7 @@ enum nft_ct_keys {
NFT_CT_DST_IP6,
NFT_CT_TIMEOUT,
NFT_CT_ID,
+ NFT_CT_EXPECT,
__NFT_CT_MAX
};
#define NFT_CT_MAX (__NFT_CT_MAX - 1)
@@ -1447,6 +1449,16 @@ enum nft_ct_timeout_timeout_attributes {
};
#define NFTA_CT_TIMEOUT_MAX (__NFTA_CT_TIMEOUT_MAX - 1)
+enum nft_ct_expectation_attributes {
+ NFTA_CT_EXPECT_UNSPEC,
+ NFTA_CT_EXPECT_L3PROTO,
+ NFTA_CT_EXPECT_L4PROTO,
+ NFTA_CT_EXPECT_DPORT,
+ NFTA_CT_EXPECT_TIMEOUT,
+ __NFTA_CT_EXPECT_MAX,
+};
+#define NFTA_CT_EXPECT_MAX (__NFTA_CT_EXPECT_MAX - 1)
+
#define NFT_OBJECT_UNSPEC 0
#define NFT_OBJECT_COUNTER 1
#define NFT_OBJECT_QUOTA 2
@@ -1456,7 +1468,8 @@ enum nft_ct_timeout_timeout_attributes {
#define NFT_OBJECT_TUNNEL 6
#define NFT_OBJECT_CT_TIMEOUT 7
#define NFT_OBJECT_SECMARK 8
-#define __NFT_OBJECT_MAX 9
+#define NFT_OBJECT_CT_EXPECT 9
+#define __NFT_OBJECT_MAX 10
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
/**
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index f043936763f3..06c13b2dfb78 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -24,6 +24,7 @@
#include <net/netfilter/nf_conntrack_labels.h>
#include <net/netfilter/nf_conntrack_timeout.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_expect.h>
struct nft_ct {
enum nft_ct_keys key:8;
@@ -790,6 +791,117 @@ static struct nft_expr_type nft_notrack_type __read_mostly = {
.owner = THIS_MODULE,
};
+struct nft_ct_expect_obj {
+ int l3num;
+ u8 l4proto;
+ __be16 dport;
+ u32 timeout;
+};
+
+static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
+ const struct nlattr * const tb[],
+ struct nft_object *obj)
+{
+ struct nft_ct_expect_obj *priv = nft_obj_data(obj);
+ int ret;
+
+ if (!tb[NFTA_CT_EXPECT_L4PROTO] ||
+ !tb[NFTA_CT_EXPECT_DPORT])
+ return -EINVAL;
+
+ priv->l3num = ctx->family;
+ if (tb[NFTA_CT_EXPECT_L3PROTO])
+ priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO]));
+ priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]);
+
+ priv->dportmin = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT_MIN]);
+
+ priv->timeout = 0;
+ if (tb[NFTA_CT_EXPECT_TIMEOUT])
+ priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]);
+
+ ret = nf_ct_netns_get(ctx->net, ctx->family);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static void nft_ct_expect_obj_destroy(const struct nft_ctx *ctx,
+ struct nft_object *obj)
+{
+ nf_ct_netns_put(ctx->net, ctx->family);
+}
+
+static int nft_ct_expect_obj_dump(struct sk_buff *skb,
+ struct nft_object *obj, bool reset)
+{
+ const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
+
+ if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) ||
+ nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) ||
+ nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) ||
+ nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout))
+ return -1
+
+ return 0;
+}
+
+static void nft_ct_expect_obj_eval(struct nft_object *obj,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
+{
+ const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = nf_ct_get(pkt->skb, ctinfo);
+ int dir = CTINFO2DIR(ctinfo);
+ struct nf_conntrack_expect *exp;
+
+ exp = nf_ct_expect_alloc(ct);
+ if (exp == NULL) {
+ nf_ct_helper_log(skb, ct, "cannot allocate expectation");
+ regs->verdict.code = NF_DROP;
+ return;
+ }
+
+ nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, priv->l3num,
+ &ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3,
+ priv->l4proto, NULL, &priv->dport);
+ if (priv->timeout)
+ exp->timeout.expires = jiffies + priv->timeout * HZ;
+
+ if (nf_ct_expect_related(exp) != 0) {
+ nf_ct_helper_log(skb, ct, "cannot add expectation");
+ regs->verdict.code = NF_DROP;
+ }
+}
+
+static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX + 1] = {
+ [NFTA_CT_EXPECT_L3PROTO] = {.type = NLA_U16 },
+ [NFTA_CT_EXPECT_L4PROTO] = {.type = NLA_U8 },
+ [NFTA_CT_EXPECT_DPORT] = {.type = NLA_U16 },
+ [NFTA_CT_EXPECT_TIMEOUT] = {.type = NLA_U32 },
+};
+
+static struct nft_object_type nft_ct_expect_obj_type;
+
+static const struct nft_object_ops nft_ct_expect_obj_ops = {
+ .type = &nft_ct_expect_obj_type,
+ .size = sizeof(struct nft_ct_expect_obj),
+ .eval = nft_ct_expect_obj_eval,
+ .init = nft_ct_expect_obj_init,
+ .destroy = nft_ct_expect_obj_destroy,
+ .dump = nft_ct_expect_obj_dump,
+};
+
+static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {
+ .type = NFT_OBJECT_CT_EXPECT,
+ .ops = &nft_ct_expect_obj_ops,
+ .maxattr = NFTA_CT_EXPECT_MAX,
+ .policy = nft_ct_expect_policy,
+ .owner = THIS_MODULE,
+};
+
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
static int
nft_ct_timeout_parse_policy(void *timeouts,
@@ -1173,17 +1285,23 @@ static int __init nft_ct_module_init(void)
err = nft_register_obj(&nft_ct_helper_obj_type);
if (err < 0)
goto err2;
+
+ err = nft_register_obj(&nft_ct_expect_obj_type);
+ if (err < 0)
+ goto err3;
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
err = nft_register_obj(&nft_ct_timeout_obj_type);
if (err < 0)
- goto err3;
+ goto err4;
#endif
return 0;
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+err4:
+ nft_unregister_obj(&nft_ct_expect_obj_type);
+#endif
err3:
nft_unregister_obj(&nft_ct_helper_obj_type);
-#endif
err2:
nft_unregister_expr(&nft_notrack_type);
err1:
@@ -1196,6 +1314,7 @@ static void __exit nft_ct_module_exit(void)
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
nft_unregister_obj(&nft_ct_timeout_obj_type);
#endif
+ nft_unregister_obj(&nft_ct_expect_obj_type);
nft_unregister_obj(&nft_ct_helper_obj_type);
nft_unregister_expr(&nft_notrack_type);
nft_unregister_expr(&nft_ct_type);
@@ -1210,3 +1329,4 @@ MODULE_ALIAS_NFT_EXPR("ct");
MODULE_ALIAS_NFT_EXPR("notrack");
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER);
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT);
+MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_EXPECT);
--
2.21.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-05 15:40 Stéphane Veyret
@ 2019-05-05 15:58 ` Florian Westphal
2019-05-05 22:51 ` Pablo Neira Ayuso
1 sibling, 0 replies; 10+ messages in thread
From: Florian Westphal @ 2019-05-05 15:58 UTC (permalink / raw)
To: Stéphane Veyret; +Cc: netfilter-devel
Stéphane Veyret <sveyret@gmail.com> wrote:
> +static void nft_ct_expect_obj_eval(struct nft_object *obj,
> + struct nft_regs *regs,
> + const struct nft_pktinfo *pkt)
> +{
> + const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
> + enum ip_conntrack_info ctinfo;
> + struct nf_conn *ct = nf_ct_get(pkt->skb, ctinfo);
> + int dir = CTINFO2DIR(ctinfo);
> + struct nf_conntrack_expect *exp;
> +
> + exp = nf_ct_expect_alloc(ct);
> + if (exp == NULL) {
> + nf_ct_helper_log(skb, ct, "cannot allocate expectation");
> + regs->verdict.code = NF_DROP;
> + return;
> + }
> +
> + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, priv->l3num,
> + &ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3,
> + priv->l4proto, NULL, &priv->dport);
> + if (priv->timeout)
> + exp->timeout.expires = jiffies + priv->timeout * HZ;
> +
> + if (nf_ct_expect_related(exp) != 0) {
> + nf_ct_helper_log(skb, ct, "cannot add expectation");
Please remove the nf_ct_helper_log() calls, it will crash in case there is no helper
attached to the conntrack.
Other than this I don't see any issues here, thanks for working on this!
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-05 15:40 Stéphane Veyret
2019-05-05 15:58 ` Florian Westphal
@ 2019-05-05 22:51 ` Pablo Neira Ayuso
2019-05-11 18:54 ` Stéphane Veyret
1 sibling, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2019-05-05 22:51 UTC (permalink / raw)
To: Stéphane Veyret; +Cc: netfilter-devel
On Sun, May 05, 2019 at 05:40:16PM +0200, Stéphane Veyret wrote:
> This patch allows to add, list and delete expectations via nft objref
> infrastructure and assigning these expectations via nft rule.
Please, add to your patch title your patch version, ie.
[PATCH nf-next,v2] nft_ct: add ct expectations support
Could you describe the usecase example for this infrastructure, please?
More comments below.
> Signed-off-by: Stéphane Veyret <sveyret@gmail.com>
> ---
> include/uapi/linux/netfilter/nf_tables.h | 15 ++-
> net/netfilter/nft_ct.c | 124 ++++++++++++++++++++++-
> 2 files changed, 136 insertions(+), 3 deletions(-)
>
> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index f0cf7b0f4f35..0a3452ca684c 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -968,6 +968,7 @@ enum nft_socket_keys {
> * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
> * @NFT_CT_TIMEOUT: connection tracking timeout policy assigned to conntrack
> * @NFT_CT_ID: conntrack id
> + * @NFT_CT_EXPECT: connection tracking expectation
> */
> enum nft_ct_keys {
> NFT_CT_STATE,
> @@ -995,6 +996,7 @@ enum nft_ct_keys {
> NFT_CT_DST_IP6,
> NFT_CT_TIMEOUT,
> NFT_CT_ID,
> + NFT_CT_EXPECT,
You don't this definition, or I don't find where this is used.
> __NFT_CT_MAX
> };
> #define NFT_CT_MAX (__NFT_CT_MAX - 1)
> @@ -1447,6 +1449,16 @@ enum nft_ct_timeout_timeout_attributes {
> };
> #define NFTA_CT_TIMEOUT_MAX (__NFTA_CT_TIMEOUT_MAX - 1)
>
> +enum nft_ct_expectation_attributes {
> + NFTA_CT_EXPECT_UNSPEC,
> + NFTA_CT_EXPECT_L3PROTO,
> + NFTA_CT_EXPECT_L4PROTO,
> + NFTA_CT_EXPECT_DPORT,
> + NFTA_CT_EXPECT_TIMEOUT,
> + __NFTA_CT_EXPECT_MAX,
> +};
> +#define NFTA_CT_EXPECT_MAX (__NFTA_CT_EXPECT_MAX - 1)
> +
> #define NFT_OBJECT_UNSPEC 0
> #define NFT_OBJECT_COUNTER 1
> #define NFT_OBJECT_QUOTA 2
> @@ -1456,7 +1468,8 @@ enum nft_ct_timeout_timeout_attributes {
> #define NFT_OBJECT_TUNNEL 6
> #define NFT_OBJECT_CT_TIMEOUT 7
> #define NFT_OBJECT_SECMARK 8
> -#define __NFT_OBJECT_MAX 9
> +#define NFT_OBJECT_CT_EXPECT 9
> +#define __NFT_OBJECT_MAX 10
> #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
>
> /**
> diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> index f043936763f3..06c13b2dfb78 100644
> --- a/net/netfilter/nft_ct.c
> +++ b/net/netfilter/nft_ct.c
> @@ -24,6 +24,7 @@
> #include <net/netfilter/nf_conntrack_labels.h>
> #include <net/netfilter/nf_conntrack_timeout.h>
> #include <net/netfilter/nf_conntrack_l4proto.h>
> +#include <net/netfilter/nf_conntrack_expect.h>
>
> struct nft_ct {
> enum nft_ct_keys key:8;
> @@ -790,6 +791,117 @@ static struct nft_expr_type nft_notrack_type __read_mostly = {
> .owner = THIS_MODULE,
> };
>
> +struct nft_ct_expect_obj {
> + int l3num;
> + u8 l4proto;
> + __be16 dport;
> + u32 timeout;
> +};
> +
> +static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
> + const struct nlattr * const tb[],
> + struct nft_object *obj)
> +{
> + struct nft_ct_expect_obj *priv = nft_obj_data(obj);
> + int ret;
> +
> + if (!tb[NFTA_CT_EXPECT_L4PROTO] ||
> + !tb[NFTA_CT_EXPECT_DPORT])
> + return -EINVAL;
> +
> + priv->l3num = ctx->family;
> + if (tb[NFTA_CT_EXPECT_L3PROTO])
> + priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO]));
> + priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]);
> +
> + priv->dportmin = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT_MIN]);
Where is NFTA_CT_EXPECT_DPORT_MIN defined? You don't check for this
attribute, it may not be present. Looks like a leftover?
> +
> + priv->timeout = 0;
> + if (tb[NFTA_CT_EXPECT_TIMEOUT])
> + priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]);
> +
> + ret = nf_ct_netns_get(ctx->net, ctx->family);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static void nft_ct_expect_obj_destroy(const struct nft_ctx *ctx,
> + struct nft_object *obj)
> +{
> + nf_ct_netns_put(ctx->net, ctx->family);
> +}
> +
> +static int nft_ct_expect_obj_dump(struct sk_buff *skb,
> + struct nft_object *obj, bool reset)
> +{
> + const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
> +
> + if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) ||
> + nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) ||
> + nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) ||
> + nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout))
> + return -1
This won't compile, missing ';'. Also indentation.
> +
> + return 0;
> +}
> +
> +static void nft_ct_expect_obj_eval(struct nft_object *obj,
> + struct nft_regs *regs,
> + const struct nft_pktinfo *pkt)
> +{
> + const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
> + enum ip_conntrack_info ctinfo;
> + struct nf_conn *ct = nf_ct_get(pkt->skb, ctinfo);
> + int dir = CTINFO2DIR(ctinfo);
> + struct nf_conntrack_expect *exp;
> +
> + exp = nf_ct_expect_alloc(ct);
> + if (exp == NULL) {
> + nf_ct_helper_log(skb, ct, "cannot allocate expectation");
> + regs->verdict.code = NF_DROP;
> + return;
> + }
> +
> + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, priv->l3num,
> + &ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3,
> + priv->l4proto, NULL, &priv->dport);
Coding style:
nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, priv->l3num,
&ct->tuplehash[!dir].tuple.src.u3,
&ct->tuplehash[!dir].tuple.dst.u3,
priv->l4proto, NULL, &priv->dport);
> + if (priv->timeout)
> + exp->timeout.expires = jiffies + priv->timeout * HZ;
timeout should be made mandatory? why check if it's set?
> + if (nf_ct_expect_related(exp) != 0) {
> + nf_ct_helper_log(skb, ct, "cannot add expectation");
> + regs->verdict.code = NF_DROP;
> + }
> +}
> +
> +static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX + 1] = {
> + [NFTA_CT_EXPECT_L3PROTO] = {.type = NLA_U16 },
> + [NFTA_CT_EXPECT_L4PROTO] = {.type = NLA_U8 },
> + [NFTA_CT_EXPECT_DPORT] = {.type = NLA_U16 },
> + [NFTA_CT_EXPECT_TIMEOUT] = {.type = NLA_U32 },
I'd prefer:
[NFTA_CT_EXPECT_L3PROTO] = { .type = NLA_U16 },
[NFTA_CT_EXPECT_L4PROTO] = { .type = NLA_U8 },
[NFTA_CT_EXPECT_DPORT] = { .type = NLA_U16 },
[NFTA_CT_EXPECT_TIMEOUT] = { .type = NLA_U32 },
Thanks!
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-05 22:51 ` Pablo Neira Ayuso
@ 2019-05-11 18:54 ` Stéphane Veyret
2019-05-12 17:56 ` Pablo Neira Ayuso
0 siblings, 1 reply; 10+ messages in thread
From: Stéphane Veyret @ 2019-05-11 18:54 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Hi Pablo,
Le lun. 6 mai 2019 à 00:51, Pablo Neira Ayuso <pablo@netfilter.org> a écrit :
> > NFT_CT_TIMEOUT,
> > NFT_CT_ID,
> > + NFT_CT_EXPECT,
>
> You don't this definition, or I don't find where this is used.
As I told previously, I just copied the way timeout is built, and
therefore, it seems that NFT_CT_TIMEOUT is not used too.
But I actually saw today that these values are used in the « nftables
» project. There is a copy of nf_tables.h there. Not sure it is a good
idea to keep the variables in « nftables » and not in kernel.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-11 18:54 ` Stéphane Veyret
@ 2019-05-12 17:56 ` Pablo Neira Ayuso
2019-05-13 6:00 ` Stéphane Veyret
0 siblings, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2019-05-12 17:56 UTC (permalink / raw)
To: Stéphane Veyret; +Cc: netfilter-devel
On Sat, May 11, 2019 at 08:54:57PM +0200, Stéphane Veyret wrote:
> Hi Pablo,
>
> Le lun. 6 mai 2019 à 00:51, Pablo Neira Ayuso <pablo@netfilter.org> a écrit :
> > > NFT_CT_TIMEOUT,
> > > NFT_CT_ID,
> > > + NFT_CT_EXPECT,
> >
> > You don't this definition, or I don't find where this is used.
>
> As I told previously, I just copied the way timeout is built, and
> therefore, it seems that NFT_CT_TIMEOUT is not used too.
> But I actually saw today that these values are used in the « nftables
> » project. There is a copy of nf_tables.h there. Not sure it is a good
> idea to keep the variables in « nftables » and not in kernel.
I have just updated the cached copy of nf_tables.h in
git.netfilter.org:
http://git.netfilter.org/nftables/commit/?id=d3869cae9d6232b9f3fa720e5516ece95fdbe73e
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-12 17:56 ` Pablo Neira Ayuso
@ 2019-05-13 6:00 ` Stéphane Veyret
2019-05-13 8:37 ` Pablo Neira Ayuso
0 siblings, 1 reply; 10+ messages in thread
From: Stéphane Veyret @ 2019-05-13 6:00 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Le dim. 12 mai 2019 à 19:56, Pablo Neira Ayuso <pablo@netfilter.org> a écrit :
>
> > But I actually saw today that these values are used in the « nftables
> > » project. There is a copy of nf_tables.h there. Not sure it is a good
> > idea to keep the variables in « nftables » and not in kernel.
>
> I have just updated the cached copy of nf_tables.h in
> git.netfilter.org:
So now nftables does not compile anymore, does it? What do you think
we should do, then? Add a new variable, out of nf_tables.h, in
nftables project?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] netfilter: nft_ct: add ct expectations support
2019-05-13 6:00 ` Stéphane Veyret
@ 2019-05-13 8:37 ` Pablo Neira Ayuso
0 siblings, 0 replies; 10+ messages in thread
From: Pablo Neira Ayuso @ 2019-05-13 8:37 UTC (permalink / raw)
To: Stéphane Veyret; +Cc: netfilter-devel
On Mon, May 13, 2019 at 08:00:53AM +0200, Stéphane Veyret wrote:
> Le dim. 12 mai 2019 à 19:56, Pablo Neira Ayuso <pablo@netfilter.org> a écrit :
> >
> > > But I actually saw today that these values are used in the « nftables
> > > » project. There is a copy of nf_tables.h there. Not sure it is a good
> > > idea to keep the variables in « nftables » and not in kernel.
> >
> > I have just updated the cached copy of nf_tables.h in
> > git.netfilter.org:
>
> So now nftables does not compile anymore, does it? What do you think
> we should do, then? Add a new variable, out of nf_tables.h, in
> nftables project?
Please, do not add a new enumeration definition to nf_tables.h for
something we do not need in UAPI.
Thanks.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-05-13 8:40 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-04 17:35 [PATCH] netfilter: nft_ct: add ct expectations support Stéphane Veyret
2019-05-05 13:24 ` Jeremy Sowden
2019-05-05 15:38 ` Stéphane Veyret
-- strict thread matches above, loose matches on Subject: below --
2019-05-05 15:40 Stéphane Veyret
2019-05-05 15:58 ` Florian Westphal
2019-05-05 22:51 ` Pablo Neira Ayuso
2019-05-11 18:54 ` Stéphane Veyret
2019-05-12 17:56 ` Pablo Neira Ayuso
2019-05-13 6:00 ` Stéphane Veyret
2019-05-13 8:37 ` Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).