From a4762e2c7945eaab88dfbbc19162083a972e4707 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 7 Sep 2026 14:34:18 +0900 Subject: [PATCH] sd-netlink: add boolean 'add' parameter to sd_nfnl_nft_message_new_table() and friends Previously, only sd_nfnl_nft_message_new_setelems() takes the 'add' flag. Let's all functions take the boolean parameter for consistency. (cherry picked from commit 534a25c885cf224048b4074adeca1e36e1ed9fb5) --- src/libsystemd/sd-netlink/netlink-internal.h | 64 +++++++++++---- .../sd-netlink/netlink-message-nfnl.c | 77 ++++++++++++------- .../sd-netlink/netlink-types-nfnl.c | 5 +- src/shared/firewall-util.c | 16 ++-- 4 files changed, 109 insertions(+), 53 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index c7d4cd70d4..dbbfec4d41 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -196,20 +196,50 @@ int sd_nfnl_message_new( uint16_t subsys, uint16_t msg_type, uint16_t flags); -int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret, - int nfproto, const char *table); -int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret, - int nfproto, const char *table, const char *chain, - const char *type, uint8_t hook, int prio); -int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret, - int nfproto, const char *table, const char *chain); -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 set_id, uint32_t klen); -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); +int sd_nfnl_nft_message_new_table( + sd_netlink *nfnl, + sd_netlink_message **ret, + int add, + int nfproto, + const char *table); +int sd_nfnl_nft_message_new_basechain( + sd_netlink *nfnl, + sd_netlink_message **ret, + int add, + int nfproto, + const char *table, + const char *chain, + const char *type, + uint8_t hook, + int prio); +int sd_nfnl_nft_message_new_rule( + sd_netlink *nfnl, + sd_netlink_message **ret, + int add, + int nfproto, + const char *table, + const char *chain); +int sd_nfnl_nft_message_new_set( + sd_netlink *nfnl, + sd_netlink_message **ret, + int add, + int nfproto, + const char *table, + const char *set_name, + uint32_t set_id, + uint32_t klen); +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 8ed2d7f037..758cf85b2b 100644 --- a/src/libsystemd/sd-netlink/netlink-message-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-nfnl.c @@ -232,6 +232,7 @@ int sd_nfnl_call_batch( int sd_nfnl_nft_message_new_basechain( sd_netlink *nfnl, sd_netlink_message **ret, + int add, /* boolean */ int nfproto, const char *table, const char *chain, @@ -246,9 +247,12 @@ int sd_nfnl_nft_message_new_basechain( assert(ret); assert(table); assert(chain); - assert(type); + assert(!add || type); - r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWCHAIN, NLM_F_CREATE); + if (add) + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWCHAIN, NLM_F_CREATE); + else + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_DELCHAIN, /* flags= */ 0); if (r < 0) return r; @@ -260,25 +264,27 @@ int sd_nfnl_nft_message_new_basechain( if (r < 0) return r; - r = sd_netlink_message_append_string(m, NFTA_CHAIN_TYPE, type); - if (r < 0) - return r; + if (add) { + r = sd_netlink_message_append_string(m, NFTA_CHAIN_TYPE, type); + if (r < 0) + return r; - r = sd_netlink_message_open_container(m, NFTA_CHAIN_HOOK); - if (r < 0) - return r; + r = sd_netlink_message_open_container(m, NFTA_CHAIN_HOOK); + if (r < 0) + return r; - r = sd_netlink_message_append_u32(m, NFTA_HOOK_HOOKNUM, htobe32(hook)); - if (r < 0) - return r; + r = sd_netlink_message_append_u32(m, NFTA_HOOK_HOOKNUM, htobe32(hook)); + if (r < 0) + return r; - r = sd_netlink_message_append_u32(m, NFTA_HOOK_PRIORITY, htobe32(prio)); - if (r < 0) - return r; + r = sd_netlink_message_append_u32(m, NFTA_HOOK_PRIORITY, htobe32(prio)); + if (r < 0) + return r; - r = sd_netlink_message_close_container(m); - if (r < 0) - return r; + r = sd_netlink_message_close_container(m); + if (r < 0) + return r; + } *ret = TAKE_PTR(m); return 0; @@ -287,6 +293,7 @@ int sd_nfnl_nft_message_new_basechain( int sd_nfnl_nft_message_new_table( sd_netlink *nfnl, sd_netlink_message **ret, + int add, /* boolean */ int nfproto, const char *table) { @@ -297,7 +304,13 @@ int sd_nfnl_nft_message_new_table( assert(ret); assert(table); - r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWTABLE, NLM_F_CREATE | NLM_F_EXCL); + /* Note, if nfproto == AF_UNSPEC, then the kernel flushes all tables. See nf_tables_deltable() in + * nf_tables_api.c in the kernel. */ + + if (add) + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWTABLE, NLM_F_CREATE | NLM_F_EXCL); + else + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_DELTABLE, /* flags= */ 0); if (r < 0) return r; @@ -312,6 +325,7 @@ int sd_nfnl_nft_message_new_table( int sd_nfnl_nft_message_new_rule( sd_netlink *nfnl, sd_netlink_message **ret, + int add, /* boolean */ int nfproto, const char *table, const char *chain) { @@ -324,7 +338,10 @@ int sd_nfnl_nft_message_new_rule( assert(table); assert(chain); - r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWRULE, NLM_F_CREATE); + if (add) + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWRULE, NLM_F_CREATE); + else + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_DELRULE, /* flags= */ 0); if (r < 0) return r; @@ -343,6 +360,7 @@ int sd_nfnl_nft_message_new_rule( int sd_nfnl_nft_message_new_set( sd_netlink *nfnl, sd_netlink_message **ret, + int add, /* boolean */ int nfproto, const char *table, const char *set_name, @@ -357,7 +375,10 @@ int sd_nfnl_nft_message_new_set( assert(table); assert(set_name); - r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSET, NLM_F_CREATE); + if (add) + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSET, NLM_F_CREATE); + else + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_DELSET, /* flags= */ 0); if (r < 0) return r; @@ -369,13 +390,15 @@ int sd_nfnl_nft_message_new_set( if (r < 0) return r; - r = sd_netlink_message_append_u32(m, NFTA_SET_ID, ++set_id); - if (r < 0) - return r; + if (add) { + r = sd_netlink_message_append_u32(m, NFTA_SET_ID, ++set_id); + if (r < 0) + return r; - r = sd_netlink_message_append_u32(m, NFTA_SET_KEY_LEN, htobe32(klen)); - if (r < 0) - return r; + r = sd_netlink_message_append_u32(m, NFTA_SET_KEY_LEN, htobe32(klen)); + if (r < 0) + return r; + } *ret = TAKE_PTR(m); return r; @@ -400,7 +423,7 @@ int sd_nfnl_nft_message_new_setelems( if (add) r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSETELEM, NLM_F_CREATE); else - r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_DELSETELEM, 0); + r = sd_nfnl_message_new(nfnl, &m, nfproto, NFNL_SUBSYS_NFTABLES, NFT_MSG_DELSETELEM, /* flags= */ 0); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-types-nfnl.c b/src/libsystemd/sd-netlink/netlink-types-nfnl.c index 3520961aed..52bd99bcf5 100644 --- a/src/libsystemd/sd-netlink/netlink-types-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-nfnl.c @@ -153,11 +153,14 @@ static const NLAPolicy nfnl_nft_setelem_list_policies[] = { DEFINE_POLICY_SET(nfnl_nft_setelem_list); static const NLAPolicy nfnl_subsys_nft_policies[] = { - [NFT_MSG_DELTABLE] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_table, sizeof(struct nfgenmsg)), [NFT_MSG_NEWTABLE] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_table, sizeof(struct nfgenmsg)), + [NFT_MSG_DELTABLE] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_table, sizeof(struct nfgenmsg)), [NFT_MSG_NEWCHAIN] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_chain, sizeof(struct nfgenmsg)), + [NFT_MSG_DELCHAIN] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_chain, sizeof(struct nfgenmsg)), [NFT_MSG_NEWRULE] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_rule, sizeof(struct nfgenmsg)), + [NFT_MSG_DELRULE] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_rule, sizeof(struct nfgenmsg)), [NFT_MSG_NEWSET] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_set, sizeof(struct nfgenmsg)), + [NFT_MSG_DELSET] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_set, sizeof(struct nfgenmsg)), [NFT_MSG_NEWSETELEM] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_setelem_list, sizeof(struct nfgenmsg)), [NFT_MSG_DELSETELEM] = BUILD_POLICY_NESTED_WITH_SIZE(nfnl_nft_setelem_list, sizeof(struct nfgenmsg)), }; diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c index 441e137ec0..986cb958a1 100644 --- a/src/shared/firewall-util.c +++ b/src/shared/firewall-util.c @@ -331,7 +331,7 @@ static int sd_nfnl_message_new_masq_rule( assert(IN_SET(family, AF_INET, AF_INET6)); assert(chain); - r = sd_nfnl_nft_message_new_rule(nfnl, &m, family, nft_table_name(), chain); + r = sd_nfnl_nft_message_new_rule(nfnl, &m, /* add= */ true, family, nft_table_name(), chain); if (r < 0) return r; @@ -386,7 +386,7 @@ static int sd_nfnl_message_new_dnat_rule_pre( assert(IN_SET(family, AF_INET, AF_INET6)); assert(chain); - r = sd_nfnl_nft_message_new_rule(nfnl, &m, family, nft_table_name(), chain); + r = sd_nfnl_nft_message_new_rule(nfnl, &m, /* add= */ true, family, nft_table_name(), chain); if (r < 0) return r; @@ -449,7 +449,7 @@ static int sd_nfnl_message_new_dnat_rule_out( assert(IN_SET(family, AF_INET, AF_INET6)); assert(chain); - r = sd_nfnl_nft_message_new_rule(nfnl, &m, family, nft_table_name(), chain); + r = sd_nfnl_nft_message_new_rule(nfnl, &m, /* add= */ true, family, nft_table_name(), chain); if (r < 0) return r; @@ -548,7 +548,7 @@ static int nft_new_set( assert(IN_SET(family, AF_INET, AF_INET6)); assert(set_name); - r = sd_nfnl_nft_message_new_set(nfnl, &m, family, nft_table_name(), set_name, set_id, klen); + r = sd_nfnl_nft_message_new_set(nfnl, &m, /* add= */ true, family, nft_table_name(), set_name, set_id, klen); if (r < 0) return r; @@ -734,23 +734,23 @@ static int fw_nftables_init_family(sd_netlink *nfnl, int family) { assert(IN_SET(family, AF_INET, AF_INET6)); /* Set F_EXCL so table add fails if the table already exists. */ - r = sd_nfnl_nft_message_new_table(nfnl, &messages[msgcnt++], family, nft_table_name()); + r = sd_nfnl_nft_message_new_table(nfnl, &messages[msgcnt++], /* add= */ true, family, nft_table_name()); if (r < 0) return r; - r = sd_nfnl_nft_message_new_basechain(nfnl, &messages[msgcnt++], family, nft_table_name(), + r = sd_nfnl_nft_message_new_basechain(nfnl, &messages[msgcnt++], /* add= */ true, family, nft_table_name(), "prerouting", "nat", NF_INET_PRE_ROUTING, NF_IP_PRI_NAT_DST + 1); if (r < 0) return r; - r = sd_nfnl_nft_message_new_basechain(nfnl, &messages[msgcnt++], family, nft_table_name(), + r = sd_nfnl_nft_message_new_basechain(nfnl, &messages[msgcnt++], /* add= */ true, family, nft_table_name(), "output", "nat", NF_INET_LOCAL_OUT, NF_IP_PRI_NAT_DST + 1); if (r < 0) return r; - r = sd_nfnl_nft_message_new_basechain(nfnl, &messages[msgcnt++], family, nft_table_name(), + r = sd_nfnl_nft_message_new_basechain(nfnl, &messages[msgcnt++], /* add= */ true, family, nft_table_name(), "postrouting", "nat", NF_INET_POST_ROUTING, NF_IP_PRI_NAT_SRC + 1); if (r < 0)