1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-27 13:57:26 +03:00

sd-netlink: split type system for nfnl

This makes the root type system for nfnl indexed by subsystem, and
itroduces a next level type system for each subsystem. The second
level type systems are indexed by message types correspond to each
subsystem.
This commit is contained in:
Yu Watanabe 2021-08-24 16:10:49 +09:00
parent 07acd0d90b
commit fae9ee25a4
2 changed files with 37 additions and 47 deletions

View File

@ -15,44 +15,18 @@
#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,
@ -64,11 +38,11 @@ static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int famil
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;
@ -79,7 +53,7 @@ static int nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int v)
};
*ret = TAKE_PTR(m);
return r;
return 0;
}
int sd_nfnl_message_batch_begin(sd_netlink *nfnl, sd_netlink_message **ret) {
@ -103,7 +77,7 @@ int sd_nfnl_nft_message_new_basechain(
_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;
@ -148,7 +122,7 @@ int sd_nfnl_nft_message_del_table(
_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;
@ -169,7 +143,7 @@ int sd_nfnl_nft_message_new_table(
_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;
@ -191,7 +165,7 @@ int sd_nfnl_nft_message_new_rule(
_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;
@ -219,7 +193,7 @@ int sd_nfnl_nft_message_new_set(
_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;
@ -253,7 +227,7 @@ 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, 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;
@ -283,7 +257,7 @@ int sd_nfnl_nft_message_del_setelems_begin(
_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;

View File

@ -209,7 +209,7 @@ static const NLTypeSystem nfnl_nft_setelem_list_type_system = {
.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) },
@ -219,9 +219,9 @@ static const NLType nfnl_nft_msg_types [] = {
[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 [] = {
@ -233,10 +233,19 @@ static const NLTypeSystem nfnl_msg_batch_type_system = {
.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 = {
@ -245,5 +254,12 @@ 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));
}