Message ID | 20240620113527.7789-1-changliang.wu@smartx.com |
---|---|
State | Accepted |
Headers | show |
Series | netfilter: ctnetlink: support CTA_FILTER for flush | expand |
PING Changliang Wu <changliang.wu@smartx.com> 于2024年6月20日周四 19:35写道: > > From cb8aa9a, we can use kernel side filtering for dump, but > this capability is not available for flush. > > This Patch allows advanced filter with CTA_FILTER for flush > > Performace > 1048576 ct flows in total, delete 50,000 flows by origin src ip > 3.06s -> dump all, compare and delete > 584ms -> directly flush with filter > > Signed-off-by: Changliang Wu <changliang.wu@smartx.com> > --- > net/netfilter/nf_conntrack_netlink.c | 9 +++------ > 1 file changed, 3 insertions(+), 6 deletions(-) > > diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c > index 3b846cbdc..93afe57d9 100644 > --- a/net/netfilter/nf_conntrack_netlink.c > +++ b/net/netfilter/nf_conntrack_netlink.c > @@ -1579,9 +1579,6 @@ static int ctnetlink_flush_conntrack(struct net *net, > }; > > if (ctnetlink_needs_filter(family, cda)) { > - if (cda[CTA_FILTER]) > - return -EOPNOTSUPP; > - > filter = ctnetlink_alloc_filter(cda, family); > if (IS_ERR(filter)) > return PTR_ERR(filter); > @@ -1610,14 +1607,14 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb, > if (err < 0) > return err; > > - if (cda[CTA_TUPLE_ORIG]) > + if (cda[CTA_TUPLE_ORIG] && !cda[CTA_FILTER]) > err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, > family, &zone); > - else if (cda[CTA_TUPLE_REPLY]) > + else if (cda[CTA_TUPLE_REPLY] && !cda[CTA_FILTER]) > err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, > family, &zone); > else { > - u_int8_t u3 = info->nfmsg->version ? family : AF_UNSPEC; > + u8 u3 = info->nfmsg->version || cda[CTA_FILTER] ? family : AF_UNSPEC; > > return ctnetlink_flush_conntrack(info->net, cda, > NETLINK_CB(skb).portid, > -- > 2.43.0 >
Please, provide an example program for libnetfilter_conntrack. See: commit 27f09380ebb0fc21c4cd20070b828a27430b5de1 Author: Felix Huettner <felix.huettner@mail.schwarz> Date: Tue Dec 5 09:35:16 2023 +0000 conntrack: support flush filtering for instance. thanks On Thu, Jul 11, 2024 at 01:40:02PM +0800, Changliang Wu wrote: > PING > > > Changliang Wu <changliang.wu@smartx.com> 于2024年6月20日周四 19:35写道: > > > > From cb8aa9a, we can use kernel side filtering for dump, but > > this capability is not available for flush. > > > > This Patch allows advanced filter with CTA_FILTER for flush > > > > Performace > > 1048576 ct flows in total, delete 50,000 flows by origin src ip > > 3.06s -> dump all, compare and delete > > 584ms -> directly flush with filter > > > > Signed-off-by: Changliang Wu <changliang.wu@smartx.com> > > --- > > net/netfilter/nf_conntrack_netlink.c | 9 +++------ > > 1 file changed, 3 insertions(+), 6 deletions(-) > > > > diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c > > index 3b846cbdc..93afe57d9 100644 > > --- a/net/netfilter/nf_conntrack_netlink.c > > +++ b/net/netfilter/nf_conntrack_netlink.c > > @@ -1579,9 +1579,6 @@ static int ctnetlink_flush_conntrack(struct net *net, > > }; > > > > if (ctnetlink_needs_filter(family, cda)) { > > - if (cda[CTA_FILTER]) > > - return -EOPNOTSUPP; > > - > > filter = ctnetlink_alloc_filter(cda, family); > > if (IS_ERR(filter)) > > return PTR_ERR(filter); > > @@ -1610,14 +1607,14 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb, > > if (err < 0) > > return err; > > > > - if (cda[CTA_TUPLE_ORIG]) > > + if (cda[CTA_TUPLE_ORIG] && !cda[CTA_FILTER]) > > err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, > > family, &zone); > > - else if (cda[CTA_TUPLE_REPLY]) > > + else if (cda[CTA_TUPLE_REPLY] && !cda[CTA_FILTER]) > > err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, > > family, &zone); > > else { > > - u_int8_t u3 = info->nfmsg->version ? family : AF_UNSPEC; > > + u8 u3 = info->nfmsg->version || cda[CTA_FILTER] ? family : AF_UNSPEC; > > > > return ctnetlink_flush_conntrack(info->net, cda, > > NETLINK_CB(skb).portid, > > -- > > 2.43.0 > >
diff --git a/src/conntrack/filter_dump.c b/src/conntrack/filter_dump.c index fd2d002..18d941b 100644 --- a/src/conntrack/filter_dump.c +++ b/src/conntrack/filter_dump.c @@ -68,9 +68,5 @@ int __build_filter_dump(struct nfnlhdr *req, size_t size, int __build_filter_flush(struct nfnlhdr *req, size_t size, const struct nfct_filter_dump *filter_dump) { - if (filter_dump->set & (1 << NFCT_FILTER_DUMP_TUPLE)) { - errno = ENOTSUP; - return -1; - } return nfct_nlmsg_build_filter(&req->nlh, filter_dump); } diff --git a/utils/Makefile.am b/utils/Makefile.am index 7e7aef4..50a1c7c 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -11,6 +11,7 @@ check_PROGRAMS = expect_dump expect_create expect_get expect_delete \ conntrack_dump_filter \ conntrack_dump_filter_tuple \ conntrack_flush_filter \ + conntrack_flush_filter_tuple \ ctexp_events conntrack_grp_create_SOURCES = conntrack_grp_create.c @@ -46,6 +47,9 @@ conntrack_flush_LDADD = ../src/libnetfilter_conntrack.la conntrack_flush_filter_SOURCES = conntrack_flush_filter.c conntrack_flush_filter_LDADD = ../src/libnetfilter_conntrack.la +conntrack_flush_filter_tuple_SOURCES = conntrack_flush_filter_tuple.c +conntrack_flush_filter_tuple_LDADD = ../src/libnetfilter_conntrack.la + conntrack_events_SOURCES = conntrack_events.c conntrack_events_LDADD = ../src/libnetfilter_conntrack.la diff --git a/utils/conntrack_flush_filter_tuple.c b/utils/conntrack_flush_filter_tuple.c new file mode 100644 index 0000000..f2bf558 --- /dev/null +++ b/utils/conntrack_flush_filter_tuple.c @@ -0,0 +1,61 @@ +#include <arpa/inet.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> + +static int cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, + void *data) { + char buf[1024]; + + nfct_snprintf(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, + NFCT_OF_SHOW_LAYER3 | NFCT_OF_TIMESTAMP); + printf("%s\n", buf); + + return NFCT_CB_CONTINUE; +} + +int main(void) { + int ret; + struct nfct_handle *h; + + h = nfct_open(CONNTRACK, 0); + if (!h) { + perror("nfct_open"); + return -1; + } + struct nfct_filter_dump *filter_dump = nfct_filter_dump_create(); + if (filter_dump == NULL) { + perror("nfct_filter_dump_alloc"); + return -1; + } + + struct nf_conntrack *ct; + ct = nfct_new(); + if (!ct) { + perror("nfct_new"); + return 0; + } + + nfct_set_attr_u8(ct, ATTR_ORIG_L3PROTO, AF_INET); + nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_ICMP); + nfct_set_attr_u32(ct, ATTR_ORIG_IPV4_DST, inet_addr("192.168.1.1")); + nfct_filter_dump_set_attr(filter_dump, NFCT_FILTER_DUMP_TUPLE, ct); + + nfct_callback_register(h, NFCT_T_ALL, cb, NULL); + ret = nfct_query(h, NFCT_Q_FLUSH_FILTER, filter_dump); + + nfct_filter_dump_destroy(filter_dump); + + printf("TEST: get conntrack "); + if (ret == -1) + printf("(%d)(%s)\n", ret, strerror(errno)); + else + printf("(OK)\n"); + + nfct_close(h); + + ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS); +} Thank you for your reply. Here is an example patch for conntrack_flush_filter_tuple above. Pablo Neira Ayuso <pablo@netfilter.org> 于2024年8月20日周二 02:47写道: > > Please, provide an example program for libnetfilter_conntrack. > > See: > > commit 27f09380ebb0fc21c4cd20070b828a27430b5de1 > Author: Felix Huettner <felix.huettner@mail.schwarz> > Date: Tue Dec 5 09:35:16 2023 +0000 > > conntrack: support flush filtering > > for instance. > > thanks > > On Thu, Jul 11, 2024 at 01:40:02PM +0800, Changliang Wu wrote: > > PING > > > > > > Changliang Wu <changliang.wu@smartx.com> 于2024年6月20日周四 19:35写道: > > > > > > From cb8aa9a, we can use kernel side filtering for dump, but > > > this capability is not available for flush. > > > > > > This Patch allows advanced filter with CTA_FILTER for flush > > > > > > Performace > > > 1048576 ct flows in total, delete 50,000 flows by origin src ip > > > 3.06s -> dump all, compare and delete > > > 584ms -> directly flush with filter > > > > > > Signed-off-by: Changliang Wu <changliang.wu@smartx.com> > > > --- > > > net/netfilter/nf_conntrack_netlink.c | 9 +++------ > > > 1 file changed, 3 insertions(+), 6 deletions(-) > > > > > > diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c > > > index 3b846cbdc..93afe57d9 100644 > > > --- a/net/netfilter/nf_conntrack_netlink.c > > > +++ b/net/netfilter/nf_conntrack_netlink.c > > > @@ -1579,9 +1579,6 @@ static int ctnetlink_flush_conntrack(struct net *net, > > > }; > > > > > > if (ctnetlink_needs_filter(family, cda)) { > > > - if (cda[CTA_FILTER]) > > > - return -EOPNOTSUPP; > > > - > > > filter = ctnetlink_alloc_filter(cda, family); > > > if (IS_ERR(filter)) > > > return PTR_ERR(filter); > > > @@ -1610,14 +1607,14 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb, > > > if (err < 0) > > > return err; > > > > > > - if (cda[CTA_TUPLE_ORIG]) > > > + if (cda[CTA_TUPLE_ORIG] && !cda[CTA_FILTER]) > > > err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, > > > family, &zone); > > > - else if (cda[CTA_TUPLE_REPLY]) > > > + else if (cda[CTA_TUPLE_REPLY] && !cda[CTA_FILTER]) > > > err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, > > > family, &zone); > > > else { > > > - u_int8_t u3 = info->nfmsg->version ? family : AF_UNSPEC; > > > + u8 u3 = info->nfmsg->version || cda[CTA_FILTER] ? family : AF_UNSPEC; > > > > > > return ctnetlink_flush_conntrack(info->net, cda, > > > NETLINK_CB(skb).portid, > > > -- > > > 2.43.0 > > >
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 3b846cbdc..93afe57d9 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1579,9 +1579,6 @@ static int ctnetlink_flush_conntrack(struct net *net, }; if (ctnetlink_needs_filter(family, cda)) { - if (cda[CTA_FILTER]) - return -EOPNOTSUPP; - filter = ctnetlink_alloc_filter(cda, family); if (IS_ERR(filter)) return PTR_ERR(filter); @@ -1610,14 +1607,14 @@ static int ctnetlink_del_conntrack(struct sk_buff *skb, if (err < 0) return err; - if (cda[CTA_TUPLE_ORIG]) + if (cda[CTA_TUPLE_ORIG] && !cda[CTA_FILTER]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, family, &zone); - else if (cda[CTA_TUPLE_REPLY]) + else if (cda[CTA_TUPLE_REPLY] && !cda[CTA_FILTER]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, family, &zone); else { - u_int8_t u3 = info->nfmsg->version ? family : AF_UNSPEC; + u8 u3 = info->nfmsg->version || cda[CTA_FILTER] ? family : AF_UNSPEC; return ctnetlink_flush_conntrack(info->net, cda, NETLINK_CB(skb).portid,
From cb8aa9a, we can use kernel side filtering for dump, but this capability is not available for flush. This Patch allows advanced filter with CTA_FILTER for flush Performace 1048576 ct flows in total, delete 50,000 flows by origin src ip 3.06s -> dump all, compare and delete 584ms -> directly flush with filter Signed-off-by: Changliang Wu <changliang.wu@smartx.com> --- net/netfilter/nf_conntrack_netlink.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)