From 462cee1b3f02ddcd5653da674b60938614c79192 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 01 2019 15:12:39 +0000 Subject: import libnftnl-1.1.1-4.el8 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7dffb2b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libnftnl-1.1.1.tar.bz2 diff --git a/.libnftnl.metadata b/.libnftnl.metadata new file mode 100644 index 0000000..012e699 --- /dev/null +++ b/.libnftnl.metadata @@ -0,0 +1 @@ +d2be642a54e0f105cb5564471ae4aaaed8b97ca6 SOURCES/libnftnl-1.1.1.tar.bz2 diff --git a/SOURCES/0001-src-remove-nftnl_rule_cmp-and-nftnl_expr_cmp.patch b/SOURCES/0001-src-remove-nftnl_rule_cmp-and-nftnl_expr_cmp.patch new file mode 100644 index 0000000..4acf258 --- /dev/null +++ b/SOURCES/0001-src-remove-nftnl_rule_cmp-and-nftnl_expr_cmp.patch @@ -0,0 +1,1348 @@ +From 00e5caa25a0cd77a1c94ee1444097db66c9e117b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 17 Dec 2018 17:28:32 +0100 +Subject: [PATCH] src: remove nftnl_rule_cmp() and nftnl_expr_cmp() + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1658533 +Upstream Status: libnftnl commit 6dc1c3d8bb640 +Conflicts: Changes to src/expr/{osf,tproxy,xfrm}.c ignored since support + for those expressions has not been backported. + +commit 6dc1c3d8bb64077da7f3f28c7368fb087d10a492 +Author: Pablo Neira Ayuso +Date: Wed Oct 24 19:18:50 2018 +0200 + + src: remove nftnl_rule_cmp() and nftnl_expr_cmp() + + These functions are not very useful, rule comparison from this layer + does not work well with implicit set definitions. + + This infrastructure was added as an attempt to support for deletion by + name from this layer, which should be done from higher level libnftables + library. Finally, we never had a client for this code in + git.netfilter.org. + + Let's remove it and bump libversion for safety reasons. + + Signed-off-by: Pablo Neira Ayuso +--- + Make_global.am | 2 +- + include/data_reg.h | 2 -- + include/expr_ops.h | 1 - + include/libnftnl/expr.h | 2 -- + include/libnftnl/rule.h | 2 -- + src/expr.c | 10 ---------- + src/expr/bitwise.c | 22 ---------------------- + src/expr/byteorder.c | 22 ---------------------- + src/expr/cmp.c | 18 ------------------ + src/expr/connlimit.c | 16 ---------------- + src/expr/counter.c | 16 ---------------- + src/expr/ct.c | 20 -------------------- + src/expr/data_reg.c | 17 ----------------- + src/expr/dup.c | 16 ---------------- + src/expr/dynset.c | 26 -------------------------- + src/expr/exthdr.c | 26 -------------------------- + src/expr/fib.c | 18 ------------------ + src/expr/flow_offload.c | 14 -------------- + src/expr/fwd.c | 18 ------------------ + src/expr/hash.c | 30 ------------------------------ + src/expr/immediate.c | 25 ------------------------- + src/expr/limit.c | 22 ---------------------- + src/expr/log.c | 24 ------------------------ + src/expr/lookup.c | 22 ---------------------- + src/expr/masq.c | 18 ------------------ + src/expr/match.c | 20 -------------------- + src/expr/meta.c | 18 ------------------ + src/expr/nat.c | 25 ------------------------- + src/expr/numgen.c | 24 ------------------------ + src/expr/objref.c | 22 ---------------------- + src/expr/payload.c | 28 ---------------------------- + src/expr/queue.c | 20 -------------------- + src/expr/redir.c | 18 ------------------ + src/expr/reject.c | 16 ---------------- + src/expr/rt.c | 16 ---------------- + src/expr/socket.c | 16 ---------------- + src/expr/target.c | 20 -------------------- + src/libnftnl.map | 18 ++++-------------- + src/rule.c | 31 ------------------------------- + 39 files changed, 5 insertions(+), 696 deletions(-) + +diff --git a/Make_global.am b/Make_global.am +index e12a3f7..307816b 100644 +--- a/Make_global.am ++++ b/Make_global.am +@@ -18,7 +18,7 @@ + # set age to 0. + # + # +-LIBVERSION=10:0:3 ++LIBVERSION=11:0:0 + + AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS} ${LIBMXML_CFLAGS} + AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN} +diff --git a/include/data_reg.h b/include/data_reg.h +index 3fec7cd..f2675f2 100644 +--- a/include/data_reg.h ++++ b/include/data_reg.h +@@ -28,8 +28,6 @@ int nftnl_data_reg_snprintf(char *buf, size_t size, + const union nftnl_data_reg *reg, + uint32_t output_format, uint32_t flags, + int reg_type); +-bool nftnl_data_reg_cmp(const union nftnl_data_reg *r1, +- const union nftnl_data_reg *r2, int reg_type); + struct nlattr; + + int nftnl_parse_data(union nftnl_data_reg *data, struct nlattr *attr, int *type); +diff --git a/include/expr_ops.h b/include/expr_ops.h +index e639390..e8809fa 100644 +--- a/include/expr_ops.h ++++ b/include/expr_ops.h +@@ -13,7 +13,6 @@ struct expr_ops { + uint32_t alloc_len; + int max_attr; + void (*free)(const struct nftnl_expr *e); +- bool (*cmp)(const struct nftnl_expr *e1, const struct nftnl_expr *e2); + int (*set)(struct nftnl_expr *e, uint16_t type, const void *data, uint32_t data_len); + const void *(*get)(const struct nftnl_expr *e, uint16_t type, uint32_t *data_len); + int (*parse)(struct nftnl_expr *e, struct nlattr *attr); +diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h +index 219104e..09dc55c 100644 +--- a/include/libnftnl/expr.h ++++ b/include/libnftnl/expr.h +@@ -36,8 +36,6 @@ uint32_t nftnl_expr_get_u32(const struct nftnl_expr *expr, uint16_t type); + uint64_t nftnl_expr_get_u64(const struct nftnl_expr *expr, uint16_t type); + const char *nftnl_expr_get_str(const struct nftnl_expr *expr, uint16_t type); + +-bool nftnl_expr_cmp(const struct nftnl_expr *e1, const struct nftnl_expr *e2); +- + int nftnl_expr_snprintf(char *buf, size_t buflen, const struct nftnl_expr *expr, uint32_t type, uint32_t flags); + int nftnl_expr_fprintf(FILE *fp, const struct nftnl_expr *expr, uint32_t type, uint32_t flags); + +diff --git a/include/libnftnl/rule.h b/include/libnftnl/rule.h +index 765d2ce..8501c86 100644 +--- a/include/libnftnl/rule.h ++++ b/include/libnftnl/rule.h +@@ -51,8 +51,6 @@ uint64_t nftnl_rule_get_u64(const struct nftnl_rule *r, uint16_t attr); + + void nftnl_rule_add_expr(struct nftnl_rule *r, struct nftnl_expr *expr); + +-bool nftnl_rule_cmp(const struct nftnl_rule *r1, const struct nftnl_rule *r2); +- + struct nlmsghdr; + + void nftnl_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_rule *t); +diff --git a/src/expr.c b/src/expr.c +index 62565e0..80c4c36 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -203,16 +203,6 @@ const char *nftnl_expr_get_str(const struct nftnl_expr *expr, uint16_t type) + return (const char *)nftnl_expr_get(expr, type, &data_len); + } + +-EXPORT_SYMBOL(nftnl_expr_cmp); +-bool nftnl_expr_cmp(const struct nftnl_expr *e1, const struct nftnl_expr *e2) +-{ +- if (e1->flags != e2->flags || +- strcmp(e1->ops->name, e2->ops->name) != 0) +- return false; +- +- return e1->ops->cmp(e1, e2); +-} +- + void nftnl_expr_build_payload(struct nlmsghdr *nlh, struct nftnl_expr *expr) + { + struct nlattr *nest; +diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c +index a89734b..6f064ec 100644 +--- a/src/expr/bitwise.c ++++ b/src/expr/bitwise.c +@@ -269,32 +269,10 @@ nftnl_expr_bitwise_snprintf(char *buf, size_t size, uint32_t type, + return -1; + } + +-static bool nftnl_expr_bitwise_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_bitwise *b1 = nftnl_expr_data(e1); +- struct nftnl_expr_bitwise *b2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_BITWISE_SREG)) +- eq &= (b1->sreg == b2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_BITWISE_DREG)) +- eq &= (b1->dreg == b2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_BITWISE_LEN)) +- eq &= (b1->len == b2->len); +- if (e1->flags & (1 << NFTNL_EXPR_BITWISE_MASK)) +- eq &= nftnl_data_reg_cmp(&b1->mask, &b2->mask, DATA_VALUE); +- if (e1->flags & (1 << NFTNL_EXPR_BITWISE_XOR)) +- eq &= nftnl_data_reg_cmp(&b1->xor, &b2->xor, DATA_VALUE); +- +- return eq; +-} +- + struct expr_ops expr_ops_bitwise = { + .name = "bitwise", + .alloc_len = sizeof(struct nftnl_expr_bitwise), + .max_attr = NFTA_BITWISE_MAX, +- .cmp = nftnl_expr_bitwise_cmp, + .set = nftnl_expr_bitwise_set, + .get = nftnl_expr_bitwise_get, + .parse = nftnl_expr_bitwise_parse, +diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c +index 47c04cf..02c8984 100644 +--- a/src/expr/byteorder.c ++++ b/src/expr/byteorder.c +@@ -284,32 +284,10 @@ nftnl_expr_byteorder_snprintf(char *buf, size_t size, uint32_t type, + return -1; + } + +-static bool nftnl_expr_byteorder_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_byteorder *b1 = nftnl_expr_data(e1); +- struct nftnl_expr_byteorder *b2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_BYTEORDER_SREG)) +- eq &= (b1->sreg == b2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_BYTEORDER_DREG)) +- eq &= (b1->dreg == b2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_BYTEORDER_OP)) +- eq &= (b1->op == b2->op); +- if (e1->flags & (1 << NFTNL_EXPR_BYTEORDER_LEN)) +- eq &= (b1->len == b2->len); +- if (e1->flags & (1 << NFTNL_EXPR_BYTEORDER_SIZE)) +- eq &= (b1->size == b2->size); +- +- return eq; +-} +- + struct expr_ops expr_ops_byteorder = { + .name = "byteorder", + .alloc_len = sizeof(struct nftnl_expr_byteorder), + .max_attr = NFTA_BYTEORDER_MAX, +- .cmp = nftnl_expr_byteorder_cmp, + .set = nftnl_expr_byteorder_set, + .get = nftnl_expr_byteorder_get, + .parse = nftnl_expr_byteorder_parse, +diff --git a/src/expr/cmp.c b/src/expr/cmp.c +index b26d0eb..5209d45 100644 +--- a/src/expr/cmp.c ++++ b/src/expr/cmp.c +@@ -258,28 +258,10 @@ nftnl_expr_cmp_snprintf(char *buf, size_t size, uint32_t type, + return -1; + } + +-static bool nftnl_expr_cmp_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_cmp *c1 = nftnl_expr_data(e1); +- struct nftnl_expr_cmp *c2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_CMP_DATA)) +- eq &= nftnl_data_reg_cmp(&c1->data, &c2->data, DATA_VALUE); +- if (e1->flags & (1 << NFTNL_EXPR_CMP_SREG)) +- eq &= (c1->sreg == c2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_CMP_OP)) +- eq &= (c1->op == c2->op); +- +- return eq; +-} +- + struct expr_ops expr_ops_cmp = { + .name = "cmp", + .alloc_len = sizeof(struct nftnl_expr_cmp), + .max_attr = NFTA_CMP_MAX, +- .cmp = nftnl_expr_cmp_cmp, + .set = nftnl_expr_cmp_set, + .get = nftnl_expr_cmp_get, + .parse = nftnl_expr_cmp_parse, +diff --git a/src/expr/connlimit.c b/src/expr/connlimit.c +index 60965b5..9b4668b 100644 +--- a/src/expr/connlimit.c ++++ b/src/expr/connlimit.c +@@ -178,26 +178,10 @@ static int nftnl_expr_connlimit_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_connlimit_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_connlimit *c1 = nftnl_expr_data(e1); +- struct nftnl_expr_connlimit *c2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_CONNLIMIT_COUNT)) +- eq &= (c1->count == c2->count); +- if (e1->flags & (1 << NFTNL_EXPR_CONNLIMIT_FLAGS)) +- eq &= (c1->flags == c2->flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_connlimit = { + .name = "connlimit", + .alloc_len = sizeof(struct nftnl_expr_connlimit), + .max_attr = NFTA_CONNLIMIT_MAX, +- .cmp = nftnl_expr_connlimit_cmp, + .set = nftnl_expr_connlimit_set, + .get = nftnl_expr_connlimit_get, + .parse = nftnl_expr_connlimit_parse, +diff --git a/src/expr/counter.c b/src/expr/counter.c +index 21901e8..1cfae2a 100644 +--- a/src/expr/counter.c ++++ b/src/expr/counter.c +@@ -176,26 +176,10 @@ static int nftnl_expr_counter_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_counter_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_counter *c1 = nftnl_expr_data(e1); +- struct nftnl_expr_counter *c2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_CTR_PACKETS)) +- eq &= (c1->pkts == c2->pkts); +- if (e1->flags & (1 << NFTNL_EXPR_CTR_BYTES)) +- eq &= (c1->pkts == c2->pkts); +- +- return eq; +-} +- + struct expr_ops expr_ops_counter = { + .name = "counter", + .alloc_len = sizeof(struct nftnl_expr_counter), + .max_attr = NFTA_COUNTER_MAX, +- .cmp = nftnl_expr_counter_cmp, + .set = nftnl_expr_counter_set, + .get = nftnl_expr_counter_get, + .parse = nftnl_expr_counter_parse, +diff --git a/src/expr/ct.c b/src/expr/ct.c +index 39e9be6..ad354b5 100644 +--- a/src/expr/ct.c ++++ b/src/expr/ct.c +@@ -329,30 +329,10 @@ nftnl_expr_ct_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_ct_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_ct *c1 = nftnl_expr_data(e1); +- struct nftnl_expr_ct *c2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_CT_KEY)) +- eq &= (c1->key == c2->key); +- if (e1->flags & (1 << NFTNL_EXPR_CT_DREG)) +- eq &= (c1->dreg == c2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_CT_SREG)) +- eq &= (c1->sreg == c2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_CT_DIR)) +- eq &= (c1->dir == c2->dir); +- +- return eq; +-} +- + struct expr_ops expr_ops_ct = { + .name = "ct", + .alloc_len = sizeof(struct nftnl_expr_ct), + .max_attr = NFTA_CT_MAX, +- .cmp = nftnl_expr_ct_cmp, + .set = nftnl_expr_ct_set, + .get = nftnl_expr_ct_get, + .parse = nftnl_expr_ct_parse, +diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c +index 1b28b29..2e02f42 100644 +--- a/src/expr/data_reg.c ++++ b/src/expr/data_reg.c +@@ -230,23 +230,6 @@ int nftnl_data_reg_snprintf(char *buf, size_t size, + return -1; + } + +-bool nftnl_data_reg_cmp(const union nftnl_data_reg *r1, +- const union nftnl_data_reg *r2, int reg_type) +-{ +- switch (reg_type) { +- case DATA_VALUE: +- return r1->len == r2->len && +- !memcmp(r1->val, r2->val, r1->len); +- case DATA_VERDICT: +- return r1->verdict == r2->verdict; +- case DATA_CHAIN: +- return r1->verdict == r2->verdict && +- !strcmp(r1->chain, r2->chain); +- default: +- return false; +- } +-} +- + static int nftnl_data_parse_cb(const struct nlattr *attr, void *data) + { + const struct nlattr **tb = data; +diff --git a/src/expr/dup.c b/src/expr/dup.c +index ed8e620..c1d4304 100644 +--- a/src/expr/dup.c ++++ b/src/expr/dup.c +@@ -182,26 +182,10 @@ static int nftnl_expr_dup_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_dup_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_dup *d1 = nftnl_expr_data(e1); +- struct nftnl_expr_dup *d2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_DUP_SREG_ADDR)) +- eq &= (d1->sreg_addr == d2->sreg_addr); +- if (e1->flags & (1 << NFTNL_EXPR_DUP_SREG_DEV)) +- eq &= (d1->sreg_dev == d2->sreg_dev); +- +- return eq; +-} +- + struct expr_ops expr_ops_dup = { + .name = "dup", + .alloc_len = sizeof(struct nftnl_expr_dup), + .max_attr = NFTA_DUP_MAX, +- .cmp = nftnl_expr_dup_cmp, + .set = nftnl_expr_dup_set, + .get = nftnl_expr_dup_get, + .parse = nftnl_expr_dup_parse, +diff --git a/src/expr/dynset.c b/src/expr/dynset.c +index 160d0e1..7e9c8b2 100644 +--- a/src/expr/dynset.c ++++ b/src/expr/dynset.c +@@ -333,37 +333,11 @@ static void nftnl_expr_dynset_free(const struct nftnl_expr *e) + xfree(dynset->set_name); + } + +-static bool nftnl_expr_dynset_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_dynset *d1 = nftnl_expr_data(e1); +- struct nftnl_expr_dynset *d2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_DYNSET_SREG_KEY)) +- eq &= (d1->sreg_key == d2->sreg_key); +- if (e1->flags & (1 << NFTNL_EXPR_DYNSET_SREG_DATA)) +- eq &= (d1->sreg_data == d2->sreg_data); +- if (e1->flags & (1 << NFTNL_EXPR_DYNSET_OP)) +- eq &= (d1->op == d2->op); +- if (e1->flags & (1 << NFTNL_EXPR_DYNSET_TIMEOUT)) +- eq &= (d1->timeout == d2->timeout); +- if (e1->flags & (1 << NFTNL_EXPR_DYNSET_EXPR)) +- eq &= nftnl_expr_cmp(d1->expr, d2->expr); +- if (e1->flags & (1 << NFTNL_EXPR_DYNSET_SET_NAME)) +- eq &= !strcmp(d1->set_name, d2->set_name); +- if (e1->flags & (1 << NFTNL_EXPR_DYNSET_SET_ID)) +- eq &= (d1->set_id == d2->set_id); +- +- return eq; +-} +- + struct expr_ops expr_ops_dynset = { + .name = "dynset", + .alloc_len = sizeof(struct nftnl_expr_dynset), + .max_attr = NFTA_DYNSET_MAX, + .free = nftnl_expr_dynset_free, +- .cmp = nftnl_expr_dynset_cmp, + .set = nftnl_expr_dynset_set, + .get = nftnl_expr_dynset_get, + .parse = nftnl_expr_dynset_parse, +diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c +index 75cafbc..4ec8920 100644 +--- a/src/expr/exthdr.c ++++ b/src/expr/exthdr.c +@@ -351,36 +351,10 @@ nftnl_expr_exthdr_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_exthdr_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_exthdr *h1 = nftnl_expr_data(e1); +- struct nftnl_expr_exthdr *h2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_EXTHDR_DREG)) +- eq &= (h1->dreg == h2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_EXTHDR_SREG)) +- eq &= (h1->sreg == h2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_EXTHDR_OFFSET)) +- eq &= (h1->offset == h2->offset); +- if (e1->flags & (1 << NFTNL_EXPR_EXTHDR_LEN)) +- eq &= (h1->len == h2->len); +- if (e1->flags & (1 << NFTNL_EXPR_EXTHDR_TYPE)) +- eq &= (h1->type == h2->type); +- if (e1->flags & (1 << NFTNL_EXPR_EXTHDR_OP)) +- eq &= (h1->op == h2->op); +- if (e1->flags & (1 << NFTNL_EXPR_EXTHDR_FLAGS)) +- eq &= (h1->flags == h2->flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_exthdr = { + .name = "exthdr", + .alloc_len = sizeof(struct nftnl_expr_exthdr), + .max_attr = NFTA_EXTHDR_MAX, +- .cmp = nftnl_expr_exthdr_cmp, + .set = nftnl_expr_exthdr_set, + .get = nftnl_expr_exthdr_get, + .parse = nftnl_expr_exthdr_parse, +diff --git a/src/expr/fib.c b/src/expr/fib.c +index b922b26..2b0b077 100644 +--- a/src/expr/fib.c ++++ b/src/expr/fib.c +@@ -248,28 +248,10 @@ nftnl_expr_fib_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_fib_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_fib *h1 = nftnl_expr_data(e1); +- struct nftnl_expr_fib *h2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_FIB_RESULT)) +- eq &= (h1->result == h2->result); +- if (e1->flags & (1 << NFTNL_EXPR_FIB_DREG)) +- eq &= (h1->dreg == h2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_FIB_FLAGS)) +- eq &= (h1->flags == h2->flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_fib = { + .name = "fib", + .alloc_len = sizeof(struct nftnl_expr_fib), + .max_attr = NFTA_FIB_MAX, +- .cmp = nftnl_expr_fib_cmp, + .set = nftnl_expr_fib_set, + .get = nftnl_expr_fib_get, + .parse = nftnl_expr_fib_parse, +diff --git a/src/expr/flow_offload.c b/src/expr/flow_offload.c +index a2001c9..58fb37f 100644 +--- a/src/expr/flow_offload.c ++++ b/src/expr/flow_offload.c +@@ -156,25 +156,11 @@ static void nftnl_expr_flow_free(const struct nftnl_expr *e) + xfree(flow->table_name); + } + +-static bool nftnl_expr_flow_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_flow *l1 = nftnl_expr_data(e1); +- struct nftnl_expr_flow *l2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_FLOW_TABLE_NAME)) +- eq &= !strcmp(l1->table_name, l2->table_name); +- +- return eq; +-} +- + struct expr_ops expr_ops_flow = { + .name = "flow_offload", + .alloc_len = sizeof(struct nftnl_expr_flow), + .max_attr = NFTA_FLOW_MAX, + .free = nftnl_expr_flow_free, +- .cmp = nftnl_expr_flow_cmp, + .set = nftnl_expr_flow_set, + .get = nftnl_expr_flow_get, + .parse = nftnl_expr_flow_parse, +diff --git a/src/expr/fwd.c b/src/expr/fwd.c +index 9021606..23fb096 100644 +--- a/src/expr/fwd.c ++++ b/src/expr/fwd.c +@@ -207,28 +207,10 @@ static int nftnl_expr_fwd_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_fwd_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_fwd *f1 = nftnl_expr_data(e1); +- struct nftnl_expr_fwd *f2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_FWD_SREG_DEV)) +- eq &= (f1->sreg_dev == f2->sreg_dev); +- if (e1->flags & (1 << NFTNL_EXPR_FWD_SREG_ADDR)) +- eq &= (f1->sreg_addr == f2->sreg_addr); +- if (e1->flags & (1 << NFTNL_EXPR_FWD_NFPROTO)) +- eq &= (f1->nfproto == f2->nfproto); +- +- return eq; +-} +- + struct expr_ops expr_ops_fwd = { + .name = "fwd", + .alloc_len = sizeof(struct nftnl_expr_fwd), + .max_attr = NFTA_FWD_MAX, +- .cmp = nftnl_expr_fwd_cmp, + .set = nftnl_expr_fwd_set, + .get = nftnl_expr_fwd_get, + .parse = nftnl_expr_fwd_parse, +diff --git a/src/expr/hash.c b/src/expr/hash.c +index 415537e..db65b2c 100644 +--- a/src/expr/hash.c ++++ b/src/expr/hash.c +@@ -345,40 +345,10 @@ nftnl_expr_hash_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_hash_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_hash *h1 = nftnl_expr_data(e1); +- struct nftnl_expr_hash *h2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_HASH_SREG)) +- eq &= (h1->sreg == h2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_DREG)) +- eq &= (h1->dreg == h2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_LEN)) +- eq &= (h1->len == h2->len); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_MODULUS)) +- eq &= (h1->modulus == h2->modulus); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_SEED)) +- eq &= (h1->seed == h2->seed); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_OFFSET)) +- eq &= (h1->offset == h2->offset); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_TYPE)) +- eq &= (h1->type == h2->type); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_SET_NAME)) +- eq &= !strcmp(h1->map.name, h2->map.name); +- if (e1->flags & (1 << NFTNL_EXPR_HASH_SET_ID)) +- eq &= (h1->map.id == h2->map.id); +- +- return eq; +-} +- + struct expr_ops expr_ops_hash = { + .name = "hash", + .alloc_len = sizeof(struct nftnl_expr_hash), + .max_attr = NFTA_HASH_MAX, +- .cmp = nftnl_expr_hash_cmp, + .set = nftnl_expr_hash_set, + .get = nftnl_expr_hash_get, + .parse = nftnl_expr_hash_parse, +diff --git a/src/expr/immediate.c b/src/expr/immediate.c +index b0570bd..dcb72a7 100644 +--- a/src/expr/immediate.c ++++ b/src/expr/immediate.c +@@ -282,36 +282,11 @@ static void nftnl_expr_immediate_free(const struct nftnl_expr *e) + nftnl_free_verdict(&imm->data); + } + +-static bool nftnl_expr_immediate_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_immediate *i1 = nftnl_expr_data(e1); +- struct nftnl_expr_immediate *i2 = nftnl_expr_data(e2); +- bool eq = true; +- int type = DATA_NONE; +- +- if (e1->flags & (1 << NFTNL_EXPR_IMM_DREG)) +- eq &= (i1->dreg == i2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_IMM_VERDICT)) +- if (e1->flags & (1 << NFTNL_EXPR_IMM_CHAIN)) +- type = DATA_CHAIN; +- else +- type = DATA_VERDICT; +- else if (e1->flags & (1 << NFTNL_EXPR_IMM_DATA)) +- type = DATA_VALUE; +- +- if (type != DATA_NONE) +- eq &= nftnl_data_reg_cmp(&i1->data, &i2->data, type); +- +- return eq; +-} +- + struct expr_ops expr_ops_immediate = { + .name = "immediate", + .alloc_len = sizeof(struct nftnl_expr_immediate), + .max_attr = NFTA_IMMEDIATE_MAX, + .free = nftnl_expr_immediate_free, +- .cmp = nftnl_expr_immediate_cmp, + .set = nftnl_expr_immediate_set, + .get = nftnl_expr_immediate_get, + .parse = nftnl_expr_immediate_parse, +diff --git a/src/expr/limit.c b/src/expr/limit.c +index 856ab18..ab177ff 100644 +--- a/src/expr/limit.c ++++ b/src/expr/limit.c +@@ -255,33 +255,11 @@ nftnl_expr_limit_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_limit_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_limit *l1 = nftnl_expr_data(e1); +- struct nftnl_expr_limit *l2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_LIMIT_RATE)) +- eq &= (l1->rate == l2->rate); +- if (e1->flags & (1 << NFTNL_EXPR_LIMIT_UNIT)) +- eq &= (l1->unit == l2->unit); +- if (e1->flags & (1 << NFTNL_EXPR_LIMIT_BURST)) +- eq &= (l1->burst == l2->burst); +- if (e1->flags & (1 << NFTNL_EXPR_LIMIT_TYPE)) +- eq &= (l1->type == l2->type); +- if (e1->flags & (1 << NFTNL_EXPR_LIMIT_FLAGS)) +- eq &= (l1->flags == l2->flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_limit = { + .name = "limit", + .alloc_len = sizeof(struct nftnl_expr_limit), + .max_attr = NFTA_LIMIT_MAX, + .set = nftnl_expr_limit_set, +- .cmp = nftnl_expr_limit_cmp, + .get = nftnl_expr_limit_get, + .parse = nftnl_expr_limit_parse, + .build = nftnl_expr_limit_build, +diff --git a/src/expr/log.c b/src/expr/log.c +index 86d9651..14a388f 100644 +--- a/src/expr/log.c ++++ b/src/expr/log.c +@@ -320,35 +320,11 @@ static void nftnl_expr_log_free(const struct nftnl_expr *e) + xfree(log->prefix); + } + +-static bool nftnl_expr_log_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_log *l1 = nftnl_expr_data(e1); +- struct nftnl_expr_log *l2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_LOG_SNAPLEN)) +- eq &= (l1->snaplen == l2->snaplen); +- if (e1->flags & (1 << NFTNL_EXPR_LOG_GROUP)) +- eq &= (l1->group == l2->group); +- if (e1->flags & (1 << NFTNL_EXPR_LOG_QTHRESHOLD)) +- eq &= (l1->qthreshold == l2->qthreshold); +- if (e1->flags & (1 << NFTNL_EXPR_LOG_LEVEL)) +- eq &= (l1->level == l2->level); +- if (e1->flags & (1 << NFTNL_EXPR_LOG_FLAGS)) +- eq &= (l1->flags == l2->flags); +- if (e1->flags & (1 << NFTNL_EXPR_LOG_PREFIX)) +- eq &= !strcmp(l1->prefix, l2->prefix); +- +- return eq; +-} +- + struct expr_ops expr_ops_log = { + .name = "log", + .alloc_len = sizeof(struct nftnl_expr_log), + .max_attr = NFTA_LOG_MAX, + .free = nftnl_expr_log_free, +- .cmp = nftnl_expr_log_cmp, + .set = nftnl_expr_log_set, + .get = nftnl_expr_log_get, + .parse = nftnl_expr_log_parse, +diff --git a/src/expr/lookup.c b/src/expr/lookup.c +index 5fcb81f..8e721e7 100644 +--- a/src/expr/lookup.c ++++ b/src/expr/lookup.c +@@ -261,33 +261,11 @@ static void nftnl_expr_lookup_free(const struct nftnl_expr *e) + xfree(lookup->set_name); + } + +-static bool nftnl_expr_lookup_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_lookup *l1 = nftnl_expr_data(e1); +- struct nftnl_expr_lookup *l2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_LOOKUP_SREG)) +- eq &= (l1->sreg == l2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_LOOKUP_DREG)) +- eq &= (l1->dreg == l2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_LOOKUP_SET)) +- eq &= !strcmp(l1->set_name, l2->set_name); +- if (e1->flags & (1 << NFTNL_EXPR_LOOKUP_SET_ID)) +- eq &= (l1->set_id == l2->set_id); +- if (e1->flags & (1 << NFTNL_EXPR_LOOKUP_FLAGS)) +- eq &= (l1->flags == l2->flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_lookup = { + .name = "lookup", + .alloc_len = sizeof(struct nftnl_expr_lookup), + .max_attr = NFTA_LOOKUP_MAX, + .free = nftnl_expr_lookup_free, +- .cmp = nftnl_expr_lookup_cmp, + .set = nftnl_expr_lookup_set, + .get = nftnl_expr_lookup_get, + .parse = nftnl_expr_lookup_parse, +diff --git a/src/expr/masq.c b/src/expr/masq.c +index 7c235d3..c2c9a94 100644 +--- a/src/expr/masq.c ++++ b/src/expr/masq.c +@@ -202,28 +202,10 @@ static int nftnl_expr_masq_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_masq_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_masq *m1 = nftnl_expr_data(e1); +- struct nftnl_expr_masq *m2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_MASQ_FLAGS)) +- eq &= (m1->flags == m2->flags); +- if (e1->flags & (1 << NFTNL_EXPR_MASQ_REG_PROTO_MIN)) +- eq &= (m1->sreg_proto_min == m2->sreg_proto_min); +- if (e1->flags & (1 << NFTNL_EXPR_MASQ_REG_PROTO_MAX)) +- eq &= (m1->sreg_proto_max == m2->sreg_proto_max); +- +- return eq; +-} +- + struct expr_ops expr_ops_masq = { + .name = "masq", + .alloc_len = sizeof(struct nftnl_expr_masq), + .max_attr = NFTA_MASQ_MAX, +- .cmp = nftnl_expr_masq_cmp, + .set = nftnl_expr_masq_set, + .get = nftnl_expr_masq_get, + .parse = nftnl_expr_masq_parse, +diff --git a/src/expr/match.c b/src/expr/match.c +index dd09e1e..89732d6 100644 +--- a/src/expr/match.c ++++ b/src/expr/match.c +@@ -220,31 +220,11 @@ static void nftnl_expr_match_free(const struct nftnl_expr *e) + xfree(match->data); + } + +-static bool nftnl_expr_match_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_match *m1 = nftnl_expr_data(e1); +- struct nftnl_expr_match *m2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_MT_NAME)) +- eq &= !strcmp(m1->name, m2->name); +- if (e1->flags & (1 << NFTNL_EXPR_MT_REV)) +- eq &= (m1->rev == m2->rev); +- if (e1->flags & (1 << NFTNL_EXPR_MT_INFO)) { +- eq &= (m1->data_len == m2->data_len); +- eq &= !memcmp(m1->data, m2->data, m1->data_len); +- } +- +- return eq; +-} +- + struct expr_ops expr_ops_match = { + .name = "match", + .alloc_len = sizeof(struct nftnl_expr_match), + .max_attr = NFTA_MATCH_MAX, + .free = nftnl_expr_match_free, +- .cmp = nftnl_expr_match_cmp, + .set = nftnl_expr_match_set, + .get = nftnl_expr_match_get, + .parse = nftnl_expr_match_parse, +diff --git a/src/expr/meta.c b/src/expr/meta.c +index de82105..8d697b7 100644 +--- a/src/expr/meta.c ++++ b/src/expr/meta.c +@@ -265,28 +265,10 @@ nftnl_expr_meta_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_meta_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_meta *m1 = nftnl_expr_data(e1); +- struct nftnl_expr_meta *m2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_META_KEY)) +- eq &= (m1->key == m2->key); +- if (e1->flags & (1 << NFTNL_EXPR_META_DREG)) +- eq &= (m1->dreg == m2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_META_SREG)) +- eq &= (m1->sreg == m2->sreg); +- +- return eq; +-} +- + struct expr_ops expr_ops_meta = { + .name = "meta", + .alloc_len = sizeof(struct nftnl_expr_meta), + .max_attr = NFTA_META_MAX, +- .cmp = nftnl_expr_meta_cmp, + .set = nftnl_expr_meta_set, + .get = nftnl_expr_meta_get, + .parse = nftnl_expr_meta_parse, +diff --git a/src/expr/nat.c b/src/expr/nat.c +index 9271303..b28734c 100644 +--- a/src/expr/nat.c ++++ b/src/expr/nat.c +@@ -351,35 +351,10 @@ nftnl_expr_nat_snprintf(char *buf, size_t size, uint32_t type, + return -1; + } + +-static bool nftnl_expr_nat_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_nat *n1 = nftnl_expr_data(e1); +- struct nftnl_expr_nat *n2 = nftnl_expr_data(e2); +- bool eq = true; +- if (e1->flags & (1 << NFTNL_EXPR_NAT_REG_ADDR_MIN)) +- eq &= (n1->sreg_addr_min == n2->sreg_addr_min); +- if (e1->flags & (1 << NFTNL_EXPR_NAT_REG_ADDR_MAX)) +- eq &= (n1->sreg_addr_max == n2->sreg_addr_max); +- if (e1->flags & (1 << NFTNL_EXPR_NAT_REG_PROTO_MIN)) +- eq &= (n1->sreg_proto_min == n2->sreg_proto_min); +- if (e1->flags & (1 << NFTNL_EXPR_NAT_REG_PROTO_MAX)) +- eq &= (n1->sreg_proto_max == n2->sreg_proto_max); +- if (e1->flags & (1 << NFTNL_EXPR_NAT_FAMILY)) +- eq &= (n1->family == n2->family); +- if (e1->flags & (1 << NFTNL_EXPR_NAT_TYPE)) +- eq &= (n1->type == n2->type); +- if (e1->flags & (1 << NFTNL_EXPR_NAT_FLAGS)) +- eq &= (n1->flags == n2->flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_nat = { + .name = "nat", + .alloc_len = sizeof(struct nftnl_expr_nat), + .max_attr = NFTA_NAT_MAX, +- .cmp = nftnl_expr_nat_cmp, + .set = nftnl_expr_nat_set, + .get = nftnl_expr_nat_get, + .parse = nftnl_expr_nat_parse, +diff --git a/src/expr/numgen.c b/src/expr/numgen.c +index 5336fde..1cfb839 100644 +--- a/src/expr/numgen.c ++++ b/src/expr/numgen.c +@@ -281,34 +281,10 @@ nftnl_expr_ng_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_ng_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_ng *n1 = nftnl_expr_data(e1); +- struct nftnl_expr_ng *n2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_NG_DREG)) +- eq &= (n1->dreg == n2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_NG_MODULUS)) +- eq &= (n1->modulus == n2->modulus); +- if (e1->flags & (1 << NFTNL_EXPR_NG_TYPE)) +- eq &= (n1->type == n2->type); +- if (e1->flags & (1 << NFTNL_EXPR_NG_OFFSET)) +- eq &= (n1->offset == n2->offset); +- if (e1->flags & (1 << NFTNL_EXPR_NG_SET_NAME)) +- eq &= !strcmp(n1->map.name, n2->map.name); +- if (e1->flags & (1 << NFTNL_EXPR_NG_SET_ID)) +- eq &= (n1->map.id == n2->map.id); +- +- return eq; +-} +- + struct expr_ops expr_ops_ng = { + .name = "numgen", + .alloc_len = sizeof(struct nftnl_expr_ng), + .max_attr = NFTA_NG_MAX, +- .cmp = nftnl_expr_ng_cmp, + .set = nftnl_expr_ng_set, + .get = nftnl_expr_ng_get, + .parse = nftnl_expr_ng_parse, +diff --git a/src/expr/objref.c b/src/expr/objref.c +index 64ee863..10ae8b8 100644 +--- a/src/expr/objref.c ++++ b/src/expr/objref.c +@@ -248,32 +248,10 @@ static int nftnl_expr_objref_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_objref_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_objref *c1 = nftnl_expr_data(e1); +- struct nftnl_expr_objref *c2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_OBJREF_IMM_TYPE)) +- eq &= (c1->imm.type == c2->imm.type); +- if (e1->flags & (1 << NFTNL_EXPR_OBJREF_IMM_NAME)) +- eq &= !strcmp(c1->imm.name, c2->imm.name); +- if (e1->flags & (1 << NFTNL_EXPR_OBJREF_SET_SREG)) +- eq &= (c1->set.sreg == c2->set.sreg); +- if (e1->flags & (1 << NFTNL_EXPR_OBJREF_SET_NAME)) +- eq &= !strcmp(c1->set.name, c2->set.name); +- if (e1->flags & (1 << NFTNL_EXPR_OBJREF_SET_ID)) +- eq &= (c1->set.id == c2->set.id); +- +- return eq; +-} +- + struct expr_ops expr_ops_objref = { + .name = "objref", + .alloc_len = sizeof(struct nftnl_expr_objref), + .max_attr = NFTA_OBJREF_MAX, +- .cmp = nftnl_expr_objref_cmp, + .set = nftnl_expr_objref_set, + .get = nftnl_expr_objref_get, + .parse = nftnl_expr_objref_parse, +diff --git a/src/expr/payload.c b/src/expr/payload.c +index 91e1587..d9866d1 100644 +--- a/src/expr/payload.c ++++ b/src/expr/payload.c +@@ -312,38 +312,10 @@ nftnl_expr_payload_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_payload_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_payload *p1 = nftnl_expr_data(e1); +- struct nftnl_expr_payload *p2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_SREG)) +- eq &= (p1->sreg == p2->sreg); +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_DREG)) +- eq &= (p1->dreg == p2->dreg); +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_BASE)) +- eq &= (p1->base == p2->base); +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_OFFSET)) +- eq &= (p1->offset == p2->offset); +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_LEN)) +- eq &= (p1->len == p2->len); +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_CSUM_TYPE)) +- eq &= (p1->csum_type == p2->csum_type); +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_CSUM_OFFSET)) +- eq &= (p1->csum_offset == p2->csum_offset); +- if (e1->flags & (1 << NFTNL_EXPR_PAYLOAD_FLAGS)) +- eq &= (p1->csum_flags == p2->csum_flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_payload = { + .name = "payload", + .alloc_len = sizeof(struct nftnl_expr_payload), + .max_attr = NFTA_PAYLOAD_MAX, +- .cmp = nftnl_expr_payload_cmp, + .set = nftnl_expr_payload_set, + .get = nftnl_expr_payload_get, + .parse = nftnl_expr_payload_parse, +diff --git a/src/expr/queue.c b/src/expr/queue.c +index a392a27..c832c58 100644 +--- a/src/expr/queue.c ++++ b/src/expr/queue.c +@@ -247,30 +247,10 @@ nftnl_expr_queue_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_queue_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_queue *q1 = nftnl_expr_data(e1); +- struct nftnl_expr_queue *q2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_QUEUE_NUM)) +- eq &= (q1->queuenum == q2->queuenum); +- if (e1->flags & (1 << NFTNL_EXPR_QUEUE_TOTAL)) +- eq &= (q1->queues_total == q2->queues_total); +- if (e1->flags & (1 << NFTNL_EXPR_QUEUE_FLAGS)) +- eq &= (q1->flags == q2->flags); +- if (e1->flags & (1 << NFTNL_EXPR_QUEUE_SREG_QNUM)) +- eq &= (q1->sreg_qnum == q2->sreg_qnum); +- +- return eq; +-} +- + struct expr_ops expr_ops_queue = { + .name = "queue", + .alloc_len = sizeof(struct nftnl_expr_queue), + .max_attr = NFTA_QUEUE_MAX, +- .cmp = nftnl_expr_queue_cmp, + .set = nftnl_expr_queue_set, + .get = nftnl_expr_queue_get, + .parse = nftnl_expr_queue_parse, +diff --git a/src/expr/redir.c b/src/expr/redir.c +index b2aa345..9ebee2f 100644 +--- a/src/expr/redir.c ++++ b/src/expr/redir.c +@@ -216,28 +216,10 @@ nftnl_expr_redir_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_redir_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_redir *r1 = nftnl_expr_data(e1); +- struct nftnl_expr_redir *r2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_REDIR_REG_PROTO_MIN)) +- eq &= (r1->sreg_proto_min== r2->sreg_proto_min); +- if (e1->flags & (1 << NFTNL_EXPR_REDIR_REG_PROTO_MAX)) +- eq &= (r1->sreg_proto_max== r2->sreg_proto_max); +- if (e1->flags & (1 << NFTNL_EXPR_REDIR_FLAGS)) +- eq &= (r1->flags== r2->flags); +- +- return eq; +-} +- + struct expr_ops expr_ops_redir = { + .name = "redir", + .alloc_len = sizeof(struct nftnl_expr_redir), + .max_attr = NFTA_REDIR_MAX, +- .cmp = nftnl_expr_redir_cmp, + .set = nftnl_expr_redir_set, + .get = nftnl_expr_redir_get, + .parse = nftnl_expr_redir_parse, +diff --git a/src/expr/reject.c b/src/expr/reject.c +index 11d8b20..ac9f189 100644 +--- a/src/expr/reject.c ++++ b/src/expr/reject.c +@@ -176,26 +176,10 @@ nftnl_expr_reject_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_reject_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_reject *r1 = nftnl_expr_data(e1); +- struct nftnl_expr_reject *r2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_REJECT_TYPE)) +- eq &= (r1->type == r2->type); +- if (e1->flags & (1 << NFTNL_EXPR_REJECT_CODE)) +- eq &= (r1->icmp_code == r2->icmp_code); +- +- return eq; +-} +- + struct expr_ops expr_ops_reject = { + .name = "reject", + .alloc_len = sizeof(struct nftnl_expr_reject), + .max_attr = NFTA_REJECT_MAX, +- .cmp = nftnl_expr_reject_cmp, + .set = nftnl_expr_reject_set, + .get = nftnl_expr_reject_get, + .parse = nftnl_expr_reject_parse, +diff --git a/src/expr/rt.c b/src/expr/rt.c +index c3c92c7..a077c30 100644 +--- a/src/expr/rt.c ++++ b/src/expr/rt.c +@@ -211,26 +211,10 @@ nftnl_expr_rt_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_rt_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_rt *r1 = nftnl_expr_data(e1); +- struct nftnl_expr_rt *r2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_RT_KEY)) +- eq &= (r1->key == r2->key); +- if (e1->flags & (1 << NFTNL_EXPR_RT_DREG)) +- eq &= (r1->dreg == r2->dreg); +- +- return eq; +-} +- + struct expr_ops expr_ops_rt = { + .name = "rt", + .alloc_len = sizeof(struct nftnl_expr_rt), + .max_attr = NFTA_RT_MAX, +- .cmp = nftnl_expr_rt_cmp, + .set = nftnl_expr_rt_set, + .get = nftnl_expr_rt_get, + .parse = nftnl_expr_rt_parse, +diff --git a/src/expr/socket.c b/src/expr/socket.c +index db160a1..cdd6863 100644 +--- a/src/expr/socket.c ++++ b/src/expr/socket.c +@@ -180,26 +180,10 @@ nftnl_expr_socket_snprintf(char *buf, size_t len, uint32_t type, + return -1; + } + +-static bool nftnl_expr_socket_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_socket *r1 = nftnl_expr_data(e1); +- struct nftnl_expr_socket *r2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_SOCKET_KEY)) +- eq &= (r1->key == r2->key); +- if (e1->flags & (1 << NFTNL_EXPR_SOCKET_DREG)) +- eq &= (r1->dreg == r2->dreg); +- +- return eq; +-} +- + struct expr_ops expr_ops_socket = { + .name = "socket", + .alloc_len = sizeof(struct nftnl_expr_socket), + .max_attr = NFTA_SOCKET_MAX, +- .cmp = nftnl_expr_socket_cmp, + .set = nftnl_expr_socket_set, + .get = nftnl_expr_socket_get, + .parse = nftnl_expr_socket_parse, +diff --git a/src/expr/target.c b/src/expr/target.c +index ed4bf7d..246158b 100644 +--- a/src/expr/target.c ++++ b/src/expr/target.c +@@ -220,31 +220,11 @@ static void nftnl_expr_target_free(const struct nftnl_expr *e) + xfree(target->data); + } + +-static bool nftnl_expr_target_cmp(const struct nftnl_expr *e1, +- const struct nftnl_expr *e2) +-{ +- struct nftnl_expr_target *t1 = nftnl_expr_data(e1); +- struct nftnl_expr_target *t2 = nftnl_expr_data(e2); +- bool eq = true; +- +- if (e1->flags & (1 << NFTNL_EXPR_TG_NAME)) +- eq &= !strcmp(t1->name, t2->name); +- if (e1->flags & (1 << NFTNL_EXPR_TG_REV)) +- eq &= (t1->rev == t2->rev); +- if (e1->flags & (1 << NFTNL_EXPR_TG_INFO)) { +- eq &= (t1->data_len == t2->data_len); +- eq &= !memcmp(t1->data, t2->data, t1->data_len); +- } +- +- return eq; +-} +- + struct expr_ops expr_ops_target = { + .name = "target", + .alloc_len = sizeof(struct nftnl_expr_target), + .max_attr = NFTA_TARGET_MAX, + .free = nftnl_expr_target_free, +- .cmp = nftnl_expr_target_cmp, + .set = nftnl_expr_target_set, + .get = nftnl_expr_target_get, + .parse = nftnl_expr_target_parse, +diff --git a/src/libnftnl.map b/src/libnftnl.map +index 0d6b20c..89414f2 100644 +--- a/src/libnftnl.map ++++ b/src/libnftnl.map +@@ -1,4 +1,4 @@ +-LIBNFTNL_5 { ++LIBNFTNL_11 { + global: + nftnl_table_alloc; + nftnl_table_free; +@@ -271,9 +271,6 @@ global: + nftnl_udata_next; + nftnl_udata_parse; + +- nftnl_rule_cmp; +- nftnl_expr_cmp; +- + nftnl_obj_alloc; + nftnl_obj_free; + nftnl_obj_is_set; +@@ -307,14 +304,8 @@ global: + nftnl_obj_list_iter_next; + nftnl_obj_list_iter_destroy; + +-local: *; +-}; +- +-LIBNFTNL_6 { + nftnl_expr_fprintf; +-} LIBNFTNL_5; + +-LIBNFTNL_7 { + nftnl_flowtable_alloc; + nftnl_flowtable_free; + nftnl_flowtable_is_set; +@@ -341,8 +332,7 @@ LIBNFTNL_7 { + nftnl_flowtable_list_del; + nftnl_flowtable_list_foreach; + +-} LIBNFTNL_6; +- +-LIBNFTNL_8 { + nftnl_rule_list_insert_at; +-} LIBNFTNL_7; ++ ++local: *; ++}; +diff --git a/src/rule.c b/src/rule.c +index 146b06c..2c70420 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -913,37 +913,6 @@ void nftnl_expr_iter_destroy(struct nftnl_expr_iter *iter) + xfree(iter); + } + +-EXPORT_SYMBOL(nftnl_rule_cmp); +-bool nftnl_rule_cmp(const struct nftnl_rule *r1, const struct nftnl_rule *r2) +-{ +- struct nftnl_expr_iter it1, it2; +- struct nftnl_expr *e1, *e2; +- unsigned int eq = 1; +- +- if (r1->flags & r1->flags & (1 << NFTNL_RULE_TABLE)) +- eq &= !strcmp(r1->table, r2->table); +- if (r1->flags & r1->flags & (1 << NFTNL_RULE_CHAIN)) +- eq &= !strcmp(r1->chain, r2->chain); +- if (r1->flags & r1->flags & (1 << NFTNL_RULE_COMPAT_FLAGS)) +- eq &= (r1->compat.flags == r2->compat.flags); +- if (r1->flags & r1->flags & (1 << NFTNL_RULE_COMPAT_PROTO)) +- eq &= (r1->compat.proto == r2->compat.proto); +- +- nftnl_expr_iter_init(r1, &it1); +- nftnl_expr_iter_init(r2, &it2); +- e1 = nftnl_expr_iter_next(&it1); +- e2 = nftnl_expr_iter_next(&it2); +- while (eq && e1 && e2) { +- eq = nftnl_expr_cmp(e1, e2); +- +- e1 = nftnl_expr_iter_next(&it1); +- e2 = nftnl_expr_iter_next(&it2); +- } +- eq &= (!e1 && !e2); +- +- return eq; +-} +- + struct nftnl_rule_list { + struct list_head list; + }; +-- +1.8.3.1 + diff --git a/SOURCES/0002-chain-Support-per-chain-rules-list.patch b/SOURCES/0002-chain-Support-per-chain-rules-list.patch new file mode 100644 index 0000000..78ae08d --- /dev/null +++ b/SOURCES/0002-chain-Support-per-chain-rules-list.patch @@ -0,0 +1,313 @@ +From 8fcb95ed6dcd47c94a924b4018177d8a833d6983 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 17 Dec 2018 17:30:06 +0100 +Subject: [PATCH] chain: Support per chain rules list + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1658533 +Upstream Status: libnftnl commit e33798478176f + +commit e33798478176f97edf2649cd61444e0375fdc12b +Author: Phil Sutter +Date: Thu Dec 6 17:17:51 2018 +0100 + + chain: Support per chain rules list + + The implementation basically copies expr_list in struct nftnl_rule. + + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + include/internal.h | 1 + + include/libnftnl/chain.h | 15 +++++++ + include/rule.h | 26 ++++++++++++ + src/chain.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++- + src/libnftnl.map | 10 +++++ + src/rule.c | 22 ---------- + 6 files changed, 155 insertions(+), 23 deletions(-) + create mode 100644 include/rule.h + +diff --git a/include/internal.h b/include/internal.h +index 7e97c4a..323f825 100644 +--- a/include/internal.h ++++ b/include/internal.h +@@ -13,5 +13,6 @@ + #include "expr.h" + #include "expr_ops.h" + #include "buffer.h" ++#include "rule.h" + + #endif /* _LIBNFTNL_INTERNAL_H_ */ +diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h +index 237683e..f04f610 100644 +--- a/include/libnftnl/chain.h ++++ b/include/libnftnl/chain.h +@@ -13,6 +13,7 @@ extern "C" { + #endif + + struct nftnl_chain; ++struct nftnl_rule; + + struct nftnl_chain *nftnl_chain_alloc(void); + void nftnl_chain_free(const struct nftnl_chain *); +@@ -54,6 +55,10 @@ uint32_t nftnl_chain_get_u32(const struct nftnl_chain *c, uint16_t attr); + int32_t nftnl_chain_get_s32(const struct nftnl_chain *c, uint16_t attr); + uint64_t nftnl_chain_get_u64(const struct nftnl_chain *c, uint16_t attr); + ++void nftnl_chain_rule_add(struct nftnl_rule *rule, struct nftnl_chain *c); ++void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c); ++void nftnl_chain_rule_insert_at(struct nftnl_rule *rule, struct nftnl_rule *pos); ++ + struct nlmsghdr; + + void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_chain *t); +@@ -68,6 +73,16 @@ int nftnl_chain_fprintf(FILE *fp, const struct nftnl_chain *c, uint32_t type, ui + #define nftnl_chain_nlmsg_build_hdr nftnl_nlmsg_build_hdr + int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *t); + ++int nftnl_rule_foreach(struct nftnl_chain *c, ++ int (*cb)(struct nftnl_rule *r, void *data), ++ void *data); ++ ++struct nftnl_rule_iter; ++ ++struct nftnl_rule_iter *nftnl_rule_iter_create(const struct nftnl_chain *c); ++struct nftnl_rule *nftnl_rule_iter_next(struct nftnl_rule_iter *iter); ++void nftnl_rule_iter_destroy(struct nftnl_rule_iter *iter); ++ + struct nftnl_chain_list; + + struct nftnl_chain_list *nftnl_chain_list_alloc(void); +diff --git a/include/rule.h b/include/rule.h +new file mode 100644 +index 0000000..5edcb6c +--- /dev/null ++++ b/include/rule.h +@@ -0,0 +1,26 @@ ++#ifndef _LIBNFTNL_RULE_INTERNAL_H_ ++#define _LIBNFTNL_RULE_INTERNAL_H_ ++ ++struct nftnl_rule { ++ struct list_head head; ++ ++ uint32_t flags; ++ uint32_t family; ++ const char *table; ++ const char *chain; ++ uint64_t handle; ++ uint64_t position; ++ uint32_t id; ++ struct { ++ void *data; ++ uint32_t len; ++ } user; ++ struct { ++ uint32_t flags; ++ uint32_t proto; ++ } compat; ++ ++ struct list_head expr_list; ++}; ++ ++#endif +diff --git a/src/chain.c b/src/chain.c +index eff5186..c374923 100644 +--- a/src/chain.c ++++ b/src/chain.c +@@ -27,6 +27,7 @@ + #include + + #include ++#include + #include + + struct nftnl_chain { +@@ -45,6 +46,8 @@ struct nftnl_chain { + uint64_t bytes; + uint64_t handle; + uint32_t flags; ++ ++ struct list_head rule_list; + }; + + static const char *nftnl_hooknum2str(int family, int hooknum) +@@ -90,12 +93,25 @@ static const char *nftnl_hooknum2str(int family, int hooknum) + EXPORT_SYMBOL(nftnl_chain_alloc); + struct nftnl_chain *nftnl_chain_alloc(void) + { +- return calloc(1, sizeof(struct nftnl_chain)); ++ struct nftnl_chain *c; ++ ++ c = calloc(1, sizeof(struct nftnl_chain)); ++ if (c == NULL) ++ return NULL; ++ ++ INIT_LIST_HEAD(&c->rule_list); ++ ++ return c; + } + + EXPORT_SYMBOL(nftnl_chain_free); + void nftnl_chain_free(const struct nftnl_chain *c) + { ++ struct nftnl_rule *r, *tmp; ++ ++ list_for_each_entry_safe(r, tmp, &c->rule_list, head) ++ nftnl_rule_free(r); ++ + if (c->flags & (1 << NFTNL_CHAIN_NAME)) + xfree(c->name); + if (c->flags & (1 << NFTNL_CHAIN_TABLE)) +@@ -406,6 +422,24 @@ void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ch + mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, c->type); + } + ++EXPORT_SYMBOL(nftnl_chain_rule_add); ++void nftnl_chain_rule_add(struct nftnl_rule *rule, struct nftnl_chain *c) ++{ ++ list_add(&rule->head, &c->rule_list); ++} ++ ++EXPORT_SYMBOL(nftnl_chain_rule_add_tail); ++void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c) ++{ ++ list_add_tail(&rule->head, &c->rule_list); ++} ++ ++EXPORT_SYMBOL(nftnl_chain_rule_insert_at); ++void nftnl_chain_rule_insert_at(struct nftnl_rule *rule, struct nftnl_rule *pos) ++{ ++ list_add(&rule->head, &pos->head); ++} ++ + static int nftnl_chain_parse_attr_cb(const struct nlattr *attr, void *data) + { + const struct nlattr **tb = data; +@@ -875,6 +909,74 @@ int nftnl_chain_fprintf(FILE *fp, const struct nftnl_chain *c, uint32_t type, + nftnl_chain_do_snprintf); + } + ++EXPORT_SYMBOL(nftnl_rule_foreach); ++int nftnl_rule_foreach(struct nftnl_chain *c, ++ int (*cb)(struct nftnl_rule *r, void *data), ++ void *data) ++{ ++ struct nftnl_rule *cur, *tmp; ++ int ret; ++ ++ list_for_each_entry_safe(cur, tmp, &c->rule_list, head) { ++ ret = cb(cur, data); ++ if (ret < 0) ++ return ret; ++ } ++ return 0; ++} ++ ++struct nftnl_rule_iter { ++ const struct nftnl_chain *c; ++ struct nftnl_rule *cur; ++}; ++ ++static void nftnl_rule_iter_init(const struct nftnl_chain *c, ++ struct nftnl_rule_iter *iter) ++{ ++ iter->c = c; ++ if (list_empty(&c->rule_list)) ++ iter->cur = NULL; ++ else ++ iter->cur = list_entry(c->rule_list.next, struct nftnl_rule, ++ head); ++} ++ ++EXPORT_SYMBOL(nftnl_rule_iter_create); ++struct nftnl_rule_iter *nftnl_rule_iter_create(const struct nftnl_chain *c) ++{ ++ struct nftnl_rule_iter *iter; ++ ++ iter = calloc(1, sizeof(struct nftnl_rule_iter)); ++ if (iter == NULL) ++ return NULL; ++ ++ nftnl_rule_iter_init(c, iter); ++ ++ return iter; ++} ++ ++EXPORT_SYMBOL(nftnl_rule_iter_next); ++struct nftnl_rule *nftnl_rule_iter_next(struct nftnl_rule_iter *iter) ++{ ++ struct nftnl_rule *rule = iter->cur; ++ ++ if (rule == NULL) ++ return NULL; ++ ++ /* get next rule, if any */ ++ iter->cur = list_entry(iter->cur->head.next, struct nftnl_rule, head); ++ if (&iter->cur->head == iter->c->rule_list.next) ++ return NULL; ++ ++ return rule; ++} ++ ++EXPORT_SYMBOL(nftnl_rule_iter_destroy); ++void nftnl_rule_iter_destroy(struct nftnl_rule_iter *iter) ++{ ++ xfree(iter); ++} ++ + struct nftnl_chain_list { + struct list_head list; + }; +diff --git a/src/libnftnl.map b/src/libnftnl.map +index 89414f2..96d5b5f 100644 +--- a/src/libnftnl.map ++++ b/src/libnftnl.map +@@ -336,3 +336,13 @@ global: + + local: *; + }; ++ ++LIBNFTNL_12 { ++ nftnl_chain_rule_add; ++ nftnl_chain_rule_add_tail; ++ nftnl_chain_rule_insert_at; ++ nftnl_rule_foreach; ++ nftnl_rule_iter_create; ++ nftnl_rule_iter_next; ++ nftnl_rule_iter_destroy; ++} LIBNFTNL_11; +diff --git a/src/rule.c b/src/rule.c +index 2c70420..6a43d3e 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -30,28 +30,6 @@ + #include + #include + +-struct nftnl_rule { +- struct list_head head; +- +- uint32_t flags; +- uint32_t family; +- const char *table; +- const char *chain; +- uint64_t handle; +- uint64_t position; +- uint32_t id; +- struct { +- void *data; +- uint32_t len; +- } user; +- struct { +- uint32_t flags; +- uint32_t proto; +- } compat; +- +- struct list_head expr_list; +-}; +- + EXPORT_SYMBOL(nftnl_rule_alloc); + struct nftnl_rule *nftnl_rule_alloc(void) + { +-- +1.8.3.1 + diff --git a/SOURCES/0003-chain-Add-lookup-functions-for-chain-list-and-rules-.patch b/SOURCES/0003-chain-Add-lookup-functions-for-chain-list-and-rules-.patch new file mode 100644 index 0000000..a3237a6 --- /dev/null +++ b/SOURCES/0003-chain-Add-lookup-functions-for-chain-list-and-rules-.patch @@ -0,0 +1,107 @@ +From 75b3a238485745de01cf6264703ba6c192d7f721 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 17 Dec 2018 17:30:06 +0100 +Subject: [PATCH] chain: Add lookup functions for chain list and rules in chain + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1658533 +Upstream Status: libnftnl commit 1a829ec0c3285 + +commit 1a829ec0c3285baac712352c3a046a4f76013e70 +Author: Phil Sutter +Date: Thu Dec 6 17:17:52 2018 +0100 + + chain: Add lookup functions for chain list and rules in chain + + For now, these lookup functions simply iterate over the linked list + until they find the right entry. In future, they may make use of more + optimized data structures behind the curtains. + + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + include/libnftnl/chain.h | 2 ++ + src/chain.c | 28 ++++++++++++++++++++++++++++ + src/libnftnl.map | 3 +++ + 3 files changed, 33 insertions(+) + +diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h +index f04f610..64e10e9 100644 +--- a/include/libnftnl/chain.h ++++ b/include/libnftnl/chain.h +@@ -76,6 +76,7 @@ int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *t); + int nftnl_rule_foreach(struct nftnl_chain *c, + int (*cb)(struct nftnl_rule *r, void *data), + void *data); ++struct nftnl_rule *nftnl_rule_lookup_byindex(struct nftnl_chain *c, uint32_t index); + + struct nftnl_rule_iter; + +@@ -89,6 +90,7 @@ struct nftnl_chain_list *nftnl_chain_list_alloc(void); + void nftnl_chain_list_free(struct nftnl_chain_list *list); + int nftnl_chain_list_is_empty(const struct nftnl_chain_list *list); + int nftnl_chain_list_foreach(struct nftnl_chain_list *chain_list, int (*cb)(struct nftnl_chain *t, void *data), void *data); ++struct nftnl_chain *nftnl_chain_list_lookup_byname(struct nftnl_chain_list *chain_list, const char *chain); + + void nftnl_chain_list_add(struct nftnl_chain *r, struct nftnl_chain_list *list); + void nftnl_chain_list_add_tail(struct nftnl_chain *r, struct nftnl_chain_list *list); +diff --git a/src/chain.c b/src/chain.c +index c374923..22bb45c 100644 +--- a/src/chain.c ++++ b/src/chain.c +@@ -925,6 +925,20 @@ int nftnl_rule_foreach(struct nftnl_chain *c, + return 0; + } + ++EXPORT_SYMBOL(nftnl_rule_lookup_byindex); ++struct nftnl_rule * ++nftnl_rule_lookup_byindex(struct nftnl_chain *c, uint32_t index) ++{ ++ struct nftnl_rule *r; ++ ++ list_for_each_entry(r, &c->rule_list, head) { ++ if (!index) ++ return r; ++ index--; ++ } ++ return NULL; ++} ++ + struct nftnl_rule_iter { + const struct nftnl_chain *c; + struct nftnl_rule *cur; +@@ -1047,6 +1061,20 @@ int nftnl_chain_list_foreach(struct nftnl_chain_list *chain_list, + return 0; + } + ++EXPORT_SYMBOL(nftnl_chain_list_lookup_byname); ++struct nftnl_chain * ++nftnl_chain_list_lookup_byname(struct nftnl_chain_list *chain_list, ++ const char *chain) ++{ ++ struct nftnl_chain *c; ++ ++ list_for_each_entry(c, &chain_list->list, head) { ++ if (!strcmp(chain, c->name)) ++ return c; ++ } ++ return NULL; ++} ++ + struct nftnl_chain_list_iter { + const struct nftnl_chain_list *list; + struct nftnl_chain *cur; +diff --git a/src/libnftnl.map b/src/libnftnl.map +index 96d5b5f..0d3be32 100644 +--- a/src/libnftnl.map ++++ b/src/libnftnl.map +@@ -345,4 +345,7 @@ LIBNFTNL_12 { + nftnl_rule_iter_create; + nftnl_rule_iter_next; + nftnl_rule_iter_destroy; ++ ++ nftnl_chain_list_lookup_byname; ++ nftnl_rule_lookup_byindex; + } LIBNFTNL_11; +-- +1.8.3.1 + diff --git a/SOURCES/0004-chain-Hash-chain-list-by-name.patch b/SOURCES/0004-chain-Hash-chain-list-by-name.patch new file mode 100644 index 0000000..a375cd5 --- /dev/null +++ b/SOURCES/0004-chain-Hash-chain-list-by-name.patch @@ -0,0 +1,143 @@ +From a3af0aff50cd3e899cb5205d4d5330a96aeffaa5 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 17 Dec 2018 17:30:06 +0100 +Subject: [PATCH] chain: Hash chain list by name + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1658533 +Upstream Status: libnftnl commit 7170f0929ef50 + +commit 7170f0929ef50a1a45d9fd5d058ea6178c8e56ef +Author: Phil Sutter +Date: Tue Dec 11 18:44:00 2018 +0100 + + chain: Hash chain list by name + + Introduce a hash table to speedup nftnl_chain_list_lookup_byname(). In + theory this could replace the linked list completely but has been left + in place so that nftnl_chain_list_add_tail() still does what it's + supposed to and iterators return chains in original order. + + Speed was tested using a simple script which creates a dump file + containing a number of custom chains and for each of them two rules in + INPUT chain jumping to it. The following table compares run-time of + iptables-legacy-restore with iptables-nft-restore before and after this + patch: + + count legacy nft-old nft-new + ---------------------------------------------- + 10000 26s 38s 31s + 50000 137s 339s 149s + + So while it is still not as quick, it now scales nicely (at least in + this very primitive test). + + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + src/chain.c | 30 +++++++++++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +diff --git a/src/chain.c b/src/chain.c +index 22bb45c..ae074fd 100644 +--- a/src/chain.c ++++ b/src/chain.c +@@ -32,6 +32,7 @@ + + struct nftnl_chain { + struct list_head head; ++ struct hlist_node hnode; + + const char *name; + const char *type; +@@ -991,20 +992,27 @@ void nftnl_rule_iter_destroy(struct nftnl_rule_iter *iter) + xfree(iter); + } + ++#define CHAIN_NAME_HSIZE 512 ++ + struct nftnl_chain_list { ++ + struct list_head list; ++ struct hlist_head name_hash[CHAIN_NAME_HSIZE]; + }; + + EXPORT_SYMBOL(nftnl_chain_list_alloc); + struct nftnl_chain_list *nftnl_chain_list_alloc(void) + { + struct nftnl_chain_list *list; ++ int i; + + list = calloc(1, sizeof(struct nftnl_chain_list)); + if (list == NULL) + return NULL; + + INIT_LIST_HEAD(&list->list); ++ for (i = 0; i < CHAIN_NAME_HSIZE; i++) ++ INIT_HLIST_HEAD(&list->name_hash[i]); + + return list; + } +@@ -1016,6 +1024,7 @@ void nftnl_chain_list_free(struct nftnl_chain_list *list) + + list_for_each_entry_safe(r, tmp, &list->list, head) { + list_del(&r->head); ++ hlist_del(&r->hnode); + nftnl_chain_free(r); + } + xfree(list); +@@ -1027,15 +1036,31 @@ int nftnl_chain_list_is_empty(const struct nftnl_chain_list *list) + return list_empty(&list->list); + } + ++static uint32_t djb_hash(const char *key) ++{ ++ uint32_t i, hash = 5381; ++ ++ for (i = 0; i < strlen(key); i++) ++ hash = ((hash << 5) + hash) + key[i]; ++ ++ return hash; ++} ++ + EXPORT_SYMBOL(nftnl_chain_list_add); + void nftnl_chain_list_add(struct nftnl_chain *r, struct nftnl_chain_list *list) + { ++ int key = djb_hash(r->name) % CHAIN_NAME_HSIZE; ++ ++ hlist_add_head(&r->hnode, &list->name_hash[key]); + list_add(&r->head, &list->list); + } + + EXPORT_SYMBOL(nftnl_chain_list_add_tail); + void nftnl_chain_list_add_tail(struct nftnl_chain *r, struct nftnl_chain_list *list) + { ++ int key = djb_hash(r->name) % CHAIN_NAME_HSIZE; ++ ++ hlist_add_head(&r->hnode, &list->name_hash[key]); + list_add_tail(&r->head, &list->list); + } + +@@ -1043,6 +1068,7 @@ EXPORT_SYMBOL(nftnl_chain_list_del); + void nftnl_chain_list_del(struct nftnl_chain *r) + { + list_del(&r->head); ++ hlist_del(&r->hnode); + } + + EXPORT_SYMBOL(nftnl_chain_list_foreach); +@@ -1066,9 +1092,11 @@ struct nftnl_chain * + nftnl_chain_list_lookup_byname(struct nftnl_chain_list *chain_list, + const char *chain) + { ++ int key = djb_hash(chain) % CHAIN_NAME_HSIZE; + struct nftnl_chain *c; ++ struct hlist_node *n; + +- list_for_each_entry(c, &chain_list->list, head) { ++ hlist_for_each_entry(c, n, &chain_list->name_hash[key], hnode) { + if (!strcmp(chain, c->name)) + return c; + } +-- +1.8.3.1 + diff --git a/SOURCES/0005-object-Avoid-obj_ops-array-overrun.patch b/SOURCES/0005-object-Avoid-obj_ops-array-overrun.patch new file mode 100644 index 0000000..c9bedc1 --- /dev/null +++ b/SOURCES/0005-object-Avoid-obj_ops-array-overrun.patch @@ -0,0 +1,40 @@ +From 34e115c1a9657f07ed8a39b81c6b21fba1faa319 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 29 Jan 2019 18:12:15 +0100 +Subject: [PATCH] object: Avoid obj_ops array overrun + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1661327 +Upstream Status: libnftnl commit 16c44d9f42170 + +commit 16c44d9f42170264c4d484478c76e940951f1b70 +Author: Phil Sutter +Date: Thu Dec 20 21:03:27 2018 +0100 + + object: Avoid obj_ops array overrun + + In version 1.1.1, obj_ops array was smaller than __NFT_OBJECT_MAX since + there are no ops for NFT_OBJECT_CONNLIMIT. Avoid this potential issue in + the future by defining the array size. + + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + src/object.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/object.c b/src/object.c +index d8278f3..7fb9bab 100644 +--- a/src/object.c ++++ b/src/object.c +@@ -25,7 +25,7 @@ + #include + #include "obj.h" + +-static struct obj_ops *obj_ops[] = { ++static struct obj_ops *obj_ops[__NFT_OBJECT_MAX] = { + [NFT_OBJECT_COUNTER] = &obj_ops_counter, + [NFT_OBJECT_QUOTA] = &obj_ops_quota, + [NFT_OBJECT_CT_HELPER] = &obj_ops_ct_helper, +-- +1.8.3.1 + diff --git a/SOURCES/0006-flowtable-Add-missing-break.patch b/SOURCES/0006-flowtable-Add-missing-break.patch new file mode 100644 index 0000000..2492fff --- /dev/null +++ b/SOURCES/0006-flowtable-Add-missing-break.patch @@ -0,0 +1,40 @@ +From d3d9966d79cc7d6d11124302dd06b7d7522e7305 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 29 Jan 2019 18:12:15 +0100 +Subject: [PATCH] flowtable: Add missing break + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1661327 +Upstream Status: libnftnl commit 404ef7222d055 + +commit 404ef7222d055aacdbd4d73dc0d8731fa8f6cbe4 +Author: Phil Sutter +Date: Thu Dec 20 21:03:28 2018 +0100 + + flowtable: Add missing break + + In nftnl_flowtable_set_data(), when setting flowtable size, the switch() + case fell through and the same value was copied into ft_flags field. + This can't be right. + + Fixes: 41fe3d38ba34b ("flowtable: support for flags") + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + src/flowtable.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/flowtable.c b/src/flowtable.c +index c1ddae4..aa6ce59 100644 +--- a/src/flowtable.c ++++ b/src/flowtable.c +@@ -163,6 +163,7 @@ int nftnl_flowtable_set_data(struct nftnl_flowtable *c, uint16_t attr, + break; + case NFTNL_FLOWTABLE_SIZE: + memcpy(&c->size, data, sizeof(c->size)); ++ break; + case NFTNL_FLOWTABLE_FLAGS: + memcpy(&c->ft_flags, data, sizeof(c->ft_flags)); + break; +-- +1.8.3.1 + diff --git a/SOURCES/0007-flowtable-Fix-use-after-free-in-two-spots.patch b/SOURCES/0007-flowtable-Fix-use-after-free-in-two-spots.patch new file mode 100644 index 0000000..97b3e24 --- /dev/null +++ b/SOURCES/0007-flowtable-Fix-use-after-free-in-two-spots.patch @@ -0,0 +1,57 @@ +From 0d3f59cbe70f55f220fafd1ffff043a35a0d4503 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 29 Jan 2019 18:12:15 +0100 +Subject: [PATCH] flowtable: Fix use after free in two spots + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1661327 +Upstream Status: libnftnl commit 822dc96815e96 + +commit 822dc96815e96465822ce4b1187c4b29c06cb7c1 +Author: Phil Sutter +Date: Thu Dec 20 21:03:29 2018 +0100 + + flowtable: Fix use after free in two spots + + When freeing flowtable devices array, the loop freeing each device + string incorrectly included the call to free the device array itself. + + Fixes: eb58f53372e74 ("src: add flowtable support") + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + src/flowtable.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/flowtable.c b/src/flowtable.c +index aa6ce59..61ff29b 100644 +--- a/src/flowtable.c ++++ b/src/flowtable.c +@@ -85,10 +85,9 @@ void nftnl_flowtable_unset(struct nftnl_flowtable *c, uint16_t attr) + case NFTNL_FLOWTABLE_FLAGS: + break; + case NFTNL_FLOWTABLE_DEVICES: +- for (i = 0; i < c->dev_array_len; i++) { ++ for (i = 0; i < c->dev_array_len; i++) + xfree(c->dev_array[i]); +- xfree(c->dev_array); +- } ++ xfree(c->dev_array); + break; + default: + return; +@@ -146,10 +145,9 @@ int nftnl_flowtable_set_data(struct nftnl_flowtable *c, uint16_t attr, + len++; + + if (c->flags & (1 << NFTNL_FLOWTABLE_DEVICES)) { +- for (i = 0; i < c->dev_array_len; i++) { ++ for (i = 0; i < c->dev_array_len; i++) + xfree(c->dev_array[i]); +- xfree(c->dev_array); +- } ++ xfree(c->dev_array); + } + + c->dev_array = calloc(len + 1, sizeof(char *)); +-- +1.8.3.1 + diff --git a/SOURCES/0008-flowtable-Fix-memleak-in-nftnl_flowtable_parse_devs.patch b/SOURCES/0008-flowtable-Fix-memleak-in-nftnl_flowtable_parse_devs.patch new file mode 100644 index 0000000..fa7cb7b --- /dev/null +++ b/SOURCES/0008-flowtable-Fix-memleak-in-nftnl_flowtable_parse_devs.patch @@ -0,0 +1,62 @@ +From c3c2777d4b62db4b49fd3dcf8293562defa95112 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 29 Jan 2019 18:12:15 +0100 +Subject: [PATCH] flowtable: Fix memleak in nftnl_flowtable_parse_devs() + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1661327 +Upstream Status: libnftnl commit 8ef66870832d5 + +commit 8ef66870832d56881703a7798ecdff9e19917b15 +Author: Phil Sutter +Date: Thu Dec 20 21:03:30 2018 +0100 + + flowtable: Fix memleak in nftnl_flowtable_parse_devs() + + Allocated strings in dev_array were not freed. Fix this by freeing them + on error path and assigning them to c->dev_array directly in regular + path. + + Fixes: eb58f53372e74 ("src: add flowtable support") + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + src/flowtable.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/flowtable.c b/src/flowtable.c +index 61ff29b..1762bd1 100644 +--- a/src/flowtable.c ++++ b/src/flowtable.c +@@ -364,7 +364,7 @@ static int nftnl_flowtable_parse_devs(struct nlattr *nest, + + mnl_attr_for_each_nested(attr, nest) { + if (mnl_attr_get_type(attr) != NFTA_DEVICE_NAME) +- return -1; ++ goto err; + dev_array[len++] = strdup(mnl_attr_get_str(attr)); + if (len >= 8) + break; +@@ -375,14 +375,18 @@ static int nftnl_flowtable_parse_devs(struct nlattr *nest, + + c->dev_array = calloc(len + 1, sizeof(char *)); + if (!c->dev_array) +- return -1; ++ goto err; + + c->dev_array_len = len; + + for (i = 0; i < len; i++) +- c->dev_array[i] = strdup(dev_array[i]); ++ c->dev_array[i] = dev_array[i]; + + return 0; ++err: ++ while (len--) ++ xfree(dev_array[len]); ++ return -1; + } + + static int nftnl_flowtable_parse_hook(struct nlattr *attr, struct nftnl_flowtable *c) +-- +1.8.3.1 + diff --git a/SOURCES/0009-flowtable-Fix-for-reading-garbage.patch b/SOURCES/0009-flowtable-Fix-for-reading-garbage.patch new file mode 100644 index 0000000..1645358 --- /dev/null +++ b/SOURCES/0009-flowtable-Fix-for-reading-garbage.patch @@ -0,0 +1,49 @@ +From 4ec80cc7d08a48a19d112da760e36fa9e47e9106 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 29 Jan 2019 18:12:15 +0100 +Subject: [PATCH] flowtable: Fix for reading garbage + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1661327 +Upstream Status: libnftnl commit f8eed54150fd4 + +commit f8eed54150fd49ed814e63a5db39eda67d4b3938 +Author: Phil Sutter +Date: Thu Dec 20 21:03:31 2018 +0100 + + flowtable: Fix for reading garbage + + nftnl_flowtable_get_data() doesn't assign to passt data_len pointer + destination in all cases, so initialize it to 0. + + Fixes: eb58f53372e74 ("src: add flowtable support") + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + src/flowtable.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/flowtable.c b/src/flowtable.c +index 1762bd1..3c3ba66 100644 +--- a/src/flowtable.c ++++ b/src/flowtable.c +@@ -245,7 +245,7 @@ EXPORT_SYMBOL(nftnl_flowtable_get_str); + + uint32_t nftnl_flowtable_get_u32(const struct nftnl_flowtable *c, uint16_t attr) + { +- uint32_t data_len; ++ uint32_t data_len = 0; + const uint32_t *val = nftnl_flowtable_get_data(c, attr, &data_len); + + nftnl_assert(val, attr, data_len == sizeof(uint32_t)); +@@ -256,7 +256,7 @@ EXPORT_SYMBOL(nftnl_flowtable_get_u32); + + int32_t nftnl_flowtable_get_s32(const struct nftnl_flowtable *c, uint16_t attr) + { +- uint32_t data_len; ++ uint32_t data_len = 0; + const int32_t *val = nftnl_flowtable_get_data(c, attr, &data_len); + + nftnl_assert(val, attr, data_len == sizeof(int32_t)); +-- +1.8.3.1 + diff --git a/SOURCES/0010-src-chain-Add-missing-nftnl_chain_rule_del.patch b/SOURCES/0010-src-chain-Add-missing-nftnl_chain_rule_del.patch new file mode 100644 index 0000000..d764bff --- /dev/null +++ b/SOURCES/0010-src-chain-Add-missing-nftnl_chain_rule_del.patch @@ -0,0 +1,72 @@ +From 36faead4c4a8ab0a87ee766bab6a062e8610067a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 29 Jan 2019 18:14:56 +0100 +Subject: [PATCH] src: chain: Add missing nftnl_chain_rule_del() + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1666495 +Upstream Status: libnftnl commit de5a23d26828a + +commit de5a23d26828a1e1f2d3351b0414925857546496 +Author: Phil Sutter +Date: Sun Dec 30 17:02:13 2018 +0100 + + src: chain: Add missing nftnl_chain_rule_del() + + Although identical to nftnl_rule_list_del(), this function adheres to + the common naming style of per chain rule list routines introduced + earlier, therefore helps with deprecating the global rule list API at a + later point. + + Fixes: e33798478176f ("chain: Support per chain rules list") + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + include/libnftnl/chain.h | 1 + + src/chain.c | 6 ++++++ + src/libnftnl.map | 1 + + 3 files changed, 8 insertions(+) + +diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h +index 64e10e9..163a824 100644 +--- a/include/libnftnl/chain.h ++++ b/include/libnftnl/chain.h +@@ -56,6 +56,7 @@ int32_t nftnl_chain_get_s32(const struct nftnl_chain *c, uint16_t attr); + uint64_t nftnl_chain_get_u64(const struct nftnl_chain *c, uint16_t attr); + + void nftnl_chain_rule_add(struct nftnl_rule *rule, struct nftnl_chain *c); ++void nftnl_chain_rule_del(struct nftnl_rule *rule); + void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c); + void nftnl_chain_rule_insert_at(struct nftnl_rule *rule, struct nftnl_rule *pos); + +diff --git a/src/chain.c b/src/chain.c +index ae074fd..6dc8f36 100644 +--- a/src/chain.c ++++ b/src/chain.c +@@ -429,6 +429,12 @@ void nftnl_chain_rule_add(struct nftnl_rule *rule, struct nftnl_chain *c) + list_add(&rule->head, &c->rule_list); + } + ++EXPORT_SYMBOL(nftnl_chain_rule_del); ++void nftnl_chain_rule_del(struct nftnl_rule *r) ++{ ++ list_del(&r->head); ++} ++ + EXPORT_SYMBOL(nftnl_chain_rule_add_tail); + void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c) + { +diff --git a/src/libnftnl.map b/src/libnftnl.map +index 0d3be32..0dad6a2 100644 +--- a/src/libnftnl.map ++++ b/src/libnftnl.map +@@ -340,6 +340,7 @@ local: *; + LIBNFTNL_12 { + nftnl_chain_rule_add; + nftnl_chain_rule_add_tail; ++ nftnl_chain_rule_del; + nftnl_chain_rule_insert_at; + nftnl_rule_foreach; + nftnl_rule_iter_create; +-- +1.8.3.1 + diff --git a/SOURCES/0011-src-chain-Fix-nftnl_chain_rule_insert_at.patch b/SOURCES/0011-src-chain-Fix-nftnl_chain_rule_insert_at.patch new file mode 100644 index 0000000..607aaff --- /dev/null +++ b/SOURCES/0011-src-chain-Fix-nftnl_chain_rule_insert_at.patch @@ -0,0 +1,71 @@ +From fca027631250013cae7323e058575deb72b8510a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 29 Jan 2019 18:14:56 +0100 +Subject: [PATCH] src: chain: Fix nftnl_chain_rule_insert_at() + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1666495 +Upstream Status: libnftnl commit 278a3b779a731 + +commit 278a3b779a731b3565595259b07b9065f6a6f425 +Author: Phil Sutter +Date: Mon Jan 14 17:42:50 2019 +0100 + + src: chain: Fix nftnl_chain_rule_insert_at() + + Extrapolating from iptables nomenclature, one would expect that "insert" + means to prepend the new item to the referenced one, not append. Change + nftnl_chain_rule_insert_at() to do just that and introduce + nftnl_chain_rule_append_at() to insert a rule after the referenced one. + + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + include/libnftnl/chain.h | 1 + + src/chain.c | 6 ++++++ + src/libnftnl.map | 1 + + 3 files changed, 8 insertions(+) + +diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h +index 163a824..31b48cf 100644 +--- a/include/libnftnl/chain.h ++++ b/include/libnftnl/chain.h +@@ -59,6 +59,7 @@ void nftnl_chain_rule_add(struct nftnl_rule *rule, struct nftnl_chain *c); + void nftnl_chain_rule_del(struct nftnl_rule *rule); + void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c); + void nftnl_chain_rule_insert_at(struct nftnl_rule *rule, struct nftnl_rule *pos); ++void nftnl_chain_rule_append_at(struct nftnl_rule *rule, struct nftnl_rule *pos); + + struct nlmsghdr; + +diff --git a/src/chain.c b/src/chain.c +index 6dc8f36..7326c2a 100644 +--- a/src/chain.c ++++ b/src/chain.c +@@ -444,6 +444,12 @@ void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c) + EXPORT_SYMBOL(nftnl_chain_rule_insert_at); + void nftnl_chain_rule_insert_at(struct nftnl_rule *rule, struct nftnl_rule *pos) + { ++ list_add_tail(&rule->head, &pos->head); ++} ++ ++EXPORT_SYMBOL(nftnl_chain_rule_append_at); ++void nftnl_chain_rule_append_at(struct nftnl_rule *rule, struct nftnl_rule *pos) ++{ + list_add(&rule->head, &pos->head); + } + +diff --git a/src/libnftnl.map b/src/libnftnl.map +index 0dad6a2..192eef8 100644 +--- a/src/libnftnl.map ++++ b/src/libnftnl.map +@@ -342,6 +342,7 @@ LIBNFTNL_12 { + nftnl_chain_rule_add_tail; + nftnl_chain_rule_del; + nftnl_chain_rule_insert_at; ++ nftnl_chain_rule_append_at; + nftnl_rule_foreach; + nftnl_rule_iter_create; + nftnl_rule_iter_next; +-- +1.8.3.1 + diff --git a/SOURCES/0012-src-rule-Support-NFTA_RULE_POSITION_ID-attribute.patch b/SOURCES/0012-src-rule-Support-NFTA_RULE_POSITION_ID-attribute.patch new file mode 100644 index 0000000..6b47337 --- /dev/null +++ b/SOURCES/0012-src-rule-Support-NFTA_RULE_POSITION_ID-attribute.patch @@ -0,0 +1,150 @@ +From 3eb9b26b8b79b0bd5b153cfdad8eb10c86ae2b64 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 31 Jan 2019 19:03:53 +0100 +Subject: [PATCH] src: rule: Support NFTA_RULE_POSITION_ID attribute + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1670565 +Upstream Status: libnftnl commit 7a7137adf6c14 + +commit 7a7137adf6c143f7cccc6440a5340a43033b61e7 +Author: Phil Sutter +Date: Tue Jan 15 20:59:04 2019 +0100 + + src: rule: Support NFTA_RULE_POSITION_ID attribute + + Signed-off-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso +--- + include/libnftnl/rule.h | 1 + + include/linux/netfilter/nf_tables.h | 2 ++ + include/rule.h | 1 + + src/rule.c | 20 ++++++++++++++++++++ + 4 files changed, 24 insertions(+) + +diff --git a/include/libnftnl/rule.h b/include/libnftnl/rule.h +index 8501c86..78bfead 100644 +--- a/include/libnftnl/rule.h ++++ b/include/libnftnl/rule.h +@@ -28,6 +28,7 @@ enum nftnl_rule_attr { + NFTNL_RULE_POSITION, + NFTNL_RULE_USERDATA, + NFTNL_RULE_ID, ++ NFTNL_RULE_POSITION_ID, + __NFTNL_RULE_MAX + }; + #define NFTNL_RULE_MAX (__NFTNL_RULE_MAX - 1) +diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h +index 91449ef..adfae98 100644 +--- a/include/linux/netfilter/nf_tables.h ++++ b/include/linux/netfilter/nf_tables.h +@@ -218,6 +218,7 @@ enum nft_chain_attributes { + * @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64) + * @NFTA_RULE_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN) + * @NFTA_RULE_ID: uniquely identifies a rule in a transaction (NLA_U32) ++ * @NFTA_RULE_POSITION_ID: transaction unique identifier of the previous rule (NLA_U32) + */ + enum nft_rule_attributes { + NFTA_RULE_UNSPEC, +@@ -230,6 +231,7 @@ enum nft_rule_attributes { + NFTA_RULE_USERDATA, + NFTA_RULE_PAD, + NFTA_RULE_ID, ++ NFTA_RULE_POSITION_ID, + __NFTA_RULE_MAX + }; + #define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1) +diff --git a/include/rule.h b/include/rule.h +index 5edcb6c..036c722 100644 +--- a/include/rule.h ++++ b/include/rule.h +@@ -11,6 +11,7 @@ struct nftnl_rule { + uint64_t handle; + uint64_t position; + uint32_t id; ++ uint32_t position_id; + struct { + void *data; + uint32_t len; +diff --git a/src/rule.c b/src/rule.c +index 6a43d3e..d9b97b6 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -87,6 +87,7 @@ void nftnl_rule_unset(struct nftnl_rule *r, uint16_t attr) + case NFTNL_RULE_POSITION: + case NFTNL_RULE_FAMILY: + case NFTNL_RULE_ID: ++ case NFTNL_RULE_POSITION_ID: + break; + case NFTNL_RULE_USERDATA: + xfree(r->user.data); +@@ -103,6 +104,7 @@ static uint32_t nftnl_rule_validate[NFTNL_RULE_MAX + 1] = { + [NFTNL_RULE_FAMILY] = sizeof(uint32_t), + [NFTNL_RULE_POSITION] = sizeof(uint64_t), + [NFTNL_RULE_ID] = sizeof(uint32_t), ++ [NFTNL_RULE_POSITION_ID] = sizeof(uint32_t), + }; + + EXPORT_SYMBOL(nftnl_rule_set_data); +@@ -158,6 +160,9 @@ int nftnl_rule_set_data(struct nftnl_rule *r, uint16_t attr, + case NFTNL_RULE_ID: + r->id = *((uint32_t *)data); + break; ++ case NFTNL_RULE_POSITION_ID: ++ memcpy(&r->position_id, data, sizeof(r->position_id)); ++ break; + } + r->flags |= (1 << attr); + return 0; +@@ -222,6 +227,9 @@ const void *nftnl_rule_get_data(const struct nftnl_rule *r, uint16_t attr, + case NFTNL_RULE_ID: + *data_len = sizeof(uint32_t); + return &r->id; ++ case NFTNL_RULE_POSITION_ID: ++ *data_len = sizeof(uint32_t); ++ return &r->position_id; + } + return NULL; + } +@@ -313,6 +321,8 @@ void nftnl_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_rule *r) + } + if (r->flags & (1 << NFTNL_RULE_ID)) + mnl_attr_put_u32(nlh, NFTA_RULE_ID, htonl(r->id)); ++ if (r->flags & (1 << NFTNL_RULE_POSITION_ID)) ++ mnl_attr_put_u32(nlh, NFTA_RULE_POSITION_ID, htonl(r->position_id)); + } + + EXPORT_SYMBOL(nftnl_rule_add_expr); +@@ -352,6 +362,7 @@ static int nftnl_rule_parse_attr_cb(const struct nlattr *attr, void *data) + abi_breakage(); + break; + case NFTA_RULE_ID: ++ case NFTA_RULE_POSITION_ID: + if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) + abi_breakage(); + break; +@@ -483,6 +494,10 @@ int nftnl_rule_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_rule *r) + r->id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_ID])); + r->flags |= (1 << NFTNL_RULE_ID); + } ++ if (tb[NFTA_RULE_POSITION_ID]) { ++ r->position_id = ntohl(mnl_attr_get_u32(tb[NFTA_RULE_POSITION_ID])); ++ r->flags |= (1 << NFTNL_RULE_POSITION_ID); ++ } + + r->family = nfg->nfgen_family; + r->flags |= (1 << NFTNL_RULE_FAMILY); +@@ -729,6 +744,11 @@ static int nftnl_rule_snprintf_default(char *buf, size_t size, + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + } + ++ if (r->flags & (1 << NFTNL_RULE_POSITION_ID)) { ++ ret = snprintf(buf + offset, remain, "%u ", r->position_id); ++ SNPRINTF_BUFFER_SIZE(ret, remain, offset); ++ } ++ + ret = snprintf(buf + offset, remain, "\n"); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); + +-- +1.8.3.1 + diff --git a/SPECS/libnftnl.spec b/SPECS/libnftnl.spec new file mode 100644 index 0000000..f13138f --- /dev/null +++ b/SPECS/libnftnl.spec @@ -0,0 +1,189 @@ +%define rpmversion 1.1.1 +%define specrelease 4%{?dist} + +Name: libnftnl +Version: %{rpmversion} +Release: %{specrelease}%{?buildid} +Summary: Library for low-level interaction with nftables Netlink's API over libmnl +License: GPLv2+ +URL: http://netfilter.org/projects/libnftnl/ +Source0: http://ftp.netfilter.org/pub/libnftnl/libnftnl-%{version}.tar.bz2 +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool +BuildRequires: libmnl-devel +Patch0: 0001-src-remove-nftnl_rule_cmp-and-nftnl_expr_cmp.patch +Patch1: 0002-chain-Support-per-chain-rules-list.patch +Patch2: 0003-chain-Add-lookup-functions-for-chain-list-and-rules-.patch +Patch3: 0004-chain-Hash-chain-list-by-name.patch +Patch4: 0005-object-Avoid-obj_ops-array-overrun.patch +Patch5: 0006-flowtable-Add-missing-break.patch +Patch6: 0007-flowtable-Fix-use-after-free-in-two-spots.patch +Patch7: 0008-flowtable-Fix-memleak-in-nftnl_flowtable_parse_devs.patch +Patch8: 0009-flowtable-Fix-for-reading-garbage.patch +Patch9: 0010-src-chain-Add-missing-nftnl_chain_rule_del.patch +Patch10: 0011-src-chain-Fix-nftnl_chain_rule_insert_at.patch +Patch11: 0012-src-rule-Support-NFTA_RULE_POSITION_ID-attribute.patch + +%description +A library for low-level interaction with nftables Netlink's API over libmnl. + +%package devel +Summary: Development files for %{name} +Requires: %{name}%{_isa} = %{version}-%{release} + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + +%prep +%autosetup -p1 + +%build +# This is what autogen.sh (only in git repo) does - without it, patches changing +# Makefile.am cause the build system to regenerate Makefile.in and trying to use +# automake-1.14 for that which is not available in RHEL. +autoreconf -fi +rm -rf autom4te*.cache + +%configure --disable-static --disable-silent-rules +make %{?_smp_mflags} + +%check +make %{?_smp_mflags} check +cd tests +# JSON parsing would fail since it's not compiled in, so disable here +sed -i -e '/^\.\/nft-parsing-test /d' test-script.sh +sh ./test-script.sh + +%install +%make_install +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%doc COPYING +%{_libdir}/*.so.* + +%files devel +%{_libdir}/libnft*.so +%{_libdir}/pkgconfig/libnftnl.pc +%{_includedir}/libnftnl + +%changelog +* Thu Jan 31 2019 Phil Sutter [1.1.1-4.el8] +- src: rule: Support NFTA_RULE_POSITION_ID attribute (Phil Sutter) [1670565] + +* Tue Jan 29 2019 Phil Sutter [1.1.1-3.el8] +- src: chain: Fix nftnl_chain_rule_insert_at() (Phil Sutter) [1666495] +- src: chain: Add missing nftnl_chain_rule_del() (Phil Sutter) [1666495] +- flowtable: Fix for reading garbage (Phil Sutter) [1661327] +- flowtable: Fix memleak in nftnl_flowtable_parse_devs() (Phil Sutter) [1661327] +- flowtable: Fix use after free in two spots (Phil Sutter) [1661327] +- flowtable: Add missing break (Phil Sutter) [1661327] +- object: Avoid obj_ops array overrun (Phil Sutter) [1661327] + +* Mon Dec 17 2018 Phil Sutter [1.1.1-2.el8] +- chain: Hash chain list by name (Phil Sutter) [1658533] +- chain: Add lookup functions for chain list and rules in chain (Phil Sutter) [1658533] +- chain: Support per chain rules list (Phil Sutter) [1658533] +- src: remove nftnl_rule_cmp() and nftnl_expr_cmp() (Phil Sutter) [1658533] + +* Thu Jul 12 2018 Phil Sutter [1.1.1-1.el8] +- Rebase onto upstream version 1.1.1 +- Sync spec file with RHEL7 +- Disable JSON parsing, deprecated by upstream +- Make use of builtin testsuite + +* Sat Jun 23 2018 Phil Sutter - 1.0.9-3 +- Drop leftover mxml dependency [1594917] + +* Wed Feb 07 2018 Fedora Release Engineering - 1.0.9-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Jan 08 2018 Kevin Fenzi - 1.0.9-1 +- Update to 1.0.9. Fixes bug #1531004 + +* Sat Oct 21 2017 Kevin Fenzi - 1.0.8-4 +- Update to 1.0.8. Fixes bug #1504350 + +* Thu Aug 03 2017 Fedora Release Engineering - 1.0.7-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1.0.7-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 1.0.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Dec 22 2016 Kevin Fenzi - 1.0.7-1 +- Update to 1.0.7. Fixes bug #1406201 + +* Wed Jun 01 2016 Kevin Fenzi - 1.0.6-1 +- Update to 1.0.6. Fixes bug #1341384 + +* Thu Feb 04 2016 Fedora Release Engineering - 1.0.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Sep 17 2015 Kevin Fenzi 1.0.5-1 +- Update to 1.0.5. Fixes bug #1263684 + +* Wed Jun 17 2015 Fedora Release Engineering - 1.0.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Dec 26 2014 Kevin Fenzi 1.0.3-1 +- Update to final 1.0.3 + +* Wed Sep 03 2014 Kevin Fenzi 1.0.3-0.1.20140903git +- Update to 20140903 git snapshot + +* Sun Aug 17 2014 Fedora Release Engineering - 1.0.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Wed Jun 25 2014 Kevin Fenzi 1.0.2-1 +- Update to 1.0.2 + +* Sat Jun 07 2014 Fedora Release Engineering - 1.0.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu Apr 24 2014 Kevin Fenzi 1.0.1-1. +- Update to 1.0.1 + +* Sun Mar 30 2014 Kevin Fenzi 1.0.0-1.20140330git +- Update to 20140330 snapshot +- Sync version to be a post 1.0.0 snapshot + +* Wed Mar 26 2014 Kevin Fenzi 0-0.10.20140326git +- Update to 20140326 snapshot + +* Fri Mar 07 2014 Kevin Fenzi 0-0.9.20140307git +- Update to 20140307 snapshot + +* Sat Jan 25 2014 Kevin Fenzi 0-0.8.20140125git +- Update to 20140125 + +* Thu Jan 23 2014 Kevin Fenzi 0-0.7.20140122git +- Add obsoletes/provides to devel subpackage as well. + +* Wed Jan 22 2014 Kevin Fenzi 0-0.6.20140122git +- Renamed libnftnl +- Update to 20140122 snapshot. + +* Sat Jan 18 2014 Kevin Fenzi 0-0.5.20140118git +- Update to 20140118 snapshot. + +* Sat Jan 11 2014 Kevin Fenzi 0-0.4.20140111git +- Update to 20140111 snapshot. +- Enable xml (some tests stll fail, but it otherwise builds ok) + +* Mon Dec 02 2013 Kevin Fenzi 0-0.3.20131202git +- Update to 20131202 snapshot, switch to upstream snapshot repo instead of git checkouts. + +* Mon Dec 02 2013 Kevin Fenzi 0-0.2 +- Fixes from review. + +* Sat Nov 30 2013 Kevin Fenzi 0-0.1 +- initial version for Fedora review