#include "netlink-types.h"
#include "socket-util.h"
-static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int family, uint16_t type, uint16_t flags) {
+static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int family, uint16_t msg_type, uint16_t flags) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
- const NLType *nl_type;
- size_t size;
int r;
assert_return(nfnl, -EINVAL);
+ assert_return(ret, -EINVAL);
- r = type_system_root_get_type(nfnl, &nl_type, NFNL_SUBSYS_NFTABLES);
+ r = message_new(nfnl, &m, NFNL_SUBSYS_NFTABLES << 8 | msg_type);
if (r < 0)
return r;
- if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
- return -EINVAL;
-
- r = message_new_empty(nfnl, &m);
- if (r < 0)
- return r;
-
- size = NLMSG_SPACE(type_get_size(nl_type));
-
- assert(size >= sizeof(struct nlmsghdr));
- m->hdr = malloc0(size);
- if (!m->hdr)
- return -ENOMEM;
-
- m->hdr->nlmsg_flags = NLM_F_REQUEST | flags;
-
- m->containers[0].type_system = type_get_type_system(nl_type);
-
- r = type_system_get_type_system(m->containers[0].type_system,
- &m->containers[0].type_system,
- type);
- if (r < 0)
- return r;
-
- m->hdr->nlmsg_len = size;
- m->hdr->nlmsg_type = NFNL_SUBSYS_NFTABLES << 8 | type;
+ m->hdr->nlmsg_flags |= flags;
*(struct nfgenmsg*) NLMSG_DATA(m->hdr) = (struct nfgenmsg) {
.nfgen_family = family,
return 0;
}
-static int nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int v) {
+static int nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, uint16_t msg_type) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = message_new(nfnl, &m, v);
+ r = message_new(nfnl, &m, NFNL_SUBSYS_NONE << 8 | msg_type);
if (r < 0)
return r;
};
*ret = TAKE_PTR(m);
- return r;
+ return 0;
}
int sd_nfnl_message_batch_begin(sd_netlink *nfnl, sd_netlink_message **ret) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWCHAIN, NLM_F_CREATE | NLM_F_ACK);
+ r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWCHAIN, NLM_F_CREATE);
if (r < 0)
return r;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = nft_message_new(nfnl, &m, family, NFT_MSG_DELTABLE, NLM_F_CREATE | NLM_F_ACK);
+ r = nft_message_new(nfnl, &m, family, NFT_MSG_DELTABLE, NLM_F_CREATE);
if (r < 0)
return r;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWTABLE, NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK);
+ r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWTABLE, NLM_F_CREATE | NLM_F_EXCL);
if (r < 0)
return r;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWRULE, NLM_F_CREATE | NLM_F_ACK);
+ r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWRULE, NLM_F_CREATE);
if (r < 0)
return r;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWSET, NLM_F_CREATE | NLM_F_ACK);
+ r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWSET, NLM_F_CREATE);
if (r < 0)
return r;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWSETELEM, NLM_F_CREATE | NLM_F_ACK);
+ r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWSETELEM, NLM_F_CREATE);
if (r < 0)
return r;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
- r = nft_message_new(nfnl, &m, family, NFT_MSG_DELSETELEM, NLM_F_ACK);
+ r = nft_message_new(nfnl, &m, family, NFT_MSG_DELSETELEM, 0);
if (r < 0)
return r;
.types = nfnl_nft_setelem_list_types,
};
-static const NLType nfnl_nft_msg_types [] = {
+static const NLType nfnl_subsys_nft_types [] = {
[NFT_MSG_DELTABLE] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_table_type_system, .size = sizeof(struct nfgenmsg) },
[NFT_MSG_NEWTABLE] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_table_type_system, .size = sizeof(struct nfgenmsg) },
[NFT_MSG_NEWCHAIN] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_chain_type_system, .size = sizeof(struct nfgenmsg) },
[NFT_MSG_DELSETELEM] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_setelem_list_type_system, .size = sizeof(struct nfgenmsg) },
};
-static const NLTypeSystem nfnl_nft_msg_type_system = {
- .count = ELEMENTSOF(nfnl_nft_msg_types),
- .types = nfnl_nft_msg_types,
+static const NLTypeSystem nfnl_subsys_nft_type_system = {
+ .count = ELEMENTSOF(nfnl_subsys_nft_types),
+ .types = nfnl_subsys_nft_types,
};
static const NLType nfnl_msg_batch_types [] = {
.types = nfnl_msg_batch_types,
};
-static const NLType nfnl_types[] = {
+static const NLType nfnl_subsys_none_types[] = {
[NFNL_MSG_BATCH_BEGIN] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_msg_batch_type_system, .size = sizeof(struct nfgenmsg) },
[NFNL_MSG_BATCH_END] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_msg_batch_type_system, .size = sizeof(struct nfgenmsg) },
- [NFNL_SUBSYS_NFTABLES] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_msg_type_system, .size = sizeof(struct nfgenmsg) },
+};
+
+static const NLTypeSystem nfnl_subsys_none_type_system = {
+ .count = ELEMENTSOF(nfnl_subsys_none_types),
+ .types = nfnl_subsys_none_types,
+};
+
+static const NLType nfnl_types[] = {
+ [NFNL_SUBSYS_NONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_subsys_none_type_system },
+ [NFNL_SUBSYS_NFTABLES] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_subsys_nft_type_system },
};
static const NLTypeSystem nfnl_type_system = {
};
int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret) {
- return type_system_get_type(&nfnl_type_system, ret, nlmsg_type);
+ const NLTypeSystem *subsys;
+ int r;
+
+ r = type_system_get_type_system(&nfnl_type_system, &subsys, nlmsg_type >> 8);
+ if (r < 0)
+ return r;
+
+ return type_system_get_type(subsys, ret, nlmsg_type & ((1U << 8) - 1));
}