Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libnftnl for openSUSE:Factory 
checked in at 2021-01-19 15:59:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libnftnl (Old)
 and      /work/SRC/openSUSE:Factory/.libnftnl.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libnftnl"

Tue Jan 19 15:59:39 2021 rev:20 rq:863413 version:1.1.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/libnftnl/libnftnl.changes        2020-10-30 
11:46:15.165632147 +0100
+++ /work/SRC/openSUSE:Factory/.libnftnl.new.28504/libnftnl.changes     
2021-01-19 16:00:04.887188342 +0100
@@ -1,0 +2,6 @@
+Fri Jan 15 21:17:24 UTC 2021 - Jan Engelhardt <jeng...@inai.de>
+
+- Update to release 1.1.9
+  * Improve formatting of registers in bitwise dumps.
+
+-------------------------------------------------------------------

Old:
----
  libnftnl-1.1.8.tar.bz2
  libnftnl-1.1.8.tar.bz2.sig

New:
----
  libnftnl-1.1.9.tar.bz2
  libnftnl-1.1.9.tar.bz2.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libnftnl.spec ++++++
--- /var/tmp/diff_new_pack.LBRcKC/_old  2021-01-19 16:00:05.543189334 +0100
+++ /var/tmp/diff_new_pack.LBRcKC/_new  2021-01-19 16:00:05.547189340 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package libnftnl
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 Name:           libnftnl
 %define lname  libnftnl11
-Version:        1.1.8
+Version:        1.1.9
 Release:        0
 Summary:        Userspace library to access the nftables Netlink interface
 License:        GPL-2.0-or-later

++++++ libnftnl-1.1.8.tar.bz2 -> libnftnl-1.1.9.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/Make_global.am 
new/libnftnl-1.1.9/Make_global.am
--- old/libnftnl-1.1.8/Make_global.am   2020-10-27 10:38:31.761284274 +0100
+++ new/libnftnl-1.1.9/Make_global.am   2021-01-15 16:59:36.452340321 +0100
@@ -18,7 +18,7 @@
 # set age to 0.
 # </snippet>
 #
-LIBVERSION=15:0:4
+LIBVERSION=16:0:5
 
 AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS} 
${LIBMXML_CFLAGS}
 AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/Makefile.in 
new/libnftnl-1.1.9/Makefile.in
--- old/libnftnl-1.1.8/Makefile.in      2020-10-27 10:38:44.801262201 +0100
+++ new/libnftnl-1.1.9/Makefile.in      2021-01-15 16:59:48.864331483 +0100
@@ -387,7 +387,7 @@
 # set age to 0.
 # </snippet>
 #
-LIBVERSION = 15:0:4
+LIBVERSION = 16:0:5
 AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS} 
${LIBMXML_CFLAGS}
 AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}
 ACLOCAL_AMFLAGS = -I m4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/configure new/libnftnl-1.1.9/configure
--- old/libnftnl-1.1.8/configure        2020-10-27 10:38:42.161266665 +0100
+++ new/libnftnl-1.1.9/configure        2021-01-15 16:59:46.412333237 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libnftnl 1.1.8.
+# Generated by GNU Autoconf 2.69 for libnftnl 1.1.9.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@
 # Identity of this package.
 PACKAGE_NAME='libnftnl'
 PACKAGE_TARNAME='libnftnl'
