* [PATCH libnetfilter_conntrack v2] conntrack: Add zone filtering for conntrack events
@ 2024-08-30 9:05 Priyankar Jain
[not found] ` <PH0PR02MB7496D619D1674886AC17798083932@PH0PR02MB7496.namprd02.prod.outlook.com>
0 siblings, 1 reply; 4+ messages in thread
From: Priyankar Jain @ 2024-08-30 9:05 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo, Priyankar Jain
This patch adds support for filtering CT entries by their zones
using bsf. Max number of zones for filtering is 127. (Although
it can be supported till 255 but keeping it consistent with
IPv4 and mark filtering). Entries which does not have ct-zone
set will be treated as ct-zone=0.
Signed-off-by: Priyankar Jain <priyankar.jain@nutanix.com>
---
include/internal/object.h | 4 ++
.../libnetfilter_conntrack.h | 1 +
src/conntrack/bsf.c | 55 +++++++++++++++++++
src/conntrack/filter.c | 10 ++++
4 files changed, 70 insertions(+)
diff --git a/include/internal/object.h b/include/internal/object.h
index 8854ef2..658e4d2 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -280,6 +280,10 @@ struct nfct_filter {
uint32_t mask;
} mark[__FILTER_MARK_MAX];
+ uint32_t zone_elems;
+#define __FILTER_ZONE_MAX 127
+ uint16_t zone[__FILTER_ZONE_MAX];
+
uint32_t set[1];
};
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index 2e9458a..27d972d 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -510,6 +510,7 @@ enum nfct_filter_attr {
NFCT_FILTER_SRC_IPV6, /* struct nfct_filter_ipv6 */
NFCT_FILTER_DST_IPV6, /* struct nfct_filter_ipv6 */
NFCT_FILTER_MARK, /* struct nfct_filter_dump_mark */
+ NFCT_FILTER_ZONE, /* uint16_t */
NFCT_FILTER_MAX
};
diff --git a/src/conntrack/bsf.c b/src/conntrack/bsf.c
index 1e78bad..da5919c 100644
--- a/src/conntrack/bsf.c
+++ b/src/conntrack/bsf.c
@@ -738,6 +738,58 @@ bsf_add_mark_filter(const struct nfct_filter *f, struct sock_filter *this)
return j;
}
+static int
+bsf_add_zone_filter(const struct nfct_filter *f, struct sock_filter *this)
+{
+ unsigned int i, j;
+ unsigned int jt;
+ struct stack *s;
+ struct jump jmp;
+ struct sock_filter __code = {
+ /* if (A == 0) skip next two */
+ .code = BPF_JMP|BPF_JEQ|BPF_K,
+ .k = 0,
+ .jt = 2,
+ .jf = 0,
+ };
+
+ /* nothing to filter, skip */
+ if (f->zone_elems == 0)
+ return 0;
+
+ /* 127 max filterable zones. One JMP instruction per zone. */
+ s = stack_create(sizeof(struct jump), 127);
+ if (s == NULL) {
+ errno = ENOMEM;
+ return 0;
+ }
+
+ jt = 1;
+ j = 0;
+ j += nfct_bsf_load_payload_offset(this, j); /* A = nla header offset */
+ j += nfct_bsf_find_attr(this, CTA_ZONE, j); /* A = CTA_ZONE offset, started from A */
+ memcpy(&this[j], &__code, sizeof(__code)); /* if A == 0 skip next two op */
+ j += NEW_POS(__code);
+ j += nfct_bsf_x_equal_a(this, j); /* X = A <CTA_ZONE offset> */
+ j += nfct_bsf_load_attr(this, BPF_H, j); /* A = skb->data[X:X + BPF_H] */
+
+ for (i = 0; i < f->zone_elems; i++) {
+ j += nfct_bsf_cmp_k_stack(this, f->zone[i], jt - j, j, s);
+ }
+
+ while (stack_pop(s, &jmp) != -1)
+ this[jmp.line].jt += jmp.jt + j;
+
+ if (f->logic[NFCT_FILTER_ZONE] == NFCT_FILTER_LOGIC_NEGATIVE)
+ j += nfct_bsf_jump_to(this, 1, j);
+
+ j += nfct_bsf_ret_verdict(this, NFCT_FILTER_REJECT, j);
+
+ stack_destroy(s);
+
+ return j;
+}
+
/* this buffer must be big enough to store all the autogenerated lines */
#define BSF_BUFFER_SIZE 2048
@@ -774,6 +826,9 @@ int __setup_netlink_socket_filter(int fd, struct nfct_filter *f)
j += bsf_add_mark_filter(f, &bsf[j]);
show_filter(bsf, from, j, "---- check mark ----");
from = j;
+ j += bsf_add_zone_filter(f, &bsf[j]);
+ show_filter(bsf, from, j, "---- check zone ----");
+ from = j;
/* nothing to filter, skip */
if (j == 0)
diff --git a/src/conntrack/filter.c b/src/conntrack/filter.c
index 57b2294..9feff80 100644
--- a/src/conntrack/filter.c
+++ b/src/conntrack/filter.c
@@ -104,6 +104,15 @@ static void filter_attr_mark(struct nfct_filter *filter, const void *value)
filter->mark_elems++;
}
+static void filter_attr_zone(struct nfct_filter *filter, const void *value)
+{
+ if (filter->zone_elems >= __FILTER_ZONE_MAX)
+ return;
+
+ filter->zone[filter->zone_elems] = *(uint16_t *) value;
+ filter->zone_elems++;
+}
+
const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
[NFCT_FILTER_L4PROTO] = filter_attr_l4proto,
[NFCT_FILTER_L4PROTO_STATE] = filter_attr_l4proto_state,
@@ -112,4 +121,5 @@ const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
[NFCT_FILTER_SRC_IPV6] = filter_attr_src_ipv6,
[NFCT_FILTER_DST_IPV6] = filter_attr_dst_ipv6,
[NFCT_FILTER_MARK] = filter_attr_mark,
+ [NFCT_FILTER_ZONE] = filter_attr_zone,
};
--
2.39.2 (Apple Git-143)
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH libnetfilter_conntrack v2] conntrack: Add zone filtering for conntrack events
[not found] ` <PH0PR02MB7496D619D1674886AC17798083932@PH0PR02MB7496.namprd02.prod.outlook.com>
@ 2024-09-03 16:07 ` Priyankar Jain
2024-09-03 16:08 ` Pablo Neira Ayuso
0 siblings, 1 reply; 4+ messages in thread
From: Priyankar Jain @ 2024-09-03 16:07 UTC (permalink / raw)
To: netfilter-devel@vger.kernel.org; +Cc: pablo@netfilter.org
Hi,
Ping for review.
Thanks,
Priyankar
On 03/09/24 9:34 pm, Priyankar Jain wrote:
> From: Priyankar Jain <priyankar.jain@nutanix.com>
> Date: Friday, 30 August 2024 at 2:35 PM
> To: netfilter-devel@vger.kernel.org <netfilter-devel@vger.kernel.org>
> Cc: pablo@netfilter.org <pablo@netfilter.org>, Priyankar Jain
> <priyankar.jain@nutanix.com>
> Subject: [PATCH libnetfilter_conntrack v2] conntrack: Add zone filtering for
> conntrack events
>
> This patch adds support for filtering CT entries by their zones
> using bsf. Max number of zones for filtering is 127. (Although
> it can be supported till 255 but keeping it consistent with
> IPv4 and mark filtering). Entries which does not have ct-zone
> set will be treated as ct-zone=0.
>
> Signed-off-by: Priyankar Jain <priyankar.jain@nutanix.com>
> ---
> include/internal/object.h | 4 ++
> .../libnetfilter_conntrack.h | 1 +
> src/conntrack/bsf.c | 55 +++++++++++++++++++
> src/conntrack/filter.c | 10 ++++
> 4 files changed, 70 insertions(+)
>
> diff --git a/include/internal/object.h b/include/internal/object.h
> index 8854ef2..658e4d2 100644
> --- a/include/internal/object.h
> +++ b/include/internal/object.h
> @@ -280,6 +280,10 @@ struct nfct_filter {
> uint32_t mask;
> } mark[__FILTER_MARK_MAX];
>
> + uint32_t zone_elems;
> +#define __FILTER_ZONE_MAX 127
> + uint16_t zone[__FILTER_ZONE_MAX];
> +
> uint32_t set[1];
> };
>
> diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/
> libnetfilter_conntrack/libnetfilter_conntrack.h
> index 2e9458a..27d972d 100644
> --- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
> +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
> @@ -510,6 +510,7 @@ enum nfct_filter_attr {
> NFCT_FILTER_SRC_IPV6, /* struct nfct_filter_ipv6 */
> NFCT_FILTER_DST_IPV6, /* struct nfct_filter_ipv6 */
> NFCT_FILTER_MARK, /* struct nfct_filter_dump_mark */
> + NFCT_FILTER_ZONE, /* uint16_t */
> NFCT_FILTER_MAX
> };
>
> diff --git a/src/conntrack/bsf.c b/src/conntrack/bsf.c
> index 1e78bad..da5919c 100644
> --- a/src/conntrack/bsf.c
> +++ b/src/conntrack/bsf.c
> @@ -738,6 +738,58 @@ bsf_add_mark_filter(const struct nfct_filter *f, struct
> sock_filter *this)
> return j;
> }
>
> +static int
> +bsf_add_zone_filter(const struct nfct_filter *f, struct sock_filter *this)
> +{
> + unsigned int i, j;
> + unsigned int jt;
> + struct stack *s;
> + struct jump jmp;
> + struct sock_filter __code = {
> + /* if (A == 0) skip next two */
> + .code = BPF_JMP|BPF_JEQ|BPF_K,
> + .k = 0,
> + .jt = 2,
> + .jf = 0,
> + };
> +
> + /* nothing to filter, skip */
> + if (f->zone_elems == 0)
> + return 0;
> +
> + /* 127 max filterable zones. One JMP instruction per zone. */
> + s = stack_create(sizeof(struct jump), 127);
> + if (s == NULL) {
> + errno = ENOMEM;
> + return 0;
> + }
> +
> + jt = 1;
> + j = 0;
> + j += nfct_bsf_load_payload_offset(this, j); /* A = nla header
> offset */
> + j += nfct_bsf_find_attr(this, CTA_ZONE, j); /* A = CTA_ZONE offset,
> started from A */
> + memcpy(&this[j], &__code, sizeof(__code)); /* if A == 0 skip next
> two op */
> + j += NEW_POS(__code);
> + j += nfct_bsf_x_equal_a(this, j); /* X = A <CTA_ZONE
> offset> */
> + j += nfct_bsf_load_attr(this, BPF_H, j); /* A = skb->data[X:X +
> BPF_H] */
> +
> + for (i = 0; i < f->zone_elems; i++) {
> + j += nfct_bsf_cmp_k_stack(this, f->zone[i], jt - j, j, s);
> + }
> +
> + while (stack_pop(s, &jmp) != -1)
> + this[jmp.line].jt += jmp.jt + j;
> +
> + if (f->logic[NFCT_FILTER_ZONE] == NFCT_FILTER_LOGIC_NEGATIVE)
> + j += nfct_bsf_jump_to(this, 1, j);
> +
> + j += nfct_bsf_ret_verdict(this, NFCT_FILTER_REJECT, j);
> +
> + stack_destroy(s);
> +
> + return j;
> +}
> +
> /* this buffer must be big enough to store all the autogenerated lines */
> #define BSF_BUFFER_SIZE 2048
>
> @@ -774,6 +826,9 @@ int __setup_netlink_socket_filter(int fd, struct nfct_filter *f)
> j += bsf_add_mark_filter(f, &bsf[j]);
> show_filter(bsf, from, j, "---- check mark ----");
> from = j;
> + j += bsf_add_zone_filter(f, &bsf[j]);
> + show_filter(bsf, from, j, "---- check zone ----");
> + from = j;
>
> /* nothing to filter, skip */
> if (j == 0)
> diff --git a/src/conntrack/filter.c b/src/conntrack/filter.c
> index 57b2294..9feff80 100644
> --- a/src/conntrack/filter.c
> +++ b/src/conntrack/filter.c
> @@ -104,6 +104,15 @@ static void filter_attr_mark(struct nfct_filter *filter,
> const void *value)
> filter->mark_elems++;
> }
>
> +static void filter_attr_zone(struct nfct_filter *filter, const void *value)
> +{
> + if (filter->zone_elems >= __FILTER_ZONE_MAX)
> + return;
> +
> + filter->zone[filter->zone_elems] = *(uint16_t *) value;
> + filter->zone_elems++;
> +}
> +
> const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
> [NFCT_FILTER_L4PROTO] = filter_attr_l4proto,
> [NFCT_FILTER_L4PROTO_STATE] = filter_attr_l4proto_state,
> @@ -112,4 +121,5 @@ const filter_attr filter_attr_array[NFCT_FILTER_MAX] = {
> [NFCT_FILTER_SRC_IPV6] = filter_attr_src_ipv6,
> [NFCT_FILTER_DST_IPV6] = filter_attr_dst_ipv6,
> [NFCT_FILTER_MARK] = filter_attr_mark,
> + [NFCT_FILTER_ZONE] = filter_attr_zone,
> };
> --
> 2.39.2 (Apple Git-143)
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH libnetfilter_conntrack v2] conntrack: Add zone filtering for conntrack events
2024-09-03 16:07 ` Priyankar Jain
@ 2024-09-03 16:08 ` Pablo Neira Ayuso
[not found] ` <PH0PR02MB7496E90FEB4D337192D7680B83932@PH0PR02MB7496.namprd02.prod.outlook.com>
0 siblings, 1 reply; 4+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-03 16:08 UTC (permalink / raw)
To: Priyankar Jain; +Cc: netfilter-devel@vger.kernel.org
On Tue, Sep 03, 2024 at 09:37:33PM +0530, Priyankar Jain wrote:
> Hi,
>
> Ping for review.
Applied, thanks
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH libnetfilter_conntrack v2] conntrack: Add zone filtering for conntrack events
[not found] ` <PH0PR02MB7496E90FEB4D337192D7680B83932@PH0PR02MB7496.namprd02.prod.outlook.com>
@ 2024-09-03 18:17 ` Pablo Neira Ayuso
0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2024-09-03 18:17 UTC (permalink / raw)
To: Priyankar Jain; +Cc: netfilter-devel@vger.kernel.org
On Tue, Sep 03, 2024 at 04:26:05PM +0000, Priyankar Jain wrote:
> Thanks a lot. Do we also have a upcoming release for this library to be available for consumption?
I plan to schedule releases once kernel 6.11 comes out.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-09-03 18:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-30 9:05 [PATCH libnetfilter_conntrack v2] conntrack: Add zone filtering for conntrack events Priyankar Jain
[not found] ` <PH0PR02MB7496D619D1674886AC17798083932@PH0PR02MB7496.namprd02.prod.outlook.com>
2024-09-03 16:07 ` Priyankar Jain
2024-09-03 16:08 ` Pablo Neira Ayuso
[not found] ` <PH0PR02MB7496E90FEB4D337192D7680B83932@PH0PR02MB7496.namprd02.prod.outlook.com>
2024-09-03 18:17 ` Pablo Neira Ayuso
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.