diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 894f9c12a7..22df5c86fd 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -188,12 +188,10 @@ int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret, int sd_nfnl_nft_message_new_set(sd_netlink *nfnl, sd_netlink_message **ret, int nfproto, const char *table, const char *set_name, uint32_t setid, uint32_t klen); -int sd_nfnl_nft_message_new_setelems_begin(sd_netlink *nfnl, sd_netlink_message **ret, - int nfproto, const char *table, const char *set_name); -int sd_nfnl_nft_message_del_setelems_begin(sd_netlink *nfnl, sd_netlink_message **ret, - int nfproto, const char *table, const char *set_name); -int sd_nfnl_nft_message_add_setelem(sd_netlink_message *m, - uint32_t index, - const void *key, size_t key_len, - const void *data, size_t data_len); -int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m); +int sd_nfnl_nft_message_new_setelems(sd_netlink *nfnl, sd_netlink_message **ret, + int add, int nfproto, const char *table, const char *set_name); +int sd_nfnl_nft_message_append_setelem(sd_netlink_message *m, + uint32_t index, + const void *key, size_t key_len, + const void *data, size_t data_len, + uint32_t flags); diff --git a/src/libsystemd/sd-netlink/netlink-message-nfnl.c b/src/libsystemd/sd-netlink/netlink-message-nfnl.c index 0b370b30f4..28f6c7e330 100644 --- a/src/libsystemd/sd-netlink/netlink-message-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-nfnl.c @@ -209,9 +209,10 @@ int sd_nfnl_nft_message_new_set( return r; } -int sd_nfnl_nft_message_new_setelems_begin( +int sd_nfnl_nft_message_new_setelems( sd_netlink *nfnl, sd_netlink_message **ret, + int add, /* boolean */ int nfproto, const char *table, const char *set_name) { @@ -219,7 +220,10 @@ int sd_nfnl_nft_message_new_setelems_begin( _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; - r = nft_message_new(nfnl, &m, nfproto, NFT_MSG_NEWSETELEM, NLM_F_CREATE); + if (add) + r = nft_message_new(nfnl, &m, nfproto, NFT_MSG_NEWSETELEM, NLM_F_CREATE); + else + r = nft_message_new(nfnl, &m, nfproto, NFT_MSG_DELSETELEM, 0); if (r < 0) return r; @@ -231,51 +235,18 @@ int sd_nfnl_nft_message_new_setelems_begin( if (r < 0) return r; - r = sd_netlink_message_open_container(m, NFTA_SET_ELEM_LIST_ELEMENTS); - if (r < 0) - return r; - *ret = TAKE_PTR(m); return r; } -int sd_nfnl_nft_message_del_setelems_begin( - sd_netlink *nfnl, - sd_netlink_message **ret, - int nfproto, - const char *table, - const char *set_name) { - - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - int r; - - r = nft_message_new(nfnl, &m, nfproto, NFT_MSG_DELSETELEM, 0); - if (r < 0) - return r; - - r = sd_netlink_message_append_string(m, NFTA_SET_ELEM_LIST_TABLE, table); - if (r < 0) - return r; - - r = sd_netlink_message_append_string(m, NFTA_SET_ELEM_LIST_SET, set_name); - if (r < 0) - return r; - - r = sd_netlink_message_open_container(m, NFTA_SET_ELEM_LIST_ELEMENTS); - if (r < 0) - return r; - - *ret = TAKE_PTR(m); - return r; -} - -int sd_nfnl_nft_message_add_setelem( +int sd_nfnl_nft_message_append_setelem( sd_netlink_message *m, uint32_t index, const void *key, size_t key_len, const void *data, - size_t data_len) { + size_t data_len, + uint32_t flags) { int r; @@ -293,17 +264,19 @@ int sd_nfnl_nft_message_add_setelem( goto cancel; } - return 0; + if (flags != 0) { + r = sd_netlink_message_append_u32(m, NFTA_SET_ELEM_FLAGS, htobe32(flags)); + if (r < 0) + goto cancel; + } + + return sd_netlink_message_close_container(m); /* array */ cancel: - sd_netlink_message_cancel_array(m); + (void) sd_netlink_message_cancel_array(m); return r; } -int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m) { - return sd_netlink_message_close_container(m); /* NFTA_SET_ELEM_LIST_ELEMENTS */ -} - int sd_nfnl_socket_open(sd_netlink **ret) { return netlink_open_family(ret, NETLINK_NETFILTER); } diff --git a/src/shared/firewall-util-nft.c b/src/shared/firewall-util-nft.c index 66ea8ee0bd..f0cf50a2ae 100644 --- a/src/shared/firewall-util-nft.c +++ b/src/shared/firewall-util-nft.c @@ -705,16 +705,21 @@ static int nft_add_element( * This replicated here and each element gets added to the set * one-by-one. */ - r = sd_nfnl_nft_message_new_setelems_begin(nfnl, &m, family, NFT_SYSTEMD_TABLE_NAME, set_name); + r = sd_nfnl_nft_message_new_setelems(nfnl, &m, /* add = */ true, family, NFT_SYSTEMD_TABLE_NAME, set_name); if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem(m, 0, key, klen, data, dlen); + r = sd_netlink_message_open_container(m, NFTA_SET_ELEM_LIST_ELEMENTS); + if (r < 0) + return r; + + r = sd_nfnl_nft_message_append_setelem(m, 0, key, klen, data, dlen, 0); if (r < 0) return r; /* could theoretically append more set elements to add here */ - r = sd_nfnl_nft_message_add_setelem_end(m); + + r = sd_netlink_message_close_container(m); /* NFTA_SET_ELEM_LIST_ELEMENTS */ if (r < 0) return r; @@ -742,15 +747,19 @@ static int nft_del_element( assert(key); assert(data); - r = sd_nfnl_nft_message_del_setelems_begin(nfnl, &m, family, NFT_SYSTEMD_TABLE_NAME, set_name); + r = sd_nfnl_nft_message_new_setelems(nfnl, &m, /* add = */ false, family, NFT_SYSTEMD_TABLE_NAME, set_name); if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem(m, 0, key, klen, data, dlen); + r = sd_netlink_message_open_container(m, NFTA_SET_ELEM_LIST_ELEMENTS); + if (r < 0) + return r; + + r = sd_nfnl_nft_message_append_setelem(m, 0, key, klen, data, dlen, 0); if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem_end(m); + r = sd_netlink_message_close_container(m); /* NFTA_SET_ELEM_LIST_ELEMENTS */ if (r < 0) return r; @@ -898,7 +907,7 @@ void fw_nftables_exit(FirewallContext *ctx) { ctx->nfnl = sd_netlink_unref(ctx->nfnl); } -static int nft_message_add_setelem_iprange( +static int nft_message_append_setelem_iprange( sd_netlink_message *m, const union in_addr_union *source, unsigned int prefixlen) { @@ -917,11 +926,11 @@ static int nft_message_add_setelem_iprange( mask = htobe32(~mask); start = source->in.s_addr & mask; - r = sd_nfnl_nft_message_add_setelem(m, 0, &start, sizeof(start), NULL, 0); + r = sd_netlink_message_open_container(m, NFTA_SET_ELEM_LIST_ELEMENTS); if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem_end(m); + r = sd_nfnl_nft_message_append_setelem(m, 0, &start, sizeof(start), NULL, 0, 0); if (r < 0) return r; @@ -930,18 +939,14 @@ static int nft_message_add_setelem_iprange( end = 0U; end = htobe32(end); - r = sd_nfnl_nft_message_add_setelem(m, 1, &end, sizeof(end), NULL, 0); + r = sd_nfnl_nft_message_append_setelem(m, 1, &end, sizeof(end), NULL, 0, NFT_SET_ELEM_INTERVAL_END); if (r < 0) return r; - r = sd_netlink_message_append_u32(m, NFTA_SET_ELEM_FLAGS, htobe32(NFT_SET_ELEM_INTERVAL_END)); - if (r < 0) - return r; - - return sd_nfnl_nft_message_add_setelem_end(m); + return sd_netlink_message_close_container(m); /* NFTA_SET_ELEM_LIST_ELEMENTS */ } -static int nft_message_add_setelem_ip6range( +static int nft_message_append_setelem_ip6range( sd_netlink_message *m, const union in_addr_union *source, unsigned int prefixlen) { @@ -956,23 +961,19 @@ static int nft_message_add_setelem_ip6range( if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem(m, 0, &start.in6, sizeof(start.in6), NULL, 0); + r = sd_netlink_message_open_container(m, NFTA_SET_ELEM_LIST_ELEMENTS); if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem_end(m); + r = sd_nfnl_nft_message_append_setelem(m, 0, &start.in6, sizeof(start.in6), NULL, 0, 0); if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem(m, 1, &end.in6, sizeof(end.in6), NULL, 0); + r = sd_nfnl_nft_message_append_setelem(m, 1, &end.in6, sizeof(end.in6), NULL, 0, NFT_SET_ELEM_INTERVAL_END); if (r < 0) return r; - r = sd_netlink_message_append_u32(m, NFTA_SET_ELEM_FLAGS, htobe32(NFT_SET_ELEM_INTERVAL_END)); - if (r < 0) - return r; - - return sd_nfnl_nft_message_add_setelem_end(m); + return sd_netlink_message_close_container(m); /* NFTA_SET_ELEM_LIST_ELEMENTS */ } static int fw_nftables_add_masquerade_internal( @@ -1000,17 +1001,14 @@ static int fw_nftables_add_masquerade_internal( if (r < 0) return r; - if (add) - r = sd_nfnl_nft_message_new_setelems_begin(nfnl, &messages[msgcnt++], af, NFT_SYSTEMD_TABLE_NAME, NFT_SYSTEMD_MASQ_SET_NAME); - else - r = sd_nfnl_nft_message_del_setelems_begin(nfnl, &messages[msgcnt++], af, NFT_SYSTEMD_TABLE_NAME, NFT_SYSTEMD_MASQ_SET_NAME); + r = sd_nfnl_nft_message_new_setelems(nfnl, &messages[msgcnt++], add, af, NFT_SYSTEMD_TABLE_NAME, NFT_SYSTEMD_MASQ_SET_NAME); if (r < 0) return r; if (af == AF_INET) - r = nft_message_add_setelem_iprange(messages[msgcnt-1], source, source_prefixlen); + r = nft_message_append_setelem_iprange(messages[msgcnt-1], source, source_prefixlen); else - r = nft_message_add_setelem_ip6range(messages[msgcnt-1], source, source_prefixlen); + r = nft_message_append_setelem_ip6range(messages[msgcnt-1], source, source_prefixlen); if (r < 0) return r;