Example usage: > nft add table mytable > exmample/nft-set-add ip mytable myset "5:my data 0" "5:my data 1" > example/nft-set-get ip json | jq #jq: https://stedolan.github.io/jq/ { "set": { "name": "myset", "table": "mytable", "flags": 2, "family": "ip", "key_type": 0, "key_len": 2, "userdata_len": 48, "userdata": [ { "type": 5, "len": 9, "val": "my data 0" }, { "type": 5, "len": 9, "val": "my data 1" } ] } } Signed-off-by: Carlos Falgueras García <carlosfg@xxxxxxxxxx> --- examples/nft-set-add.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/examples/nft-set-add.c b/examples/nft-set-add.c index e040aca..42ff3c8 100644 --- a/examples/nft-set-add.c +++ b/examples/nft-set-add.c @@ -28,8 +28,14 @@ #include <libmnl/libmnl.h> #include <libnftnl/set.h> +#define ATTRBUF_SIZE 256 + +static bool parse_user_data(char *argv[], int argc, + struct nftnl_attrbuf *attrbuf); + static struct nftnl_set *setup_set(uint8_t family, const char *table, - const char *name) + const char *name, const char *udata, + unsigned int udlen) { struct nftnl_set *s = NULL; @@ -44,6 +50,8 @@ static struct nftnl_set *setup_set(uint8_t family, const char *table, nftnl_set_set_u32(s, NFTNL_SET_FAMILY, family); nftnl_set_set_u32(s, NFTNL_SET_KEY_LEN, 2); nftnl_set_set_u32(s, NFTNL_SET_ID, 1); + if (udata != NULL) + nftnl_set_set_data(s, NFTNL_SET_USERDATA, udata, udlen); nftnl_set_set_u32(s, NFTNL_SET_FLAGS, NFT_SET_CONSTANT); return s; @@ -71,13 +79,17 @@ int main(int argc, char *argv[]) struct nftnl_set *s; struct nlmsghdr *nlh; struct mnl_nlmsg_batch *batch; + struct nftnl_attrbuf *attrbuf = NULL; uint8_t family; char buf[MNL_SOCKET_BUFFER_SIZE]; uint32_t seq = time(NULL); int ret; - if (argc != 4) { - fprintf(stderr, "Usage: %s <family> <table> <setname>\n", argv[0]); + if (argc < 4) { + fprintf(stderr, + "Usage: %s <family> <table> <setname> [<type:user_data>[ <type:user_data>...]]\n", + argv[0] + ); exit(EXIT_FAILURE); } @@ -94,7 +106,21 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - s = setup_set(family, argv[2], argv[3]); + if (argc >= 5) { + attrbuf = nftnl_attrbuf_alloc(ATTRBUF_SIZE); + if (!parse_user_data(argv, argc, attrbuf)) { + fprintf(stderr, "Error parsing user data\n"); + free(attrbuf); + return EXIT_FAILURE; + } + + s = setup_set(family, argv[2], argv[3], + (char *)nftnl_attrbuf_data(attrbuf), + nftnl_attrbuf_len(attrbuf) + ); + } else { + s = setup_set(family, argv[2], argv[3], NULL, 0); + } nl = mnl_socket_open(NETLINK_NETFILTER); if (nl == NULL) { @@ -147,6 +173,25 @@ int main(int argc, char *argv[]) } mnl_socket_close(nl); + if (attrbuf) + free(attrbuf); return EXIT_SUCCESS; } + +static bool parse_user_data(char *argv[], int argc, + struct nftnl_attrbuf *attrbuf) +{ + int i; + char *type, *value; + + for (i = 4; i < argc; i++) { + type = strchr(argv[i], ':') - 1; + value = type + 2; + if (!nftnl_attr_put_check(attrbuf, ATTRBUF_SIZE, atoi(type), + strlen(value), value)) + return false; + } + + return true; +} -- 2.6.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html