-PACKAGE_VERSION='1.1.8'
-PACKAGE_STRING='libnftnl 1.1.8'
+PACKAGE_VERSION='1.1.9'
+PACKAGE_STRING='libnftnl 1.1.9'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1333,7 +1333,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libnftnl 1.1.8 to adapt to many kinds of systems.
+\`configure' configures libnftnl 1.1.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1404,7 +1404,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libnftnl 1.1.8:";;
+     short | recursive ) echo "Configuration of libnftnl 1.1.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1522,7 +1522,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libnftnl configure 1.1.8
+libnftnl configure 1.1.9
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1800,7 +1800,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libnftnl $as_me 1.1.8, which was
+It was created by libnftnl $as_me 1.1.9, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3821,7 +3821,7 @@
 
 # Define the identity of the package.
  PACKAGE='libnftnl'
- VERSION='1.1.8'
+ VERSION='1.1.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13577,7 +13577,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libnftnl $as_me 1.1.8, which was
+This file was extended by libnftnl $as_me 1.1.9, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -13643,7 +13643,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-libnftnl config.status 1.1.8
+libnftnl config.status 1.1.9
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/configure.ac 
new/libnftnl-1.1.9/configure.ac
--- old/libnftnl-1.1.8/configure.ac     2020-10-27 10:38:31.761284274 +0100
+++ new/libnftnl-1.1.9/configure.ac     2021-01-15 16:59:36.456340319 +0100
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to create configure.
 
-AC_INIT([libnftnl], [1.1.8])
+AC_INIT([libnftnl], [1.1.9])
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CANONICAL_HOST
 AC_CONFIG_MACRO_DIR([m4])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/examples/Makefile.in 
new/libnftnl-1.1.9/examples/Makefile.in
--- old/libnftnl-1.1.8/examples/Makefile.in     2020-10-27 10:38:44.897262038 
+0100
+++ new/libnftnl-1.1.9/examples/Makefile.in     2021-01-15 16:59:48.972331406 
+0100
@@ -538,7 +538,7 @@
 # set age to 0.
 # </snippet>
 #
-LIBVERSION = 15:0:4
+LIBVERSION = 16:0:5
 AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS} 
${LIBMXML_CFLAGS}
 AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}
 nft_table_add_SOURCES = nft-table-add.c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/include/data_reg.h 
new/libnftnl-1.1.9/include/data_reg.h
--- old/libnftnl-1.1.8/include/data_reg.h       2020-10-27 10:38:31.785284233 
+0100
+++ new/libnftnl-1.1.9/include/data_reg.h       2021-01-15 16:59:36.468340310 
+0100
@@ -13,6 +13,10 @@
        DATA_CHAIN,
 };
 
+enum {
+       DATA_F_NOPFX = 1 << 0,
+};
+
 union nftnl_data_reg {
        struct {
                uint32_t        val[NFT_DATA_VALUE_MAXLEN / sizeof(uint32_t)];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/include/expr_ops.h 
new/libnftnl-1.1.9/include/expr_ops.h
--- old/libnftnl-1.1.8/include/expr_ops.h       2020-10-27 10:38:31.785284233 
+0100
+++ new/libnftnl-1.1.9/include/expr_ops.h       2021-01-15 16:59:36.468340310 
+0100
@@ -12,6 +12,7 @@
        const char *name;
        uint32_t alloc_len;
        int     max_attr;
+       void    (*init)(const struct nftnl_expr *e);
        void    (*free)(const struct nftnl_expr *e);
        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);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/include/libnftnl/expr.h 
new/libnftnl-1.1.9/include/libnftnl/expr.h
--- old/libnftnl-1.1.8/include/libnftnl/expr.h  2020-10-27 10:38:31.789284226 
+0100
+++ new/libnftnl-1.1.9/include/libnftnl/expr.h  2021-01-15 16:59:36.476340304 
+0100
@@ -38,6 +38,12 @@
 
 void nftnl_expr_build_payload(struct nlmsghdr *nlh, struct nftnl_expr *expr);
 
+/* For dynset expressions. */
+void nftnl_expr_add_expr(struct nftnl_expr *expr, uint32_t type, struct 
nftnl_expr *e);
+int nftnl_expr_expr_foreach(const struct nftnl_expr *e,
+                           int (*cb)(struct nftnl_expr *e, void *data),
+                           void *data);
+
 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);
 
@@ -167,6 +173,8 @@
        NFTNL_EXPR_DYNSET_SET_NAME,
        NFTNL_EXPR_DYNSET_SET_ID,
        NFTNL_EXPR_DYNSET_EXPR,
+       NFTNL_EXPR_DYNSET_EXPRESSIONS,
+       NFTNL_EXPR_DYNSET_FLAGS,
 };
 
 enum {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/include/libnftnl/set.h 
new/libnftnl-1.1.9/include/libnftnl/set.h
--- old/libnftnl-1.1.8/include/libnftnl/set.h   2020-10-27 10:38:31.793284218 
+0100
+++ new/libnftnl-1.1.9/include/libnftnl/set.h   2021-01-15 16:59:36.476340304 
+0100
@@ -31,6 +31,7 @@
        NFTNL_SET_HANDLE,
        NFTNL_SET_DESC_CONCAT,
        NFTNL_SET_EXPR,
+       NFTNL_SET_EXPRESSIONS,
        __NFTNL_SET_MAX
 };
 #define NFTNL_SET_MAX (__NFTNL_SET_MAX - 1)
@@ -80,6 +81,12 @@
 struct nftnl_set *nftnl_set_list_lookup_byname(struct nftnl_set_list *set_list,
                                               const char *set);
 
+struct nftnl_expr;
+void nftnl_set_add_expr(struct nftnl_set *s, struct nftnl_expr *expr);
+int nftnl_set_expr_foreach(const struct nftnl_set *s,
+                          int (*cb)(struct nftnl_expr *e, void *data),
+                          void *data);
+
 struct nftnl_set_list_iter;
 struct nftnl_set_list_iter *nftnl_set_list_iter_create(const struct 
nftnl_set_list *l);
 struct nftnl_set *nftnl_set_list_iter_cur(const struct nftnl_set_list_iter 
*iter);
@@ -107,6 +114,7 @@
        NFTNL_SET_ELEM_EXPR,
        NFTNL_SET_ELEM_OBJREF,
        NFTNL_SET_ELEM_KEY_END,
+       NFTNL_SET_ELEM_EXPRESSIONS,
        __NFTNL_SET_ELEM_MAX
 };
 #define NFTNL_SET_ELEM_MAX (__NFTNL_SET_ELEM_MAX - 1)
@@ -144,6 +152,12 @@
 int nftnl_set_elem_snprintf(char *buf, size_t size, const struct 
nftnl_set_elem *s, uint32_t type, uint32_t flags);
 int nftnl_set_elem_fprintf(FILE *fp, const struct nftnl_set_elem *se, uint32_t 
type, uint32_t flags);
 
+struct nftnl_expr;
+void nftnl_set_elem_add_expr(struct nftnl_set_elem *e, struct nftnl_expr 
*expr);
+int nftnl_set_elem_expr_foreach(struct nftnl_set_elem *e,
+                               int (*cb)(struct nftnl_expr *e, void *data),
+                               void *data);
+
 int nftnl_set_elem_foreach(struct nftnl_set *s, int (*cb)(struct 
nftnl_set_elem *e, void *data), void *data);
 
 struct nftnl_set_elems_iter;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/include/linux/netfilter/nf_tables.h 
new/libnftnl-1.1.9/include/linux/netfilter/nf_tables.h
--- old/libnftnl-1.1.8/include/linux/netfilter/nf_tables.h      2020-10-27 
10:38:31.797284212 +0100
+++ new/libnftnl-1.1.9/include/linux/netfilter/nf_tables.h      2021-01-15 
16:59:36.484340299 +0100
@@ -367,6 +367,7 @@
        NFTA_SET_OBJ_TYPE,
        NFTA_SET_HANDLE,
        NFTA_SET_EXPR,
+       NFTA_SET_EXPRESSIONS,
        __NFTA_SET_MAX
 };
 #define NFTA_SET_MAX           (__NFTA_SET_MAX - 1)
@@ -405,6 +406,7 @@
        NFTA_SET_ELEM_PAD,
        NFTA_SET_ELEM_OBJREF,
        NFTA_SET_ELEM_KEY_END,
+       NFTA_SET_ELEM_EXPRESSIONS,
        __NFTA_SET_ELEM_MAX
 };
 #define NFTA_SET_ELEM_MAX      (__NFTA_SET_ELEM_MAX - 1)
@@ -712,6 +714,7 @@
        NFTA_DYNSET_EXPR,
        NFTA_DYNSET_PAD,
        NFTA_DYNSET_FLAGS,
+       NFTA_DYNSET_EXPRESSIONS,
        __NFTA_DYNSET_MAX,
 };
 #define NFTA_DYNSET_MAX                (__NFTA_DYNSET_MAX - 1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/include/set.h 
new/libnftnl-1.1.9/include/set.h
--- old/libnftnl-1.1.8/include/set.h    2020-10-27 10:38:31.801284206 +0100
+++ new/libnftnl-1.1.9/include/set.h    2021-01-15 16:59:36.484340299 +0100
@@ -33,7 +33,7 @@
        uint32_t                flags;
        uint32_t                gc_interval;
        uint64_t                timeout;
-       struct nftnl_expr       *expr;
+       struct list_head        expr_list;
 };
 
 struct nftnl_set_list;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/include/set_elem.h 
new/libnftnl-1.1.9/include/set_elem.h
--- old/libnftnl-1.1.8/include/set_elem.h       2020-10-27 10:38:31.801284206 
+0100
+++ new/libnftnl-1.1.9/include/set_elem.h       2021-01-15 16:59:36.484340299 
+0100
@@ -10,7 +10,7 @@
        union nftnl_data_reg    key;
        union nftnl_data_reg    key_end;
        union nftnl_data_reg    data;
-       struct nftnl_expr       *expr;
+       struct list_head        expr_list;
        uint64_t                timeout;
        uint64_t                expiration;
        const char              *objref;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/Makefile.in 
new/libnftnl-1.1.9/src/Makefile.in
--- old/libnftnl-1.1.8/src/Makefile.in  2020-10-27 10:38:45.065261754 +0100
+++ new/libnftnl-1.1.9/src/Makefile.in  2021-01-15 16:59:49.152331277 +0100
@@ -396,7 +396,7 @@
 # set age to 0.
 # </snippet>
 #
-LIBVERSION = 15:0:4
+LIBVERSION = 16:0:5
 AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS} 
${LIBMXML_CFLAGS}
 AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}
 lib_LTLIBRARIES = libnftnl.la
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/expr/bitwise.c 
new/libnftnl-1.1.9/src/expr/bitwise.c
--- old/libnftnl-1.1.8/src/expr/bitwise.c       2020-10-27 10:38:31.809284191 
+0100
+++ new/libnftnl-1.1.9/src/expr/bitwise.c       2021-01-15 16:59:36.492340293 
+0100
@@ -215,7 +215,7 @@
 {
        int remain = size, offset = 0, ret;
 
-       ret = snprintf(buf, remain, "reg %u = (reg=%u & ",
+       ret = snprintf(buf, remain, "reg %u = ( reg %u & ",
                       bitwise->dreg, bitwise->sreg);
        SNPRINTF_BUFFER_SIZE(ret, remain, offset);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/expr/data_reg.c 
new/libnftnl-1.1.9/src/expr/data_reg.c
--- old/libnftnl-1.1.8/src/expr/data_reg.c      2020-10-27 10:38:31.809284191 
+0100
+++ new/libnftnl-1.1.9/src/expr/data_reg.c      2021-01-15 16:59:36.492340293 
+0100
@@ -29,10 +29,14 @@
                                      const union nftnl_data_reg *reg,
                                      uint32_t flags)
 {
+       const char *pfx = flags & DATA_F_NOPFX ? "" : "0x";
        int remain = size, offset = 0, ret, i;
 
+
+
        for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) {
-               ret = snprintf(buf + offset, remain, "0x%.8x ", reg->val[i]);
+               ret = snprintf(buf + offset, remain,
+                              "%s%.8x ", pfx, reg->val[i]);
                SNPRINTF_BUFFER_SIZE(ret, remain, offset);
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/expr/dynset.c 
new/libnftnl-1.1.9/src/expr/dynset.c
--- old/libnftnl-1.1.8/src/expr/dynset.c        2020-10-27 10:38:31.809284191 
+0100
+++ new/libnftnl-1.1.9/src/expr/dynset.c        2021-01-15 16:59:36.496340291 
+0100
@@ -26,9 +26,10 @@
        enum nft_registers      sreg_data;
        enum nft_dynset_ops     op;
        uint64_t                timeout;
-       struct nftnl_expr       *expr;
+       struct list_head        expr_list;
        char                    *set_name;
        uint32_t                set_id;
+       uint32_t                dynset_flags;
 };
 
 static int
@@ -36,6 +37,7 @@
                         const void *data, uint32_t data_len)
 {
        struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
+       struct nftnl_expr *expr, *next;
 
        switch (type) {
        case NFTNL_EXPR_DYNSET_SREG_KEY:
@@ -59,7 +61,14 @@
                memcpy(&dynset->set_id, data, sizeof(dynset->set_id));
                break;
        case NFTNL_EXPR_DYNSET_EXPR:
-               dynset->expr = (void *)data;
+               list_for_each_entry_safe(expr, next, &dynset->expr_list, head)
+                       nftnl_expr_free(expr);
+
+               expr = (void *)data;
+               list_add(&expr->head, &dynset->expr_list);
+               break;
+       case NFTNL_EXPR_DYNSET_FLAGS:
+               memcpy(&dynset->dynset_flags, data, 
sizeof(dynset->dynset_flags));
                break;
        default:
                return -1;
@@ -72,6 +81,7 @@
                         uint32_t *data_len)
 {
        struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
+       struct nftnl_expr *expr;
 
        switch (type) {
        case NFTNL_EXPR_DYNSET_SREG_KEY:
@@ -93,7 +103,12 @@
                *data_len = sizeof(dynset->set_id);
                return &dynset->set_id;
        case NFTNL_EXPR_DYNSET_EXPR:
-               return dynset->expr;
+               list_for_each_entry(expr, &dynset->expr_list, head)
+                       break;
+               return expr;
+       case NFTNL_EXPR_DYNSET_FLAGS:
+               *data_len = sizeof(dynset->dynset_flags);
+               return &dynset->dynset_flags;
        }
        return NULL;
 }
@@ -111,6 +126,7 @@
        case NFTA_DYNSET_SREG_DATA:
        case NFTA_DYNSET_SET_ID:
        case NFTA_DYNSET_OP:
+       case NFTA_DYNSET_FLAGS:
                if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
                        abi_breakage();
                break;
@@ -137,6 +153,7 @@
 {
        struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
        struct nlattr *nest;
+       int num_exprs = 0;
 
        if (e->flags & (1 << NFTNL_EXPR_DYNSET_SREG_KEY))
                mnl_attr_put_u32(nlh, NFTA_DYNSET_SREG_KEY, 
htonl(dynset->sreg_key));
@@ -150,11 +167,58 @@
                mnl_attr_put_strz(nlh, NFTA_DYNSET_SET_NAME, dynset->set_name);
        if (e->flags & (1 << NFTNL_EXPR_DYNSET_SET_ID))
                mnl_attr_put_u32(nlh, NFTA_DYNSET_SET_ID, 
htonl(dynset->set_id));
-       if (e->flags & (1 << NFTNL_EXPR_DYNSET_EXPR)) {
-               nest = mnl_attr_nest_start(nlh, NFTA_DYNSET_EXPR);
-               nftnl_expr_build_payload(nlh, dynset->expr);
-               mnl_attr_nest_end(nlh, nest);
+       if (!list_empty(&dynset->expr_list)) {
+               struct nftnl_expr *expr;
+
+               list_for_each_entry(expr, &dynset->expr_list, head)
+                       num_exprs++;
+
+               if (num_exprs == 1) {
+                       nest = mnl_attr_nest_start(nlh, NFTA_DYNSET_EXPR);
+                       list_for_each_entry(expr, &dynset->expr_list, head)
+                               nftnl_expr_build_payload(nlh, expr);
+                       mnl_attr_nest_end(nlh, nest);
+               } else if (num_exprs > 1) {
+                       struct nlattr *nest1, *nest2;
+
+                       nest1 = mnl_attr_nest_start(nlh, 
NFTA_DYNSET_EXPRESSIONS);
+                       list_for_each_entry(expr, &dynset->expr_list, head) {
+                               nest2 = mnl_attr_nest_start(nlh, 
NFTA_LIST_ELEM);
+                               nftnl_expr_build_payload(nlh, expr);
+                               mnl_attr_nest_end(nlh, nest2);
+                       }
+                       mnl_attr_nest_end(nlh, nest1);
+               }
+       }
+       if (e->flags & (1 << NFTNL_EXPR_DYNSET_FLAGS))
+               mnl_attr_put_u32(nlh, NFTA_DYNSET_FLAGS,
+                                htonl(dynset->dynset_flags));
+}
+
+EXPORT_SYMBOL(nftnl_expr_add_expr);
+void nftnl_expr_add_expr(struct nftnl_expr *e, uint32_t type,
+                        struct nftnl_expr *expr)
+{
+       struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
+
+       list_add_tail(&expr->head, &dynset->expr_list);
+}
+
+EXPORT_SYMBOL(nftnl_expr_expr_foreach);
+int nftnl_expr_expr_foreach(const struct nftnl_expr *e,
+                           int (*cb)(struct nftnl_expr *e, void *data),
+                           void *data)
+{
+       struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
+       struct nftnl_expr *cur, *tmp;
+       int ret;
+
+       list_for_each_entry_safe(cur, tmp, &dynset->expr_list, head) {
+               ret = cb(cur, data);
+               if (ret < 0)
+                       return ret;
        }
+       return 0;
 }
 
 static int
@@ -162,6 +226,7 @@
 {
        struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
        struct nlattr *tb[NFTA_SET_MAX+1] = {};
+       struct nftnl_expr *expr, *next;
        int ret = 0;
 
        if (mnl_attr_parse_nested(attr, nftnl_expr_dynset_cb, tb) < 0)
@@ -195,13 +260,38 @@
                e->flags |= (1 << NFTNL_EXPR_DYNSET_SET_ID);
        }
        if (tb[NFTA_DYNSET_EXPR]) {
-               e->flags |= (1 << NFTNL_EXPR_DYNSET_EXPR);
-               dynset->expr = nftnl_expr_parse(tb[NFTA_DYNSET_EXPR]);
-               if (dynset->expr == NULL)
+               expr = nftnl_expr_parse(tb[NFTA_DYNSET_EXPR]);
+               if (expr == NULL)
                        return -1;
+
+               list_add(&expr->head, &dynset->expr_list);
+               e->flags |= (1 << NFTNL_EXPR_DYNSET_EXPR);
+       } else if (tb[NFTA_DYNSET_EXPRESSIONS]) {
+               struct nlattr *attr2;
+
+               mnl_attr_for_each_nested(attr2, tb[NFTA_DYNSET_EXPRESSIONS]) {
+                       if (mnl_attr_get_type(attr2) != NFTA_LIST_ELEM)
+                               goto out_dynset_expr;
+
+                       expr = nftnl_expr_parse(attr2);
+                       if (!expr)
+                               goto out_dynset_expr;
+
+                       list_add_tail(&expr->head, &dynset->expr_list);
+               }
+               e->flags |= (1 << NFTNL_EXPR_DYNSET_EXPRESSIONS);
+       }
+       if (tb[NFTA_DYNSET_FLAGS]) {
+               dynset->dynset_flags = 
ntohl(mnl_attr_get_u32(tb[NFTA_DYNSET_FLAGS]));
+               e->flags |= (1 << NFTNL_EXPR_DYNSET_FLAGS);
        }
 
        return ret;
+out_dynset_expr:
+       list_for_each_entry_safe(expr, next, &dynset->expr_list, head)
+               nftnl_expr_free(expr);
+
+       return -1;
 }
 
 static const char *op2str_array[] = {
@@ -239,8 +329,7 @@
                               dynset->timeout);
                SNPRINTF_BUFFER_SIZE(ret, remain, offset);
        }
-       if (e->flags & (1 << NFTNL_EXPR_DYNSET_EXPR)) {
-               expr = dynset->expr;
+       list_for_each_entry(expr, &dynset->expr_list, head) {
                ret = snprintf(buf + offset, remain, "expr [ %s ",
                               expr->ops->name);
                SNPRINTF_BUFFER_SIZE(ret, remain, offset);
@@ -272,19 +361,28 @@
        return -1;
 }
 
+static void nftnl_expr_dynset_init(const struct nftnl_expr *e)
+{
+       struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
+
+       INIT_LIST_HEAD(&dynset->expr_list);
+}
+
 static void nftnl_expr_dynset_free(const struct nftnl_expr *e)
 {
        struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
+       struct nftnl_expr *expr, *next;
 
        xfree(dynset->set_name);
-       if (dynset->expr)
-               nftnl_expr_free(dynset->expr);
+       list_for_each_entry_safe(expr, next, &dynset->expr_list, head)
+               nftnl_expr_free(expr);
 }
 
 struct expr_ops expr_ops_dynset = {
        .name           = "dynset",
        .alloc_len      = sizeof(struct nftnl_expr_dynset),
        .max_attr       = NFTA_DYNSET_MAX,
+       .init           = nftnl_expr_dynset_init,
        .free           = nftnl_expr_dynset_free,
        .set            = nftnl_expr_dynset_set,
        .get            = nftnl_expr_dynset_get,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/expr.c 
new/libnftnl-1.1.9/src/expr.c
--- old/libnftnl-1.1.8/src/expr.c       2020-10-27 10:38:31.805284199 +0100
+++ new/libnftnl-1.1.9/src/expr.c       2021-01-15 16:59:36.488340296 +0100
@@ -42,6 +42,9 @@
        expr->flags |= (1 << NFTNL_EXPR_NAME);
        expr->ops = ops;
 
+       if (ops->init)
+               ops->init(expr);
+
        return expr;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/libnftnl.map 
new/libnftnl-1.1.9/src/libnftnl.map
--- old/libnftnl-1.1.8/src/libnftnl.map 2020-10-27 10:38:31.825284165 +0100
+++ new/libnftnl-1.1.9/src/libnftnl.map 2021-01-15 16:59:36.512340279 +0100
@@ -374,3 +374,12 @@
   nftnl_expr_build_payload;
   nftnl_rule_del_expr;
 } LIBNFTNL_14;
+
+LIBNFTNL_16 {
+  nftnl_set_add_expr;
+  nftnl_set_expr_foreach;
+  nftnl_set_elem_add_expr;
+  nftnl_set_elem_expr_foreach;
+  nftnl_expr_add_expr;
+  nftnl_expr_expr_foreach;
+} LIBNFTNL_15;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/set.c new/libnftnl-1.1.9/src/set.c
--- old/libnftnl-1.1.8/src/set.c        2020-10-27 10:38:31.833284151 +0100
+++ new/libnftnl-1.1.9/src/set.c        2021-01-15 16:59:36.516340276 +0100
@@ -37,6 +37,7 @@
                return NULL;
 
        INIT_LIST_HEAD(&s->element_list);
+       INIT_LIST_HEAD(&s->expr_list);
        return s;
 }
 
@@ -44,6 +45,7 @@
 void nftnl_set_free(const struct nftnl_set *s)
 {
        struct nftnl_set_elem *elem, *tmp;
+       struct nftnl_expr *expr, *next;
 
        if (s->flags & (1 << NFTNL_SET_TABLE))
                xfree(s->table);
@@ -51,8 +53,9 @@
                xfree(s->name);
        if (s->flags & (1 << NFTNL_SET_USERDATA))
                xfree(s->user.data);
-       if (s->flags & (1 << NFTNL_SET_EXPR))
-               nftnl_expr_free(s->expr);
+
+       list_for_each_entry_safe(expr, next, &s->expr_list, head)
+               nftnl_expr_free(expr);
 
        list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
                list_del(&elem->head);
@@ -70,6 +73,8 @@
 EXPORT_SYMBOL(nftnl_set_unset);
 void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
 {
+       struct nftnl_expr *expr, *tmp;
+
        if (!(s->flags & (1 << attr)))
                return;
 
@@ -99,7 +104,9 @@
                xfree(s->user.data);
                break;
        case NFTNL_SET_EXPR:
-               nftnl_expr_free(s->expr);
+       case NFTNL_SET_EXPRESSIONS:
+               list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+                       nftnl_expr_free(expr);
                break;
        default:
                return;
@@ -127,6 +134,8 @@
 int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
                       uint32_t data_len)
 {
+       struct nftnl_expr *expr, *tmp;
+
        nftnl_assert_attr_exists(attr, NFTNL_SET_MAX);
        nftnl_assert_validate(data, nftnl_set_validate, attr, data_len);
 
@@ -201,10 +210,11 @@
                s->user.len = data_len;
                break;
        case NFTNL_SET_EXPR:
-               if (s->flags & (1 << NFTNL_SET_EXPR))
-                       nftnl_expr_free(s->expr);
+               list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+                       nftnl_expr_free(expr);
 
-               s->expr = (void *)data;
+               expr = (void *)data;
+               list_add(&expr->head, &s->expr_list);
                break;
        }
        s->flags |= (1 << attr);
@@ -239,6 +249,8 @@
 const void *nftnl_set_get_data(const struct nftnl_set *s, uint16_t attr,
                               uint32_t *data_len)
 {
+       struct nftnl_expr *expr;
+
        if (!(s->flags & (1 << attr)))
                return NULL;
 
@@ -295,7 +307,9 @@
                *data_len = s->user.len;
                return s->user.data;
        case NFTNL_SET_EXPR:
-               return s->expr;
+               list_for_each_entry(expr, &s->expr_list, head)
+                       break;
+               return expr;
        }
        return NULL;
 }
@@ -414,6 +428,8 @@
 EXPORT_SYMBOL(nftnl_set_nlmsg_build_payload);
 void nftnl_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
 {
+       int num_exprs = 0;
+
        if (s->flags & (1 << NFTNL_SET_TABLE))
                mnl_attr_put_strz(nlh, NFTA_SET_TABLE, s->table);
        if (s->flags & (1 << NFTNL_SET_NAME))
@@ -445,15 +461,55 @@
                mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, 
htonl(s->gc_interval));
        if (s->flags & (1 << NFTNL_SET_USERDATA))
                mnl_attr_put(nlh, NFTA_SET_USERDATA, s->user.len, s->user.data);
-       if (s->flags & (1 << NFTNL_SET_EXPR)) {
-               struct nlattr *nest1;
+       if (!list_empty(&s->expr_list)) {
+               struct nftnl_expr *expr;
+
+               list_for_each_entry(expr, &s->expr_list, head)
+                       num_exprs++;
 
-               nest1 = mnl_attr_nest_start(nlh, NFTA_SET_EXPR);
-               nftnl_expr_build_payload(nlh, s->expr);
-               mnl_attr_nest_end(nlh, nest1);
+               if (num_exprs == 1) {
+                       struct nlattr *nest1;
+
+                       nest1 = mnl_attr_nest_start(nlh, NFTA_SET_EXPR);
+                       list_for_each_entry(expr, &s->expr_list, head)
+                               nftnl_expr_build_payload(nlh, expr);
+
+                       mnl_attr_nest_end(nlh, nest1);
+               } else if (num_exprs > 1) {
+                       struct nlattr *nest1, *nest2;
+
+                       nest1 = mnl_attr_nest_start(nlh, NFTA_SET_EXPRESSIONS);
+                       list_for_each_entry(expr, &s->expr_list, head) {
+                               nest2 = mnl_attr_nest_start(nlh, 
NFTA_LIST_ELEM);
+                               nftnl_expr_build_payload(nlh, expr);
+                               mnl_attr_nest_end(nlh, nest2);
+                       }
+                       mnl_attr_nest_end(nlh, nest1);
+               }
        }
 }
 
+EXPORT_SYMBOL(nftnl_set_add_expr);
+void nftnl_set_add_expr(struct nftnl_set *s, struct nftnl_expr *expr)
+{
+       list_add_tail(&expr->head, &s->expr_list);
+}
+
+EXPORT_SYMBOL(nftnl_set_expr_foreach);
+int nftnl_set_expr_foreach(const struct nftnl_set *s,
+                          int (*cb)(struct nftnl_expr *e, void *data),
+                          void *data)
+{
+       struct nftnl_expr *cur, *tmp;
+       int ret;
+
+       list_for_each_entry_safe(cur, tmp, &s->expr_list, head) {
+               ret = cb(cur, data);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+}
 
 static int nftnl_set_parse_attr_cb(const struct nlattr *attr, void *data)
 {
@@ -493,6 +549,8 @@
                        abi_breakage();
                break;
        case NFTA_SET_DESC:
+       case NFTA_SET_EXPR:
+       case NFTA_SET_EXPRESSIONS:
                if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
                        abi_breakage();
                break;
@@ -578,6 +636,7 @@
 {
        struct nlattr *tb[NFTA_SET_MAX+1] = {};
        struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
+       struct nftnl_expr *expr, *next;
        int ret;
 
        if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_set_parse_attr_cb, tb) < 0)
@@ -656,17 +715,37 @@
                        return ret;
        }
        if (tb[NFTA_SET_EXPR]) {
-               s->expr = nftnl_expr_parse(tb[NFTA_SET_EXPR]);
-               if (!s->expr)
-                       return -1;
+               expr = nftnl_expr_parse(tb[NFTA_SET_EXPR]);
+               if (!expr)
+                       goto out_set_expr;
 
+               list_add(&expr->head, &s->expr_list);
                s->flags |= (1 << NFTNL_SET_EXPR);
+       } else if (tb[NFTA_SET_EXPRESSIONS]) {
+               struct nlattr *attr;
+
+               mnl_attr_for_each_nested(attr, tb[NFTA_SET_EXPRESSIONS]) {
+                       if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
+                               goto out_set_expr;
+
+                       expr = nftnl_expr_parse(attr);
+                       if (expr == NULL)
+                               goto out_set_expr;
+
+                       list_add_tail(&expr->head, &s->expr_list);
+               }
+               s->flags |= (1 << NFTNL_SET_EXPRESSIONS);
        }
 
        s->family = nfg->nfgen_family;
        s->flags |= (1 << NFTNL_SET_FAMILY);
 
        return 0;
+out_set_expr:
+       list_for_each_entry_safe(expr, next, &s->expr_list, head)
+               nftnl_expr_free(expr);
+
+       return -1;
 }
 
 static int nftnl_set_do_parse(struct nftnl_set *s, enum nftnl_parse_type type,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/src/set_elem.c 
new/libnftnl-1.1.9/src/set_elem.c
--- old/libnftnl-1.1.8/src/set_elem.c   2020-10-27 10:38:31.833284151 +0100
+++ new/libnftnl-1.1.9/src/set_elem.c   2021-01-15 16:59:36.520340274 +0100
@@ -36,17 +36,21 @@
        if (s == NULL)
                return NULL;
 
+       INIT_LIST_HEAD(&s->expr_list);
+
        return s;
 }
 
 EXPORT_SYMBOL(nftnl_set_elem_free);
 void nftnl_set_elem_free(struct nftnl_set_elem *s)
 {
+       struct nftnl_expr *e, *tmp;
+
        if (s->flags & (1 << NFTNL_SET_ELEM_CHAIN))
                xfree(s->data.chain);
 
-       if (s->flags & (1 << NFTNL_SET_ELEM_EXPR))
-               nftnl_expr_free(s->expr);
+       list_for_each_entry_safe(e, tmp, &s->expr_list, head)
+               nftnl_expr_free(e);
 
        if (s->flags & (1 << NFTNL_SET_ELEM_USERDATA))
                xfree(s->user.data);
@@ -66,6 +70,8 @@
 EXPORT_SYMBOL(nftnl_set_elem_unset);
 void nftnl_set_elem_unset(struct nftnl_set_elem *s, uint16_t attr)
 {
+       struct nftnl_expr *expr, *tmp;
+
        if (!(s->flags & (1 << attr)))
                return;
 
@@ -85,7 +91,9 @@
                xfree(s->user.data);
                break;
        case NFTNL_SET_ELEM_EXPR:
-               nftnl_expr_free(s->expr);
+       case NFTNL_SET_ELEM_EXPRESSIONS:
+               list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+                       nftnl_expr_free(expr);
                break;
        case NFTNL_SET_ELEM_OBJREF:
                xfree(s->objref);
@@ -108,6 +116,8 @@
 int nftnl_set_elem_set(struct nftnl_set_elem *s, uint16_t attr,
                       const void *data, uint32_t data_len)
 {
+       struct nftnl_expr *expr, *tmp;
+
        nftnl_assert_attr_exists(attr, NFTNL_SET_ELEM_MAX);
        nftnl_assert_validate(data, nftnl_set_elem_validate, attr, data_len);
 
@@ -163,10 +173,11 @@
                        return -1;
                break;
        case NFTNL_SET_ELEM_EXPR:
-               if (s->flags & (1 << NFTNL_SET_ELEM_EXPR))
-                       nftnl_expr_free(s->expr);
+               list_for_each_entry_safe(expr, tmp, &s->expr_list, head)
+                       nftnl_expr_free(expr);
 
-               s->expr = (void *)data;
+               expr = (void *)data;
+               list_add(&expr->head, &s->expr_list);
                break;
        }
        s->flags |= (1 << attr);
@@ -194,6 +205,8 @@
 EXPORT_SYMBOL(nftnl_set_elem_get);
 const void *nftnl_set_elem_get(struct nftnl_set_elem *s, uint16_t attr, 
uint32_t *data_len)
 {
+       struct nftnl_expr *expr;
+
        if (!(s->flags & (1 << attr)))
                return NULL;
 
@@ -226,7 +239,9 @@
                *data_len = s->user.len;
                return s->user.data;
        case NFTNL_SET_ELEM_EXPR:
-               return s->expr;
+               list_for_each_entry(expr, &s->expr_list, head)
+                       break;
+               return expr;
        case NFTNL_SET_ELEM_OBJREF:
                *data_len = strlen(s->objref) + 1;
                return s->objref;
@@ -288,6 +303,9 @@
 void nftnl_set_elem_nlmsg_build_payload(struct nlmsghdr *nlh,
                                      struct nftnl_set_elem *e)
 {
+       struct nftnl_expr *expr;
+       int num_exprs = 0;
+
        if (e->flags & (1 << NFTNL_SET_ELEM_FLAGS))
                mnl_attr_put_u32(nlh, NFTA_SET_ELEM_FLAGS, 
htonl(e->set_elem_flags));
        if (e->flags & (1 << NFTNL_SET_ELEM_TIMEOUT))
@@ -332,12 +350,30 @@
                mnl_attr_put(nlh, NFTA_SET_ELEM_USERDATA, e->user.len, 
e->user.data);
        if (e->flags & (1 << NFTNL_SET_ELEM_OBJREF))
                mnl_attr_put_strz(nlh, NFTA_SET_ELEM_OBJREF, e->objref);
-       if (e->flags & (1 << NFTNL_SET_ELEM_EXPR)) {
-               struct nlattr *nest1;
 
-               nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_EXPR);
-               nftnl_expr_build_payload(nlh, e->expr);
-               mnl_attr_nest_end(nlh, nest1);
+       if (!list_empty(&e->expr_list)) {
+               list_for_each_entry(expr, &e->expr_list, head)
+                       num_exprs++;
+
+               if (num_exprs == 1) {
+                       struct nlattr *nest1;
+
+                       nest1 = mnl_attr_nest_start(nlh, NFTA_SET_ELEM_EXPR);
+                       list_for_each_entry(expr, &e->expr_list, head)
+                               nftnl_expr_build_payload(nlh, expr);
+
+                       mnl_attr_nest_end(nlh, nest1);
+               } else if (num_exprs > 1) {
+                       struct nlattr *nest1, *nest2;
+
+                       nest1 = mnl_attr_nest_start(nlh, 
NFTA_SET_ELEM_EXPRESSIONS);
+                       list_for_each_entry(expr, &e->expr_list, head) {
+                               nest2 = mnl_attr_nest_start(nlh, 
NFTA_LIST_ELEM);
+                               nftnl_expr_build_payload(nlh, expr);
+                               mnl_attr_nest_end(nlh, nest2);
+                       }
+                       mnl_attr_nest_end(nlh, nest1);
+               }
        }
 }
 
@@ -383,6 +419,28 @@
        mnl_attr_nest_end(nlh, nest1);
 }
 
+EXPORT_SYMBOL(nftnl_set_elem_add_expr);
+void nftnl_set_elem_add_expr(struct nftnl_set_elem *e, struct nftnl_expr *expr)
+{
+       list_add_tail(&expr->head, &e->expr_list);
+}
+
+EXPORT_SYMBOL(nftnl_set_elem_expr_foreach);
+int nftnl_set_elem_expr_foreach(struct nftnl_set_elem *e,
+                               int (*cb)(struct nftnl_expr *e, void *data),
+                               void *data)
+{
+       struct nftnl_expr *cur, *tmp;
+       int ret;
+
+       list_for_each_entry_safe(cur, tmp, &e->expr_list, head) {
+               ret = cb(cur, data);
+               if (ret < 0)
+                       return ret;
+       }
+       return 0;
+}
+
 static int nftnl_set_elem_parse_attr_cb(const struct nlattr *attr, void *data)
 {
        const struct nlattr **tb = data;
@@ -405,6 +463,7 @@
        case NFTA_SET_ELEM_KEY_END:
        case NFTA_SET_ELEM_DATA:
        case NFTA_SET_ELEM_EXPR:
+       case NFTA_SET_ELEM_EXPRESSIONS:
                if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
                        abi_breakage();
                break;
@@ -476,12 +535,32 @@
                }
         }
        if (tb[NFTA_SET_ELEM_EXPR]) {
-               e->expr = nftnl_expr_parse(tb[NFTA_SET_ELEM_EXPR]);
-               if (e->expr == NULL) {
+               struct nftnl_expr *expr;
+
+               expr = nftnl_expr_parse(tb[NFTA_SET_ELEM_EXPR]);
+               if (expr == NULL) {
                        ret = -1;
                        goto out_set_elem;
                }
+               list_add_tail(&expr->head, &e->expr_list);
                e->flags |= (1 << NFTNL_SET_ELEM_EXPR);
+       } else if (tb[NFTA_SET_ELEM_EXPRESSIONS]) {
+               struct nftnl_expr *expr;
+               struct nlattr *attr;
+
+               mnl_attr_for_each_nested(attr, tb[NFTA_SET_ELEM_EXPRESSIONS]) {
+                       if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM) {
+                               ret = -1;
+                               goto out_set_elem;
+                       }
+                       expr = nftnl_expr_parse(attr);
+                       if (expr == NULL) {
+                               ret = -1;
+                               goto out_set_elem;
+                       }
+                       list_add_tail(&expr->head, &e->expr_list);
+               }
+               e->flags |= (1 << NFTNL_SET_ELEM_EXPRESSIONS);
        }
        if (tb[NFTA_SET_ELEM_USERDATA]) {
                const void *udata =
@@ -494,7 +573,7 @@
                e->user.data = malloc(e->user.len);
                if (e->user.data == NULL) {
                        ret = -1;
-                       goto out_expr;
+                       goto out_set_elem;
                }
                memcpy(e->user.data, udata, e->user.len);
                e->flags |= (1 << NFTNL_RULE_USERDATA);
@@ -512,8 +591,6 @@
        list_add_tail(&e->head, &s->element_list);
 
        return 0;
-out_expr:
-       nftnl_expr_free(e->expr);
 out_set_elem:
        nftnl_set_elem_free(e);
        return ret;
@@ -629,18 +706,28 @@
        ret = snprintf(buf, remain, "element ");
        SNPRINTF_BUFFER_SIZE(ret, remain, offset);
 
-       for (i = 0; i < div_round_up(e->key.len, sizeof(uint32_t)); i++) {
-               ret = snprintf(buf + offset, remain, "%.8x ", e->key.val[i]);
+       ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->key,
+                                     NFTNL_OUTPUT_DEFAULT,
+                                     DATA_F_NOPFX, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
+       if (e->flags & (1 << NFTNL_SET_ELEM_KEY_END)) {
+               ret = snprintf(buf + offset, remain, " - ");
+               SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+
+               ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->key_end,
+                                             NFTNL_OUTPUT_DEFAULT,
+                                             DATA_F_NOPFX, DATA_VALUE);
                SNPRINTF_BUFFER_SIZE(ret, remain, offset);
        }
 
        ret = snprintf(buf + offset, remain, " : ");
        SNPRINTF_BUFFER_SIZE(ret, remain, offset);
 
-       for (i = 0; i < div_round_up(e->data.len, sizeof(uint32_t)); i++) {
-               ret = snprintf(buf + offset, remain, "%.8x ", e->data.val[i]);
-               SNPRINTF_BUFFER_SIZE(ret, remain, offset);
-       }
+       ret = nftnl_data_reg_snprintf(buf + offset, remain, &e->data,
+                                     NFTNL_OUTPUT_DEFAULT,
+                                     DATA_F_NOPFX, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, remain, offset);
 
        ret = snprintf(buf + offset, remain, "%u [end]", e->set_elem_flags);
        SNPRINTF_BUFFER_SIZE(ret, remain, offset);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libnftnl-1.1.8/tests/Makefile.in 
new/libnftnl-1.1.9/tests/Makefile.in
--- old/libnftnl-1.1.8/tests/Makefile.in        2020-10-27 10:38:45.217261497 
+0100
+++ new/libnftnl-1.1.9/tests/Makefile.in        2021-01-15 16:59:49.300331172 
+0100
@@ -730,7 +730,7 @@
 # set age to 0.
 # </snippet>
 #
-LIBVERSION = 15:0:4
+LIBVERSION = 16:0:5
 AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS} 
${LIBMXML_CFLAGS}
 AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}
 TESTS = $(check_PROGRAMS)

Reply via email to