From 9d7fbec1e53fd566d4adca698f0aa124d835f66a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Jun 2021 15:26:25 +0900 Subject: [PATCH 01/29] sd-netlink: drop unused type --- src/systemd/sd-netlink.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index b7e1a90958..1a2d3c1046 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -31,7 +31,6 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_netlink sd_netlink; -typedef struct sd_genl_socket sd_genl_socket; typedef struct sd_netlink_message sd_netlink_message; typedef struct sd_netlink_slot sd_netlink_slot; From 0c45a60f8e36f8c0e3785084a739837e2317ee53 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Jun 2021 15:33:58 +0900 Subject: [PATCH 02/29] test: add usual log messages in test-netlink --- src/libsystemd/sd-netlink/test-netlink.c | 38 +++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 41a7280477..76a567ec4d 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -14,12 +14,14 @@ #include "stdio-util.h" #include "string-util.h" #include "strv.h" -#include "util.h" +#include "tests.h" static void test_message_link_bridge(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; uint32_t cost; + log_debug("/* %s */", __func__); + assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 1) >= 0); assert_se(sd_rtnl_message_link_set_family(message, AF_BRIDGE) >= 0); assert_se(sd_netlink_message_open_container(message, IFLA_PROTINFO) >= 0); @@ -40,6 +42,8 @@ static void test_link_configure(sd_netlink *rtnl, int ifindex) { const char *name_out; struct ether_addr mac_out; + log_debug("/* %s */", __func__); + /* we'd really like to test NEWLINK, but let's not mess with the running kernel */ assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0); @@ -57,6 +61,8 @@ static void test_link_get(sd_netlink *rtnl, int ifindex) { uint32_t u32_data; struct ether_addr eth_data; + log_debug("/* %s */", __func__); + assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0); assert_se(m); @@ -83,6 +89,8 @@ static void test_address_get(sd_netlink *rtnl, int ifindex) { struct ifa_cacheinfo cache; const char *label; + log_debug("/* %s */", __func__); + assert_se(sd_rtnl_message_new_addr(rtnl, &m, RTM_GETADDR, ifindex, AF_INET) >= 0); assert_se(m); assert_se(sd_netlink_message_request_dump(m, true) >= 0); @@ -100,6 +108,8 @@ static void test_route(sd_netlink *rtnl) { uint32_t index = 2, u32_data; int r; + log_debug("/* %s */", __func__); + r = sd_rtnl_message_new_route(rtnl, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC); if (r < 0) { log_error_errno(r, "Could not create RTM_NEWROUTE message: %m"); @@ -134,6 +144,8 @@ static void test_route(sd_netlink *rtnl) { static void test_multiple(void) { sd_netlink *rtnl1, *rtnl2; + log_debug("/* %s */", __func__); + assert_se(sd_netlink_open(&rtnl1) >= 0); assert_se(sd_netlink_open(&rtnl2) >= 0); @@ -164,6 +176,8 @@ static void test_event_loop(int ifindex) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; char *ifname; + log_debug("/* %s */", __func__); + ifname = strdup("lo2"); assert_se(ifname); @@ -194,6 +208,8 @@ static void test_async(int ifindex) { const char *description; char *ifname; + log_debug("/* %s */", __func__); + ifname = strdup("lo"); assert_se(ifname); @@ -225,6 +241,8 @@ static void test_slot_set(int ifindex) { const char *description; char *ifname; + log_debug("/* %s */", __func__); + ifname = strdup("lo"); assert_se(ifname); @@ -303,6 +321,8 @@ static void test_async_destroy_callback(int ifindex) { _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL; char *ifname; + log_debug("/* %s */", __func__); + assert_se(t = new(struct test_async_object, 1)); assert_se(ifname = strdup("lo")); *t = (struct test_async_object) { @@ -371,6 +391,8 @@ static void test_pipe(int ifindex) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m1 = NULL, *m2 = NULL; int counter = 0; + log_debug("/* %s */", __func__); + assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(sd_rtnl_message_new_link(rtnl, &m1, RTM_GETLINK, ifindex) >= 0); @@ -396,6 +418,8 @@ static void test_container(sd_netlink *rtnl) { uint32_t u32_data; const char *string_data; + log_debug("/* %s */", __func__); + assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0); assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0); @@ -429,6 +453,8 @@ static void test_match(void) { _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *s1 = NULL, *s2 = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + log_debug("/* %s */", __func__); + assert_se(sd_netlink_open(&rtnl) >= 0); assert_se(sd_netlink_add_match(rtnl, &s1, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0); @@ -445,6 +471,8 @@ static void test_get_addresses(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; sd_netlink_message *m; + log_debug("/* %s */", __func__); + assert_se(sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC) >= 0); assert_se(sd_netlink_message_request_dump(req, true) >= 0); assert_se(sd_netlink_call(rtnl, req, 0, &reply) >= 0); @@ -472,6 +500,8 @@ static void test_get_addresses(sd_netlink *rtnl) { static void test_message(sd_netlink *rtnl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + log_debug("/* %s */", __func__); + assert_se(rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0); assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT); } @@ -480,6 +510,8 @@ static void test_array(void) { _cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + log_debug("/* %s */", __func__); + assert_se(sd_genl_socket_open(&genl) >= 0); assert_se(sd_genl_message_new(genl, SD_GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &m) >= 0); @@ -522,6 +554,8 @@ static void test_strv(sd_netlink *rtnl) { _cleanup_strv_free_ char **names_in = NULL, **names_out; const char *p; + log_debug("/* %s */", __func__); + assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1) >= 0); for (unsigned i = 0; i < 10; i++) { @@ -555,6 +589,8 @@ int main(void) { int if_loopback; uint16_t type; + test_setup_logging(LOG_DEBUG); + test_match(); test_multiple(); From 409856d328b5bcb7b5305bf835a846d3985442f1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 7 Jul 2021 09:42:41 +0900 Subject: [PATCH 03/29] sd-netlink: rename variables, arguments, and functions Most changes are 'rtnl' -> 'nl' where the function is not only for rtnl. --- src/libsystemd/sd-netlink/netlink-internal.h | 27 +- src/libsystemd/sd-netlink/netlink-message.c | 59 ++- src/libsystemd/sd-netlink/netlink-socket.c | 60 +-- src/libsystemd/sd-netlink/netlink-util.c | 19 - src/libsystemd/sd-netlink/netlink-util.h | 4 - src/libsystemd/sd-netlink/nfnl-message.c | 8 +- src/libsystemd/sd-netlink/rtnl-message.c | 10 +- src/libsystemd/sd-netlink/sd-netlink.c | 394 +++++++++---------- src/libsystemd/sd-netlink/test-netlink.c | 7 +- src/systemd/sd-netlink.h | 20 +- 10 files changed, 301 insertions(+), 307 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 49c7dd773d..d85b4a0774 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -10,11 +10,11 @@ #include "prioq.h" #include "time-util.h" -#define RTNL_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC)) +#define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC)) -#define RTNL_RQUEUE_MAX 64*1024 +#define NETLINK_RQUEUE_MAX 64*1024 -#define RTNL_CONTAINER_DEPTH 32 +#define NETLINK_CONTAINER_DEPTH 32 struct reply_callback { sd_netlink_message_handler_t callback; @@ -118,7 +118,7 @@ struct sd_netlink_message { int protocol; struct nlmsghdr *hdr; - struct netlink_container containers[RTNL_CONTAINER_DEPTH]; + struct netlink_container containers[NETLINK_CONTAINER_DEPTH]; unsigned n_containers; /* number of containers */ bool sealed:1; bool broadcast:1; @@ -126,10 +126,16 @@ struct sd_netlink_message { sd_netlink_message *next; /* next in a chain of multi-part messages */ }; -int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type); -int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret); +int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type); +int message_new_empty(sd_netlink *nl, sd_netlink_message **ret); +int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret); +uint32_t message_get_serial(sd_netlink_message *m); +void message_seal(sd_netlink_message *m); int netlink_open_family(sd_netlink **ret, int family); +bool netlink_pid_changed(sd_netlink *nl); +int netlink_rqueue_make_room(sd_netlink *nl); +int netlink_rqueue_partial_make_room(sd_netlink *nl); int socket_open(int family); int socket_bind(sd_netlink *nl); @@ -139,9 +145,6 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m); int socket_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount); int socket_read_message(sd_netlink *nl); -int rtnl_rqueue_make_room(sd_netlink *rtnl); -int rtnl_rqueue_partial_make_room(sd_netlink *rtnl); - -/* Make sure callbacks don't destroy the rtnl connection */ -#define NETLINK_DONT_DESTROY(rtnl) \ - _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl) +/* Make sure callbacks don't destroy the netlink connection */ +#define NETLINK_DONT_DESTROY(nl) \ + _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index c4dc4e67dd..922700c634 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -20,15 +20,13 @@ #define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK) #define RTA_FLAGS(rta) ((rta)->rta_type & ~NLA_TYPE_MASK) -int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) { +int message_new_empty(sd_netlink *nl, sd_netlink_message **ret) { sd_netlink_message *m; assert_return(ret, -EINVAL); - /* Note that 'rtnl' is currently unused, if we start using it internally - we must take care to avoid problems due to mutual references between - buses and their queued messages. See sd-bus. - */ + /* Note that 'nl' is currently unused, if we start using it internally we must take care to + * avoid problems due to mutual references between buses and their queued messages. See sd-bus. */ m = new(sd_netlink_message, 1); if (!m) @@ -36,7 +34,7 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) { *m = (sd_netlink_message) { .n_ref = 1, - .protocol = rtnl->protocol, + .protocol = nl->protocol, .sealed = false, }; @@ -45,22 +43,22 @@ int message_new_empty(sd_netlink *rtnl, sd_netlink_message **ret) { return 0; } -int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { +int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const NLType *nl_type; size_t size; int r; - assert_return(rtnl, -EINVAL); + assert_return(nl, -EINVAL); - r = type_system_root_get_type(rtnl, &nl_type, type); + r = type_system_root_get_type(nl, &nl_type, type); if (r < 0) return r; if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) return -EINVAL; - r = message_new_empty(rtnl, &m); + r = message_new_empty(nl, &m); if (r < 0) return r; @@ -82,6 +80,25 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { return 0; } +int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret) { + struct nlmsgerr *err; + int r; + + assert(error <= 0); + + r = message_new(nl, ret, NLMSG_ERROR); + if (r < 0) + return r; + + message_seal(*ret); + (*ret)->hdr->nlmsg_seq = serial; + + err = NLMSG_DATA((*ret)->hdr); + err->error = error; + + return 0; +} + int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) { assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); @@ -538,7 +555,7 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); /* m->containers[m->n_containers + 1] is accessed both in read and write. Prevent access out of bound */ - assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE); + assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -ERANGE); r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED); if (r < 0) { @@ -585,7 +602,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE); + assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -ERANGE); r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); if (r < 0) @@ -628,7 +645,7 @@ int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type) { assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -ERANGE); + assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -ERANGE); r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0); if (r < 0) @@ -673,7 +690,7 @@ static int netlink_message_read_internal( assert_return(m, -EINVAL); assert_return(m->sealed, -EPERM); - assert(m->n_containers < RTNL_CONTAINER_DEPTH); + assert(m->n_containers < NETLINK_CONTAINER_DEPTH); if (!m->containers[m->n_containers].attributes) return -ENODATA; @@ -1008,7 +1025,7 @@ int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container int r; assert_return(m, -EINVAL); - assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL); + assert_return(m->n_containers < NETLINK_CONTAINER_DEPTH, -EINVAL); r = type_system_get_type(m->containers[m->n_containers].type_system, &nl_type, @@ -1079,7 +1096,7 @@ static int netlink_container_parse(sd_netlink_message *m, return -ENOMEM; if (attributes[type].offset != 0) - log_debug("rtnl: message parse - overwriting repeated attribute"); + log_debug("sd-netlink: message parse - overwriting repeated attribute"); attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr; attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED; @@ -1104,7 +1121,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ int r; assert_return(m, -EINVAL); - assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -EINVAL); + assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -EINVAL); r = type_system_get_type(m->containers[m->n_containers].type_system, &nl_type, @@ -1195,7 +1212,7 @@ int sd_netlink_message_enter_array(sd_netlink_message *m, unsigned short type_id int r; assert_return(m, -EINVAL); - assert_return(m->n_containers < (RTNL_CONTAINER_DEPTH - 1), -EINVAL); + assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -EINVAL); r = netlink_message_read_internal(m, type_id, &container, NULL); if (r < 0) @@ -1231,7 +1248,7 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) { return 0; } -uint32_t rtnl_message_get_serial(sd_netlink_message *m) { +uint32_t message_get_serial(sd_netlink_message *m) { assert(m); assert(m->hdr); @@ -1291,7 +1308,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) { /* don't allow appending to message once parsed */ if (!m->sealed) - rtnl_message_seal(m); + message_seal(m); for (unsigned i = 1; i <= m->n_containers; i++) m->containers[i].attributes = mfree(m->containers[i].attributes); @@ -1332,7 +1349,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) { return 0; } -void rtnl_message_seal(sd_netlink_message *m) { +void message_seal(sd_netlink_message *m) { assert(m); assert(!m->sealed); diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 21ec00cca0..1168f4edc0 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -238,7 +238,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr n = recvmsg_safe(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0)); if (n == -ENOBUFS) - return log_debug_errno(n, "rtnl: kernel receive buffer overrun"); + return log_debug_errno(n, "sd-netlink: kernel receive buffer overrun"); if (IN_SET(n, -EAGAIN, -EINTR)) return 0; if (n < 0) @@ -246,7 +246,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr if (sender.nl.nl_pid != 0) { /* not from the kernel, ignore */ - log_debug("rtnl: ignoring message from PID %"PRIu32, sender.nl.nl_pid); + log_debug("sd-netlink: ignoring message from PID %"PRIu32, sender.nl.nl_pid); if (peek) { /* drop the message */ @@ -276,7 +276,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr * If nothing useful was received 0 is returned. * On failure, a negative error code is returned. */ -int socket_read_message(sd_netlink *rtnl) { +int socket_read_message(sd_netlink *nl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *first = NULL; bool multi_part = false, done = false; size_t len, allocated; @@ -285,25 +285,25 @@ int socket_read_message(sd_netlink *rtnl) { unsigned i = 0; int r; - assert(rtnl); - assert(rtnl->rbuffer); + assert(nl); + assert(nl->rbuffer); /* read nothing, just get the pending message size */ - r = socket_recv_message(rtnl->fd, &iov, NULL, true); + r = socket_recv_message(nl->fd, &iov, NULL, true); if (r <= 0) return r; else len = (size_t) r; /* make room for the pending message */ - if (!greedy_realloc((void **)&rtnl->rbuffer, len, sizeof(uint8_t))) + if (!greedy_realloc((void**) &nl->rbuffer, len, sizeof(uint8_t))) return -ENOMEM; - allocated = MALLOC_SIZEOF_SAFE(rtnl->rbuffer); - iov = IOVEC_MAKE(rtnl->rbuffer, allocated); + allocated = MALLOC_SIZEOF_SAFE(nl->rbuffer); + iov = IOVEC_MAKE(nl->rbuffer, allocated); /* read the pending message */ - r = socket_recv_message(rtnl->fd, &iov, &group, false); + r = socket_recv_message(nl->fd, &iov, &group, false); if (r <= 0) return r; else @@ -313,22 +313,22 @@ int socket_read_message(sd_netlink *rtnl) { /* message did not fit in read buffer */ return -EIO; - if (NLMSG_OK(rtnl->rbuffer, len) && rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI) { + if (NLMSG_OK(nl->rbuffer, len) && nl->rbuffer->nlmsg_flags & NLM_F_MULTI) { multi_part = true; - for (i = 0; i < rtnl->rqueue_partial_size; i++) - if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) == - rtnl->rbuffer->nlmsg_seq) { - first = rtnl->rqueue_partial[i]; + for (i = 0; i < nl->rqueue_partial_size; i++) + if (message_get_serial(nl->rqueue_partial[i]) == + nl->rbuffer->nlmsg_seq) { + first = nl->rqueue_partial[i]; break; } } - for (struct nlmsghdr *new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) { + for (struct nlmsghdr *new_msg = nl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const NLType *nl_type; - if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid) + if (!group && new_msg->nlmsg_pid != nl->sockaddr.nl.nl_pid) /* not broadcast and not for us */ continue; @@ -346,7 +346,7 @@ int socket_read_message(sd_netlink *rtnl) { } /* check that we support this message type */ - r = type_system_root_get_type(rtnl, &nl_type, new_msg->nlmsg_type); + r = type_system_root_get_type(nl, &nl_type, new_msg->nlmsg_type); if (r < 0) { if (r == -EOPNOTSUPP) log_debug("sd-netlink: ignored message with unknown type: %i", @@ -361,7 +361,7 @@ int socket_read_message(sd_netlink *rtnl) { continue; } - r = message_new_empty(rtnl, &m); + r = message_new_empty(nl, &m); if (r < 0) return r; @@ -372,7 +372,7 @@ int socket_read_message(sd_netlink *rtnl) { return -ENOMEM; /* seal and parse the top-level message */ - r = sd_netlink_message_rewind(m, rtnl); + r = sd_netlink_message_rewind(m, nl); if (r < 0) return r; @@ -390,31 +390,31 @@ int socket_read_message(sd_netlink *rtnl) { if (!multi_part || done) { /* we got a complete message, push it on the read queue */ - r = rtnl_rqueue_make_room(rtnl); + r = netlink_rqueue_make_room(nl); if (r < 0) return r; - rtnl->rqueue[rtnl->rqueue_size++] = TAKE_PTR(first); + nl->rqueue[nl->rqueue_size++] = TAKE_PTR(first); - if (multi_part && (i < rtnl->rqueue_partial_size)) { + if (multi_part && (i < nl->rqueue_partial_size)) { /* remove the message form the partial read queue */ - memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1, - sizeof(sd_netlink_message*) * (rtnl->rqueue_partial_size - i - 1)); - rtnl->rqueue_partial_size--; + memmove(nl->rqueue_partial + i, nl->rqueue_partial + i + 1, + sizeof(sd_netlink_message*) * (nl->rqueue_partial_size - i - 1)); + nl->rqueue_partial_size--; } return 1; } else { /* we only got a partial multi-part message, push it on the partial read queue */ - if (i < rtnl->rqueue_partial_size) - rtnl->rqueue_partial[i] = TAKE_PTR(first); + if (i < nl->rqueue_partial_size) + nl->rqueue_partial[i] = TAKE_PTR(first); else { - r = rtnl_rqueue_partial_make_room(rtnl); + r = netlink_rqueue_partial_make_room(nl); if (r < 0) return r; - rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = TAKE_PTR(first); + nl->rqueue_partial[nl->rqueue_partial_size++] = TAKE_PTR(first); } return 0; diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 1211145fbf..886bb48210 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -400,25 +400,6 @@ int rtnl_get_link_info(sd_netlink **rtnl, int ifindex, unsigned short *ret_iftyp return 0; } -int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) { - struct nlmsgerr *err; - int r; - - assert(error <= 0); - - r = message_new(rtnl, ret, NLMSG_ERROR); - if (r < 0) - return r; - - rtnl_message_seal(*ret); - (*ret)->hdr->nlmsg_seq = serial; - - err = NLMSG_DATA((*ret)->hdr); - err->error = error; - - return 0; -} - int rtnl_log_parse_error(int r) { return log_error_errno(r, "Failed to parse netlink message: %m"); } diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index a5d725655d..5208dd94e4 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -29,10 +29,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(MultipathRoute*, multipath_route_free); int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret); -int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret); -uint32_t rtnl_message_get_serial(sd_netlink_message *m); -void rtnl_message_seal(sd_netlink_message *m); - static inline bool rtnl_message_type_is_neigh(uint16_t type) { return IN_SET(type, RTM_NEWNEIGH, RTM_GETNEIGH, RTM_DELNEIGH); } diff --git a/src/libsystemd/sd-netlink/nfnl-message.c b/src/libsystemd/sd-netlink/nfnl-message.c index 5f669f750b..001a7b277e 100644 --- a/src/libsystemd/sd-netlink/nfnl-message.c +++ b/src/libsystemd/sd-netlink/nfnl-message.c @@ -13,9 +13,7 @@ #include "format-util.h" #include "netlink-internal.h" #include "netlink-types.h" -#include "netlink-util.h" #include "socket-util.h" -#include "util.h" static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int family, uint16_t type, uint16_t flags) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; @@ -66,7 +64,7 @@ static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int famil return 0; } -static int sd_nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int v) { +static int nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int v) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -85,11 +83,11 @@ static int sd_nfnl_message_batch(sd_netlink *nfnl, sd_netlink_message **ret, int } int sd_nfnl_message_batch_begin(sd_netlink *nfnl, sd_netlink_message **ret) { - return sd_nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_BEGIN); + return nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_BEGIN); } int sd_nfnl_message_batch_end(sd_netlink *nfnl, sd_netlink_message **ret) { - return sd_nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_END); + return nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_END); } int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret, diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c index 9127167bb2..313857699a 100644 --- a/src/libsystemd/sd-netlink/rtnl-message.c +++ b/src/libsystemd/sd-netlink/rtnl-message.c @@ -271,13 +271,13 @@ int sd_rtnl_message_new_route(sd_netlink *rtnl, sd_netlink_message **ret, } int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, - uint16_t nhmsg_type, int nh_family, + uint16_t nlmsg_type, int nh_family, unsigned char nh_protocol) { struct nhmsg *nhm; int r; - assert_return(rtnl_message_type_is_nexthop(nhmsg_type), -EINVAL); - switch(nhmsg_type) { + assert_return(rtnl_message_type_is_nexthop(nlmsg_type), -EINVAL); + switch(nlmsg_type) { case RTM_DELNEXTHOP: assert_return(nh_family == AF_UNSPEC, -EINVAL); _fallthrough_; @@ -292,11 +292,11 @@ int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, } assert_return(ret, -EINVAL); - r = message_new(rtnl, ret, nhmsg_type); + r = message_new(rtnl, ret, nlmsg_type); if (r < 0) return r; - if (nhmsg_type == RTM_NEWNEXTHOP) + if (nlmsg_type == RTM_NEWNEXTHOP) (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND; nhm = NLMSG_DATA((*ret)->hdr); diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index f8a1bde6a6..22697aa992 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -11,25 +11,23 @@ #include "macro.h" #include "netlink-internal.h" #include "netlink-slot.h" -#include "netlink-util.h" #include "process-util.h" #include "socket-util.h" #include "string-util.h" -#include "util.h" /* Some really high limit, to catch programming errors */ #define REPLY_CALLBACKS_MAX UINT16_MAX -static int sd_netlink_new(sd_netlink **ret) { - _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; +static int netlink_new(sd_netlink **ret) { + _cleanup_(sd_netlink_unrefp) sd_netlink *nl = NULL; assert_return(ret, -EINVAL); - rtnl = new(sd_netlink, 1); - if (!rtnl) + nl = new(sd_netlink, 1); + if (!nl) return -ENOMEM; - *rtnl = (sd_netlink) { + *nl = (sd_netlink) { .n_ref = 1, .fd = -1, .sockaddr.nl.nl_family = AF_NETLINK, @@ -61,60 +59,48 @@ static int sd_netlink_new(sd_netlink **ret) { .serial = (uint32_t) (now(CLOCK_MONOTONIC) % UINT32_MAX) + 1, }; - /* We guarantee that the read buffer has at least space for - * a message header */ - if (!greedy_realloc((void**)&rtnl->rbuffer, sizeof(struct nlmsghdr), sizeof(uint8_t))) + /* We guarantee that the read buffer has at least space for a message header */ + if (!greedy_realloc((void**) &nl->rbuffer, sizeof(struct nlmsghdr), sizeof(uint8_t))) return -ENOMEM; - *ret = TAKE_PTR(rtnl); - + *ret = TAKE_PTR(nl); return 0; } -int sd_netlink_new_from_netlink(sd_netlink **ret, int fd) { - _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; +int sd_netlink_new_from_fd(sd_netlink **ret, int fd) { + _cleanup_(sd_netlink_unrefp) sd_netlink *nl = NULL; socklen_t addrlen; int r; assert_return(ret, -EINVAL); - r = sd_netlink_new(&rtnl); + r = netlink_new(&nl); if (r < 0) return r; - addrlen = sizeof(rtnl->sockaddr); + addrlen = sizeof(nl->sockaddr); - r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen); + r = getsockname(fd, &nl->sockaddr.sa, &addrlen); if (r < 0) return -errno; - if (rtnl->sockaddr.nl.nl_family != AF_NETLINK) + if (nl->sockaddr.nl.nl_family != AF_NETLINK) return -EINVAL; - rtnl->fd = fd; - - *ret = TAKE_PTR(rtnl); + nl->fd = fd; + *ret = TAKE_PTR(nl); return 0; } -static bool rtnl_pid_changed(const sd_netlink *rtnl) { - assert(rtnl); - - /* We don't support people creating an rtnl connection and - * keeping it around over a fork(). Let's complain. */ - - return rtnl->original_pid != getpid_cached(); -} - int sd_netlink_open_fd(sd_netlink **ret, int fd) { - _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + _cleanup_(sd_netlink_unrefp) sd_netlink *nl = NULL; int r, protocol; assert_return(ret, -EINVAL); assert_return(fd >= 0, -EBADF); - r = sd_netlink_new(&rtnl); + r = netlink_new(&nl); if (r < 0) return r; @@ -122,8 +108,8 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) { if (r < 0) return r; - rtnl->fd = fd; - rtnl->protocol = protocol; + nl->fd = fd; + nl->protocol = protocol; r = setsockopt_int(fd, SOL_NETLINK, NETLINK_EXT_ACK, true); if (r < 0) @@ -133,14 +119,14 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) { if (r < 0) log_debug_errno(r, "sd-netlink: Failed to enable NETLINK_GET_STRICT_CHK option, ignoring: %m"); - r = socket_bind(rtnl); + r = socket_bind(nl); if (r < 0) { - rtnl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */ - rtnl->protocol = -1; + nl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */ + nl->protocol = -1; return r; } - *ret = TAKE_PTR(rtnl); + *ret = TAKE_PTR(nl); return 0; } @@ -165,91 +151,102 @@ int sd_netlink_open(sd_netlink **ret) { return netlink_open_family(ret, NETLINK_ROUTE); } -int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) { - assert_return(rtnl, -EINVAL); - assert_return(!rtnl_pid_changed(rtnl), -ECHILD); +bool netlink_pid_changed(sd_netlink *nl) { + assert(nl); - return fd_inc_rcvbuf(rtnl->fd, size); + /* We don't support people creating an nl connection and + * keeping it around over a fork(). Let's complain. */ + + return nl->original_pid != getpid_cached(); } -static sd_netlink *netlink_free(sd_netlink *rtnl) { +int sd_netlink_inc_rcvbuf(sd_netlink *nl, size_t size) { + assert_return(nl, -EINVAL); + assert_return(!netlink_pid_changed(nl), -ECHILD); + + return fd_inc_rcvbuf(nl->fd, size); +} + +static sd_netlink *netlink_free(sd_netlink *nl) { sd_netlink_slot *s; unsigned i; - assert(rtnl); + assert(nl); - for (i = 0; i < rtnl->rqueue_size; i++) - sd_netlink_message_unref(rtnl->rqueue[i]); - free(rtnl->rqueue); + for (i = 0; i < nl->rqueue_size; i++) + sd_netlink_message_unref(nl->rqueue[i]); + free(nl->rqueue); - for (i = 0; i < rtnl->rqueue_partial_size; i++) - sd_netlink_message_unref(rtnl->rqueue_partial[i]); - free(rtnl->rqueue_partial); + for (i = 0; i < nl->rqueue_partial_size; i++) + sd_netlink_message_unref(nl->rqueue_partial[i]); + free(nl->rqueue_partial); - free(rtnl->rbuffer); + free(nl->rbuffer); - while ((s = rtnl->slots)) { + while ((s = nl->slots)) { assert(s->floating); netlink_slot_disconnect(s, true); } - hashmap_free(rtnl->reply_callbacks); - prioq_free(rtnl->reply_callbacks_prioq); + hashmap_free(nl->reply_callbacks); + prioq_free(nl->reply_callbacks_prioq); - sd_event_source_unref(rtnl->io_event_source); - sd_event_source_unref(rtnl->time_event_source); - sd_event_unref(rtnl->event); + sd_event_source_unref(nl->io_event_source); + sd_event_source_unref(nl->time_event_source); + sd_event_unref(nl->event); - hashmap_free(rtnl->broadcast_group_refs); + hashmap_free(nl->broadcast_group_refs); - hashmap_free(rtnl->genl_family_to_nlmsg_type); - hashmap_free(rtnl->nlmsg_type_to_genl_family); + hashmap_free(nl->genl_family_to_nlmsg_type); + hashmap_free(nl->nlmsg_type_to_genl_family); - safe_close(rtnl->fd); - return mfree(rtnl); + safe_close(nl->fd); + return mfree(nl); } DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_netlink, sd_netlink, netlink_free); -static void rtnl_seal_message(sd_netlink *rtnl, sd_netlink_message *m) { +static void netlink_seal_message(sd_netlink *nl, sd_netlink_message *m) { uint32_t picked; - assert(rtnl); - assert(!rtnl_pid_changed(rtnl)); + assert(nl); + assert(!netlink_pid_changed(nl)); assert(m); assert(m->hdr); /* Avoid collisions with outstanding requests */ do { - picked = rtnl->serial; + picked = nl->serial; /* Don't use seq == 0, as that is used for broadcasts, so we would get confused by replies to such messages */ - rtnl->serial = rtnl->serial == UINT32_MAX ? 1 : rtnl->serial + 1; + nl->serial = nl->serial == UINT32_MAX ? 1 : nl->serial + 1; - } while (hashmap_contains(rtnl->reply_callbacks, UINT32_TO_PTR(picked))); + } while (hashmap_contains(nl->reply_callbacks, UINT32_TO_PTR(picked))); m->hdr->nlmsg_seq = picked; - rtnl_message_seal(m); + message_seal(m); } -int sd_netlink_send(sd_netlink *nl, - sd_netlink_message *message, - uint32_t *serial) { +int sd_netlink_send( + sd_netlink *nl, + sd_netlink_message *message, + uint32_t *serial) { + int r; assert_return(nl, -EINVAL); - assert_return(!rtnl_pid_changed(nl), -ECHILD); + assert_return(!netlink_pid_changed(nl), -ECHILD); assert_return(message, -EINVAL); assert_return(!message->sealed, -EPERM); - rtnl_seal_message(nl, message); + netlink_seal_message(nl, message); r = socket_write_message(nl, message); if (r < 0) return r; if (serial) - *serial = rtnl_message_get_serial(message); + *serial = message_get_serial(message); return 1; } @@ -264,7 +261,7 @@ int sd_netlink_sendv( int r; assert_return(nl, -EINVAL); - assert_return(!rtnl_pid_changed(nl), -ECHILD); + assert_return(!netlink_pid_changed(nl), -ECHILD); assert_return(messages, -EINVAL); assert_return(msgcount > 0, -EINVAL); @@ -277,9 +274,9 @@ int sd_netlink_sendv( for (unsigned i = 0; i < msgcount; i++) { assert_return(!messages[i]->sealed, -EPERM); - rtnl_seal_message(nl, messages[i]); + netlink_seal_message(nl, messages[i]); if (serials) - serials[i] = rtnl_message_get_serial(messages[i]); + serials[i] = message_get_serial(messages[i]); } r = socket_writev_message(nl, messages, msgcount); @@ -292,45 +289,45 @@ int sd_netlink_sendv( return r; } -int rtnl_rqueue_make_room(sd_netlink *rtnl) { - assert(rtnl); +int netlink_rqueue_make_room(sd_netlink *nl) { + assert(nl); - if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX) + if (nl->rqueue_size >= NETLINK_RQUEUE_MAX) return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS), - "rtnl: exhausted the read queue size (%d)", - RTNL_RQUEUE_MAX); + "sd-netlink: exhausted the read queue size (%d)", + NETLINK_RQUEUE_MAX); - if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_size + 1)) + if (!GREEDY_REALLOC(nl->rqueue, nl->rqueue_size + 1)) return -ENOMEM; return 0; } -int rtnl_rqueue_partial_make_room(sd_netlink *rtnl) { - assert(rtnl); +int netlink_rqueue_partial_make_room(sd_netlink *nl) { + assert(nl); - if (rtnl->rqueue_partial_size >= RTNL_RQUEUE_MAX) + if (nl->rqueue_partial_size >= NETLINK_RQUEUE_MAX) return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS), - "rtnl: exhausted the partial read queue size (%d)", - RTNL_RQUEUE_MAX); + "sd-netlink: exhausted the partial read queue size (%d)", + NETLINK_RQUEUE_MAX); - if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_size + 1)) + if (!GREEDY_REALLOC(nl->rqueue_partial, nl->rqueue_partial_size + 1)) return -ENOMEM; return 0; } -static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) { +static int dispatch_rqueue(sd_netlink *nl, sd_netlink_message **message) { int r; - assert(rtnl); + assert(nl); assert(message); - if (rtnl->rqueue_size <= 0) { + if (nl->rqueue_size <= 0) { /* Try to read a new message */ - r = socket_read_message(rtnl); + r = socket_read_message(nl); if (r == -ENOBUFS) { /* FIXME: ignore buffer overruns for now */ - log_debug_errno(r, "Got ENOBUFS from netlink socket, ignoring."); + log_debug_errno(r, "sd-netlink: Got ENOBUFS from netlink socket, ignoring."); return 1; } if (r <= 0) @@ -338,23 +335,23 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) { } /* Dispatch a queued message */ - *message = rtnl->rqueue[0]; - rtnl->rqueue_size--; - memmove(rtnl->rqueue, rtnl->rqueue + 1, sizeof(sd_netlink_message*) * rtnl->rqueue_size); + *message = nl->rqueue[0]; + nl->rqueue_size--; + memmove(nl->rqueue, nl->rqueue + 1, sizeof(sd_netlink_message*) * nl->rqueue_size); return 1; } -static int process_timeout(sd_netlink *rtnl) { +static int process_timeout(sd_netlink *nl) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; struct reply_callback *c; sd_netlink_slot *slot; usec_t n; int r; - assert(rtnl); + assert(nl); - c = prioq_peek(rtnl->reply_callbacks_prioq); + c = prioq_peek(nl->reply_callbacks_prioq); if (!c) return 0; @@ -362,17 +359,17 @@ static int process_timeout(sd_netlink *rtnl) { if (c->timeout > n) return 0; - r = rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, c->serial, &m); + r = message_new_synthetic_error(nl, -ETIMEDOUT, c->serial, &m); if (r < 0) return r; - assert_se(prioq_pop(rtnl->reply_callbacks_prioq) == c); + assert_se(prioq_pop(nl->reply_callbacks_prioq) == c); c->timeout = 0; - hashmap_remove(rtnl->reply_callbacks, UINT32_TO_PTR(c->serial)); + hashmap_remove(nl->reply_callbacks, UINT32_TO_PTR(c->serial)); slot = container_of(c, sd_netlink_slot, reply_callback); - r = c->callback(rtnl, m, slot->userdata); + r = c->callback(nl, m, slot->userdata); if (r < 0) log_debug_errno(r, "sd-netlink: timedout callback %s%s%sfailed: %m", slot->description ? "'" : "", @@ -385,23 +382,23 @@ static int process_timeout(sd_netlink *rtnl) { return 1; } -static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) { +static int process_reply(sd_netlink *nl, sd_netlink_message *m) { struct reply_callback *c; sd_netlink_slot *slot; uint32_t serial; uint16_t type; int r; - assert(rtnl); + assert(nl); assert(m); - serial = rtnl_message_get_serial(m); - c = hashmap_remove(rtnl->reply_callbacks, UINT32_TO_PTR(serial)); + serial = message_get_serial(m); + c = hashmap_remove(nl->reply_callbacks, UINT32_TO_PTR(serial)); if (!c) return 0; if (c->timeout != 0) { - prioq_remove(rtnl->reply_callbacks_prioq, c, &c->prioq_idx); + prioq_remove(nl->reply_callbacks_prioq, c, &c->prioq_idx); c->timeout = 0; } @@ -414,7 +411,7 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) { slot = container_of(c, sd_netlink_slot, reply_callback); - r = c->callback(rtnl, m, slot->userdata); + r = c->callback(nl, m, slot->userdata); if (r < 0) log_debug_errno(r, "sd-netlink: reply callback %s%s%sfailed: %m", slot->description ? "'" : "", @@ -427,26 +424,26 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) { return 1; } -static int process_match(sd_netlink *rtnl, sd_netlink_message *m) { +static int process_match(sd_netlink *nl, sd_netlink_message *m) { struct match_callback *c; sd_netlink_slot *slot; uint16_t type; int r; - assert(rtnl); + assert(nl); assert(m); r = sd_netlink_message_get_type(m, &type); if (r < 0) return r; - LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) { + LIST_FOREACH(match_callbacks, c, nl->match_callbacks) { if (type != c->type) continue; slot = container_of(c, sd_netlink_slot, match_callback); - r = c->callback(rtnl, m, slot->userdata); + r = c->callback(nl, m, slot->userdata); if (r < 0) log_debug_errno(r, "sd-netlink: match callback %s%s%sfailed: %m", slot->description ? "'" : "", @@ -459,28 +456,28 @@ static int process_match(sd_netlink *rtnl, sd_netlink_message *m) { return 1; } -static int process_running(sd_netlink *rtnl, sd_netlink_message **ret) { +static int process_running(sd_netlink *nl, sd_netlink_message **ret) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; - assert(rtnl); + assert(nl); - r = process_timeout(rtnl); + r = process_timeout(nl); if (r != 0) goto null_message; - r = dispatch_rqueue(rtnl, &m); + r = dispatch_rqueue(nl, &m); if (r < 0) return r; if (!m) goto null_message; if (sd_netlink_message_is_broadcast(m)) { - r = process_match(rtnl, m); + r = process_match(nl, m); if (r != 0) goto null_message; } else { - r = process_reply(rtnl, m); + r = process_reply(nl, m); if (r != 0) goto null_message; } @@ -500,17 +497,17 @@ null_message: return r; } -int sd_netlink_process(sd_netlink *rtnl, sd_netlink_message **ret) { - NETLINK_DONT_DESTROY(rtnl); +int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret) { + NETLINK_DONT_DESTROY(nl); int r; - assert_return(rtnl, -EINVAL); - assert_return(!rtnl_pid_changed(rtnl), -ECHILD); - assert_return(!rtnl->processing, -EBUSY); + assert_return(nl, -EINVAL); + assert_return(!netlink_pid_changed(nl), -ECHILD); + assert_return(!nl->processing, -EBUSY); - rtnl->processing = true; - r = process_running(rtnl, ret); - rtnl->processing = false; + nl->processing = true; + r = process_running(nl, ret); + nl->processing = false; return r; } @@ -520,18 +517,18 @@ static usec_t calc_elapse(uint64_t usec) { return 0; if (usec == 0) - usec = RTNL_DEFAULT_TIMEOUT; + usec = NETLINK_DEFAULT_TIMEOUT_USEC; return usec_add(now(CLOCK_MONOTONIC), usec); } -static int rtnl_poll(sd_netlink *rtnl, bool need_more, usec_t timeout_usec) { +static int netlink_poll(sd_netlink *nl, bool need_more, usec_t timeout_usec) { usec_t m = USEC_INFINITY; int r, e; - assert(rtnl); + assert(nl); - e = sd_netlink_get_events(rtnl); + e = sd_netlink_get_events(nl); if (e < 0) return e; @@ -545,14 +542,14 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, usec_t timeout_usec) { /* Caller wants to process if there is something to * process, but doesn't care otherwise */ - r = sd_netlink_get_timeout(rtnl, &until); + r = sd_netlink_get_timeout(nl, &until); if (r < 0) return r; m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC)); } - r = fd_wait_for_event(rtnl->fd, e, MIN(m, timeout_usec)); + r = fd_wait_for_event(nl->fd, e, MIN(m, timeout_usec)); if (r <= 0) return r; @@ -561,12 +558,12 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, usec_t timeout_usec) { int sd_netlink_wait(sd_netlink *nl, uint64_t timeout_usec) { assert_return(nl, -EINVAL); - assert_return(!rtnl_pid_changed(nl), -ECHILD); + assert_return(!netlink_pid_changed(nl), -ECHILD); if (nl->rqueue_size > 0) return 0; - return rtnl_poll(nl, false, timeout_usec); + return netlink_poll(nl, false, timeout_usec); } static int timeout_compare(const void *a, const void *b) { @@ -597,7 +594,7 @@ int sd_netlink_call_async( assert_return(nl, -EINVAL); assert_return(m, -EINVAL); assert_return(callback, -EINVAL); - assert_return(!rtnl_pid_changed(nl), -ECHILD); + assert_return(!netlink_pid_changed(nl), -ECHILD); if (hashmap_size(nl->reply_callbacks) >= REPLY_CALLBACKS_MAX) return -ERANGE; @@ -647,7 +644,7 @@ int sd_netlink_call_async( } int sd_netlink_read( - sd_netlink *rtnl, + sd_netlink *nl, uint32_t serial, uint64_t usec, sd_netlink_message **ret) { @@ -655,29 +652,29 @@ int sd_netlink_read( usec_t timeout; int r; - assert_return(rtnl, -EINVAL); - assert_return(!rtnl_pid_changed(rtnl), -ECHILD); + assert_return(nl, -EINVAL); + assert_return(!netlink_pid_changed(nl), -ECHILD); timeout = calc_elapse(usec); for (;;) { usec_t left; - for (unsigned i = 0; i < rtnl->rqueue_size; i++) { + for (unsigned i = 0; i < nl->rqueue_size; i++) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *incoming = NULL; uint32_t received_serial; uint16_t type; - received_serial = rtnl_message_get_serial(rtnl->rqueue[i]); + received_serial = message_get_serial(nl->rqueue[i]); if (received_serial != serial) continue; - incoming = rtnl->rqueue[i]; + incoming = nl->rqueue[i]; /* found a match, remove from rqueue and return it */ - memmove(rtnl->rqueue + i,rtnl->rqueue + i + 1, - sizeof(sd_netlink_message*) * (rtnl->rqueue_size - i - 1)); - rtnl->rqueue_size--; + memmove(nl->rqueue + i, nl->rqueue + i + 1, + sizeof(sd_netlink_message*) * (nl->rqueue_size - i - 1)); + nl->rqueue_size--; r = sd_netlink_message_get_errno(incoming); if (r < 0) @@ -697,7 +694,7 @@ int sd_netlink_read( return 1; } - r = socket_read_message(rtnl); + r = socket_read_message(nl); if (r < 0) return r; if (r > 0) @@ -715,7 +712,7 @@ int sd_netlink_read( } else left = USEC_INFINITY; - r = rtnl_poll(rtnl, true, left); + r = netlink_poll(nl, true, left); if (r < 0) return r; if (r == 0) @@ -724,7 +721,7 @@ int sd_netlink_read( } int sd_netlink_call( - sd_netlink *rtnl, + sd_netlink *nl, sd_netlink_message *message, uint64_t usec, sd_netlink_message **ret) { @@ -732,37 +729,37 @@ int sd_netlink_call( uint32_t serial; int r; - assert_return(rtnl, -EINVAL); - assert_return(!rtnl_pid_changed(rtnl), -ECHILD); + assert_return(nl, -EINVAL); + assert_return(!netlink_pid_changed(nl), -ECHILD); assert_return(message, -EINVAL); - r = sd_netlink_send(rtnl, message, &serial); + r = sd_netlink_send(nl, message, &serial); if (r < 0) return r; - return sd_netlink_read(rtnl, serial, usec, ret); + return sd_netlink_read(nl, serial, usec, ret); } -int sd_netlink_get_events(sd_netlink *rtnl) { - assert_return(rtnl, -EINVAL); - assert_return(!rtnl_pid_changed(rtnl), -ECHILD); +int sd_netlink_get_events(sd_netlink *nl) { + assert_return(nl, -EINVAL); + assert_return(!netlink_pid_changed(nl), -ECHILD); - return rtnl->rqueue_size == 0 ? POLLIN : 0; + return nl->rqueue_size == 0 ? POLLIN : 0; } -int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) { +int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *timeout_usec) { struct reply_callback *c; - assert_return(rtnl, -EINVAL); + assert_return(nl, -EINVAL); assert_return(timeout_usec, -EINVAL); - assert_return(!rtnl_pid_changed(rtnl), -ECHILD); + assert_return(!netlink_pid_changed(nl), -ECHILD); - if (rtnl->rqueue_size > 0) { + if (nl->rqueue_size > 0) { *timeout_usec = 0; return 1; } - c = prioq_peek(rtnl->reply_callbacks_prioq); + c = prioq_peek(nl->reply_callbacks_prioq); if (!c) { *timeout_usec = UINT64_MAX; return 0; @@ -774,12 +771,12 @@ int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) { } static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - sd_netlink *rtnl = userdata; + sd_netlink *nl = userdata; int r; - assert(rtnl); + assert(nl); - r = sd_netlink_process(rtnl, NULL); + r = sd_netlink_process(nl, NULL); if (r < 0) return r; @@ -787,12 +784,12 @@ static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userd } static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) { - sd_netlink *rtnl = userdata; + sd_netlink *nl = userdata; int r; - assert(rtnl); + assert(nl); - r = sd_netlink_process(rtnl, NULL); + r = sd_netlink_process(nl, NULL); if (r < 0) return r; @@ -800,100 +797,100 @@ static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) { } static int prepare_callback(sd_event_source *s, void *userdata) { - sd_netlink *rtnl = userdata; + sd_netlink *nl = userdata; int r, e; usec_t until; assert(s); - assert(rtnl); + assert(nl); - e = sd_netlink_get_events(rtnl); + e = sd_netlink_get_events(nl); if (e < 0) return e; - r = sd_event_source_set_io_events(rtnl->io_event_source, e); + r = sd_event_source_set_io_events(nl->io_event_source, e); if (r < 0) return r; - r = sd_netlink_get_timeout(rtnl, &until); + r = sd_netlink_get_timeout(nl, &until); if (r < 0) return r; if (r > 0) { int j; - j = sd_event_source_set_time(rtnl->time_event_source, until); + j = sd_event_source_set_time(nl->time_event_source, until); if (j < 0) return j; } - r = sd_event_source_set_enabled(rtnl->time_event_source, r > 0); + r = sd_event_source_set_enabled(nl->time_event_source, r > 0); if (r < 0) return r; return 1; } -int sd_netlink_attach_event(sd_netlink *rtnl, sd_event *event, int64_t priority) { +int sd_netlink_attach_event(sd_netlink *nl, sd_event *event, int64_t priority) { int r; - assert_return(rtnl, -EINVAL); - assert_return(!rtnl->event, -EBUSY); + assert_return(nl, -EINVAL); + assert_return(!nl->event, -EBUSY); - assert(!rtnl->io_event_source); - assert(!rtnl->time_event_source); + assert(!nl->io_event_source); + assert(!nl->time_event_source); if (event) - rtnl->event = sd_event_ref(event); + nl->event = sd_event_ref(event); else { - r = sd_event_default(&rtnl->event); + r = sd_event_default(&nl->event); if (r < 0) return r; } - r = sd_event_add_io(rtnl->event, &rtnl->io_event_source, rtnl->fd, 0, io_callback, rtnl); + r = sd_event_add_io(nl->event, &nl->io_event_source, nl->fd, 0, io_callback, nl); if (r < 0) goto fail; - r = sd_event_source_set_priority(rtnl->io_event_source, priority); + r = sd_event_source_set_priority(nl->io_event_source, priority); if (r < 0) goto fail; - r = sd_event_source_set_description(rtnl->io_event_source, "rtnl-receive-message"); + r = sd_event_source_set_description(nl->io_event_source, "netlink-receive-message"); if (r < 0) goto fail; - r = sd_event_source_set_prepare(rtnl->io_event_source, prepare_callback); + r = sd_event_source_set_prepare(nl->io_event_source, prepare_callback); if (r < 0) goto fail; - r = sd_event_add_time(rtnl->event, &rtnl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, rtnl); + r = sd_event_add_time(nl->event, &nl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, nl); if (r < 0) goto fail; - r = sd_event_source_set_priority(rtnl->time_event_source, priority); + r = sd_event_source_set_priority(nl->time_event_source, priority); if (r < 0) goto fail; - r = sd_event_source_set_description(rtnl->time_event_source, "rtnl-timer"); + r = sd_event_source_set_description(nl->time_event_source, "netlink-timer"); if (r < 0) goto fail; return 0; fail: - sd_netlink_detach_event(rtnl); + sd_netlink_detach_event(nl); return r; } -int sd_netlink_detach_event(sd_netlink *rtnl) { - assert_return(rtnl, -EINVAL); - assert_return(rtnl->event, -ENXIO); +int sd_netlink_detach_event(sd_netlink *nl) { + assert_return(nl, -EINVAL); + assert_return(nl->event, -ENXIO); - rtnl->io_event_source = sd_event_source_unref(rtnl->io_event_source); + nl->io_event_source = sd_event_source_unref(nl->io_event_source); - rtnl->time_event_source = sd_event_source_unref(rtnl->time_event_source); + nl->time_event_source = sd_event_source_unref(nl->time_event_source); - rtnl->event = sd_event_unref(rtnl->event); + nl->event = sd_event_unref(nl->event); return 0; } @@ -906,12 +903,13 @@ int sd_netlink_add_match( sd_netlink_destroy_t destroy_callback, void *userdata, const char *description) { + _cleanup_free_ sd_netlink_slot *slot = NULL; int r; assert_return(rtnl, -EINVAL); assert_return(callback, -EINVAL); - assert_return(!rtnl_pid_changed(rtnl), -ECHILD); + assert_return(!netlink_pid_changed(rtnl), -ECHILD); r = netlink_slot_allocate(rtnl, !ret_slot, NETLINK_MATCH_CALLBACK, sizeof(struct match_callback), userdata, description, &slot); if (r < 0) diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 76a567ec4d..1076ec55a4 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -9,6 +9,7 @@ #include "alloc-util.h" #include "ether-addr-util.h" #include "macro.h" +#include "netlink-internal.h" #include "netlink-util.h" #include "socket-util.h" #include "stdio-util.h" @@ -502,7 +503,7 @@ static void test_message(sd_netlink *rtnl) { log_debug("/* %s */", __func__); - assert_se(rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0); + assert_se(message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0); assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT); } @@ -528,7 +529,7 @@ static void test_array(void) { } assert_se(sd_netlink_message_close_container(m) >= 0); - rtnl_message_seal(m); + message_seal(m); assert_se(sd_netlink_message_rewind(m, genl) >= 0); assert_se(sd_netlink_message_enter_container(m, CTRL_ATTR_MCAST_GROUPS) >= 0); @@ -569,7 +570,7 @@ static void test_strv(sd_netlink *rtnl) { assert_se(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, names_in) >= 0); assert_se(sd_netlink_message_close_container(m) >= 0); - rtnl_message_seal(m); + message_seal(m); assert_se(sd_netlink_message_rewind(m, NULL) >= 0); assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 1a2d3c1046..f2f2541284 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -50,12 +50,11 @@ typedef enum sd_genl_family_t { } sd_genl_family_t; /* callback */ - typedef int (*sd_netlink_message_handler_t)(sd_netlink *nl, sd_netlink_message *m, void *userdata); typedef _sd_destroy_t sd_netlink_destroy_t; /* bus */ -int sd_netlink_new_from_netlink(sd_netlink **nl, int fd); +int sd_netlink_new_from_fd(sd_netlink **nl, int fd); int sd_netlink_open(sd_netlink **nl); int sd_netlink_open_fd(sd_netlink **nl, int fd); int sd_netlink_inc_rcvbuf(sd_netlink *nl, const size_t size); @@ -85,6 +84,7 @@ int sd_netlink_add_match(sd_netlink *nl, sd_netlink_slot **ret_slot, uint16_t ma int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority); int sd_netlink_detach_event(sd_netlink *nl); +/* message */ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data); int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data); int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type); @@ -181,12 +181,12 @@ int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len); int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type); -int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nhmsg_type, int nh_family, unsigned char nh_protocol); +int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int nh_family, unsigned char nh_protocol); int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags); int sd_rtnl_message_nexthop_get_family(sd_netlink_message *m, uint8_t *family); int sd_rtnl_message_nexthop_get_protocol(sd_netlink_message *m, uint8_t *protocol); -int sd_rtnl_message_new_neigh(sd_netlink *nl, sd_netlink_message **ret, uint16_t msg_type, int index, int nda_family); +int sd_rtnl_message_new_neigh(sd_netlink *nl, sd_netlink_message **ret, uint16_t nlmsg_type, int index, int nda_family); int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags); int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state); int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family); @@ -223,7 +223,7 @@ int sd_rtnl_message_set_tclass_handle(sd_netlink_message *m, uint32_t handle); int sd_rtnl_message_new_mdb(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int mdb_ifindex); /* nfnl */ -int sd_nfnl_socket_open(sd_netlink **nl); +int sd_nfnl_socket_open(sd_netlink **ret); int sd_nfnl_message_batch_begin(sd_netlink *nfnl, sd_netlink_message **ret); int sd_nfnl_message_batch_end(sd_netlink *nfnl, sd_netlink_message **ret); int sd_nfnl_nft_message_del_table(sd_netlink *nfnl, sd_netlink_message **ret, @@ -249,13 +249,13 @@ int sd_nfnl_nft_message_add_setelem(sd_netlink_message *m, int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m); /* genl */ -int sd_genl_socket_open(sd_netlink **nl); -int sd_genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret); -int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *ret); +int sd_genl_socket_open(sd_netlink **ret); +int sd_genl_message_new(sd_netlink *genl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret); +int sd_genl_message_get_family(sd_netlink *genl, sd_netlink_message *m, sd_genl_family_t *ret); /* slot */ -sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *nl); -sd_netlink_slot *sd_netlink_slot_unref(sd_netlink_slot *nl); +sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *slot); +sd_netlink_slot *sd_netlink_slot_unref(sd_netlink_slot *slot); sd_netlink *sd_netlink_slot_get_netlink(sd_netlink_slot *slot); void *sd_netlink_slot_get_userdata(sd_netlink_slot *slot); From c737abd31bfb71f81145906f2364a6265fcf55d9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 7 Jul 2021 10:05:08 +0900 Subject: [PATCH 04/29] sd-netlink: make message_seal() accept already sealed messages The function can be idempotent. It is not necessary to refuse already sealed messages. --- src/libsystemd/sd-netlink/netlink-message.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 922700c634..075d021884 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -1307,8 +1307,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) { assert_return(genl || m->protocol != NETLINK_GENERIC, -EINVAL); /* don't allow appending to message once parsed */ - if (!m->sealed) - message_seal(m); + message_seal(m); for (unsigned i = 1; i <= m->n_containers; i++) m->containers[i].attributes = mfree(m->containers[i].attributes); @@ -1351,7 +1350,6 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) { void message_seal(sd_netlink_message *m) { assert(m); - assert(!m->sealed); m->sealed = true; } From 49eb0a6889881fcaaf3863b60c6eb8d4f8309078 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 4 Jul 2021 14:33:02 +0900 Subject: [PATCH 05/29] sd-netlink: make type_get_type_system{,_union}() return value directly --- src/libsystemd/sd-netlink/generic-netlink.c | 4 ++-- src/libsystemd/sd-netlink/netlink-message.c | 8 ++------ src/libsystemd/sd-netlink/netlink-types.c | 19 ++++++------------- src/libsystemd/sd-netlink/netlink-types.h | 4 ++-- src/libsystemd/sd-netlink/nfnl-message.c | 2 +- 5 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/libsystemd/sd-netlink/generic-netlink.c b/src/libsystemd/sd-netlink/generic-netlink.c index 69f1a0cef5..648b840771 100644 --- a/src/libsystemd/sd-netlink/generic-netlink.c +++ b/src/libsystemd/sd-netlink/generic-netlink.c @@ -53,7 +53,7 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - type_get_type_system(genl_cmd_type, &type_system); + type_system = type_get_type_system(genl_cmd_type); r = type_system_get_type(type_system, &nl_type, cmd); if (r < 0) @@ -62,7 +62,7 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = nlmsg_type; - type_get_type_system(nl_type, &m->containers[0].type_system); + m->containers[0].type_system = type_get_type_system(nl_type); *(struct genlmsghdr *) NLMSG_DATA(m->hdr) = (struct genlmsghdr) { .cmd = cmd, diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 075d021884..f3ed96b9f6 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -71,7 +71,7 @@ int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type) { m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - type_get_type_system(nl_type, &m->containers[0].type_system); + m->containers[0].type_system = type_get_type_system(nl_type); m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; @@ -1328,11 +1328,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) { size = type_get_size(nl_type); if (type == NETLINK_TYPE_NESTED) { - const NLTypeSystem *type_system; - - type_get_type_system(nl_type, &type_system); - - m->containers[0].type_system = type_system; + m->containers[0].type_system = type_get_type_system(nl_type); if (sd_netlink_message_is_error(m)) r = netlink_message_parse_error(m); diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index beb926d40b..ccece76bf8 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -1700,22 +1700,18 @@ size_t type_get_size(const NLType *type) { return type->size; } -void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) { +const NLTypeSystem *type_get_type_system(const NLType *nl_type) { assert(nl_type); - assert(ret); assert(nl_type->type == NETLINK_TYPE_NESTED); assert(nl_type->type_system); - - *ret = nl_type->type_system; + return nl_type->type_system; } -void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion **ret) { +const NLTypeSystemUnion *type_get_type_system_union(const NLType *nl_type) { assert(nl_type); - assert(ret); assert(nl_type->type == NETLINK_TYPE_UNION); assert(nl_type->type_system_union); - - *ret = nl_type->type_system_union; + return nl_type->type_system_union; } uint16_t type_system_get_count(const NLTypeSystem *type_system) { @@ -1778,7 +1774,6 @@ int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, ui return -EOPNOTSUPP; *ret = nl_type; - return 0; } @@ -1792,7 +1787,7 @@ int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSys if (r < 0) return r; - type_get_type_system(nl_type, ret); + *ret = type_get_type_system(nl_type); return 0; } @@ -1806,7 +1801,7 @@ int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLT if (r < 0) return r; - type_get_type_system_union(nl_type, ret); + *ret = type_get_type_system_union(nl_type); return 0; } @@ -1827,7 +1822,6 @@ int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union assert(type < type_system_union->num); *ret = &type_system_union->type_systems[type]; - return 0; } @@ -1847,6 +1841,5 @@ int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_sys return -EOPNOTSUPP; *ret = type_system; - return 0; } diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 316d7f1b87..607af01391 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -47,8 +47,8 @@ extern const NLTypeSystem genl_family_type_system_root; uint16_t type_get_type(const NLType *type); size_t type_get_size(const NLType *type); -void type_get_type_system(const NLType *type, const NLTypeSystem **ret); -void type_get_type_system_union(const NLType *type, const NLTypeSystemUnion **ret); +const NLTypeSystem *type_get_type_system(const NLType *type); +const NLTypeSystemUnion *type_get_type_system_union(const NLType *type); const NLTypeSystem* type_system_get_root(int protocol); uint16_t type_system_get_count(const NLTypeSystem *type_system); diff --git a/src/libsystemd/sd-netlink/nfnl-message.c b/src/libsystemd/sd-netlink/nfnl-message.c index 001a7b277e..e55b480402 100644 --- a/src/libsystemd/sd-netlink/nfnl-message.c +++ b/src/libsystemd/sd-netlink/nfnl-message.c @@ -43,7 +43,7 @@ static int nft_message_new(sd_netlink *nfnl, sd_netlink_message **ret, int famil m->hdr->nlmsg_flags = NLM_F_REQUEST | flags; - type_get_type_system(nl_type, &m->containers[0].type_system); + 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, From ea073c8fcee731ff1d5be23ad2d1b84b7f28afbb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 4 Jul 2021 14:58:20 +0900 Subject: [PATCH 06/29] sd-netlink: rename functions --- src/libsystemd/sd-netlink/netlink-message.c | 28 ++++++++++++--------- src/libsystemd/sd-netlink/netlink-types.c | 4 +-- src/libsystemd/sd-netlink/netlink-types.h | 4 +-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index f3ed96b9f6..a0de7a0036 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -574,9 +574,10 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type if (r < 0) return r; - r = type_system_union_protocol_get_type_system(type_system_union, - &m->containers[m->n_containers + 1].type_system, - family); + r = type_system_union_get_type_system_by_protocol( + type_system_union, + &m->containers[m->n_containers + 1].type_system, + family); if (r < 0) return r; } else { @@ -608,9 +609,10 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor if (r < 0) return r; - r = type_system_union_get_type_system(type_system_union, - &m->containers[m->n_containers + 1].type_system, - key); + r = type_system_union_get_type_system_by_string( + type_system_union, + &m->containers[m->n_containers + 1].type_system, + key); if (r < 0) return r; @@ -1155,9 +1157,10 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - r = type_system_union_get_type_system(type_system_union, - &type_system, - key); + r = type_system_union_get_type_system_by_string( + type_system_union, + &type_system, + key); if (r < 0) return r; @@ -1171,9 +1174,10 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - r = type_system_union_protocol_get_type_system(type_system_union, - &type_system, - family); + r = type_system_union_get_type_system_by_protocol( + type_system_union, + &type_system, + family); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index ccece76bf8..d0719b3cc5 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -1805,7 +1805,7 @@ int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLT return 0; } -int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) { +int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) { int type; assert(type_system_union); @@ -1825,7 +1825,7 @@ int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union return 0; } -int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) { +int type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) { const NLTypeSystem *type_system; assert(type_system_union); diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 607af01391..59c7dfabcd 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -56,8 +56,8 @@ int type_system_root_get_type(sd_netlink *nl, const NLType **ret, uint16_t type) int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); -int type_system_union_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key); -int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol); +int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key); +int type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol); typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_BOND, From b019c545e982de08c024b91db4e8839cafa2381b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 4 Jul 2021 15:11:08 +0900 Subject: [PATCH 07/29] sd-netlink: introduce two helper functions for type system union --- src/libsystemd/sd-netlink/netlink-message.c | 15 +++++++------ src/libsystemd/sd-netlink/netlink-types.c | 25 ++++++++++++++++++--- src/libsystemd/sd-netlink/netlink-types.h | 10 ++------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index a0de7a0036..169e9cd957 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -616,7 +616,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor if (r < 0) return r; - r = sd_netlink_message_append_string(m, type_system_union->match, key); + r = sd_netlink_message_append_string(m, type_system_union_get_match_attribute(type_system_union), key); if (r < 0) return r; @@ -1148,12 +1148,14 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - switch (type_system_union->match_type) { - case NL_MATCH_SIBLING: - { + switch (type_system_union_get_match_type(type_system_union)) { + case NL_MATCH_SIBLING: { const char *key; - r = sd_netlink_message_read_string(m, type_system_union->match, &key); + r = sd_netlink_message_read_string( + m, + type_system_union_get_match_attribute(type_system_union), + &key); if (r < 0) return r; @@ -1166,8 +1168,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ break; } - case NL_MATCH_PROTOCOL: - { + case NL_MATCH_PROTOCOL: { int family; r = sd_rtnl_message_get_family(m, &family); diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index d0719b3cc5..f7ea451b3b 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -72,6 +72,14 @@ struct NLTypeSystem { const NLType *types; }; +struct NLTypeSystemUnion { + int num; + NLMatchType match_type; + uint16_t match_attribute; + int (*lookup)(const char *); + const NLTypeSystem *type_systems; +}; + static const NLTypeSystem rtnl_link_type_system; static const NLType empty_types[1] = { @@ -476,7 +484,7 @@ static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { .lookup = nl_union_link_info_data_from_string, .type_systems = rtnl_link_info_data_type_systems, .match_type = NL_MATCH_SIBLING, - .match = IFLA_INFO_KIND, + .match_attribute = IFLA_INFO_KIND, }; static const NLType rtnl_link_info_types[] = { @@ -1013,7 +1021,7 @@ static const NLTypeSystemUnion rtnl_tca_option_data_type_system_union = { .lookup = nl_union_tca_option_data_from_string, .type_systems = rtnl_tca_option_data_type_systems, .match_type = NL_MATCH_SIBLING, - .match = TCA_KIND, + .match_attribute = TCA_KIND, }; static const NLType rtnl_tca_types[] = { @@ -1570,7 +1578,7 @@ static const NLTypeSystemUnion nfnl_nft_data_expr_type_system_union = { .lookup = nl_union_nft_expr_data_from_string, .type_systems = nfnl_expr_data_type_systems, .match_type = NL_MATCH_SIBLING, - .match = NFTA_EXPR_NAME, + .match_attribute = NFTA_EXPR_NAME, }; static const NLType nfnl_nft_rule_expr_types[] = { @@ -1805,6 +1813,17 @@ int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLT return 0; } +NLMatchType type_system_union_get_match_type(const NLTypeSystemUnion *type_system_union) { + assert(type_system_union); + return type_system_union->match_type; +} + +uint16_t type_system_union_get_match_attribute(const NLTypeSystemUnion *type_system_union) { + assert(type_system_union); + assert(type_system_union->match_type == NL_MATCH_SIBLING); + return type_system_union->match_attribute; +} + int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) { int type; diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 59c7dfabcd..5c292ab2b3 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -35,14 +35,6 @@ typedef struct NLTypeSystemUnion NLTypeSystemUnion; typedef struct NLTypeSystem NLTypeSystem; typedef struct NLType NLType; -struct NLTypeSystemUnion { - int num; - NLMatchType match_type; - uint16_t match; - int (*lookup)(const char *); - const NLTypeSystem *type_systems; -}; - extern const NLTypeSystem genl_family_type_system_root; uint16_t type_get_type(const NLType *type); @@ -56,6 +48,8 @@ int type_system_root_get_type(sd_netlink *nl, const NLType **ret, uint16_t type) int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); +NLMatchType type_system_union_get_match_type(const NLTypeSystemUnion *type_system_union); +uint16_t type_system_union_get_match_attribute(const NLTypeSystemUnion *type_system_union); int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key); int type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol); From 0dac2688a43be587d8bb698fbd9ffe080a4de4c3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Jun 2021 16:06:04 +0900 Subject: [PATCH 08/29] sd-netlink: move type systems --- src/libsystemd/sd-netlink/netlink-types.c | 721 +++++++++++----------- 1 file changed, 368 insertions(+), 353 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index f7ea451b3b..80492af0dd 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -80,7 +80,7 @@ struct NLTypeSystemUnion { const NLTypeSystem *type_systems; }; -static const NLTypeSystem rtnl_link_type_system; +/***************** basic type systems *****************/ static const NLType empty_types[1] = { /* fake array to avoid .types==NULL, which denotes invalid type-systems */ @@ -91,6 +91,20 @@ static const NLTypeSystem empty_type_system = { .types = empty_types, }; +static const NLType error_types[] = { + [NLMSGERR_ATTR_MSG] = { .type = NETLINK_TYPE_STRING }, + [NLMSGERR_ATTR_OFFS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem error_type_system = { + .count = ELEMENTSOF(error_types), + .types = error_types, +}; + +/***************** rtnl type systems *****************/ + +static const NLTypeSystem rtnl_link_type_system; + static const NLType rtnl_link_info_data_batadv_types[] = { [IFLA_BATADV_ALGO_NAME] = { .type = NETLINK_TYPE_STRING, .size = 20 }, }; @@ -1045,16 +1059,6 @@ static const NLTypeSystem rtnl_mdb_type_system = { .types = mdb_types, }; -static const NLType error_types[] = { - [NLMSGERR_ATTR_MSG] = { .type = NETLINK_TYPE_STRING }, - [NLMSGERR_ATTR_OFFS] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem error_type_system = { - .count = ELEMENTSOF(error_types), - .types = error_types, -}; - static const NLType rtnl_types[] = { [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, @@ -1099,348 +1103,7 @@ const NLTypeSystem rtnl_type_system_root = { .types = rtnl_types, }; -static const NLType genl_wireguard_allowedip_types[] = { - [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, - [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLTypeSystem genl_wireguard_allowedip_type_system = { - .count = ELEMENTSOF(genl_wireguard_allowedip_types), - .types = genl_wireguard_allowedip_types, -}; - -static const NLType genl_wireguard_peer_types[] = { - [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, - [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, - [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 }, - [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR }, - [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, -}; - -static const NLTypeSystem genl_wireguard_peer_type_system = { - .count = ELEMENTSOF(genl_wireguard_peer_types), - .types = genl_wireguard_peer_types, -}; - -static const NLType genl_wireguard_set_device_types[] = { - [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 }, - [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN }, - [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 }, - [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, -}; - -static const NLTypeSystem genl_wireguard_set_device_type_system = { - .count = ELEMENTSOF(genl_wireguard_set_device_types), - .types = genl_wireguard_set_device_types, -}; - -static const NLType genl_wireguard_cmds[] = { - [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_set_device_type_system }, -}; - -static const NLTypeSystem genl_wireguard_type_system = { - .count = ELEMENTSOF(genl_wireguard_cmds), - .types = genl_wireguard_cmds, -}; - -static const NLType genl_mcast_group_types[] = { - [CTRL_ATTR_MCAST_GRP_NAME] = { .type = NETLINK_TYPE_STRING }, - [CTRL_ATTR_MCAST_GRP_ID] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem genl_mcast_group_type_system = { - .count = ELEMENTSOF(genl_mcast_group_types), - .types = genl_mcast_group_types, -}; - -static const NLType genl_get_family_types[] = { - [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, - [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, - [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_mcast_group_type_system }, -}; - -static const NLTypeSystem genl_get_family_type_system = { - .count = ELEMENTSOF(genl_get_family_types), - .types = genl_get_family_types, -}; - -static const NLType genl_ctrl_id_ctrl_cmds[] = { - [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system }, -}; - -static const NLTypeSystem genl_ctrl_id_ctrl_type_system = { - .count = ELEMENTSOF(genl_ctrl_id_ctrl_cmds), - .types = genl_ctrl_id_ctrl_cmds, -}; - -static const NLType genl_fou_types[] = { - [FOU_ATTR_PORT] = { .type = NETLINK_TYPE_U16 }, - [FOU_ATTR_AF] = { .type = NETLINK_TYPE_U8 }, - [FOU_ATTR_IPPROTO] = { .type = NETLINK_TYPE_U8 }, - [FOU_ATTR_TYPE] = { .type = NETLINK_TYPE_U8 }, - [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, - [FOU_ATTR_LOCAL_V4] = { .type = NETLINK_TYPE_IN_ADDR }, - [FOU_ATTR_PEER_V4] = { .type = NETLINK_TYPE_IN_ADDR }, - [FOU_ATTR_LOCAL_V6] = { .type = NETLINK_TYPE_IN_ADDR }, - [FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR}, - [FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16}, - [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32}, -}; - -static const NLTypeSystem genl_fou_type_system = { - .count = ELEMENTSOF(genl_fou_types), - .types = genl_fou_types, -}; - -static const NLType genl_fou_cmds[] = { - [FOU_CMD_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, - [FOU_CMD_DEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, - [FOU_CMD_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, -}; - -static const NLTypeSystem genl_fou_cmds_type_system = { - .count = ELEMENTSOF(genl_fou_cmds), - .types = genl_fou_cmds, -}; - -static const NLType genl_l2tp_types[] = { - [L2TP_ATTR_PW_TYPE] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_OFFSET] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_DATA_SEQ] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_L2SPEC_TYPE] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_L2SPEC_LEN] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_PROTO_VERSION] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_IFNAME] = { .type = NETLINK_TYPE_STRING }, - [L2TP_ATTR_CONN_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_PEER_CONN_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_PEER_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_RECV_SEQ] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_SEND_SEQ] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_LNS_MODE] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_USING_IPSEC] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_FD] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_IP_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_IP_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_UDP_SPORT] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_UDP_DPORT] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_IP6_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_IP6_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_FLAG }, - [L2TP_ATTR_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_FLAG }, -}; - -static const NLTypeSystem genl_l2tp_type_system = { - .count = ELEMENTSOF(genl_l2tp_types), - .types = genl_l2tp_types, -}; - -static const NLType genl_l2tp[] = { - [L2TP_CMD_TUNNEL_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, -}; - -static const NLTypeSystem genl_l2tp_tunnel_session_type_system = { - .count = ELEMENTSOF(genl_l2tp), - .types = genl_l2tp, -}; - -static const NLType genl_rxsc_types[] = { - [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, -}; - -static const NLTypeSystem genl_rxsc_config_type_system = { - .count = ELEMENTSOF(genl_rxsc_types), - .types = genl_rxsc_types, -}; - -static const NLType genl_macsec_rxsc_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, -}; - -static const NLTypeSystem genl_macsec_rxsc_type_system = { - .count = ELEMENTSOF(genl_macsec_rxsc_types), - .types = genl_macsec_rxsc_types, -}; - -static const NLType genl_macsec_sa_config_types[] = { - [MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 }, - [MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 }, - [MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_SA_ATTR_KEYID] = { .size = MACSEC_KEYID_LEN }, - [MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN }, -}; - -static const NLTypeSystem genl_macsec_sa_config_type_system = { - .count = ELEMENTSOF(genl_macsec_sa_config_types), - .types = genl_macsec_sa_config_types, -}; - -static const NLType genl_macsec_rxsa_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, -}; - -static const NLTypeSystem genl_macsec_rxsa_type_system = { - .count = ELEMENTSOF(genl_macsec_rxsa_types), - .types = genl_macsec_rxsa_types, -}; - -static const NLType genl_macsec_sa_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, - [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, -}; - -static const NLTypeSystem genl_macsec_sa_type_system = { - .count = ELEMENTSOF(genl_macsec_sa_types), - .types = genl_macsec_sa_types, -}; - -static const NLType genl_macsec[] = { - [MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system }, - [MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsa_type_system}, - [MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, -}; - -static const NLTypeSystem genl_macsec_device_type_system = { - .count = ELEMENTSOF(genl_macsec), - .types = genl_macsec, -}; - -static const NLType genl_nl80211_types[] = { - [NL80211_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [NL80211_ATTR_MAC] = { .type = NETLINK_TYPE_ETHER_ADDR }, - [NL80211_ATTR_SSID] = { .type = NETLINK_TYPE_STRING }, - [NL80211_ATTR_IFTYPE] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem genl_nl80211_type_system = { - .count = ELEMENTSOF(genl_nl80211_types), - .types = genl_nl80211_types, -}; - -static const NLType genl_nl80211_cmds[] = { - [NL80211_CMD_GET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_GET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_GET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, -}; - -static const NLTypeSystem genl_nl80211_cmds_type_system = { - .count = ELEMENTSOF(genl_nl80211_cmds), - .types = genl_nl80211_cmds, -}; - -static const NLType genl_batadv_types[] = { - [BATADV_ATTR_VERSION] = { .type = NETLINK_TYPE_STRING }, - [BATADV_ATTR_ALGO_NAME] = { .type = NETLINK_TYPE_STRING }, - [BATADV_ATTR_MESH_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_MESH_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, - [BATADV_ATTR_MESH_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_HARD_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_HARD_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, - [BATADV_ATTR_HARD_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_ORIG_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_TPMETER_RESULT] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_TPMETER_BYTES] = { .type = NETLINK_TYPE_U64 }, - [BATADV_ATTR_TPMETER_COOKIE] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_PAD] = { .type = NETLINK_TYPE_UNSPEC }, - [BATADV_ATTR_ACTIVE] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_TT_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_TT_TTVN] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_TT_LAST_TTVN] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_TT_CRC32] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_TT_VID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_TT_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_FLAG_BEST] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_NEIGH_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_TQ] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_THROUGHPUT] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_ROUTER] = { .size = ETH_ALEN }, - [BATADV_ATTR_BLA_OWN] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_BLA_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_BLA_VID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_BLA_BACKBONE] = { .size = ETH_ALEN }, - [BATADV_ATTR_BLA_CRC] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_DAT_CACHE_VID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_MCAST_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_VLANID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_ISOLATION_MARK] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_ISOLATION_MASK] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_BONDING_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_GW_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_GW_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_GW_MODE] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_GW_SEL_CLASS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_HOP_PENALTY] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_LOG_LEVEL] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_MULTICAST_FANOUT] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_NETWORK_CODING_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_ORIG_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_ELP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem genl_batadv_type_system = { - .count = ELEMENTSOF(genl_batadv_types), - .types = genl_batadv_types, -}; - -static const NLType genl_batadv_cmds[] = { - [BATADV_CMD_SET_MESH] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, -}; - -static const NLTypeSystem genl_batadv_cmds_type_system = { - .count = ELEMENTSOF(genl_batadv_cmds), - .types = genl_batadv_cmds, -}; - -static const NLType genl_families[] = { - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system }, - [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, - [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmds_type_system }, - [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system }, - [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmds_type_system }, - [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmds_type_system }, -}; +/***************** nfnl type systems *****************/ static const NLType nfnl_nft_table_types[] = { [NFTA_TABLE_NAME] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, @@ -1679,6 +1342,358 @@ const NLTypeSystem nfnl_type_system_root = { .types = nfnl_types, }; +/***************** genl type systems *****************/ + +/***************** genl ctrl type systems *****************/ +static const NLType genl_mcast_group_types[] = { + [CTRL_ATTR_MCAST_GRP_NAME] = { .type = NETLINK_TYPE_STRING }, + [CTRL_ATTR_MCAST_GRP_ID] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem genl_mcast_group_type_system = { + .count = ELEMENTSOF(genl_mcast_group_types), + .types = genl_mcast_group_types, +}; + +static const NLType genl_get_family_types[] = { + [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, + [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, + [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_mcast_group_type_system }, +}; + +static const NLTypeSystem genl_get_family_type_system = { + .count = ELEMENTSOF(genl_get_family_types), + .types = genl_get_family_types, +}; + +static const NLType genl_ctrl_id_ctrl_cmds[] = { + [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system }, +}; + +static const NLTypeSystem genl_ctrl_id_ctrl_type_system = { + .count = ELEMENTSOF(genl_ctrl_id_ctrl_cmds), + .types = genl_ctrl_id_ctrl_cmds, +}; + +/***************** genl batadv type systems *****************/ +static const NLType genl_batadv_types[] = { + [BATADV_ATTR_VERSION] = { .type = NETLINK_TYPE_STRING }, + [BATADV_ATTR_ALGO_NAME] = { .type = NETLINK_TYPE_STRING }, + [BATADV_ATTR_MESH_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_MESH_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, + [BATADV_ATTR_MESH_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_HARD_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_HARD_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, + [BATADV_ATTR_HARD_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_ORIG_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_TPMETER_RESULT] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_TPMETER_BYTES] = { .type = NETLINK_TYPE_U64 }, + [BATADV_ATTR_TPMETER_COOKIE] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_PAD] = { .type = NETLINK_TYPE_UNSPEC }, + [BATADV_ATTR_ACTIVE] = { .type = NETLINK_TYPE_FLAG }, + [BATADV_ATTR_TT_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_TT_TTVN] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_TT_LAST_TTVN] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_TT_CRC32] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_TT_VID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_TT_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_FLAG_BEST] = { .type = NETLINK_TYPE_FLAG }, + [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_NEIGH_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_TQ] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_THROUGHPUT] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_ROUTER] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_OWN] = { .type = NETLINK_TYPE_FLAG }, + [BATADV_ATTR_BLA_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_VID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_BLA_BACKBONE] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_CRC] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_DAT_CACHE_VID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_MCAST_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_VLANID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_ISOLATION_MARK] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_ISOLATION_MASK] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_BONDING_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_GW_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_GW_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_GW_MODE] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_GW_SEL_CLASS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_HOP_PENALTY] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_LOG_LEVEL] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_MULTICAST_FANOUT] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_NETWORK_CODING_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_ORIG_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_ELP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem genl_batadv_type_system = { + .count = ELEMENTSOF(genl_batadv_types), + .types = genl_batadv_types, +}; + +static const NLType genl_batadv_cmds[] = { + [BATADV_CMD_SET_MESH] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, +}; + +static const NLTypeSystem genl_batadv_cmds_type_system = { + .count = ELEMENTSOF(genl_batadv_cmds), + .types = genl_batadv_cmds, +}; + +/***************** genl fou type systems *****************/ +static const NLType genl_fou_types[] = { + [FOU_ATTR_PORT] = { .type = NETLINK_TYPE_U16 }, + [FOU_ATTR_AF] = { .type = NETLINK_TYPE_U8 }, + [FOU_ATTR_IPPROTO] = { .type = NETLINK_TYPE_U8 }, + [FOU_ATTR_TYPE] = { .type = NETLINK_TYPE_U8 }, + [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, + [FOU_ATTR_LOCAL_V4] = { .type = NETLINK_TYPE_IN_ADDR }, + [FOU_ATTR_PEER_V4] = { .type = NETLINK_TYPE_IN_ADDR }, + [FOU_ATTR_LOCAL_V6] = { .type = NETLINK_TYPE_IN_ADDR }, + [FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR}, + [FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16}, + [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32}, +}; + +static const NLTypeSystem genl_fou_type_system = { + .count = ELEMENTSOF(genl_fou_types), + .types = genl_fou_types, +}; + +static const NLType genl_fou_cmds[] = { + [FOU_CMD_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, + [FOU_CMD_DEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, + [FOU_CMD_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, +}; + +static const NLTypeSystem genl_fou_cmds_type_system = { + .count = ELEMENTSOF(genl_fou_cmds), + .types = genl_fou_cmds, +}; + +/***************** genl l2tp type systems *****************/ +static const NLType genl_l2tp_types[] = { + [L2TP_ATTR_PW_TYPE] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_OFFSET] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_DATA_SEQ] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_L2SPEC_TYPE] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_L2SPEC_LEN] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_PROTO_VERSION] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_IFNAME] = { .type = NETLINK_TYPE_STRING }, + [L2TP_ATTR_CONN_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_PEER_CONN_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_PEER_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_RECV_SEQ] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_SEND_SEQ] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_LNS_MODE] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_USING_IPSEC] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_FD] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_IP_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_IP_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_UDP_SPORT] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_UDP_DPORT] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_IP6_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_IP6_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_FLAG }, + [L2TP_ATTR_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_FLAG }, +}; + +static const NLTypeSystem genl_l2tp_type_system = { + .count = ELEMENTSOF(genl_l2tp_types), + .types = genl_l2tp_types, +}; + +static const NLType genl_l2tp[] = { + [L2TP_CMD_TUNNEL_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_TUNNEL_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_TUNNEL_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_TUNNEL_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, +}; + +static const NLTypeSystem genl_l2tp_tunnel_session_type_system = { + .count = ELEMENTSOF(genl_l2tp), + .types = genl_l2tp, +}; + +/***************** genl macsec type systems *****************/ +static const NLType genl_rxsc_types[] = { + [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, +}; + +static const NLTypeSystem genl_rxsc_config_type_system = { + .count = ELEMENTSOF(genl_rxsc_types), + .types = genl_rxsc_types, +}; + +static const NLType genl_macsec_rxsc_types[] = { + [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, +}; + +static const NLTypeSystem genl_macsec_rxsc_type_system = { + .count = ELEMENTSOF(genl_macsec_rxsc_types), + .types = genl_macsec_rxsc_types, +}; + +static const NLType genl_macsec_sa_config_types[] = { + [MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 }, + [MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 }, + [MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_SA_ATTR_KEYID] = { .size = MACSEC_KEYID_LEN }, + [MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN }, +}; + +static const NLTypeSystem genl_macsec_sa_config_type_system = { + .count = ELEMENTSOF(genl_macsec_sa_config_types), + .types = genl_macsec_sa_config_types, +}; + +static const NLType genl_macsec_rxsa_types[] = { + [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, +}; + +static const NLTypeSystem genl_macsec_rxsa_type_system = { + .count = ELEMENTSOF(genl_macsec_rxsa_types), + .types = genl_macsec_rxsa_types, +}; + +static const NLType genl_macsec_sa_types[] = { + [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, + [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, +}; + +static const NLTypeSystem genl_macsec_sa_type_system = { + .count = ELEMENTSOF(genl_macsec_sa_types), + .types = genl_macsec_sa_types, +}; + +static const NLType genl_macsec[] = { + [MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system }, + [MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsa_type_system}, + [MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, +}; + +static const NLTypeSystem genl_macsec_device_type_system = { + .count = ELEMENTSOF(genl_macsec), + .types = genl_macsec, +}; + +/***************** genl nl80211 type systems *****************/ +static const NLType genl_nl80211_types[] = { + [NL80211_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [NL80211_ATTR_MAC] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [NL80211_ATTR_SSID] = { .type = NETLINK_TYPE_STRING }, + [NL80211_ATTR_IFTYPE] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem genl_nl80211_type_system = { + .count = ELEMENTSOF(genl_nl80211_types), + .types = genl_nl80211_types, +}; + +static const NLType genl_nl80211_cmds[] = { + [NL80211_CMD_GET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_SET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_NEW_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_DEL_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_GET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_SET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_NEW_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_DEL_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_GET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_SET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_NEW_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_DEL_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, +}; + +static const NLTypeSystem genl_nl80211_cmds_type_system = { + .count = ELEMENTSOF(genl_nl80211_cmds), + .types = genl_nl80211_cmds, +}; + +/***************** genl wireguard type systems *****************/ +static const NLType genl_wireguard_allowedip_types[] = { + [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, + [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLTypeSystem genl_wireguard_allowedip_type_system = { + .count = ELEMENTSOF(genl_wireguard_allowedip_types), + .types = genl_wireguard_allowedip_types, +}; + +static const NLType genl_wireguard_peer_types[] = { + [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 }, + [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR }, + [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, +}; + +static const NLTypeSystem genl_wireguard_peer_type_system = { + .count = ELEMENTSOF(genl_wireguard_peer_types), + .types = genl_wireguard_peer_types, +}; + +static const NLType genl_wireguard_set_device_types[] = { + [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 }, + [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN }, + [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 }, + [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, +}; + +static const NLTypeSystem genl_wireguard_set_device_type_system = { + .count = ELEMENTSOF(genl_wireguard_set_device_types), + .types = genl_wireguard_set_device_types, +}; + +static const NLType genl_wireguard_cmds[] = { + [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_set_device_type_system }, +}; + +static const NLTypeSystem genl_wireguard_type_system = { + .count = ELEMENTSOF(genl_wireguard_cmds), + .types = genl_wireguard_cmds, +}; + +static const NLType genl_families[] = { + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system }, + [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, + [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmds_type_system }, + [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system }, + [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmds_type_system }, + [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmds_type_system }, +}; + /* Mainly used when sending message */ const NLTypeSystem genl_family_type_system_root = { .count = ELEMENTSOF(genl_families), From b5beb9b0f5d7c65e244e11182db08fe48ae65a20 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Jun 2021 16:07:21 +0900 Subject: [PATCH 09/29] sd-netlink: make several type systems static --- src/libsystemd/sd-netlink/netlink-types.c | 8 ++++---- src/libsystemd/sd-netlink/netlink-types.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 80492af0dd..38ea22bfd9 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -1098,7 +1098,7 @@ static const NLType rtnl_types[] = { [RTM_GETMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, }; -const NLTypeSystem rtnl_type_system_root = { +static const NLTypeSystem rtnl_type_system_root = { .count = ELEMENTSOF(rtnl_types), .types = rtnl_types, }; @@ -1337,7 +1337,7 @@ static const NLType nfnl_types[] = { [NFNL_SUBSYS_NFTABLES] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_msg_type_system, .size = sizeof(struct nfgenmsg) }, }; -const NLTypeSystem nfnl_type_system_root = { +static const NLTypeSystem nfnl_type_system_root = { .count = ELEMENTSOF(nfnl_types), .types = nfnl_types, }; @@ -1708,7 +1708,7 @@ static const NLType genl_types[] = { }; /* Mainly used when message received */ -const NLTypeSystem genl_type_system_root = { +static const NLTypeSystem genl_type_system_root = { .count = ELEMENTSOF(genl_types), .types = genl_types, }; @@ -1742,7 +1742,7 @@ uint16_t type_system_get_count(const NLTypeSystem *type_system) { return type_system->count; } -const NLTypeSystem *type_system_get_root(int protocol) { +static const NLTypeSystem *type_system_get_root(int protocol) { switch (protocol) { case NETLINK_GENERIC: return &genl_type_system_root; diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 5c292ab2b3..b78ed21a41 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -42,7 +42,6 @@ size_t type_get_size(const NLType *type); const NLTypeSystem *type_get_type_system(const NLType *type); const NLTypeSystemUnion *type_get_type_system_union(const NLType *type); -const NLTypeSystem* type_system_get_root(int protocol); uint16_t type_system_get_count(const NLTypeSystem *type_system); int type_system_root_get_type(sd_netlink *nl, const NLType **ret, uint16_t type); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); From 021273b782e8bbcdf05481713f6352a6faeb49d5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 7 Jul 2021 13:42:04 +0900 Subject: [PATCH 10/29] sd-netlink: split netlink-types.[ch] into small files Also renames several files. --- src/libsystemd/meson.build | 12 +- .../{generic-netlink.c => netlink-genl.c} | 2 +- .../{generic-netlink.h => netlink-genl.h} | 0 ...{nfnl-message.c => netlink-message-nfnl.c} | 0 ...{rtnl-message.c => netlink-message-rtnl.c} | 0 .../sd-netlink/netlink-types-genl.c | 405 ++++ .../sd-netlink/netlink-types-internal.h | 107 + .../sd-netlink/netlink-types-nfnl.c | 251 +++ .../sd-netlink/netlink-types-rtnl.c | 1056 ++++++++++ src/libsystemd/sd-netlink/netlink-types.c | 1738 +---------------- src/libsystemd/sd-netlink/netlink-types.h | 85 +- src/network/test-network-tables.c | 2 - 12 files changed, 1846 insertions(+), 1812 deletions(-) rename src/libsystemd/sd-netlink/{generic-netlink.c => netlink-genl.c} (99%) rename src/libsystemd/sd-netlink/{generic-netlink.h => netlink-genl.h} (100%) rename src/libsystemd/sd-netlink/{nfnl-message.c => netlink-message-nfnl.c} (100%) rename src/libsystemd/sd-netlink/{rtnl-message.c => netlink-message-rtnl.c} (100%) create mode 100644 src/libsystemd/sd-netlink/netlink-types-genl.c create mode 100644 src/libsystemd/sd-netlink/netlink-types-internal.h create mode 100644 src/libsystemd/sd-netlink/netlink-types-nfnl.c create mode 100644 src/libsystemd/sd-netlink/netlink-types-rtnl.c diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 479b81b352..8ec871f6a4 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -132,19 +132,23 @@ libsystemd_sources = files(''' sd-device/sd-device.c sd-hwdb/hwdb-internal.h sd-hwdb/sd-hwdb.c - sd-netlink/generic-netlink.c - sd-netlink/generic-netlink.h + sd-netlink/netlink-genl.c + sd-netlink/netlink-genl.h sd-netlink/netlink-internal.h + sd-netlink/netlink-message-nfnl.c + sd-netlink/netlink-message-rtnl.c sd-netlink/netlink-message.c sd-netlink/netlink-slot.c sd-netlink/netlink-slot.h sd-netlink/netlink-socket.c + sd-netlink/netlink-types-genl.c + sd-netlink/netlink-types-internal.h + sd-netlink/netlink-types-nfnl.c + sd-netlink/netlink-types-rtnl.c sd-netlink/netlink-types.c sd-netlink/netlink-types.h sd-netlink/netlink-util.c sd-netlink/netlink-util.h - sd-netlink/nfnl-message.c - sd-netlink/rtnl-message.c sd-netlink/sd-netlink.c sd-network/network-util.c sd-network/network-util.h diff --git a/src/libsystemd/sd-netlink/generic-netlink.c b/src/libsystemd/sd-netlink/netlink-genl.c similarity index 99% rename from src/libsystemd/sd-netlink/generic-netlink.c rename to src/libsystemd/sd-netlink/netlink-genl.c index 648b840771..401f263d97 100644 --- a/src/libsystemd/sd-netlink/generic-netlink.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -5,7 +5,7 @@ #include "sd-netlink.h" #include "alloc-util.h" -#include "generic-netlink.h" +#include "netlink-genl.h" #include "netlink-internal.h" typedef struct { diff --git a/src/libsystemd/sd-netlink/generic-netlink.h b/src/libsystemd/sd-netlink/netlink-genl.h similarity index 100% rename from src/libsystemd/sd-netlink/generic-netlink.h rename to src/libsystemd/sd-netlink/netlink-genl.h diff --git a/src/libsystemd/sd-netlink/nfnl-message.c b/src/libsystemd/sd-netlink/netlink-message-nfnl.c similarity index 100% rename from src/libsystemd/sd-netlink/nfnl-message.c rename to src/libsystemd/sd-netlink/netlink-message-nfnl.c diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/netlink-message-rtnl.c similarity index 100% rename from src/libsystemd/sd-netlink/rtnl-message.c rename to src/libsystemd/sd-netlink/netlink-message-rtnl.c diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c new file mode 100644 index 0000000000..3dfe47a7f3 --- /dev/null +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netlink-genl.h" +#include "netlink-types-internal.h" + +/***************** genl ctrl type systems *****************/ +static const NLType genl_mcast_group_types[] = { + [CTRL_ATTR_MCAST_GRP_NAME] = { .type = NETLINK_TYPE_STRING }, + [CTRL_ATTR_MCAST_GRP_ID] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem genl_mcast_group_type_system = { + .count = ELEMENTSOF(genl_mcast_group_types), + .types = genl_mcast_group_types, +}; + +static const NLType genl_get_family_types[] = { + [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, + [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, + [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_mcast_group_type_system }, +}; + +static const NLTypeSystem genl_get_family_type_system = { + .count = ELEMENTSOF(genl_get_family_types), + .types = genl_get_family_types, +}; + +static const NLType genl_ctrl_id_ctrl_cmds[] = { + [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system }, +}; + +static const NLTypeSystem genl_ctrl_id_ctrl_type_system = { + .count = ELEMENTSOF(genl_ctrl_id_ctrl_cmds), + .types = genl_ctrl_id_ctrl_cmds, +}; + +/***************** genl batadv type systems *****************/ +static const NLType genl_batadv_types[] = { + [BATADV_ATTR_VERSION] = { .type = NETLINK_TYPE_STRING }, + [BATADV_ATTR_ALGO_NAME] = { .type = NETLINK_TYPE_STRING }, + [BATADV_ATTR_MESH_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_MESH_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, + [BATADV_ATTR_MESH_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_HARD_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_HARD_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, + [BATADV_ATTR_HARD_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_ORIG_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_TPMETER_RESULT] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_TPMETER_BYTES] = { .type = NETLINK_TYPE_U64 }, + [BATADV_ATTR_TPMETER_COOKIE] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_PAD] = { .type = NETLINK_TYPE_UNSPEC }, + [BATADV_ATTR_ACTIVE] = { .type = NETLINK_TYPE_FLAG }, + [BATADV_ATTR_TT_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_TT_TTVN] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_TT_LAST_TTVN] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_TT_CRC32] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_TT_VID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_TT_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_FLAG_BEST] = { .type = NETLINK_TYPE_FLAG }, + [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_NEIGH_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_TQ] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_THROUGHPUT] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_ROUTER] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_OWN] = { .type = NETLINK_TYPE_FLAG }, + [BATADV_ATTR_BLA_ADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_VID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_BLA_BACKBONE] = { .size = ETH_ALEN }, + [BATADV_ATTR_BLA_CRC] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .size = ETH_ALEN }, + [BATADV_ATTR_DAT_CACHE_VID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_MCAST_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_VLANID] = { .type = NETLINK_TYPE_U16 }, + [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_ISOLATION_MARK] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_ISOLATION_MASK] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_BONDING_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_GW_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_GW_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_GW_MODE] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_GW_SEL_CLASS] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_HOP_PENALTY] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_LOG_LEVEL] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_MULTICAST_FANOUT] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_NETWORK_CODING_ENABLED] = { .type = NETLINK_TYPE_U8 }, + [BATADV_ATTR_ORIG_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_ELP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem genl_batadv_type_system = { + .count = ELEMENTSOF(genl_batadv_types), + .types = genl_batadv_types, +}; + +static const NLType genl_batadv_cmds[] = { + [BATADV_CMD_SET_MESH] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, +}; + +static const NLTypeSystem genl_batadv_cmds_type_system = { + .count = ELEMENTSOF(genl_batadv_cmds), + .types = genl_batadv_cmds, +}; + +/***************** genl fou type systems *****************/ +static const NLType genl_fou_types[] = { + [FOU_ATTR_PORT] = { .type = NETLINK_TYPE_U16 }, + [FOU_ATTR_AF] = { .type = NETLINK_TYPE_U8 }, + [FOU_ATTR_IPPROTO] = { .type = NETLINK_TYPE_U8 }, + [FOU_ATTR_TYPE] = { .type = NETLINK_TYPE_U8 }, + [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, + [FOU_ATTR_LOCAL_V4] = { .type = NETLINK_TYPE_IN_ADDR }, + [FOU_ATTR_PEER_V4] = { .type = NETLINK_TYPE_IN_ADDR }, + [FOU_ATTR_LOCAL_V6] = { .type = NETLINK_TYPE_IN_ADDR }, + [FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR}, + [FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16}, + [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32}, +}; + +static const NLTypeSystem genl_fou_type_system = { + .count = ELEMENTSOF(genl_fou_types), + .types = genl_fou_types, +}; + +static const NLType genl_fou_cmds[] = { + [FOU_CMD_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, + [FOU_CMD_DEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, + [FOU_CMD_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, +}; + +static const NLTypeSystem genl_fou_cmds_type_system = { + .count = ELEMENTSOF(genl_fou_cmds), + .types = genl_fou_cmds, +}; + +/***************** genl l2tp type systems *****************/ +static const NLType genl_l2tp_types[] = { + [L2TP_ATTR_PW_TYPE] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_OFFSET] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_DATA_SEQ] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_L2SPEC_TYPE] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_L2SPEC_LEN] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_PROTO_VERSION] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_IFNAME] = { .type = NETLINK_TYPE_STRING }, + [L2TP_ATTR_CONN_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_PEER_CONN_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_PEER_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_RECV_SEQ] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_SEND_SEQ] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_LNS_MODE] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_USING_IPSEC] = { .type = NETLINK_TYPE_U8 }, + [L2TP_ATTR_FD] = { .type = NETLINK_TYPE_U32 }, + [L2TP_ATTR_IP_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_IP_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_UDP_SPORT] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_UDP_DPORT] = { .type = NETLINK_TYPE_U16 }, + [L2TP_ATTR_IP6_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_IP6_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [L2TP_ATTR_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_FLAG }, + [L2TP_ATTR_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_FLAG }, +}; + +static const NLTypeSystem genl_l2tp_type_system = { + .count = ELEMENTSOF(genl_l2tp_types), + .types = genl_l2tp_types, +}; + +static const NLType genl_l2tp[] = { + [L2TP_CMD_TUNNEL_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_TUNNEL_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_TUNNEL_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_TUNNEL_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [L2TP_CMD_SESSION_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, +}; + +static const NLTypeSystem genl_l2tp_tunnel_session_type_system = { + .count = ELEMENTSOF(genl_l2tp), + .types = genl_l2tp, +}; + +/***************** genl macsec type systems *****************/ +static const NLType genl_rxsc_types[] = { + [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, +}; + +static const NLTypeSystem genl_rxsc_config_type_system = { + .count = ELEMENTSOF(genl_rxsc_types), + .types = genl_rxsc_types, +}; + +static const NLType genl_macsec_rxsc_types[] = { + [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, +}; + +static const NLTypeSystem genl_macsec_rxsc_type_system = { + .count = ELEMENTSOF(genl_macsec_rxsc_types), + .types = genl_macsec_rxsc_types, +}; + +static const NLType genl_macsec_sa_config_types[] = { + [MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 }, + [MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 }, + [MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_SA_ATTR_KEYID] = { .size = MACSEC_KEYID_LEN }, + [MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN }, +}; + +static const NLTypeSystem genl_macsec_sa_config_type_system = { + .count = ELEMENTSOF(genl_macsec_sa_config_types), + .types = genl_macsec_sa_config_types, +}; + +static const NLType genl_macsec_rxsa_types[] = { + [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, +}; + +static const NLTypeSystem genl_macsec_rxsa_type_system = { + .count = ELEMENTSOF(genl_macsec_rxsa_types), + .types = genl_macsec_rxsa_types, +}; + +static const NLType genl_macsec_sa_types[] = { + [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, + [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, +}; + +static const NLTypeSystem genl_macsec_sa_type_system = { + .count = ELEMENTSOF(genl_macsec_sa_types), + .types = genl_macsec_sa_types, +}; + +static const NLType genl_macsec[] = { + [MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system }, + [MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsa_type_system}, + [MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, +}; + +static const NLTypeSystem genl_macsec_device_type_system = { + .count = ELEMENTSOF(genl_macsec), + .types = genl_macsec, +}; + +/***************** genl nl80211 type systems *****************/ +static const NLType genl_nl80211_types[] = { + [NL80211_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [NL80211_ATTR_MAC] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [NL80211_ATTR_SSID] = { .type = NETLINK_TYPE_STRING }, + [NL80211_ATTR_IFTYPE] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem genl_nl80211_type_system = { + .count = ELEMENTSOF(genl_nl80211_types), + .types = genl_nl80211_types, +}; + +static const NLType genl_nl80211_cmds[] = { + [NL80211_CMD_GET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_SET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_NEW_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_DEL_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_GET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_SET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_NEW_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_DEL_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_GET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_SET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_NEW_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [NL80211_CMD_DEL_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, +}; + +static const NLTypeSystem genl_nl80211_cmds_type_system = { + .count = ELEMENTSOF(genl_nl80211_cmds), + .types = genl_nl80211_cmds, +}; + +/***************** genl wireguard type systems *****************/ +static const NLType genl_wireguard_allowedip_types[] = { + [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, + [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLTypeSystem genl_wireguard_allowedip_type_system = { + .count = ELEMENTSOF(genl_wireguard_allowedip_types), + .types = genl_wireguard_allowedip_types, +}; + +static const NLType genl_wireguard_peer_types[] = { + [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 }, + [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR }, + [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, +}; + +static const NLTypeSystem genl_wireguard_peer_type_system = { + .count = ELEMENTSOF(genl_wireguard_peer_types), + .types = genl_wireguard_peer_types, +}; + +static const NLType genl_wireguard_set_device_types[] = { + [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 }, + [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN }, + [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 }, + [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, +}; + +static const NLTypeSystem genl_wireguard_set_device_type_system = { + .count = ELEMENTSOF(genl_wireguard_set_device_types), + .types = genl_wireguard_set_device_types, +}; + +static const NLType genl_wireguard_cmds[] = { + [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_set_device_type_system }, +}; + +static const NLTypeSystem genl_wireguard_type_system = { + .count = ELEMENTSOF(genl_wireguard_cmds), + .types = genl_wireguard_cmds, +}; + +static const NLType genl_families[] = { + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system }, + [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, + [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmds_type_system }, + [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system }, + [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmds_type_system }, + [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmds_type_system }, +}; + +/* Mainly used when sending message */ +const NLTypeSystem genl_family_type_system_root = { + .count = ELEMENTSOF(genl_families), + .types = genl_families, +}; + +static const NLType genl_types[] = { + [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, + [SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, +}; + +/* Mainly used when message received */ +static const NLTypeSystem genl_type_system = { + .count = ELEMENTSOF(genl_types), + .types = genl_types, +}; + +int genl_get_type(sd_netlink *genl, uint16_t nlmsg_type, const NLType **ret) { + sd_genl_family_t family; + const NLType *nl_type; + int r; + + r = nlmsg_type_to_genl_family(genl, nlmsg_type, &family); + if (r < 0) + return r; + + if (family >= genl_type_system.count) + return -EOPNOTSUPP; + + nl_type = &genl_type_system.types[family]; + + if (nl_type->type == NETLINK_TYPE_UNSPEC) + return -EOPNOTSUPP; + + *ret = nl_type; + return 0; +} diff --git a/src/libsystemd/sd-netlink/netlink-types-internal.h b/src/libsystemd/sd-netlink/netlink-types-internal.h new file mode 100644 index 0000000000..66a25a4dfb --- /dev/null +++ b/src/libsystemd/sd-netlink/netlink-types-internal.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "macro.h" +#include "netlink-types.h" + +struct NLType { + uint16_t type; + size_t size; + const NLTypeSystem *type_system; + const NLTypeSystemUnion *type_system_union; +}; + +struct NLTypeSystem { + uint16_t count; + const NLType *types; +}; + +struct NLTypeSystemUnion { + int num; + NLMatchType match_type; + uint16_t match_attribute; + int (*lookup)(const char *); + const NLTypeSystem *type_systems; +}; + +extern const NLTypeSystem empty_type_system; +extern const NLTypeSystem error_type_system; + +typedef enum NLUnionLinkInfoData { + NL_UNION_LINK_INFO_DATA_BOND, + NL_UNION_LINK_INFO_DATA_BRIDGE, + NL_UNION_LINK_INFO_DATA_VLAN, + NL_UNION_LINK_INFO_DATA_VETH, + NL_UNION_LINK_INFO_DATA_DUMMY, + NL_UNION_LINK_INFO_DATA_MACVLAN, + NL_UNION_LINK_INFO_DATA_MACVTAP, + NL_UNION_LINK_INFO_DATA_IPVLAN, + NL_UNION_LINK_INFO_DATA_IPVTAP, + NL_UNION_LINK_INFO_DATA_VXLAN, + NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL, + NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL, + NL_UNION_LINK_INFO_DATA_ERSPAN, + NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL, + NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL, + NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL, + NL_UNION_LINK_INFO_DATA_SIT_TUNNEL, + NL_UNION_LINK_INFO_DATA_VTI_TUNNEL, + NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL, + NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL, + NL_UNION_LINK_INFO_DATA_VRF, + NL_UNION_LINK_INFO_DATA_VCAN, + NL_UNION_LINK_INFO_DATA_GENEVE, + NL_UNION_LINK_INFO_DATA_VXCAN, + NL_UNION_LINK_INFO_DATA_WIREGUARD, + NL_UNION_LINK_INFO_DATA_NETDEVSIM, + NL_UNION_LINK_INFO_DATA_CAN, + NL_UNION_LINK_INFO_DATA_MACSEC, + NL_UNION_LINK_INFO_DATA_NLMON, + NL_UNION_LINK_INFO_DATA_XFRM, + NL_UNION_LINK_INFO_DATA_IFB, + NL_UNION_LINK_INFO_DATA_BAREUDP, + NL_UNION_LINK_INFO_DATA_BATADV, + _NL_UNION_LINK_INFO_DATA_MAX, + _NL_UNION_LINK_INFO_DATA_INVALID = -EINVAL, +} NLUnionLinkInfoData; + +const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_; +NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_; + +typedef enum NLUnionTCAOptionData { + NL_UNION_TCA_OPTION_DATA_CAKE, + NL_UNION_TCA_OPTION_DATA_CODEL, + NL_UNION_TCA_OPTION_DATA_DRR, + NL_UNION_TCA_OPTION_DATA_ETS, + NL_UNION_TCA_OPTION_DATA_FQ, + NL_UNION_TCA_OPTION_DATA_FQ_CODEL, + NL_UNION_TCA_OPTION_DATA_FQ_PIE, + NL_UNION_TCA_OPTION_DATA_GRED, + NL_UNION_TCA_OPTION_DATA_HHF, + NL_UNION_TCA_OPTION_DATA_HTB, + NL_UNION_TCA_OPTION_DATA_PIE, + NL_UNION_TCA_OPTION_DATA_QFQ, + NL_UNION_TCA_OPTION_DATA_SFB, + NL_UNION_TCA_OPTION_DATA_TBF, + _NL_UNION_TCA_OPTION_DATA_MAX, + _NL_UNION_TCA_OPTION_DATA_INVALID = -EINVAL, +} NLUnionTCAOptionData; + +const char *nl_union_tca_option_data_to_string(NLUnionTCAOptionData p) _const_; +NLUnionTCAOptionData nl_union_tca_option_data_from_string(const char *p) _pure_; + +typedef enum NLUnionNFTExprData { + NL_UNION_NFT_EXPR_DATA_BITWISE, + NL_UNION_NFT_EXPR_DATA_CMP, + NL_UNION_NFT_EXPR_DATA_FIB, + NL_UNION_NFT_EXPR_DATA_LOOKUP, + NL_UNION_NFT_EXPR_DATA_PAYLOAD, + NL_UNION_NFT_EXPR_DATA_MASQ, + NL_UNION_NFT_EXPR_DATA_META, + NL_UNION_NFT_EXPR_DATA_NAT, + _NL_UNION_NFT_EXPR_DATA_MAX, + _NL_UNION_NFT_EXPR_DATA_INVALID = -EINVAL, +} NLUnionNFTExprData; + +const char *nl_union_nft_expr_data_to_string(NLUnionNFTExprData p) _const_; +NLUnionNFTExprData nl_union_nft_expr_data_from_string(const char *p) _pure_; diff --git a/src/libsystemd/sd-netlink/netlink-types-nfnl.c b/src/libsystemd/sd-netlink/netlink-types-nfnl.c new file mode 100644 index 0000000000..ba6c076e39 --- /dev/null +++ b/src/libsystemd/sd-netlink/netlink-types-nfnl.c @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include +#include +#include +#include + +#include "netlink-types-internal.h" +#include "string-table.h" + +static const NLType nfnl_nft_table_types[] = { + [NFTA_TABLE_NAME] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_TABLE_FLAGS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem nfnl_nft_table_type_system = { + .count = ELEMENTSOF(nfnl_nft_table_types), + .types = nfnl_nft_table_types, +}; + +static const NLType nfnl_nft_chain_hook_types[] = { + [NFTA_HOOK_HOOKNUM] = { .type = NETLINK_TYPE_U32 }, + [NFTA_HOOK_PRIORITY] = { .type = NETLINK_TYPE_U32 }, + [NFTA_HOOK_DEV] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, +}; + +static const NLTypeSystem nfnl_nft_chain_hook_type_system = { + .count = ELEMENTSOF(nfnl_nft_chain_hook_types), + .types = nfnl_nft_chain_hook_types, +}; + +static const NLType nfnl_nft_chain_types[] = { + [NFTA_CHAIN_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_CHAIN_NAME] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_CHAIN_HOOK] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_chain_hook_type_system }, + [NFTA_CHAIN_TYPE] = { .type = NETLINK_TYPE_STRING, .size = 16 }, + [NFTA_CHAIN_FLAGS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem nfnl_nft_chain_type_system = { + .count = ELEMENTSOF(nfnl_nft_chain_types), + .types = nfnl_nft_chain_types, +}; + +static const NLType nfnl_nft_expr_meta_types[] = { + [NFTA_META_DREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_META_KEY] = { .type = NETLINK_TYPE_U32 }, + [NFTA_META_SREG] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType nfnl_nft_expr_payload_types[] = { + [NFTA_PAYLOAD_DREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_PAYLOAD_BASE] = { .type = NETLINK_TYPE_U32 }, + [NFTA_PAYLOAD_OFFSET] = { .type = NETLINK_TYPE_U32 }, + [NFTA_PAYLOAD_LEN] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType nfnl_nft_expr_nat_types[] = { + [NFTA_NAT_TYPE] = { .type = NETLINK_TYPE_U32 }, + [NFTA_NAT_FAMILY] = { .type = NETLINK_TYPE_U32 }, + [NFTA_NAT_REG_ADDR_MIN] = { .type = NETLINK_TYPE_U32 }, + [NFTA_NAT_REG_ADDR_MAX] = { .type = NETLINK_TYPE_U32 }, + [NFTA_NAT_REG_PROTO_MIN] = { .type = NETLINK_TYPE_U32 }, + [NFTA_NAT_REG_PROTO_MAX] = { .type = NETLINK_TYPE_U32 }, + [NFTA_NAT_FLAGS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType nfnl_nft_data_types[] = { + [NFTA_DATA_VALUE] = { .type = NETLINK_TYPE_BINARY }, +}; + +static const NLTypeSystem nfnl_nft_data_type_system = { + .count = ELEMENTSOF(nfnl_nft_data_types), + .types = nfnl_nft_data_types, +}; + +static const NLType nfnl_nft_expr_bitwise_types[] = { + [NFTA_BITWISE_SREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_BITWISE_DREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_BITWISE_LEN] = { .type = NETLINK_TYPE_U32 }, + [NFTA_BITWISE_MASK] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, + [NFTA_BITWISE_XOR] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, +}; + +static const NLType nfnl_nft_expr_cmp_types[] = { + [NFTA_CMP_SREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_CMP_OP] = { .type = NETLINK_TYPE_U32 }, + [NFTA_CMP_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, +}; + +static const NLType nfnl_nft_expr_fib_types[] = { + [NFTA_FIB_DREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_FIB_RESULT] = { .type = NETLINK_TYPE_U32 }, + [NFTA_FIB_FLAGS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType nfnl_nft_expr_lookup_types[] = { + [NFTA_LOOKUP_SET] = { .type = NETLINK_TYPE_STRING }, + [NFTA_LOOKUP_SREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_LOOKUP_DREG] = { .type = NETLINK_TYPE_U32 }, + [NFTA_LOOKUP_FLAGS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType nfnl_nft_expr_masq_types[] = { + [NFTA_MASQ_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [NFTA_MASQ_REG_PROTO_MIN] = { .type = NETLINK_TYPE_U32 }, + [NFTA_MASQ_REG_PROTO_MAX] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem nfnl_expr_data_type_systems[] = { + [NL_UNION_NFT_EXPR_DATA_BITWISE] = { .count = ELEMENTSOF(nfnl_nft_expr_bitwise_types), + .types = nfnl_nft_expr_bitwise_types }, + [NL_UNION_NFT_EXPR_DATA_CMP] = { .count = ELEMENTSOF(nfnl_nft_expr_cmp_types), + .types = nfnl_nft_expr_cmp_types }, + [NL_UNION_NFT_EXPR_DATA_FIB] = { .count = ELEMENTSOF(nfnl_nft_expr_fib_types), + .types = nfnl_nft_expr_fib_types }, + [NL_UNION_NFT_EXPR_DATA_LOOKUP] = { .count = ELEMENTSOF(nfnl_nft_expr_lookup_types), + .types = nfnl_nft_expr_lookup_types }, + [NL_UNION_NFT_EXPR_DATA_MASQ] = { .count = ELEMENTSOF(nfnl_nft_expr_masq_types), + .types = nfnl_nft_expr_masq_types }, + [NL_UNION_NFT_EXPR_DATA_META] = { .count = ELEMENTSOF(nfnl_nft_expr_meta_types), + .types = nfnl_nft_expr_meta_types }, + [NL_UNION_NFT_EXPR_DATA_NAT] = { .count = ELEMENTSOF(nfnl_nft_expr_nat_types), + .types = nfnl_nft_expr_nat_types }, + [NL_UNION_NFT_EXPR_DATA_PAYLOAD] = { .count = ELEMENTSOF(nfnl_nft_expr_payload_types), + .types = nfnl_nft_expr_payload_types }, +}; + +static const char* const nl_union_nft_expr_data_table[] = { + [NL_UNION_NFT_EXPR_DATA_BITWISE] = "bitwise", + [NL_UNION_NFT_EXPR_DATA_CMP] = "cmp", + [NL_UNION_NFT_EXPR_DATA_LOOKUP] = "lookup", + [NL_UNION_NFT_EXPR_DATA_META] = "meta", + [NL_UNION_NFT_EXPR_DATA_FIB] = "fib", + [NL_UNION_NFT_EXPR_DATA_MASQ] = "masq", + [NL_UNION_NFT_EXPR_DATA_NAT] = "nat", + [NL_UNION_NFT_EXPR_DATA_PAYLOAD] = "payload", +}; + +DEFINE_STRING_TABLE_LOOKUP(nl_union_nft_expr_data, NLUnionNFTExprData); + +static const NLTypeSystemUnion nfnl_nft_data_expr_type_system_union = { + .num = _NL_UNION_NFT_EXPR_DATA_MAX, + .lookup = nl_union_nft_expr_data_from_string, + .type_systems = nfnl_expr_data_type_systems, + .match_type = NL_MATCH_SIBLING, + .match_attribute = NFTA_EXPR_NAME, +}; + +static const NLType nfnl_nft_rule_expr_types[] = { + [NFTA_EXPR_NAME] = { .type = NETLINK_TYPE_STRING, .size = 16 }, + [NFTA_EXPR_DATA] = { .type = NETLINK_TYPE_UNION, + .type_system_union = &nfnl_nft_data_expr_type_system_union }, +}; + +static const NLTypeSystem nfnl_nft_rule_expr_type_system = { + .count = ELEMENTSOF(nfnl_nft_rule_expr_types), + .types = nfnl_nft_rule_expr_types, +}; + +static const NLType nfnl_nft_rule_types[] = { + [NFTA_RULE_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_RULE_CHAIN] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_RULE_EXPRESSIONS] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_rule_expr_type_system } +}; + +static const NLTypeSystem nfnl_nft_rule_type_system = { + .count = ELEMENTSOF(nfnl_nft_rule_types), + .types = nfnl_nft_rule_types, +}; + +static const NLType nfnl_nft_set_types[] = { + [NFTA_SET_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_SET_NAME] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_SET_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [NFTA_SET_KEY_TYPE] = { .type = NETLINK_TYPE_U32 }, + [NFTA_SET_KEY_LEN] = { .type = NETLINK_TYPE_U32 }, + [NFTA_SET_DATA_TYPE] = { .type = NETLINK_TYPE_U32 }, + [NFTA_SET_DATA_LEN] = { .type = NETLINK_TYPE_U32 }, + [NFTA_SET_POLICY] = { .type = NETLINK_TYPE_U32 }, + [NFTA_SET_ID] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem nfnl_nft_set_type_system = { + .count = ELEMENTSOF(nfnl_nft_set_types), + .types = nfnl_nft_set_types, +}; + +static const NLType nfnl_nft_setelem_types[] = { + [NFTA_SET_ELEM_KEY] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, + [NFTA_SET_ELEM_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, + [NFTA_SET_ELEM_FLAGS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem nfnl_nft_setelem_type_system = { + .count = ELEMENTSOF(nfnl_nft_setelem_types), + .types = nfnl_nft_setelem_types, +}; + +static const NLType nfnl_nft_setelem_list_types[] = { + [NFTA_SET_ELEM_LIST_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_SET_ELEM_LIST_SET] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, + [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_setelem_type_system }, +}; + +static const NLTypeSystem nfnl_nft_setelem_list_type_system = { + .count = ELEMENTSOF(nfnl_nft_setelem_list_types), + .types = nfnl_nft_setelem_list_types, +}; + +static const NLType nfnl_nft_msg_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_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_rule_type_system, .size = sizeof(struct nfgenmsg) }, + [NFT_MSG_NEWSET] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_set_type_system, .size = sizeof(struct nfgenmsg) }, + [NFT_MSG_NEWSETELEM] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_setelem_list_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 NLType nfnl_msg_batch_types [] = { + [NFNL_BATCH_GENID] = { .type = NETLINK_TYPE_U32 } +}; + +static const NLTypeSystem nfnl_msg_batch_type_system = { + .count = ELEMENTSOF(nfnl_msg_batch_types), + .types = nfnl_msg_batch_types, +}; + +static const NLType nfnl_types[] = { + [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, + [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, + [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_type_system = { + .count = ELEMENTSOF(nfnl_types), + .types = nfnl_types, +}; + +int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret) { + return type_system_get_type(&nfnl_type_system, ret, nlmsg_type); +} diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c new file mode 100644 index 0000000000..7f7f4150b6 --- /dev/null +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -0,0 +1,1056 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sd-netlink.h" + +#include "netlink-types-internal.h" +#include "string-table.h" + +/* Maximum ARP IP target defined in kernel */ +#define BOND_MAX_ARP_TARGETS 16 + +typedef enum { + BOND_ARP_TARGETS_0, + BOND_ARP_TARGETS_1, + BOND_ARP_TARGETS_2, + BOND_ARP_TARGETS_3, + BOND_ARP_TARGETS_4, + BOND_ARP_TARGETS_5, + BOND_ARP_TARGETS_6, + BOND_ARP_TARGETS_7, + BOND_ARP_TARGETS_8, + BOND_ARP_TARGETS_9, + BOND_ARP_TARGETS_10, + BOND_ARP_TARGETS_11, + BOND_ARP_TARGETS_12, + BOND_ARP_TARGETS_13, + BOND_ARP_TARGETS_14, + BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS, +} BondArpTargets; + +static const NLTypeSystem rtnl_link_type_system; + +static const NLType rtnl_link_info_data_batadv_types[] = { + [IFLA_BATADV_ALGO_NAME] = { .type = NETLINK_TYPE_STRING, .size = 20 }, +}; + +static const NLType rtnl_link_info_data_veth_types[] = { + [VETH_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, +}; + +static const NLType rtnl_link_info_data_vxcan_types[] = { + [VXCAN_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, +}; + +static const NLType rtnl_link_info_data_ipvlan_types[] = { + [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, +}; + +static const NLType rtnl_macvlan_macaddr_types[] = { + [IFLA_MACVLAN_MACADDR] = { .type = NETLINK_TYPE_ETHER_ADDR }, +}; + +static const NLTypeSystem rtnl_macvlan_macaddr_type_system = { + .count = ELEMENTSOF(rtnl_macvlan_macaddr_types), + .types = rtnl_macvlan_macaddr_types, +}; + +static const NLType rtnl_link_info_data_macvlan_types[] = { + [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_MACVLAN_MACADDR_MODE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_MACADDR_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_macvlan_macaddr_type_system }, + [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_BC_QUEUE_LEN] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = { .type = NETLINK_TYPE_REJECT }, +}; + +static const NLType rtnl_link_info_data_bridge_types[] = { + [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_VLAN_FILTERING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_ROOT_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_ROOT_PATH_COST] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_TOPOLOGY_CHANGE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_HELLO_TIMER] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_TCN_TIMER] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_GC_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_GROUP_ADDR] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_FDB_FLUSH] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_MCAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_SNOOPING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_QUERY_USE_IFADDR] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_QUERIER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_MCAST_HASH_ELASTICITY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_HASH_MAX] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_MCAST_LAST_MEMBER_CNT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERIER_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BR_NF_CALL_IPTABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BR_VLAN_DEFAULT_PVID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BR_MCAST_IGMP_VERSION] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLType rtnl_vlan_qos_map_types[] = { + [IFLA_VLAN_QOS_MAPPING] = { .size = sizeof(struct ifla_vlan_qos_mapping) }, +}; + +static const NLTypeSystem rtnl_vlan_qos_map_type_system = { + .count = ELEMENTSOF(rtnl_vlan_qos_map_types), + .types = rtnl_vlan_qos_map_types, +}; + +static const NLType rtnl_link_info_data_vlan_types[] = { + [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_VLAN_FLAGS] = { .size = sizeof(struct ifla_vlan_flags) }, + [IFLA_VLAN_EGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, + [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, + [IFLA_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, +}; + +static const NLType rtnl_link_info_data_vxlan_types[] = { + [IFLA_VXLAN_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_GROUP] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VXLAN_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VXLAN_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_LEARNING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_AGEING] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_LIMIT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_PORT_RANGE] = { .type = NETLINK_TYPE_U32}, + [IFLA_VXLAN_PROXY] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_RSC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_L2MISS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_L3MISS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_VXLAN_GROUP6] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VXLAN_LOCAL6] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VXLAN_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_REMCSUM_TX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_REMCSUM_RX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_GBP] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_TTL_INHERIT] = { .type = NETLINK_TYPE_FLAG }, + [IFLA_VXLAN_DF] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLType rtnl_bond_arp_target_types[] = { + [BOND_ARP_TARGETS_0] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_1] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_2] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_3] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_4] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_5] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_6] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_7] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_8] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_9] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_10] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_11] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_12] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_13] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_14] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_MAX] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem rtnl_bond_arp_type_system = { + .count = ELEMENTSOF(rtnl_bond_arp_target_types), + .types = rtnl_bond_arp_target_types, +}; + +static const NLType rtnl_link_info_data_bond_types[] = { + [IFLA_BOND_MODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_ACTIVE_SLAVE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_MIIMON] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_UPDELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_DOWNDELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_USE_CARRIER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_ARP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_ARP_IP_TARGET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_type_system }, + [IFLA_BOND_ARP_VALIDATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_PRIMARY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_PRIMARY_RESELECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_FAIL_OVER_MAC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_RESEND_IGMP] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_MIN_LINKS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_LP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_AD_LACP_RATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_AD_SELECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_AD_INFO] = { .type = NETLINK_TYPE_NESTED }, + [IFLA_BOND_AD_ACTOR_SYS_PRIO] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BOND_AD_USER_PORT_KEY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLType rtnl_link_info_data_iptun_types[] = { + [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_6RD_PREFIX] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, +}; + +static const NLType rtnl_link_info_data_ipgre_types[] = { + [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_IKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_OKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ERSPAN_INDEX] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_link_info_data_ipvti_types[] = { + [IFLA_VTI_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_IKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_OKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VTI_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, +}; + +static const NLType rtnl_link_info_data_ip6tnl_types[] = { + [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_link_info_data_vrf_types[] = { + [IFLA_VRF_TABLE] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_link_info_data_geneve_types[] = { + [IFLA_GENEVE_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GENEVE_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GENEVE_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GENEVE_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GENEVE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GENEVE_REMOTE6] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GENEVE_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GENEVE_LABEL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GENEVE_TTL_INHERIT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GENEVE_DF] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLType rtnl_link_info_data_can_types[] = { + [IFLA_CAN_BITTIMING] = { .size = sizeof(struct can_bittiming) }, + [IFLA_CAN_RESTART_MS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CAN_CTRLMODE] = { .size = sizeof(struct can_ctrlmode) }, + [IFLA_CAN_TERMINATION] = { .type = NETLINK_TYPE_U16 }, +}; + +static const NLType rtnl_link_info_data_macsec_types[] = { + [IFLA_MACSEC_SCI] = { .type = NETLINK_TYPE_U64 }, + [IFLA_MACSEC_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_MACSEC_ICV_LEN] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_CIPHER_SUITE] = { .type = NETLINK_TYPE_U64 }, + [IFLA_MACSEC_WINDOW] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACSEC_ENCODING_SA] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_ENCRYPT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_PROTECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_INC_SCI] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_ES] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_SCB] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_MACSEC_VALIDATION] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLType rtnl_link_info_data_xfrm_types[] = { + [IFLA_XFRM_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_XFRM_IF_ID] = { .type = NETLINK_TYPE_U32 } +}; + +static const NLType rtnl_link_info_data_bareudp_types[] = { + [IFLA_BAREUDP_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BAREUDP_ETHERTYPE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BAREUDP_SRCPORT_MIN] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BAREUDP_MULTIPROTO_MODE] = { .type = NETLINK_TYPE_FLAG }, +}; + +/* these strings must match the .kind entries in the kernel */ +static const char* const nl_union_link_info_data_table[] = { + [NL_UNION_LINK_INFO_DATA_BOND] = "bond", + [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge", + [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan", + [NL_UNION_LINK_INFO_DATA_VETH] = "veth", + [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy", + [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan", + [NL_UNION_LINK_INFO_DATA_MACVTAP] = "macvtap", + [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan", + [NL_UNION_LINK_INFO_DATA_IPVTAP] = "ipvtap", + [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan", + [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip", + [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre", + [NL_UNION_LINK_INFO_DATA_ERSPAN] = "erspan", + [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap", + [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre", + [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap", + [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit", + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti", + [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6", + [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl", + [NL_UNION_LINK_INFO_DATA_VRF] = "vrf", + [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan", + [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve", + [NL_UNION_LINK_INFO_DATA_VXCAN] = "vxcan", + [NL_UNION_LINK_INFO_DATA_WIREGUARD] = "wireguard", + [NL_UNION_LINK_INFO_DATA_NETDEVSIM] = "netdevsim", + [NL_UNION_LINK_INFO_DATA_CAN] = "can", + [NL_UNION_LINK_INFO_DATA_MACSEC] = "macsec", + [NL_UNION_LINK_INFO_DATA_NLMON] = "nlmon", + [NL_UNION_LINK_INFO_DATA_XFRM] = "xfrm", + [NL_UNION_LINK_INFO_DATA_IFB] = "ifb", + [NL_UNION_LINK_INFO_DATA_BAREUDP] = "bareudp", + [NL_UNION_LINK_INFO_DATA_BATADV] = "batadv", +}; + +DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); + +static const NLTypeSystem rtnl_link_info_data_type_systems[] = { + [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), + .types = rtnl_link_info_data_bond_types }, + [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), + .types = rtnl_link_info_data_bridge_types }, + [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), + .types = rtnl_link_info_data_vlan_types }, + [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), + .types = rtnl_link_info_data_veth_types }, + [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types }, + [NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types }, + [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), + .types = rtnl_link_info_data_ipvlan_types }, + [NL_UNION_LINK_INFO_DATA_IPVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), + .types = rtnl_link_info_data_ipvlan_types }, + [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), + .types = rtnl_link_info_data_vxlan_types }, + [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types }, + [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_ERSPAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types }, + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types }, + [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types }, + [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), + .types = rtnl_link_info_data_ip6tnl_types }, + [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), + .types = rtnl_link_info_data_vrf_types }, + [NL_UNION_LINK_INFO_DATA_GENEVE] = { .count = ELEMENTSOF(rtnl_link_info_data_geneve_types), + .types = rtnl_link_info_data_geneve_types }, + [NL_UNION_LINK_INFO_DATA_VXCAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types), + .types = rtnl_link_info_data_vxcan_types }, + [NL_UNION_LINK_INFO_DATA_CAN] = { .count = ELEMENTSOF(rtnl_link_info_data_can_types), + .types = rtnl_link_info_data_can_types }, + [NL_UNION_LINK_INFO_DATA_MACSEC] = { .count = ELEMENTSOF(rtnl_link_info_data_macsec_types), + .types = rtnl_link_info_data_macsec_types }, + [NL_UNION_LINK_INFO_DATA_XFRM] = { .count = ELEMENTSOF(rtnl_link_info_data_xfrm_types), + .types = rtnl_link_info_data_xfrm_types }, + [NL_UNION_LINK_INFO_DATA_BAREUDP] = { .count = ELEMENTSOF(rtnl_link_info_data_bareudp_types), + .types = rtnl_link_info_data_bareudp_types }, + [NL_UNION_LINK_INFO_DATA_BATADV] = { .count = ELEMENTSOF(rtnl_link_info_data_batadv_types), + .types = rtnl_link_info_data_batadv_types }, +}; + +static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { + .num = _NL_UNION_LINK_INFO_DATA_MAX, + .lookup = nl_union_link_info_data_from_string, + .type_systems = rtnl_link_info_data_type_systems, + .match_type = NL_MATCH_SIBLING, + .match_attribute = IFLA_INFO_KIND, +}; + +static const NLType rtnl_link_info_types[] = { + [IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING }, + [IFLA_INFO_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union }, +/* + [IFLA_INFO_XSTATS], + [IFLA_INFO_SLAVE_KIND] = { .type = NETLINK_TYPE_STRING }, + [IFLA_INFO_SLAVE_DATA] = { .type = NETLINK_TYPE_NESTED }, +*/ +}; + +static const NLTypeSystem rtnl_link_info_type_system = { + .count = ELEMENTSOF(rtnl_link_info_types), + .types = rtnl_link_info_types, +}; + +static const struct NLType rtnl_prot_info_bridge_port_types[] = { + [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_MODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_GUARD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PROTECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_FAST_LEAVE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_LEARNING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PROXYARP] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_LEARNING_SYNC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PROXYARP_WIFI] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_ROOT_ID] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_BRIDGE_ID] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_DESIGNATED_PORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_DESIGNATED_COST] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_ID] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_NO] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_CONFIG_PENDING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MESSAGE_AGE_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BRPORT_FORWARD_DELAY_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BRPORT_HOLD_TIMER] = { .type = NETLINK_TYPE_U64 }, + [IFLA_BRPORT_FLUSH] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PAD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_VLAN_TUNNEL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_BCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_ISOLATED] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_BACKUP_PORT] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem rtnl_prot_info_type_systems[] = { + [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), + .types = rtnl_prot_info_bridge_port_types }, +}; + +static const NLTypeSystemUnion rtnl_prot_info_type_system_union = { + .num = AF_MAX, + .type_systems = rtnl_prot_info_type_systems, + .match_type = NL_MATCH_PROTOCOL, +}; + +static const struct NLType rtnl_af_spec_inet6_types[] = { + [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 }, +/* + IFLA_INET6_CONF, + IFLA_INET6_STATS, + IFLA_INET6_MCAST, + IFLA_INET6_CACHEINFO, + IFLA_INET6_ICMP6STATS, +*/ + [IFLA_INET6_TOKEN] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_INET6_ADDR_GEN_MODE] = { .type = NETLINK_TYPE_U8 }, +}; + +static const NLTypeSystem rtnl_af_spec_inet6_type_system = { + .count = ELEMENTSOF(rtnl_af_spec_inet6_types), + .types = rtnl_af_spec_inet6_types, +}; + +static const NLType rtnl_af_spec_unspec_types[] = { + [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system }, +}; + +static const NLType rtnl_af_spec_bridge_types[] = { + [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRIDGE_VLAN_INFO] = { .size = sizeof(struct bridge_vlan_info) }, +}; + +static const NLTypeSystem rtnl_af_spec_type_systems[] = { + [AF_UNSPEC] = { .count = ELEMENTSOF(rtnl_af_spec_unspec_types), + .types = rtnl_af_spec_unspec_types }, + [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_af_spec_bridge_types), + .types = rtnl_af_spec_bridge_types }, +}; + +static const NLTypeSystemUnion rtnl_af_spec_type_system_union = { + .num = AF_MAX, + .type_systems = rtnl_af_spec_type_systems, + .match_type = NL_MATCH_PROTOCOL, +}; + +static const NLType rtnl_prop_list_types[] = { + [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, +}; + +static const NLTypeSystem rtnl_prop_list_type_system = { + .count = ELEMENTSOF(rtnl_prop_list_types), + .types = rtnl_prop_list_types, +}; + +static const NLType rtnl_vf_vlan_list_types[] = { + [IFLA_VF_VLAN_INFO] = { .size = sizeof(struct ifla_vf_vlan_info) }, +}; + +static const NLTypeSystem rtnl_vf_vlan_type_system = { + .count = ELEMENTSOF(rtnl_vf_vlan_list_types), + .types = rtnl_vf_vlan_list_types, +}; + +static const NLType rtnl_vf_vlan_info_types[] = { + [IFLA_VF_MAC] = { .size = sizeof(struct ifla_vf_mac) }, + [IFLA_VF_VLAN] = { .size = sizeof(struct ifla_vf_vlan) }, + [IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_type_system}, + [IFLA_VF_TX_RATE] = { .size = sizeof(struct ifla_vf_tx_rate) }, + [IFLA_VF_SPOOFCHK] = { .size = sizeof(struct ifla_vf_spoofchk) }, + [IFLA_VF_RATE] = { .size = sizeof(struct ifla_vf_rate) }, + [IFLA_VF_LINK_STATE] = { .size = sizeof(struct ifla_vf_link_state) }, + [IFLA_VF_RSS_QUERY_EN] = { .size = sizeof(struct ifla_vf_rss_query_en) }, + [IFLA_VF_TRUST] = { .size = sizeof(struct ifla_vf_trust) }, + [IFLA_VF_IB_NODE_GUID] = { .size = sizeof(struct ifla_vf_guid) }, + [IFLA_VF_IB_PORT_GUID] = { .size = sizeof(struct ifla_vf_guid) }, +}; + +static const NLTypeSystem rtnl_vf_vlan_info_type_system = { + .count = ELEMENTSOF(rtnl_vf_vlan_info_types), + .types = rtnl_vf_vlan_info_types, +}; + +static const NLType rtnl_link_io_srv_types[] = { + [IFLA_VF_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_info_type_system }, +}; + +static const NLTypeSystem rtnl_io_srv_type_system = { + .count = ELEMENTSOF(rtnl_link_io_srv_types), + .types = rtnl_link_io_srv_types, +}; + +static const NLType rtnl_link_types[] = { + [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [IFLA_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, + [IFLA_MTU] = { .type = NETLINK_TYPE_U32 }, + [IFLA_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_QDISC] = { .type = NETLINK_TYPE_STRING }, + [IFLA_STATS] = { .size = sizeof(struct rtnl_link_stats) }, +/* + [IFLA_COST], + [IFLA_PRIORITY], +*/ + [IFLA_MASTER] = { .type = NETLINK_TYPE_U32 }, +/* + [IFLA_WIRELESS], +*/ + [IFLA_PROTINFO] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_prot_info_type_system_union }, + [IFLA_TXQLEN] = { .type = NETLINK_TYPE_U32 }, +/* + [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, +*/ + [IFLA_WEIGHT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_OPERSTATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_LINKMODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_LINKINFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system }, + [IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 }, + [IFLA_NUM_VF] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_io_srv_type_system }, + [IFLA_STATS64] = { .size = sizeof(struct rtnl_link_stats64) }, +/* + [IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED }, + [IFLA_PORT_SELF] = { .type = NETLINK_TYPE_NESTED }, +*/ + [IFLA_AF_SPEC] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_af_spec_type_system_union }, +/* + [IFLA_VF_PORTS], + [IFLA_PORT_SELF], +*/ + [IFLA_GROUP] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NET_NS_FD] = { .type = NETLINK_TYPE_U32 }, + [IFLA_EXT_MASK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PROMISCUITY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NUM_TX_QUEUES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NUM_RX_QUEUES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GSO_MAX_SEGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GSO_MAX_SIZE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CARRIER] = { .type = NETLINK_TYPE_U8 }, +/* + [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN }, +*/ + [IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system }, + [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, +}; + +static const NLTypeSystem rtnl_link_type_system = { + .count = ELEMENTSOF(rtnl_link_types), + .types = rtnl_link_types, +}; + +/* IFA_FLAGS was defined in kernel 3.14, but we still support older + * kernels where IFA_MAX is lower. */ +static const NLType rtnl_address_types[] = { + [IFA_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFA_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFA_LABEL] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, + [IFA_BROADCAST] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFA_ANYCAST] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) }, + [IFA_MULTICAST] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFA_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFA_RT_PRIORITY] = { .type = NETLINK_TYPE_U32 }, + [IFA_TARGET_NETNSID] = { .type = NETLINK_TYPE_S32 }, +}; + +static const NLTypeSystem rtnl_address_type_system = { + .count = ELEMENTSOF(rtnl_address_types), + .types = rtnl_address_types, +}; + +/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */ + +static const NLType rtnl_route_metrics_types[] = { + [RTAX_MTU] = { .type = NETLINK_TYPE_U32 }, + [RTAX_WINDOW] = { .type = NETLINK_TYPE_U32 }, + [RTAX_RTT] = { .type = NETLINK_TYPE_U32 }, + [RTAX_RTTVAR] = { .type = NETLINK_TYPE_U32 }, + [RTAX_SSTHRESH] = { .type = NETLINK_TYPE_U32 }, + [RTAX_CWND] = { .type = NETLINK_TYPE_U32 }, + [RTAX_ADVMSS] = { .type = NETLINK_TYPE_U32 }, + [RTAX_REORDERING] = { .type = NETLINK_TYPE_U32 }, + [RTAX_HOPLIMIT] = { .type = NETLINK_TYPE_U32 }, + [RTAX_INITCWND] = { .type = NETLINK_TYPE_U32 }, + [RTAX_FEATURES] = { .type = NETLINK_TYPE_U32 }, + [RTAX_RTO_MIN] = { .type = NETLINK_TYPE_U32 }, + [RTAX_INITRWND] = { .type = NETLINK_TYPE_U32 }, + [RTAX_QUICKACK] = { .type = NETLINK_TYPE_U32 }, + [RTAX_CC_ALGO] = { .type = NETLINK_TYPE_U32 }, + [RTAX_FASTOPEN_NO_COOKIE] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem rtnl_route_metrics_type_system = { + .count = ELEMENTSOF(rtnl_route_metrics_types), + .types = rtnl_route_metrics_types, +}; + +static const NLType rtnl_route_types[] = { + [RTA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ + [RTA_SRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ + [RTA_IIF] = { .type = NETLINK_TYPE_U32 }, + [RTA_OIF] = { .type = NETLINK_TYPE_U32 }, + [RTA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR }, + [RTA_PRIORITY] = { .type = NETLINK_TYPE_U32 }, + [RTA_PREFSRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ + [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_metrics_type_system}, + [RTA_MULTIPATH] = { .size = sizeof(struct rtnexthop) }, + [RTA_FLOW] = { .type = NETLINK_TYPE_U32 }, /* 6? */ + [RTA_CACHEINFO] = { .size = sizeof(struct rta_cacheinfo) }, + [RTA_TABLE] = { .type = NETLINK_TYPE_U32 }, + [RTA_MARK] = { .type = NETLINK_TYPE_U32 }, + [RTA_MFC_STATS] = { .type = NETLINK_TYPE_U64 }, + [RTA_VIA] = { /* See struct rtvia */ }, + [RTA_NEWDST] = { .type = NETLINK_TYPE_U32 }, + [RTA_PREF] = { .type = NETLINK_TYPE_U8 }, + [RTA_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [RTA_ENCAP] = { .type = NETLINK_TYPE_NESTED }, /* Multiple type systems i.e. LWTUNNEL_ENCAP_MPLS/LWTUNNEL_ENCAP_IP/LWTUNNEL_ENCAP_ILA etc... */ + [RTA_EXPIRES] = { .type = NETLINK_TYPE_U32 }, + [RTA_UID] = { .type = NETLINK_TYPE_U32 }, + [RTA_TTL_PROPAGATE] = { .type = NETLINK_TYPE_U8 }, + [RTA_IP_PROTO] = { .type = NETLINK_TYPE_U8 }, + [RTA_SPORT] = { .type = NETLINK_TYPE_U16 }, + [RTA_DPORT] = { .type = NETLINK_TYPE_U16 }, + [RTA_NH_ID] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem rtnl_route_type_system = { + .count = ELEMENTSOF(rtnl_route_types), + .types = rtnl_route_types, +}; + +static const NLType rtnl_neigh_types[] = { + [NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, + [NDA_LLADDR] = { /* struct ether_addr, struct in_addr, or struct in6_addr */ }, + [NDA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) }, + [NDA_PROBES] = { .type = NETLINK_TYPE_U32 }, + [NDA_VLAN] = { .type = NETLINK_TYPE_U16 }, + [NDA_PORT] = { .type = NETLINK_TYPE_U16 }, + [NDA_VNI] = { .type = NETLINK_TYPE_U32 }, + [NDA_IFINDEX] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem rtnl_neigh_type_system = { + .count = ELEMENTSOF(rtnl_neigh_types), + .types = rtnl_neigh_types, +}; + +static const NLType rtnl_addrlabel_types[] = { + [IFAL_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) }, + [IFAL_LABEL] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem rtnl_addrlabel_type_system = { + .count = ELEMENTSOF(rtnl_addrlabel_types), + .types = rtnl_addrlabel_types, +}; + +static const NLType rtnl_routing_policy_rule_types[] = { + [FRA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, + [FRA_SRC] = { .type = NETLINK_TYPE_IN_ADDR }, + [FRA_IIFNAME] = { .type = NETLINK_TYPE_STRING }, + [FRA_GOTO] = { .type = NETLINK_TYPE_U32 }, + [FRA_PRIORITY] = { .type = NETLINK_TYPE_U32 }, + [FRA_FWMARK] = { .type = NETLINK_TYPE_U32 }, + [FRA_FLOW] = { .type = NETLINK_TYPE_U32 }, + [FRA_TUN_ID] = { .type = NETLINK_TYPE_U64 }, + [FRA_SUPPRESS_IFGROUP] = { .type = NETLINK_TYPE_U32 }, + [FRA_SUPPRESS_PREFIXLEN] = { .type = NETLINK_TYPE_U32 }, + [FRA_TABLE] = { .type = NETLINK_TYPE_U32 }, + [FRA_FWMASK] = { .type = NETLINK_TYPE_U32 }, + [FRA_OIFNAME] = { .type = NETLINK_TYPE_STRING }, + [FRA_PAD] = { .type = NETLINK_TYPE_U32 }, + [FRA_L3MDEV] = { .type = NETLINK_TYPE_U8 }, + [FRA_UID_RANGE] = { .size = sizeof(struct fib_rule_uid_range) }, + [FRA_PROTOCOL] = { .type = NETLINK_TYPE_U8 }, + [FRA_IP_PROTO] = { .type = NETLINK_TYPE_U8 }, + [FRA_SPORT_RANGE] = { .size = sizeof(struct fib_rule_port_range) }, + [FRA_DPORT_RANGE] = { .size = sizeof(struct fib_rule_port_range) }, +}; + +static const NLTypeSystem rtnl_routing_policy_rule_type_system = { + .count = ELEMENTSOF(rtnl_routing_policy_rule_types), + .types = rtnl_routing_policy_rule_types, +}; + +static const NLType rtnl_nexthop_types[] = { + [NHA_ID] = { .type = NETLINK_TYPE_U32 }, + [NHA_GROUP] = { /* array of struct nexthop_grp */ }, + [NHA_GROUP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [NHA_BLACKHOLE] = { .type = NETLINK_TYPE_FLAG }, + [NHA_OIF] = { .type = NETLINK_TYPE_U32 }, + [NHA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR }, + [NHA_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [NHA_ENCAP] = { .type = NETLINK_TYPE_NESTED }, + [NHA_GROUPS] = { .type = NETLINK_TYPE_FLAG }, + [NHA_MASTER] = { .type = NETLINK_TYPE_U32 }, + [NHA_FDB] = { .type = NETLINK_TYPE_FLAG }, +}; + +static const NLTypeSystem rtnl_nexthop_type_system = { + .count = ELEMENTSOF(rtnl_nexthop_types), + .types = rtnl_nexthop_types, +}; + +static const NLType rtnl_tca_option_data_cake_types[] = { + [TCA_CAKE_BASE_RATE64] = { .type = NETLINK_TYPE_U64 }, + [TCA_CAKE_OVERHEAD] = { .type = NETLINK_TYPE_S32 }, + [TCA_CAKE_MPU] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_codel_types[] = { + [TCA_CODEL_TARGET] = { .type = NETLINK_TYPE_U32 }, + [TCA_CODEL_LIMIT] = { .type = NETLINK_TYPE_U32 }, + [TCA_CODEL_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [TCA_CODEL_ECN] = { .type = NETLINK_TYPE_U32 }, + [TCA_CODEL_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_drr_types[] = { + [TCA_DRR_QUANTUM] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_ets_quanta_types[] = { + [TCA_ETS_QUANTA_BAND] = { .type = NETLINK_TYPE_U32, }, +}; + +static const NLTypeSystem rtnl_tca_option_data_ets_quanta_type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_ets_quanta_types), + .types = rtnl_tca_option_data_ets_quanta_types, +}; + +static const NLType rtnl_tca_option_data_ets_prio_types[] = { + [TCA_ETS_PRIOMAP_BAND] = { .type = NETLINK_TYPE_U8, }, +}; + +static const NLTypeSystem rtnl_tca_option_data_ets_prio_type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_ets_prio_types), + .types = rtnl_tca_option_data_ets_prio_types, +}; + +static const NLType rtnl_tca_option_data_ets_types[] = { + [TCA_ETS_NBANDS] = { .type = NETLINK_TYPE_U8 }, + [TCA_ETS_NSTRICT] = { .type = NETLINK_TYPE_U8 }, + [TCA_ETS_QUANTA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_option_data_ets_quanta_type_system }, + [TCA_ETS_PRIOMAP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_option_data_ets_prio_type_system }, + [TCA_ETS_QUANTA_BAND] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_fq_types[] = { + [TCA_FQ_PLIMIT] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_FLOW_PLIMIT] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_QUANTUM] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_INITIAL_QUANTUM] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_RATE_ENABLE] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_FLOW_MAX_RATE] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_BUCKETS_LOG] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_LOW_RATE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_ORPHAN_MASK] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_fq_codel_types[] = { + [TCA_FQ_CODEL_TARGET] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_LIMIT] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_ECN] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_FLOWS] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_QUANTUM] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_DROP_BATCH_SIZE] = { .type = NETLINK_TYPE_U32 }, + [TCA_FQ_CODEL_MEMORY_LIMIT] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_fq_pie_types[] = { + [TCA_FQ_PIE_LIMIT] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_gred_types[] = { + [TCA_GRED_DPS] = { .size = sizeof(struct tc_gred_sopt) }, +}; + +static const NLType rtnl_tca_option_data_hhf_types[] = { + [TCA_HHF_BACKLOG_LIMIT] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_htb_types[] = { + [TCA_HTB_PARMS] = { .size = sizeof(struct tc_htb_opt) }, + [TCA_HTB_INIT] = { .size = sizeof(struct tc_htb_glob) }, + [TCA_HTB_CTAB] = { .size = TC_RTAB_SIZE }, + [TCA_HTB_RTAB] = { .size = TC_RTAB_SIZE }, + [TCA_HTB_RATE64] = { .type = NETLINK_TYPE_U64 }, + [TCA_HTB_CEIL64] = { .type = NETLINK_TYPE_U64 }, +}; + +static const NLType rtnl_tca_option_data_pie_types[] = { + [TCA_PIE_LIMIT] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_qfq_types[] = { + [TCA_QFQ_WEIGHT] = { .type = NETLINK_TYPE_U32 }, + [TCA_QFQ_LMAX] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLType rtnl_tca_option_data_sfb_types[] = { + [TCA_SFB_PARMS] = { .size = sizeof(struct tc_sfb_qopt) }, +}; + +static const NLType rtnl_tca_option_data_tbf_types[] = { + [TCA_TBF_PARMS] = { .size = sizeof(struct tc_tbf_qopt) }, + [TCA_TBF_RTAB] = { .size = TC_RTAB_SIZE }, + [TCA_TBF_PTAB] = { .size = TC_RTAB_SIZE }, + [TCA_TBF_RATE64] = { .type = NETLINK_TYPE_U64 }, + [TCA_TBF_PRATE64] = { .type = NETLINK_TYPE_U64 }, + [TCA_TBF_BURST] = { .type = NETLINK_TYPE_U32 }, + [TCA_TBF_PBURST] = { .type = NETLINK_TYPE_U32 }, +}; + +static const char* const nl_union_tca_option_data_table[] = { + [NL_UNION_TCA_OPTION_DATA_CAKE] = "cake", + [NL_UNION_TCA_OPTION_DATA_CODEL] = "codel", + [NL_UNION_TCA_OPTION_DATA_DRR] = "drr", + [NL_UNION_TCA_OPTION_DATA_ETS] = "ets", + [NL_UNION_TCA_OPTION_DATA_FQ] = "fq", + [NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel", + [NL_UNION_TCA_OPTION_DATA_FQ_PIE] = "fq_pie", + [NL_UNION_TCA_OPTION_DATA_GRED] = "gred", + [NL_UNION_TCA_OPTION_DATA_HHF] = "hhf", + [NL_UNION_TCA_OPTION_DATA_HTB] = "htb", + [NL_UNION_TCA_OPTION_DATA_PIE] = "pie", + [NL_UNION_TCA_OPTION_DATA_QFQ] = "qfq", + [NL_UNION_TCA_OPTION_DATA_SFB] = "sfb", + [NL_UNION_TCA_OPTION_DATA_TBF] = "tbf", +}; + +DEFINE_STRING_TABLE_LOOKUP(nl_union_tca_option_data, NLUnionTCAOptionData); + +static const NLTypeSystem rtnl_tca_option_data_type_systems[] = { + [NL_UNION_TCA_OPTION_DATA_CAKE] = { .count = ELEMENTSOF(rtnl_tca_option_data_cake_types), + .types = rtnl_tca_option_data_cake_types }, + [NL_UNION_TCA_OPTION_DATA_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_codel_types), + .types = rtnl_tca_option_data_codel_types }, + [NL_UNION_TCA_OPTION_DATA_DRR] = { .count = ELEMENTSOF(rtnl_tca_option_data_drr_types), + .types = rtnl_tca_option_data_drr_types }, + [NL_UNION_TCA_OPTION_DATA_ETS] = { .count = ELEMENTSOF(rtnl_tca_option_data_ets_types), + .types = rtnl_tca_option_data_ets_types }, + [NL_UNION_TCA_OPTION_DATA_FQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_types), + .types = rtnl_tca_option_data_fq_types }, + [NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types), + .types = rtnl_tca_option_data_fq_codel_types }, + [NL_UNION_TCA_OPTION_DATA_FQ_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_pie_types), + .types = rtnl_tca_option_data_fq_pie_types }, + [NL_UNION_TCA_OPTION_DATA_GRED] = { .count = ELEMENTSOF(rtnl_tca_option_data_gred_types), + .types = rtnl_tca_option_data_gred_types }, + [NL_UNION_TCA_OPTION_DATA_HHF] = { .count = ELEMENTSOF(rtnl_tca_option_data_hhf_types), + .types = rtnl_tca_option_data_hhf_types }, + [NL_UNION_TCA_OPTION_DATA_HTB] = { .count = ELEMENTSOF(rtnl_tca_option_data_htb_types), + .types = rtnl_tca_option_data_htb_types }, + [NL_UNION_TCA_OPTION_DATA_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_pie_types), + .types = rtnl_tca_option_data_pie_types }, + [NL_UNION_TCA_OPTION_DATA_QFQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_qfq_types), + .types = rtnl_tca_option_data_qfq_types }, + [NL_UNION_TCA_OPTION_DATA_SFB] = { .count = ELEMENTSOF(rtnl_tca_option_data_sfb_types), + .types = rtnl_tca_option_data_sfb_types }, + [NL_UNION_TCA_OPTION_DATA_TBF] = { .count = ELEMENTSOF(rtnl_tca_option_data_tbf_types), + .types = rtnl_tca_option_data_tbf_types }, +}; + +static const NLTypeSystemUnion rtnl_tca_option_data_type_system_union = { + .num = _NL_UNION_TCA_OPTION_DATA_MAX, + .lookup = nl_union_tca_option_data_from_string, + .type_systems = rtnl_tca_option_data_type_systems, + .match_type = NL_MATCH_SIBLING, + .match_attribute = TCA_KIND, +}; + +static const NLType rtnl_tca_types[] = { + [TCA_KIND] = { .type = NETLINK_TYPE_STRING }, + [TCA_OPTIONS] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_tca_option_data_type_system_union }, + [TCA_INGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 }, + [TCA_EGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem rtnl_tca_type_system = { + .count = ELEMENTSOF(rtnl_tca_types), + .types = rtnl_tca_types, +}; + +static const NLType mdb_types[] = { + [MDBA_SET_ENTRY] = { .size = sizeof(struct br_port_msg) }, +}; + +static const NLTypeSystem rtnl_mdb_type_system = { + .count = ELEMENTSOF(mdb_types), + .types = mdb_types, +}; + +static const NLType rtnl_types[] = { + [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, + [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, + [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, + [RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, + [RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, + [RTM_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, + [RTM_DELRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, + [RTM_GETRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, + [RTM_NEWNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, + [RTM_DELNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, + [RTM_GETNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, + [RTM_NEWQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_DELQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_GETQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_NEWTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_DELTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_GETTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_NEWMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, + [RTM_DELMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, + [RTM_GETMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, +}; + +static const NLTypeSystem rtnl_type_system = { + .count = ELEMENTSOF(rtnl_types), + .types = rtnl_types, +}; + +int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret) { + return type_system_get_type(&rtnl_type_system, ret, nlmsg_type); +} diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 38ea22bfd9..83ba725fd8 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -1,92 +1,15 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sd-netlink.h" - -#include "generic-netlink.h" -#include "hashmap.h" -#include "macro.h" #include "netlink-internal.h" -#include "netlink-types.h" -#include "string-table.h" -#include "util.h" - -/* Maximum ARP IP target defined in kernel */ -#define BOND_MAX_ARP_TARGETS 16 - -typedef enum { - BOND_ARP_TARGETS_0, - BOND_ARP_TARGETS_1, - BOND_ARP_TARGETS_2, - BOND_ARP_TARGETS_3, - BOND_ARP_TARGETS_4, - BOND_ARP_TARGETS_5, - BOND_ARP_TARGETS_6, - BOND_ARP_TARGETS_7, - BOND_ARP_TARGETS_8, - BOND_ARP_TARGETS_9, - BOND_ARP_TARGETS_10, - BOND_ARP_TARGETS_11, - BOND_ARP_TARGETS_12, - BOND_ARP_TARGETS_13, - BOND_ARP_TARGETS_14, - BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS, -} BondArpTargets; - -struct NLType { - uint16_t type; - size_t size; - const NLTypeSystem *type_system; - const NLTypeSystemUnion *type_system_union; -}; - -struct NLTypeSystem { - uint16_t count; - const NLType *types; -}; - -struct NLTypeSystemUnion { - int num; - NLMatchType match_type; - uint16_t match_attribute; - int (*lookup)(const char *); - const NLTypeSystem *type_systems; -}; - -/***************** basic type systems *****************/ +#include "netlink-types-internal.h" static const NLType empty_types[1] = { /* fake array to avoid .types==NULL, which denotes invalid type-systems */ }; -static const NLTypeSystem empty_type_system = { +const NLTypeSystem empty_type_system = { .count = 0, .types = empty_types, }; @@ -96,1623 +19,11 @@ static const NLType error_types[] = { [NLMSGERR_ATTR_OFFS] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem error_type_system = { +const NLTypeSystem error_type_system = { .count = ELEMENTSOF(error_types), .types = error_types, }; -/***************** rtnl type systems *****************/ - -static const NLTypeSystem rtnl_link_type_system; - -static const NLType rtnl_link_info_data_batadv_types[] = { - [IFLA_BATADV_ALGO_NAME] = { .type = NETLINK_TYPE_STRING, .size = 20 }, -}; - -static const NLType rtnl_link_info_data_veth_types[] = { - [VETH_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, -}; - -static const NLType rtnl_link_info_data_vxcan_types[] = { - [VXCAN_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, -}; - -static const NLType rtnl_link_info_data_ipvlan_types[] = { - [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, -}; - -static const NLType rtnl_macvlan_macaddr_types[] = { - [IFLA_MACVLAN_MACADDR] = { .type = NETLINK_TYPE_ETHER_ADDR }, -}; - -static const NLTypeSystem rtnl_macvlan_macaddr_type_system = { - .count = ELEMENTSOF(rtnl_macvlan_macaddr_types), - .types = rtnl_macvlan_macaddr_types, -}; - -static const NLType rtnl_link_info_data_macvlan_types[] = { - [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_MACVLAN_MACADDR_MODE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_MACADDR_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_macvlan_macaddr_type_system }, - [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_BC_QUEUE_LEN] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = { .type = NETLINK_TYPE_REJECT }, -}; - -static const NLType rtnl_link_info_data_bridge_types[] = { - [IFLA_BR_FORWARD_DELAY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_HELLO_TIME] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_MAX_AGE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_AGEING_TIME] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_STP_STATE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_PRIORITY] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_VLAN_FILTERING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_ROOT_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_ROOT_PATH_COST] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_TOPOLOGY_CHANGE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_TOPOLOGY_CHANGE_DETECTED] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_HELLO_TIMER] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_TCN_TIMER] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_TOPOLOGY_CHANGE_TIMER] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_GC_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_GROUP_ADDR] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_FDB_FLUSH] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_SNOOPING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_QUERY_USE_IFADDR] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_QUERIER] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_MCAST_HASH_ELASTICITY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_MCAST_HASH_MAX] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_LAST_MEMBER_CNT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BR_MCAST_STARTUP_QUERY_CNT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_LAST_MEMBER_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_MEMBERSHIP_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_QUERIER_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BR_NF_CALL_IPTABLES] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BR_VLAN_DEFAULT_PVID] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BR_MCAST_IGMP_VERSION] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLType rtnl_vlan_qos_map_types[] = { - [IFLA_VLAN_QOS_MAPPING] = { .size = sizeof(struct ifla_vlan_qos_mapping) }, -}; - -static const NLTypeSystem rtnl_vlan_qos_map_type_system = { - .count = ELEMENTSOF(rtnl_vlan_qos_map_types), - .types = rtnl_vlan_qos_map_types, -}; - -static const NLType rtnl_link_info_data_vlan_types[] = { - [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, - [IFLA_VLAN_FLAGS] = { .size = sizeof(struct ifla_vlan_flags) }, - [IFLA_VLAN_EGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, - [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vlan_qos_map_type_system }, - [IFLA_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, -}; - -static const NLType rtnl_link_info_data_vxlan_types[] = { - [IFLA_VXLAN_ID] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_GROUP] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_LEARNING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_AGEING] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_LIMIT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_PORT_RANGE] = { .type = NETLINK_TYPE_U32}, - [IFLA_VXLAN_PROXY] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_RSC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_L2MISS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_L3MISS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_VXLAN_GROUP6] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_LOCAL6] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VXLAN_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_REMCSUM_TX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_REMCSUM_RX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_GBP] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 }, - [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_TTL_INHERIT] = { .type = NETLINK_TYPE_FLAG }, - [IFLA_VXLAN_DF] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLType rtnl_bond_arp_target_types[] = { - [BOND_ARP_TARGETS_0] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_1] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_2] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_3] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_4] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_5] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_6] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_7] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_8] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_9] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_10] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_11] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_12] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_13] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_14] = { .type = NETLINK_TYPE_U32 }, - [BOND_ARP_TARGETS_MAX] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem rtnl_bond_arp_type_system = { - .count = ELEMENTSOF(rtnl_bond_arp_target_types), - .types = rtnl_bond_arp_target_types, -}; - -static const NLType rtnl_link_info_data_bond_types[] = { - [IFLA_BOND_MODE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_ACTIVE_SLAVE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_MIIMON] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_UPDELAY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_DOWNDELAY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_USE_CARRIER] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_ARP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_ARP_IP_TARGET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_type_system }, - [IFLA_BOND_ARP_VALIDATE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_PRIMARY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_PRIMARY_RESELECT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_FAIL_OVER_MAC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_RESEND_IGMP] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_MIN_LINKS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_LP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_AD_LACP_RATE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_AD_SELECT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BOND_AD_INFO] = { .type = NETLINK_TYPE_NESTED }, - [IFLA_BOND_AD_ACTOR_SYS_PRIO] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BOND_AD_USER_PORT_KEY] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BOND_AD_ACTOR_SYSTEM] = { .type = NETLINK_TYPE_ETHER_ADDR }, - [IFLA_BOND_TLB_DYNAMIC_LB] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLType rtnl_link_info_data_iptun_types[] = { - [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_6RD_PREFIX] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_IPTUN_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, -}; - -static const NLType rtnl_link_info_data_ipgre_types[] = { - [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_IKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_OKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GRE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GRE_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_ERSPAN_INDEX] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_link_info_data_ipvti_types[] = { - [IFLA_VTI_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VTI_IKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VTI_OKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VTI_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_VTI_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, -}; - -static const NLType rtnl_link_info_data_ip6tnl_types[] = { - [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_IPTUN_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_link_info_data_vrf_types[] = { - [IFLA_VRF_TABLE] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_link_info_data_geneve_types[] = { - [IFLA_GENEVE_ID] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GENEVE_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GENEVE_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GENEVE_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GENEVE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GENEVE_REMOTE6] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GENEVE_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GENEVE_LABEL] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GENEVE_TTL_INHERIT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GENEVE_DF] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLType rtnl_link_info_data_can_types[] = { - [IFLA_CAN_BITTIMING] = { .size = sizeof(struct can_bittiming) }, - [IFLA_CAN_RESTART_MS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_CAN_CTRLMODE] = { .size = sizeof(struct can_ctrlmode) }, - [IFLA_CAN_TERMINATION] = { .type = NETLINK_TYPE_U16 }, -}; - -static const NLType rtnl_link_info_data_macsec_types[] = { - [IFLA_MACSEC_SCI] = { .type = NETLINK_TYPE_U64 }, - [IFLA_MACSEC_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_MACSEC_ICV_LEN] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_CIPHER_SUITE] = { .type = NETLINK_TYPE_U64 }, - [IFLA_MACSEC_WINDOW] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MACSEC_ENCODING_SA] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_ENCRYPT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_PROTECT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_INC_SCI] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_ES] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_SCB] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_REPLAY_PROTECT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_MACSEC_VALIDATION] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLType rtnl_link_info_data_xfrm_types[] = { - [IFLA_XFRM_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_XFRM_IF_ID] = { .type = NETLINK_TYPE_U32 } -}; - -static const NLType rtnl_link_info_data_bareudp_types[] = { - [IFLA_BAREUDP_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BAREUDP_ETHERTYPE] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BAREUDP_SRCPORT_MIN] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BAREUDP_MULTIPROTO_MODE] = { .type = NETLINK_TYPE_FLAG }, -}; - -/* these strings must match the .kind entries in the kernel */ -static const char* const nl_union_link_info_data_table[] = { - [NL_UNION_LINK_INFO_DATA_BOND] = "bond", - [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge", - [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan", - [NL_UNION_LINK_INFO_DATA_VETH] = "veth", - [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy", - [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan", - [NL_UNION_LINK_INFO_DATA_MACVTAP] = "macvtap", - [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan", - [NL_UNION_LINK_INFO_DATA_IPVTAP] = "ipvtap", - [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan", - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip", - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre", - [NL_UNION_LINK_INFO_DATA_ERSPAN] = "erspan", - [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap", - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre", - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap", - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit", - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti", - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6", - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl", - [NL_UNION_LINK_INFO_DATA_VRF] = "vrf", - [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan", - [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve", - [NL_UNION_LINK_INFO_DATA_VXCAN] = "vxcan", - [NL_UNION_LINK_INFO_DATA_WIREGUARD] = "wireguard", - [NL_UNION_LINK_INFO_DATA_NETDEVSIM] = "netdevsim", - [NL_UNION_LINK_INFO_DATA_CAN] = "can", - [NL_UNION_LINK_INFO_DATA_MACSEC] = "macsec", - [NL_UNION_LINK_INFO_DATA_NLMON] = "nlmon", - [NL_UNION_LINK_INFO_DATA_XFRM] = "xfrm", - [NL_UNION_LINK_INFO_DATA_IFB] = "ifb", - [NL_UNION_LINK_INFO_DATA_BAREUDP] = "bareudp", - [NL_UNION_LINK_INFO_DATA_BATADV] = "batadv", -}; - -DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); - -static const NLTypeSystem rtnl_link_info_data_type_systems[] = { - [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), - .types = rtnl_link_info_data_bond_types }, - [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), - .types = rtnl_link_info_data_bridge_types }, - [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), - .types = rtnl_link_info_data_vlan_types }, - [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), - .types = rtnl_link_info_data_veth_types }, - [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), - .types = rtnl_link_info_data_vxlan_types }, - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_ERSPAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), - .types = rtnl_link_info_data_ip6tnl_types }, - [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), - .types = rtnl_link_info_data_vrf_types }, - [NL_UNION_LINK_INFO_DATA_GENEVE] = { .count = ELEMENTSOF(rtnl_link_info_data_geneve_types), - .types = rtnl_link_info_data_geneve_types }, - [NL_UNION_LINK_INFO_DATA_VXCAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types), - .types = rtnl_link_info_data_vxcan_types }, - [NL_UNION_LINK_INFO_DATA_CAN] = { .count = ELEMENTSOF(rtnl_link_info_data_can_types), - .types = rtnl_link_info_data_can_types }, - [NL_UNION_LINK_INFO_DATA_MACSEC] = { .count = ELEMENTSOF(rtnl_link_info_data_macsec_types), - .types = rtnl_link_info_data_macsec_types }, - [NL_UNION_LINK_INFO_DATA_XFRM] = { .count = ELEMENTSOF(rtnl_link_info_data_xfrm_types), - .types = rtnl_link_info_data_xfrm_types }, - [NL_UNION_LINK_INFO_DATA_BAREUDP] = { .count = ELEMENTSOF(rtnl_link_info_data_bareudp_types), - .types = rtnl_link_info_data_bareudp_types }, - [NL_UNION_LINK_INFO_DATA_BATADV] = { .count = ELEMENTSOF(rtnl_link_info_data_batadv_types), - .types = rtnl_link_info_data_batadv_types }, -}; - -static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { - .num = _NL_UNION_LINK_INFO_DATA_MAX, - .lookup = nl_union_link_info_data_from_string, - .type_systems = rtnl_link_info_data_type_systems, - .match_type = NL_MATCH_SIBLING, - .match_attribute = IFLA_INFO_KIND, -}; - -static const NLType rtnl_link_info_types[] = { - [IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING }, - [IFLA_INFO_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union }, -/* - [IFLA_INFO_XSTATS], - [IFLA_INFO_SLAVE_KIND] = { .type = NETLINK_TYPE_STRING }, - [IFLA_INFO_SLAVE_DATA] = { .type = NETLINK_TYPE_NESTED }, -*/ -}; - -static const NLTypeSystem rtnl_link_info_type_system = { - .count = ELEMENTSOF(rtnl_link_info_types), - .types = rtnl_link_info_types, -}; - -static const struct NLType rtnl_prot_info_bridge_port_types[] = { - [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_MODE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_GUARD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PROTECT] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_FAST_LEAVE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_LEARNING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PROXYARP] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_LEARNING_SYNC] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PROXYARP_WIFI] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_ROOT_ID] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_BRIDGE_ID] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_DESIGNATED_PORT] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_DESIGNATED_COST] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_ID] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_NO] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_TOPOLOGY_CHANGE_ACK] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_CONFIG_PENDING] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MESSAGE_AGE_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BRPORT_FORWARD_DELAY_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BRPORT_HOLD_TIMER] = { .type = NETLINK_TYPE_U64 }, - [IFLA_BRPORT_FLUSH] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_PAD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_VLAN_TUNNEL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_BCAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_GROUP_FWD_MASK] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_ISOLATED] = { .type = NETLINK_TYPE_U8 }, - [IFLA_BRPORT_BACKUP_PORT] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem rtnl_prot_info_type_systems[] = { - [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), - .types = rtnl_prot_info_bridge_port_types }, -}; - -static const NLTypeSystemUnion rtnl_prot_info_type_system_union = { - .num = AF_MAX, - .type_systems = rtnl_prot_info_type_systems, - .match_type = NL_MATCH_PROTOCOL, -}; - -static const struct NLType rtnl_af_spec_inet6_types[] = { - [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 }, -/* - IFLA_INET6_CONF, - IFLA_INET6_STATS, - IFLA_INET6_MCAST, - IFLA_INET6_CACHEINFO, - IFLA_INET6_ICMP6STATS, -*/ - [IFLA_INET6_TOKEN] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_INET6_ADDR_GEN_MODE] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLTypeSystem rtnl_af_spec_inet6_type_system = { - .count = ELEMENTSOF(rtnl_af_spec_inet6_types), - .types = rtnl_af_spec_inet6_types, -}; - -static const NLType rtnl_af_spec_unspec_types[] = { - [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system }, -}; - -static const NLType rtnl_af_spec_bridge_types[] = { - [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_BRIDGE_VLAN_INFO] = { .size = sizeof(struct bridge_vlan_info) }, -}; - -static const NLTypeSystem rtnl_af_spec_type_systems[] = { - [AF_UNSPEC] = { .count = ELEMENTSOF(rtnl_af_spec_unspec_types), - .types = rtnl_af_spec_unspec_types }, - [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_af_spec_bridge_types), - .types = rtnl_af_spec_bridge_types }, -}; - -static const NLTypeSystemUnion rtnl_af_spec_type_system_union = { - .num = AF_MAX, - .type_systems = rtnl_af_spec_type_systems, - .match_type = NL_MATCH_PROTOCOL, -}; - -static const NLType rtnl_prop_list_types[] = { - [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, -}; - -static const NLTypeSystem rtnl_prop_list_type_system = { - .count = ELEMENTSOF(rtnl_prop_list_types), - .types = rtnl_prop_list_types, -}; - -static const NLType rtnl_vf_vlan_list_types[] = { - [IFLA_VF_VLAN_INFO] = { .size = sizeof(struct ifla_vf_vlan_info) }, -}; - -static const NLTypeSystem rtnl_vf_vlan_type_system = { - .count = ELEMENTSOF(rtnl_vf_vlan_list_types), - .types = rtnl_vf_vlan_list_types, -}; - -static const NLType rtnl_vf_vlan_info_types[] = { - [IFLA_VF_MAC] = { .size = sizeof(struct ifla_vf_mac) }, - [IFLA_VF_VLAN] = { .size = sizeof(struct ifla_vf_vlan) }, - [IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_type_system}, - [IFLA_VF_TX_RATE] = { .size = sizeof(struct ifla_vf_tx_rate) }, - [IFLA_VF_SPOOFCHK] = { .size = sizeof(struct ifla_vf_spoofchk) }, - [IFLA_VF_RATE] = { .size = sizeof(struct ifla_vf_rate) }, - [IFLA_VF_LINK_STATE] = { .size = sizeof(struct ifla_vf_link_state) }, - [IFLA_VF_RSS_QUERY_EN] = { .size = sizeof(struct ifla_vf_rss_query_en) }, - [IFLA_VF_TRUST] = { .size = sizeof(struct ifla_vf_trust) }, - [IFLA_VF_IB_NODE_GUID] = { .size = sizeof(struct ifla_vf_guid) }, - [IFLA_VF_IB_PORT_GUID] = { .size = sizeof(struct ifla_vf_guid) }, -}; - -static const NLTypeSystem rtnl_vf_vlan_info_type_system = { - .count = ELEMENTSOF(rtnl_vf_vlan_info_types), - .types = rtnl_vf_vlan_info_types, -}; - -static const NLType rtnl_link_io_srv_types[] = { - [IFLA_VF_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_info_type_system }, -}; - -static const NLTypeSystem rtnl_io_srv_type_system = { - .count = ELEMENTSOF(rtnl_link_io_srv_types), - .types = rtnl_link_io_srv_types, -}; - -static const NLType rtnl_link_types[] = { - [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, - [IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR }, - [IFLA_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, - [IFLA_MTU] = { .type = NETLINK_TYPE_U32 }, - [IFLA_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_QDISC] = { .type = NETLINK_TYPE_STRING }, - [IFLA_STATS] = { .size = sizeof(struct rtnl_link_stats) }, -/* - [IFLA_COST], - [IFLA_PRIORITY], -*/ - [IFLA_MASTER] = { .type = NETLINK_TYPE_U32 }, -/* - [IFLA_WIRELESS], -*/ - [IFLA_PROTINFO] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_prot_info_type_system_union }, - [IFLA_TXQLEN] = { .type = NETLINK_TYPE_U32 }, -/* - [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, -*/ - [IFLA_WEIGHT] = { .type = NETLINK_TYPE_U32 }, - [IFLA_OPERSTATE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_LINKMODE] = { .type = NETLINK_TYPE_U8 }, - [IFLA_LINKINFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system }, - [IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 }, - [IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 }, - [IFLA_NUM_VF] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_io_srv_type_system }, - [IFLA_STATS64] = { .size = sizeof(struct rtnl_link_stats64) }, -/* - [IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED }, - [IFLA_PORT_SELF] = { .type = NETLINK_TYPE_NESTED }, -*/ - [IFLA_AF_SPEC] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_af_spec_type_system_union }, -/* - [IFLA_VF_PORTS], - [IFLA_PORT_SELF], -*/ - [IFLA_GROUP] = { .type = NETLINK_TYPE_U32 }, - [IFLA_NET_NS_FD] = { .type = NETLINK_TYPE_U32 }, - [IFLA_EXT_MASK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_PROMISCUITY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_NUM_TX_QUEUES] = { .type = NETLINK_TYPE_U32 }, - [IFLA_NUM_RX_QUEUES] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GSO_MAX_SEGS] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GSO_MAX_SIZE] = { .type = NETLINK_TYPE_U32 }, - [IFLA_CARRIER] = { .type = NETLINK_TYPE_U8 }, -/* - [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN }, -*/ - [IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 }, - [IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 }, - [IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system }, - [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, -}; - -static const NLTypeSystem rtnl_link_type_system = { - .count = ELEMENTSOF(rtnl_link_types), - .types = rtnl_link_types, -}; - -/* IFA_FLAGS was defined in kernel 3.14, but we still support older - * kernels where IFA_MAX is lower. */ -static const NLType rtnl_address_types[] = { - [IFA_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFA_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFA_LABEL] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, - [IFA_BROADCAST] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFA_ANYCAST] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) }, - [IFA_MULTICAST] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFA_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [IFA_RT_PRIORITY] = { .type = NETLINK_TYPE_U32 }, - [IFA_TARGET_NETNSID] = { .type = NETLINK_TYPE_S32 }, -}; - -static const NLTypeSystem rtnl_address_type_system = { - .count = ELEMENTSOF(rtnl_address_types), - .types = rtnl_address_types, -}; - -/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */ - -static const NLType rtnl_route_metrics_types[] = { - [RTAX_MTU] = { .type = NETLINK_TYPE_U32 }, - [RTAX_WINDOW] = { .type = NETLINK_TYPE_U32 }, - [RTAX_RTT] = { .type = NETLINK_TYPE_U32 }, - [RTAX_RTTVAR] = { .type = NETLINK_TYPE_U32 }, - [RTAX_SSTHRESH] = { .type = NETLINK_TYPE_U32 }, - [RTAX_CWND] = { .type = NETLINK_TYPE_U32 }, - [RTAX_ADVMSS] = { .type = NETLINK_TYPE_U32 }, - [RTAX_REORDERING] = { .type = NETLINK_TYPE_U32 }, - [RTAX_HOPLIMIT] = { .type = NETLINK_TYPE_U32 }, - [RTAX_INITCWND] = { .type = NETLINK_TYPE_U32 }, - [RTAX_FEATURES] = { .type = NETLINK_TYPE_U32 }, - [RTAX_RTO_MIN] = { .type = NETLINK_TYPE_U32 }, - [RTAX_INITRWND] = { .type = NETLINK_TYPE_U32 }, - [RTAX_QUICKACK] = { .type = NETLINK_TYPE_U32 }, - [RTAX_CC_ALGO] = { .type = NETLINK_TYPE_U32 }, - [RTAX_FASTOPEN_NO_COOKIE] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem rtnl_route_metrics_type_system = { - .count = ELEMENTSOF(rtnl_route_metrics_types), - .types = rtnl_route_metrics_types, -}; - -static const NLType rtnl_route_types[] = { - [RTA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ - [RTA_SRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ - [RTA_IIF] = { .type = NETLINK_TYPE_U32 }, - [RTA_OIF] = { .type = NETLINK_TYPE_U32 }, - [RTA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR }, - [RTA_PRIORITY] = { .type = NETLINK_TYPE_U32 }, - [RTA_PREFSRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ - [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_metrics_type_system}, - [RTA_MULTIPATH] = { .size = sizeof(struct rtnexthop) }, - [RTA_FLOW] = { .type = NETLINK_TYPE_U32 }, /* 6? */ - [RTA_CACHEINFO] = { .size = sizeof(struct rta_cacheinfo) }, - [RTA_TABLE] = { .type = NETLINK_TYPE_U32 }, - [RTA_MARK] = { .type = NETLINK_TYPE_U32 }, - [RTA_MFC_STATS] = { .type = NETLINK_TYPE_U64 }, - [RTA_VIA] = { /* See struct rtvia */ }, - [RTA_NEWDST] = { .type = NETLINK_TYPE_U32 }, - [RTA_PREF] = { .type = NETLINK_TYPE_U8 }, - [RTA_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [RTA_ENCAP] = { .type = NETLINK_TYPE_NESTED }, /* Multiple type systems i.e. LWTUNNEL_ENCAP_MPLS/LWTUNNEL_ENCAP_IP/LWTUNNEL_ENCAP_ILA etc... */ - [RTA_EXPIRES] = { .type = NETLINK_TYPE_U32 }, - [RTA_UID] = { .type = NETLINK_TYPE_U32 }, - [RTA_TTL_PROPAGATE] = { .type = NETLINK_TYPE_U8 }, - [RTA_IP_PROTO] = { .type = NETLINK_TYPE_U8 }, - [RTA_SPORT] = { .type = NETLINK_TYPE_U16 }, - [RTA_DPORT] = { .type = NETLINK_TYPE_U16 }, - [RTA_NH_ID] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem rtnl_route_type_system = { - .count = ELEMENTSOF(rtnl_route_types), - .types = rtnl_route_types, -}; - -static const NLType rtnl_neigh_types[] = { - [NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, - [NDA_LLADDR] = { /* struct ether_addr, struct in_addr, or struct in6_addr */ }, - [NDA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) }, - [NDA_PROBES] = { .type = NETLINK_TYPE_U32 }, - [NDA_VLAN] = { .type = NETLINK_TYPE_U16 }, - [NDA_PORT] = { .type = NETLINK_TYPE_U16 }, - [NDA_VNI] = { .type = NETLINK_TYPE_U32 }, - [NDA_IFINDEX] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem rtnl_neigh_type_system = { - .count = ELEMENTSOF(rtnl_neigh_types), - .types = rtnl_neigh_types, -}; - -static const NLType rtnl_addrlabel_types[] = { - [IFAL_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) }, - [IFAL_LABEL] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem rtnl_addrlabel_type_system = { - .count = ELEMENTSOF(rtnl_addrlabel_types), - .types = rtnl_addrlabel_types, -}; - -static const NLType rtnl_routing_policy_rule_types[] = { - [FRA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, - [FRA_SRC] = { .type = NETLINK_TYPE_IN_ADDR }, - [FRA_IIFNAME] = { .type = NETLINK_TYPE_STRING }, - [FRA_GOTO] = { .type = NETLINK_TYPE_U32 }, - [FRA_PRIORITY] = { .type = NETLINK_TYPE_U32 }, - [FRA_FWMARK] = { .type = NETLINK_TYPE_U32 }, - [FRA_FLOW] = { .type = NETLINK_TYPE_U32 }, - [FRA_TUN_ID] = { .type = NETLINK_TYPE_U64 }, - [FRA_SUPPRESS_IFGROUP] = { .type = NETLINK_TYPE_U32 }, - [FRA_SUPPRESS_PREFIXLEN] = { .type = NETLINK_TYPE_U32 }, - [FRA_TABLE] = { .type = NETLINK_TYPE_U32 }, - [FRA_FWMASK] = { .type = NETLINK_TYPE_U32 }, - [FRA_OIFNAME] = { .type = NETLINK_TYPE_STRING }, - [FRA_PAD] = { .type = NETLINK_TYPE_U32 }, - [FRA_L3MDEV] = { .type = NETLINK_TYPE_U8 }, - [FRA_UID_RANGE] = { .size = sizeof(struct fib_rule_uid_range) }, - [FRA_PROTOCOL] = { .type = NETLINK_TYPE_U8 }, - [FRA_IP_PROTO] = { .type = NETLINK_TYPE_U8 }, - [FRA_SPORT_RANGE] = { .size = sizeof(struct fib_rule_port_range) }, - [FRA_DPORT_RANGE] = { .size = sizeof(struct fib_rule_port_range) }, -}; - -static const NLTypeSystem rtnl_routing_policy_rule_type_system = { - .count = ELEMENTSOF(rtnl_routing_policy_rule_types), - .types = rtnl_routing_policy_rule_types, -}; - -static const NLType rtnl_nexthop_types[] = { - [NHA_ID] = { .type = NETLINK_TYPE_U32 }, - [NHA_GROUP] = { /* array of struct nexthop_grp */ }, - [NHA_GROUP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [NHA_BLACKHOLE] = { .type = NETLINK_TYPE_FLAG }, - [NHA_OIF] = { .type = NETLINK_TYPE_U32 }, - [NHA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR }, - [NHA_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [NHA_ENCAP] = { .type = NETLINK_TYPE_NESTED }, - [NHA_GROUPS] = { .type = NETLINK_TYPE_FLAG }, - [NHA_MASTER] = { .type = NETLINK_TYPE_U32 }, - [NHA_FDB] = { .type = NETLINK_TYPE_FLAG }, -}; - -static const NLTypeSystem rtnl_nexthop_type_system = { - .count = ELEMENTSOF(rtnl_nexthop_types), - .types = rtnl_nexthop_types, -}; - -static const NLType rtnl_tca_option_data_cake_types[] = { - [TCA_CAKE_BASE_RATE64] = { .type = NETLINK_TYPE_U64 }, - [TCA_CAKE_OVERHEAD] = { .type = NETLINK_TYPE_S32 }, - [TCA_CAKE_MPU] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_codel_types[] = { - [TCA_CODEL_TARGET] = { .type = NETLINK_TYPE_U32 }, - [TCA_CODEL_LIMIT] = { .type = NETLINK_TYPE_U32 }, - [TCA_CODEL_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [TCA_CODEL_ECN] = { .type = NETLINK_TYPE_U32 }, - [TCA_CODEL_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_drr_types[] = { - [TCA_DRR_QUANTUM] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_ets_quanta_types[] = { - [TCA_ETS_QUANTA_BAND] = { .type = NETLINK_TYPE_U32, }, -}; - -static const NLTypeSystem rtnl_tca_option_data_ets_quanta_type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_ets_quanta_types), - .types = rtnl_tca_option_data_ets_quanta_types, -}; - -static const NLType rtnl_tca_option_data_ets_prio_types[] = { - [TCA_ETS_PRIOMAP_BAND] = { .type = NETLINK_TYPE_U8, }, -}; - -static const NLTypeSystem rtnl_tca_option_data_ets_prio_type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_ets_prio_types), - .types = rtnl_tca_option_data_ets_prio_types, -}; - -static const NLType rtnl_tca_option_data_ets_types[] = { - [TCA_ETS_NBANDS] = { .type = NETLINK_TYPE_U8 }, - [TCA_ETS_NSTRICT] = { .type = NETLINK_TYPE_U8 }, - [TCA_ETS_QUANTA] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_option_data_ets_quanta_type_system }, - [TCA_ETS_PRIOMAP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_option_data_ets_prio_type_system }, - [TCA_ETS_QUANTA_BAND] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_fq_types[] = { - [TCA_FQ_PLIMIT] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_FLOW_PLIMIT] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_QUANTUM] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_INITIAL_QUANTUM] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_RATE_ENABLE] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_FLOW_MAX_RATE] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_BUCKETS_LOG] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_LOW_RATE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_ORPHAN_MASK] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_fq_codel_types[] = { - [TCA_FQ_CODEL_TARGET] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_LIMIT] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_ECN] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_FLOWS] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_QUANTUM] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_DROP_BATCH_SIZE] = { .type = NETLINK_TYPE_U32 }, - [TCA_FQ_CODEL_MEMORY_LIMIT] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_fq_pie_types[] = { - [TCA_FQ_PIE_LIMIT] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_gred_types[] = { - [TCA_GRED_DPS] = { .size = sizeof(struct tc_gred_sopt) }, -}; - -static const NLType rtnl_tca_option_data_hhf_types[] = { - [TCA_HHF_BACKLOG_LIMIT] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_htb_types[] = { - [TCA_HTB_PARMS] = { .size = sizeof(struct tc_htb_opt) }, - [TCA_HTB_INIT] = { .size = sizeof(struct tc_htb_glob) }, - [TCA_HTB_CTAB] = { .size = TC_RTAB_SIZE }, - [TCA_HTB_RTAB] = { .size = TC_RTAB_SIZE }, - [TCA_HTB_RATE64] = { .type = NETLINK_TYPE_U64 }, - [TCA_HTB_CEIL64] = { .type = NETLINK_TYPE_U64 }, -}; - -static const NLType rtnl_tca_option_data_pie_types[] = { - [TCA_PIE_LIMIT] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_qfq_types[] = { - [TCA_QFQ_WEIGHT] = { .type = NETLINK_TYPE_U32 }, - [TCA_QFQ_LMAX] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType rtnl_tca_option_data_sfb_types[] = { - [TCA_SFB_PARMS] = { .size = sizeof(struct tc_sfb_qopt) }, -}; - -static const NLType rtnl_tca_option_data_tbf_types[] = { - [TCA_TBF_PARMS] = { .size = sizeof(struct tc_tbf_qopt) }, - [TCA_TBF_RTAB] = { .size = TC_RTAB_SIZE }, - [TCA_TBF_PTAB] = { .size = TC_RTAB_SIZE }, - [TCA_TBF_RATE64] = { .type = NETLINK_TYPE_U64 }, - [TCA_TBF_PRATE64] = { .type = NETLINK_TYPE_U64 }, - [TCA_TBF_BURST] = { .type = NETLINK_TYPE_U32 }, - [TCA_TBF_PBURST] = { .type = NETLINK_TYPE_U32 }, -}; - -static const char* const nl_union_tca_option_data_table[] = { - [NL_UNION_TCA_OPTION_DATA_CAKE] = "cake", - [NL_UNION_TCA_OPTION_DATA_CODEL] = "codel", - [NL_UNION_TCA_OPTION_DATA_DRR] = "drr", - [NL_UNION_TCA_OPTION_DATA_ETS] = "ets", - [NL_UNION_TCA_OPTION_DATA_FQ] = "fq", - [NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel", - [NL_UNION_TCA_OPTION_DATA_FQ_PIE] = "fq_pie", - [NL_UNION_TCA_OPTION_DATA_GRED] = "gred", - [NL_UNION_TCA_OPTION_DATA_HHF] = "hhf", - [NL_UNION_TCA_OPTION_DATA_HTB] = "htb", - [NL_UNION_TCA_OPTION_DATA_PIE] = "pie", - [NL_UNION_TCA_OPTION_DATA_QFQ] = "qfq", - [NL_UNION_TCA_OPTION_DATA_SFB] = "sfb", - [NL_UNION_TCA_OPTION_DATA_TBF] = "tbf", -}; - -DEFINE_STRING_TABLE_LOOKUP(nl_union_tca_option_data, NLUnionTCAOptionData); - -static const NLTypeSystem rtnl_tca_option_data_type_systems[] = { - [NL_UNION_TCA_OPTION_DATA_CAKE] = { .count = ELEMENTSOF(rtnl_tca_option_data_cake_types), - .types = rtnl_tca_option_data_cake_types }, - [NL_UNION_TCA_OPTION_DATA_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_codel_types), - .types = rtnl_tca_option_data_codel_types }, - [NL_UNION_TCA_OPTION_DATA_DRR] = { .count = ELEMENTSOF(rtnl_tca_option_data_drr_types), - .types = rtnl_tca_option_data_drr_types }, - [NL_UNION_TCA_OPTION_DATA_ETS] = { .count = ELEMENTSOF(rtnl_tca_option_data_ets_types), - .types = rtnl_tca_option_data_ets_types }, - [NL_UNION_TCA_OPTION_DATA_FQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_types), - .types = rtnl_tca_option_data_fq_types }, - [NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types), - .types = rtnl_tca_option_data_fq_codel_types }, - [NL_UNION_TCA_OPTION_DATA_FQ_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_pie_types), - .types = rtnl_tca_option_data_fq_pie_types }, - [NL_UNION_TCA_OPTION_DATA_GRED] = { .count = ELEMENTSOF(rtnl_tca_option_data_gred_types), - .types = rtnl_tca_option_data_gred_types }, - [NL_UNION_TCA_OPTION_DATA_HHF] = { .count = ELEMENTSOF(rtnl_tca_option_data_hhf_types), - .types = rtnl_tca_option_data_hhf_types }, - [NL_UNION_TCA_OPTION_DATA_HTB] = { .count = ELEMENTSOF(rtnl_tca_option_data_htb_types), - .types = rtnl_tca_option_data_htb_types }, - [NL_UNION_TCA_OPTION_DATA_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_pie_types), - .types = rtnl_tca_option_data_pie_types }, - [NL_UNION_TCA_OPTION_DATA_QFQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_qfq_types), - .types = rtnl_tca_option_data_qfq_types }, - [NL_UNION_TCA_OPTION_DATA_SFB] = { .count = ELEMENTSOF(rtnl_tca_option_data_sfb_types), - .types = rtnl_tca_option_data_sfb_types }, - [NL_UNION_TCA_OPTION_DATA_TBF] = { .count = ELEMENTSOF(rtnl_tca_option_data_tbf_types), - .types = rtnl_tca_option_data_tbf_types }, -}; - -static const NLTypeSystemUnion rtnl_tca_option_data_type_system_union = { - .num = _NL_UNION_TCA_OPTION_DATA_MAX, - .lookup = nl_union_tca_option_data_from_string, - .type_systems = rtnl_tca_option_data_type_systems, - .match_type = NL_MATCH_SIBLING, - .match_attribute = TCA_KIND, -}; - -static const NLType rtnl_tca_types[] = { - [TCA_KIND] = { .type = NETLINK_TYPE_STRING }, - [TCA_OPTIONS] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_tca_option_data_type_system_union }, - [TCA_INGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 }, - [TCA_EGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem rtnl_tca_type_system = { - .count = ELEMENTSOF(rtnl_tca_types), - .types = rtnl_tca_types, -}; - -static const NLType mdb_types[] = { - [MDBA_SET_ENTRY] = { .size = sizeof(struct br_port_msg) }, -}; - -static const NLTypeSystem rtnl_mdb_type_system = { - .count = ELEMENTSOF(mdb_types), - .types = mdb_types, -}; - -static const NLType rtnl_types[] = { - [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, - [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, - [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, - [RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, - [RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, - [RTM_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, - [RTM_DELRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, - [RTM_GETRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, - [RTM_NEWNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, - [RTM_DELNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, - [RTM_GETNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, - [RTM_NEWQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_DELQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_GETQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_NEWTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_DELTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_GETTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_NEWMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, - [RTM_DELMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, - [RTM_GETMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, -}; - -static const NLTypeSystem rtnl_type_system_root = { - .count = ELEMENTSOF(rtnl_types), - .types = rtnl_types, -}; - -/***************** nfnl type systems *****************/ - -static const NLType nfnl_nft_table_types[] = { - [NFTA_TABLE_NAME] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_TABLE_FLAGS] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem nfnl_nft_table_type_system = { - .count = ELEMENTSOF(nfnl_nft_table_types), - .types = nfnl_nft_table_types, -}; - -static const NLType nfnl_nft_chain_hook_types[] = { - [NFTA_HOOK_HOOKNUM] = { .type = NETLINK_TYPE_U32 }, - [NFTA_HOOK_PRIORITY] = { .type = NETLINK_TYPE_U32 }, - [NFTA_HOOK_DEV] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, -}; - -static const NLTypeSystem nfnl_nft_chain_hook_type_system = { - .count = ELEMENTSOF(nfnl_nft_chain_hook_types), - .types = nfnl_nft_chain_hook_types, -}; - -static const NLType nfnl_nft_chain_types[] = { - [NFTA_CHAIN_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_CHAIN_NAME] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_CHAIN_HOOK] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_chain_hook_type_system }, - [NFTA_CHAIN_TYPE] = { .type = NETLINK_TYPE_STRING, .size = 16 }, - [NFTA_CHAIN_FLAGS] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem nfnl_nft_chain_type_system = { - .count = ELEMENTSOF(nfnl_nft_chain_types), - .types = nfnl_nft_chain_types, -}; - -static const NLType nfnl_nft_expr_meta_types[] = { - [NFTA_META_DREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_META_KEY] = { .type = NETLINK_TYPE_U32 }, - [NFTA_META_SREG] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType nfnl_nft_expr_payload_types[] = { - [NFTA_PAYLOAD_DREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_PAYLOAD_BASE] = { .type = NETLINK_TYPE_U32 }, - [NFTA_PAYLOAD_OFFSET] = { .type = NETLINK_TYPE_U32 }, - [NFTA_PAYLOAD_LEN] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType nfnl_nft_expr_nat_types[] = { - [NFTA_NAT_TYPE] = { .type = NETLINK_TYPE_U32 }, - [NFTA_NAT_FAMILY] = { .type = NETLINK_TYPE_U32 }, - [NFTA_NAT_REG_ADDR_MIN] = { .type = NETLINK_TYPE_U32 }, - [NFTA_NAT_REG_ADDR_MAX] = { .type = NETLINK_TYPE_U32 }, - [NFTA_NAT_REG_PROTO_MIN] = { .type = NETLINK_TYPE_U32 }, - [NFTA_NAT_REG_PROTO_MAX] = { .type = NETLINK_TYPE_U32 }, - [NFTA_NAT_FLAGS] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType nfnl_nft_data_types[] = { - [NFTA_DATA_VALUE] = { .type = NETLINK_TYPE_BINARY }, -}; - -static const NLTypeSystem nfnl_nft_data_type_system = { - .count = ELEMENTSOF(nfnl_nft_data_types), - .types = nfnl_nft_data_types, -}; - -static const NLType nfnl_nft_expr_bitwise_types[] = { - [NFTA_BITWISE_SREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_BITWISE_DREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_BITWISE_LEN] = { .type = NETLINK_TYPE_U32 }, - [NFTA_BITWISE_MASK] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, - [NFTA_BITWISE_XOR] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, -}; - -static const NLType nfnl_nft_expr_cmp_types[] = { - [NFTA_CMP_SREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_CMP_OP] = { .type = NETLINK_TYPE_U32 }, - [NFTA_CMP_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, -}; - -static const NLType nfnl_nft_expr_fib_types[] = { - [NFTA_FIB_DREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_FIB_RESULT] = { .type = NETLINK_TYPE_U32 }, - [NFTA_FIB_FLAGS] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType nfnl_nft_expr_lookup_types[] = { - [NFTA_LOOKUP_SET] = { .type = NETLINK_TYPE_STRING }, - [NFTA_LOOKUP_SREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_LOOKUP_DREG] = { .type = NETLINK_TYPE_U32 }, - [NFTA_LOOKUP_FLAGS] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLType nfnl_nft_expr_masq_types[] = { - [NFTA_MASQ_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [NFTA_MASQ_REG_PROTO_MIN] = { .type = NETLINK_TYPE_U32 }, - [NFTA_MASQ_REG_PROTO_MAX] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem nfnl_expr_data_type_systems[] = { - [NL_UNION_NFT_EXPR_DATA_BITWISE] = { .count = ELEMENTSOF(nfnl_nft_expr_bitwise_types), - .types = nfnl_nft_expr_bitwise_types }, - [NL_UNION_NFT_EXPR_DATA_CMP] = { .count = ELEMENTSOF(nfnl_nft_expr_cmp_types), - .types = nfnl_nft_expr_cmp_types }, - [NL_UNION_NFT_EXPR_DATA_FIB] = { .count = ELEMENTSOF(nfnl_nft_expr_fib_types), - .types = nfnl_nft_expr_fib_types }, - [NL_UNION_NFT_EXPR_DATA_LOOKUP] = { .count = ELEMENTSOF(nfnl_nft_expr_lookup_types), - .types = nfnl_nft_expr_lookup_types }, - [NL_UNION_NFT_EXPR_DATA_MASQ] = { .count = ELEMENTSOF(nfnl_nft_expr_masq_types), - .types = nfnl_nft_expr_masq_types }, - [NL_UNION_NFT_EXPR_DATA_META] = { .count = ELEMENTSOF(nfnl_nft_expr_meta_types), - .types = nfnl_nft_expr_meta_types }, - [NL_UNION_NFT_EXPR_DATA_NAT] = { .count = ELEMENTSOF(nfnl_nft_expr_nat_types), - .types = nfnl_nft_expr_nat_types }, - [NL_UNION_NFT_EXPR_DATA_PAYLOAD] = { .count = ELEMENTSOF(nfnl_nft_expr_payload_types), - .types = nfnl_nft_expr_payload_types }, -}; - -static const char* const nl_union_nft_expr_data_table[] = { - [NL_UNION_NFT_EXPR_DATA_BITWISE] = "bitwise", - [NL_UNION_NFT_EXPR_DATA_CMP] = "cmp", - [NL_UNION_NFT_EXPR_DATA_LOOKUP] = "lookup", - [NL_UNION_NFT_EXPR_DATA_META] = "meta", - [NL_UNION_NFT_EXPR_DATA_FIB] = "fib", - [NL_UNION_NFT_EXPR_DATA_MASQ] = "masq", - [NL_UNION_NFT_EXPR_DATA_NAT] = "nat", - [NL_UNION_NFT_EXPR_DATA_PAYLOAD] = "payload", -}; - -DEFINE_STRING_TABLE_LOOKUP(nl_union_nft_expr_data, NLUnionNFTExprData); - -static const NLTypeSystemUnion nfnl_nft_data_expr_type_system_union = { - .num = _NL_UNION_NFT_EXPR_DATA_MAX, - .lookup = nl_union_nft_expr_data_from_string, - .type_systems = nfnl_expr_data_type_systems, - .match_type = NL_MATCH_SIBLING, - .match_attribute = NFTA_EXPR_NAME, -}; - -static const NLType nfnl_nft_rule_expr_types[] = { - [NFTA_EXPR_NAME] = { .type = NETLINK_TYPE_STRING, .size = 16 }, - [NFTA_EXPR_DATA] = { .type = NETLINK_TYPE_UNION, - .type_system_union = &nfnl_nft_data_expr_type_system_union }, -}; - -static const NLTypeSystem nfnl_nft_rule_expr_type_system = { - .count = ELEMENTSOF(nfnl_nft_rule_expr_types), - .types = nfnl_nft_rule_expr_types, -}; - -static const NLType nfnl_nft_rule_types[] = { - [NFTA_RULE_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_RULE_CHAIN] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_RULE_EXPRESSIONS] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_rule_expr_type_system } -}; - -static const NLTypeSystem nfnl_nft_rule_type_system = { - .count = ELEMENTSOF(nfnl_nft_rule_types), - .types = nfnl_nft_rule_types, -}; - -static const NLType nfnl_nft_set_types[] = { - [NFTA_SET_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_SET_NAME] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_SET_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [NFTA_SET_KEY_TYPE] = { .type = NETLINK_TYPE_U32 }, - [NFTA_SET_KEY_LEN] = { .type = NETLINK_TYPE_U32 }, - [NFTA_SET_DATA_TYPE] = { .type = NETLINK_TYPE_U32 }, - [NFTA_SET_DATA_LEN] = { .type = NETLINK_TYPE_U32 }, - [NFTA_SET_POLICY] = { .type = NETLINK_TYPE_U32 }, - [NFTA_SET_ID] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem nfnl_nft_set_type_system = { - .count = ELEMENTSOF(nfnl_nft_set_types), - .types = nfnl_nft_set_types, -}; - -static const NLType nfnl_nft_setelem_types[] = { - [NFTA_SET_ELEM_KEY] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, - [NFTA_SET_ELEM_DATA] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, - [NFTA_SET_ELEM_FLAGS] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem nfnl_nft_setelem_type_system = { - .count = ELEMENTSOF(nfnl_nft_setelem_types), - .types = nfnl_nft_setelem_types, -}; - -static const NLType nfnl_nft_setelem_list_types[] = { - [NFTA_SET_ELEM_LIST_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_SET_ELEM_LIST_SET] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, - [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_setelem_type_system }, -}; - -static const NLTypeSystem nfnl_nft_setelem_list_type_system = { - .count = ELEMENTSOF(nfnl_nft_setelem_list_types), - .types = nfnl_nft_setelem_list_types, -}; - -static const NLType nfnl_nft_msg_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_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_rule_type_system, .size = sizeof(struct nfgenmsg) }, - [NFT_MSG_NEWSET] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_set_type_system, .size = sizeof(struct nfgenmsg) }, - [NFT_MSG_NEWSETELEM] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_setelem_list_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 NLType nfnl_msg_batch_types [] = { - [NFNL_BATCH_GENID] = { .type = NETLINK_TYPE_U32 } -}; - -static const NLTypeSystem nfnl_msg_batch_type_system = { - .count = ELEMENTSOF(nfnl_msg_batch_types), - .types = nfnl_msg_batch_types, -}; - -static const NLType nfnl_types[] = { - [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, - [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, - [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_type_system_root = { - .count = ELEMENTSOF(nfnl_types), - .types = nfnl_types, -}; - -/***************** genl type systems *****************/ - -/***************** genl ctrl type systems *****************/ -static const NLType genl_mcast_group_types[] = { - [CTRL_ATTR_MCAST_GRP_NAME] = { .type = NETLINK_TYPE_STRING }, - [CTRL_ATTR_MCAST_GRP_ID] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem genl_mcast_group_type_system = { - .count = ELEMENTSOF(genl_mcast_group_types), - .types = genl_mcast_group_types, -}; - -static const NLType genl_get_family_types[] = { - [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, - [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, - [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_mcast_group_type_system }, -}; - -static const NLTypeSystem genl_get_family_type_system = { - .count = ELEMENTSOF(genl_get_family_types), - .types = genl_get_family_types, -}; - -static const NLType genl_ctrl_id_ctrl_cmds[] = { - [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system }, -}; - -static const NLTypeSystem genl_ctrl_id_ctrl_type_system = { - .count = ELEMENTSOF(genl_ctrl_id_ctrl_cmds), - .types = genl_ctrl_id_ctrl_cmds, -}; - -/***************** genl batadv type systems *****************/ -static const NLType genl_batadv_types[] = { - [BATADV_ATTR_VERSION] = { .type = NETLINK_TYPE_STRING }, - [BATADV_ATTR_ALGO_NAME] = { .type = NETLINK_TYPE_STRING }, - [BATADV_ATTR_MESH_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_MESH_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, - [BATADV_ATTR_MESH_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_HARD_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_HARD_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ }, - [BATADV_ATTR_HARD_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_ORIG_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_TPMETER_RESULT] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_TPMETER_TEST_TIME] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_TPMETER_BYTES] = { .type = NETLINK_TYPE_U64 }, - [BATADV_ATTR_TPMETER_COOKIE] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_PAD] = { .type = NETLINK_TYPE_UNSPEC }, - [BATADV_ATTR_ACTIVE] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_TT_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_TT_TTVN] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_TT_LAST_TTVN] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_TT_CRC32] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_TT_VID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_TT_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_FLAG_BEST] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_NEIGH_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_TQ] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_THROUGHPUT] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_ROUTER] = { .size = ETH_ALEN }, - [BATADV_ATTR_BLA_OWN] = { .type = NETLINK_TYPE_FLAG }, - [BATADV_ATTR_BLA_ADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_BLA_VID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_BLA_BACKBONE] = { .size = ETH_ALEN }, - [BATADV_ATTR_BLA_CRC] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_DAT_CACHE_IP4ADDRESS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_DAT_CACHE_HWADDRESS] = { .size = ETH_ALEN }, - [BATADV_ATTR_DAT_CACHE_VID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_MCAST_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_VLANID] = { .type = NETLINK_TYPE_U16 }, - [BATADV_ATTR_AGGREGATED_OGMS_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_AP_ISOLATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_ISOLATION_MARK] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_ISOLATION_MASK] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_BONDING_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_FRAGMENTATION_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_GW_BANDWIDTH_DOWN] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_GW_BANDWIDTH_UP] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_GW_MODE] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_GW_SEL_CLASS] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_HOP_PENALTY] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_LOG_LEVEL] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_MULTICAST_FORCEFLOOD_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_MULTICAST_FANOUT] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_NETWORK_CODING_ENABLED] = { .type = NETLINK_TYPE_U8 }, - [BATADV_ATTR_ORIG_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_ELP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem genl_batadv_type_system = { - .count = ELEMENTSOF(genl_batadv_types), - .types = genl_batadv_types, -}; - -static const NLType genl_batadv_cmds[] = { - [BATADV_CMD_SET_MESH] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, -}; - -static const NLTypeSystem genl_batadv_cmds_type_system = { - .count = ELEMENTSOF(genl_batadv_cmds), - .types = genl_batadv_cmds, -}; - -/***************** genl fou type systems *****************/ -static const NLType genl_fou_types[] = { - [FOU_ATTR_PORT] = { .type = NETLINK_TYPE_U16 }, - [FOU_ATTR_AF] = { .type = NETLINK_TYPE_U8 }, - [FOU_ATTR_IPPROTO] = { .type = NETLINK_TYPE_U8 }, - [FOU_ATTR_TYPE] = { .type = NETLINK_TYPE_U8 }, - [FOU_ATTR_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG }, - [FOU_ATTR_LOCAL_V4] = { .type = NETLINK_TYPE_IN_ADDR }, - [FOU_ATTR_PEER_V4] = { .type = NETLINK_TYPE_IN_ADDR }, - [FOU_ATTR_LOCAL_V6] = { .type = NETLINK_TYPE_IN_ADDR }, - [FOU_ATTR_PEER_V6] = { .type = NETLINK_TYPE_IN_ADDR}, - [FOU_ATTR_PEER_PORT] = { .type = NETLINK_TYPE_U16}, - [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32}, -}; - -static const NLTypeSystem genl_fou_type_system = { - .count = ELEMENTSOF(genl_fou_types), - .types = genl_fou_types, -}; - -static const NLType genl_fou_cmds[] = { - [FOU_CMD_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, - [FOU_CMD_DEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, - [FOU_CMD_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, -}; - -static const NLTypeSystem genl_fou_cmds_type_system = { - .count = ELEMENTSOF(genl_fou_cmds), - .types = genl_fou_cmds, -}; - -/***************** genl l2tp type systems *****************/ -static const NLType genl_l2tp_types[] = { - [L2TP_ATTR_PW_TYPE] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_OFFSET] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_DATA_SEQ] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_L2SPEC_TYPE] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_L2SPEC_LEN] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_PROTO_VERSION] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_IFNAME] = { .type = NETLINK_TYPE_STRING }, - [L2TP_ATTR_CONN_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_PEER_CONN_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_PEER_SESSION_ID] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_UDP_CSUM] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_RECV_SEQ] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_SEND_SEQ] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_LNS_MODE] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_USING_IPSEC] = { .type = NETLINK_TYPE_U8 }, - [L2TP_ATTR_FD] = { .type = NETLINK_TYPE_U32 }, - [L2TP_ATTR_IP_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_IP_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_UDP_SPORT] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_UDP_DPORT] = { .type = NETLINK_TYPE_U16 }, - [L2TP_ATTR_IP6_SADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_IP6_DADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [L2TP_ATTR_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_FLAG }, - [L2TP_ATTR_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_FLAG }, -}; - -static const NLTypeSystem genl_l2tp_type_system = { - .count = ELEMENTSOF(genl_l2tp_types), - .types = genl_l2tp_types, -}; - -static const NLType genl_l2tp[] = { - [L2TP_CMD_TUNNEL_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, -}; - -static const NLTypeSystem genl_l2tp_tunnel_session_type_system = { - .count = ELEMENTSOF(genl_l2tp), - .types = genl_l2tp, -}; - -/***************** genl macsec type systems *****************/ -static const NLType genl_rxsc_types[] = { - [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, -}; - -static const NLTypeSystem genl_rxsc_config_type_system = { - .count = ELEMENTSOF(genl_rxsc_types), - .types = genl_rxsc_types, -}; - -static const NLType genl_macsec_rxsc_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, -}; - -static const NLTypeSystem genl_macsec_rxsc_type_system = { - .count = ELEMENTSOF(genl_macsec_rxsc_types), - .types = genl_macsec_rxsc_types, -}; - -static const NLType genl_macsec_sa_config_types[] = { - [MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 }, - [MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 }, - [MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_SA_ATTR_KEYID] = { .size = MACSEC_KEYID_LEN }, - [MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN }, -}; - -static const NLTypeSystem genl_macsec_sa_config_type_system = { - .count = ELEMENTSOF(genl_macsec_sa_config_types), - .types = genl_macsec_sa_config_types, -}; - -static const NLType genl_macsec_rxsa_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, -}; - -static const NLTypeSystem genl_macsec_rxsa_type_system = { - .count = ELEMENTSOF(genl_macsec_rxsa_types), - .types = genl_macsec_rxsa_types, -}; - -static const NLType genl_macsec_sa_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, - [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, -}; - -static const NLTypeSystem genl_macsec_sa_type_system = { - .count = ELEMENTSOF(genl_macsec_sa_types), - .types = genl_macsec_sa_types, -}; - -static const NLType genl_macsec[] = { - [MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system }, - [MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsa_type_system}, - [MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, -}; - -static const NLTypeSystem genl_macsec_device_type_system = { - .count = ELEMENTSOF(genl_macsec), - .types = genl_macsec, -}; - -/***************** genl nl80211 type systems *****************/ -static const NLType genl_nl80211_types[] = { - [NL80211_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [NL80211_ATTR_MAC] = { .type = NETLINK_TYPE_ETHER_ADDR }, - [NL80211_ATTR_SSID] = { .type = NETLINK_TYPE_STRING }, - [NL80211_ATTR_IFTYPE] = { .type = NETLINK_TYPE_U32 }, -}; - -static const NLTypeSystem genl_nl80211_type_system = { - .count = ELEMENTSOF(genl_nl80211_types), - .types = genl_nl80211_types, -}; - -static const NLType genl_nl80211_cmds[] = { - [NL80211_CMD_GET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_GET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_GET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, -}; - -static const NLTypeSystem genl_nl80211_cmds_type_system = { - .count = ELEMENTSOF(genl_nl80211_cmds), - .types = genl_nl80211_cmds, -}; - -/***************** genl wireguard type systems *****************/ -static const NLType genl_wireguard_allowedip_types[] = { - [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, - [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR }, - [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 }, -}; - -static const NLTypeSystem genl_wireguard_allowedip_type_system = { - .count = ELEMENTSOF(genl_wireguard_allowedip_types), - .types = genl_wireguard_allowedip_types, -}; - -static const NLType genl_wireguard_peer_types[] = { - [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, - [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, - [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 }, - [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR }, - [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, -}; - -static const NLTypeSystem genl_wireguard_peer_type_system = { - .count = ELEMENTSOF(genl_wireguard_peer_types), - .types = genl_wireguard_peer_types, -}; - -static const NLType genl_wireguard_set_device_types[] = { - [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 }, - [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN }, - [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 }, - [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, -}; - -static const NLTypeSystem genl_wireguard_set_device_type_system = { - .count = ELEMENTSOF(genl_wireguard_set_device_types), - .types = genl_wireguard_set_device_types, -}; - -static const NLType genl_wireguard_cmds[] = { - [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_set_device_type_system }, -}; - -static const NLTypeSystem genl_wireguard_type_system = { - .count = ELEMENTSOF(genl_wireguard_cmds), - .types = genl_wireguard_cmds, -}; - -static const NLType genl_families[] = { - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system }, - [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, - [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmds_type_system }, - [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system }, - [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmds_type_system }, - [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmds_type_system }, -}; - -/* Mainly used when sending message */ -const NLTypeSystem genl_family_type_system_root = { - .count = ELEMENTSOF(genl_families), - .types = genl_families, -}; - -static const NLType genl_types[] = { - [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, - [SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, -}; - -/* Mainly used when message received */ -static const NLTypeSystem genl_type_system_root = { - .count = ELEMENTSOF(genl_types), - .types = genl_types, -}; - uint16_t type_get_type(const NLType *type) { assert(type); return type->type; @@ -1742,43 +53,20 @@ uint16_t type_system_get_count(const NLTypeSystem *type_system) { return type_system->count; } -static const NLTypeSystem *type_system_get_root(int protocol) { - switch (protocol) { - case NETLINK_GENERIC: - return &genl_type_system_root; - case NETLINK_NETFILTER: - return &nfnl_type_system_root; - default: /* NETLINK_ROUTE: */ - return &rtnl_type_system_root; - } -} - int type_system_root_get_type(sd_netlink *nl, const NLType **ret, uint16_t type) { - sd_genl_family_t family; - const NLType *nl_type; - int r; - if (!nl) - return type_system_get_type(&rtnl_type_system_root, ret, type); + return rtnl_get_type(type, ret); - if (nl->protocol != NETLINK_GENERIC) - return type_system_get_type(type_system_get_root(nl->protocol), ret, type); - - r = nlmsg_type_to_genl_family(nl, type, &family); - if (r < 0) - return r; - - if (family >= genl_type_system_root.count) + switch(nl->protocol) { + case NETLINK_ROUTE: + return rtnl_get_type(type, ret); + case NETLINK_NETFILTER: + return nfnl_get_type(type, ret); + case NETLINK_GENERIC: + return genl_get_type(nl, type, ret); + default: return -EOPNOTSUPP; - - nl_type = &genl_type_system_root.types[family]; - - if (nl_type->type == NETLINK_TYPE_UNSPEC) - return -EOPNOTSUPP; - - *ret = nl_type; - - return 0; + } } int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index b78ed21a41..14a3c7417a 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "macro.h" +#include "sd-netlink.h" enum { NETLINK_TYPE_UNSPEC, @@ -37,6 +37,10 @@ typedef struct NLType NLType; extern const NLTypeSystem genl_family_type_system_root; +int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret); +int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret); +int genl_get_type(sd_netlink *genl, uint16_t nlmsg_type, const NLType **ret); + uint16_t type_get_type(const NLType *type); size_t type_get_size(const NLType *type); const NLTypeSystem *type_get_type_system(const NLType *type); @@ -51,82 +55,3 @@ NLMatchType type_system_union_get_match_type(const NLTypeSystemUnion *type_syste uint16_t type_system_union_get_match_attribute(const NLTypeSystemUnion *type_system_union); int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key); int type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol); - -typedef enum NLUnionLinkInfoData { - NL_UNION_LINK_INFO_DATA_BOND, - NL_UNION_LINK_INFO_DATA_BRIDGE, - NL_UNION_LINK_INFO_DATA_VLAN, - NL_UNION_LINK_INFO_DATA_VETH, - NL_UNION_LINK_INFO_DATA_DUMMY, - NL_UNION_LINK_INFO_DATA_MACVLAN, - NL_UNION_LINK_INFO_DATA_MACVTAP, - NL_UNION_LINK_INFO_DATA_IPVLAN, - NL_UNION_LINK_INFO_DATA_IPVTAP, - NL_UNION_LINK_INFO_DATA_VXLAN, - NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL, - NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL, - NL_UNION_LINK_INFO_DATA_ERSPAN, - NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL, - NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL, - NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL, - NL_UNION_LINK_INFO_DATA_SIT_TUNNEL, - NL_UNION_LINK_INFO_DATA_VTI_TUNNEL, - NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL, - NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL, - NL_UNION_LINK_INFO_DATA_VRF, - NL_UNION_LINK_INFO_DATA_VCAN, - NL_UNION_LINK_INFO_DATA_GENEVE, - NL_UNION_LINK_INFO_DATA_VXCAN, - NL_UNION_LINK_INFO_DATA_WIREGUARD, - NL_UNION_LINK_INFO_DATA_NETDEVSIM, - NL_UNION_LINK_INFO_DATA_CAN, - NL_UNION_LINK_INFO_DATA_MACSEC, - NL_UNION_LINK_INFO_DATA_NLMON, - NL_UNION_LINK_INFO_DATA_XFRM, - NL_UNION_LINK_INFO_DATA_IFB, - NL_UNION_LINK_INFO_DATA_BAREUDP, - NL_UNION_LINK_INFO_DATA_BATADV, - _NL_UNION_LINK_INFO_DATA_MAX, - _NL_UNION_LINK_INFO_DATA_INVALID = -EINVAL, -} NLUnionLinkInfoData; - -const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_; -NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_; - -typedef enum NLUnionTCAOptionData { - NL_UNION_TCA_OPTION_DATA_CAKE, - NL_UNION_TCA_OPTION_DATA_CODEL, - NL_UNION_TCA_OPTION_DATA_DRR, - NL_UNION_TCA_OPTION_DATA_ETS, - NL_UNION_TCA_OPTION_DATA_FQ, - NL_UNION_TCA_OPTION_DATA_FQ_CODEL, - NL_UNION_TCA_OPTION_DATA_FQ_PIE, - NL_UNION_TCA_OPTION_DATA_GRED, - NL_UNION_TCA_OPTION_DATA_HHF, - NL_UNION_TCA_OPTION_DATA_HTB, - NL_UNION_TCA_OPTION_DATA_PIE, - NL_UNION_TCA_OPTION_DATA_QFQ, - NL_UNION_TCA_OPTION_DATA_SFB, - NL_UNION_TCA_OPTION_DATA_TBF, - _NL_UNION_TCA_OPTION_DATA_MAX, - _NL_UNION_TCA_OPTION_DATA_INVALID = -EINVAL, -} NLUnionTCAOptionData; - -const char *nl_union_tca_option_data_to_string(NLUnionTCAOptionData p) _const_; -NLUnionTCAOptionData nl_union_tca_option_data_from_string(const char *p) _pure_; - -typedef enum NLUnionNFTExprData { - NL_UNION_NFT_EXPR_DATA_BITWISE, - NL_UNION_NFT_EXPR_DATA_CMP, - NL_UNION_NFT_EXPR_DATA_FIB, - NL_UNION_NFT_EXPR_DATA_LOOKUP, - NL_UNION_NFT_EXPR_DATA_PAYLOAD, - NL_UNION_NFT_EXPR_DATA_MASQ, - NL_UNION_NFT_EXPR_DATA_META, - NL_UNION_NFT_EXPR_DATA_NAT, - _NL_UNION_NFT_EXPR_DATA_MAX, - _NL_UNION_NFT_EXPR_DATA_INVALID = -EINVAL, -} NLUnionNFTExprData; - -const char *nl_union_nft_expr_data_to_string(NLUnionNFTExprData p) _const_; -NLUnionNFTExprData nl_union_nft_expr_data_from_string(const char *p) _pure_; diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c index f55e524ae9..f687a1a370 100644 --- a/src/network/test-network-tables.c +++ b/src/network/test-network-tables.c @@ -8,7 +8,6 @@ #include "lldp-internal.h" #include "macvlan.h" #include "ndisc-internal.h" -#include "netlink-internal.h" #include "networkd-link.h" #include "networkd-network.h" #include "networkd-util.h" @@ -35,7 +34,6 @@ int main(int argc, char **argv) { /* test_table(link_state, LINK_STATE); — not a reversible mapping */ test_table(lldp_mode, LLDP_MODE); test_table(netdev_kind, NETDEV_KIND); - test_table(nl_union_link_info_data, NL_UNION_LINK_INFO_DATA); test_table(radv_prefix_delegation, RADV_PREFIX_DELEGATION); test_table(lldp_event, SD_LLDP_EVENT); test_table(ndisc_event, SD_NDISC_EVENT); From e6d58c2f7161e270929f8e5f0c980d5caff1bf52 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 14:55:16 +0900 Subject: [PATCH 11/29] sd-netlink: rename several type systems for generic netlink --- src/libsystemd/sd-netlink/netlink-genl.c | 2 +- .../sd-netlink/netlink-types-genl.c | 193 ++++++++---------- src/libsystemd/sd-netlink/netlink-types.h | 2 +- 3 files changed, 89 insertions(+), 108 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 401f263d97..9330d66fe2 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -38,7 +38,7 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl assert(nl->protocol == NETLINK_GENERIC); assert(ret); - r = type_system_get_type(&genl_family_type_system_root, &genl_cmd_type, family); + r = type_system_get_type(&genl_family_type_system, &genl_cmd_type, family); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index 3dfe47a7f3..a88609c0be 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -15,34 +15,34 @@ #include "netlink-types-internal.h" /***************** genl ctrl type systems *****************/ -static const NLType genl_mcast_group_types[] = { +static const NLType genl_ctrl_mcast_group_types[] = { [CTRL_ATTR_MCAST_GRP_NAME] = { .type = NETLINK_TYPE_STRING }, [CTRL_ATTR_MCAST_GRP_ID] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem genl_mcast_group_type_system = { - .count = ELEMENTSOF(genl_mcast_group_types), - .types = genl_mcast_group_types, +static const NLTypeSystem genl_ctrl_mcast_group_type_system = { + .count = ELEMENTSOF(genl_ctrl_mcast_group_types), + .types = genl_ctrl_mcast_group_types, }; -static const NLType genl_get_family_types[] = { - [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, +static const NLType genl_ctrl_types[] = { [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, - [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_mcast_group_type_system }, + [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, + [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_mcast_group_type_system }, }; -static const NLTypeSystem genl_get_family_type_system = { - .count = ELEMENTSOF(genl_get_family_types), - .types = genl_get_family_types, +static const NLTypeSystem genl_ctrl_type_system = { + .count = ELEMENTSOF(genl_ctrl_types), + .types = genl_ctrl_types, }; -static const NLType genl_ctrl_id_ctrl_cmds[] = { - [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system }, +static const NLType genl_ctrl_cmd_types[] = { + [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, }, }; -static const NLTypeSystem genl_ctrl_id_ctrl_type_system = { - .count = ELEMENTSOF(genl_ctrl_id_ctrl_cmds), - .types = genl_ctrl_id_ctrl_cmds, +static const NLTypeSystem genl_ctrl_cmd_type_system = { + .count = ELEMENTSOF(genl_ctrl_cmd_types), + .types = genl_ctrl_cmd_types, }; /***************** genl batadv type systems *****************/ @@ -114,13 +114,13 @@ static const NLTypeSystem genl_batadv_type_system = { .types = genl_batadv_types, }; -static const NLType genl_batadv_cmds[] = { +static const NLType genl_batadv_cmd_types[] = { [BATADV_CMD_SET_MESH] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, }; -static const NLTypeSystem genl_batadv_cmds_type_system = { - .count = ELEMENTSOF(genl_batadv_cmds), - .types = genl_batadv_cmds, +static const NLTypeSystem genl_batadv_cmd_type_system = { + .count = ELEMENTSOF(genl_batadv_cmd_types), + .types = genl_batadv_cmd_types, }; /***************** genl fou type systems *****************/ @@ -143,15 +143,15 @@ static const NLTypeSystem genl_fou_type_system = { .types = genl_fou_types, }; -static const NLType genl_fou_cmds[] = { +static const NLType genl_fou_cmd_types[] = { [FOU_CMD_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, [FOU_CMD_DEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, [FOU_CMD_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, }; -static const NLTypeSystem genl_fou_cmds_type_system = { - .count = ELEMENTSOF(genl_fou_cmds), - .types = genl_fou_cmds, +static const NLTypeSystem genl_fou_cmd_type_system = { + .count = ELEMENTSOF(genl_fou_cmd_types), + .types = genl_fou_cmd_types, }; /***************** genl l2tp type systems *****************/ @@ -190,7 +190,7 @@ static const NLTypeSystem genl_l2tp_type_system = { .types = genl_l2tp_types, }; -static const NLType genl_l2tp[] = { +static const NLType genl_l2tp_cmd_types[] = { [L2TP_CMD_TUNNEL_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, [L2TP_CMD_TUNNEL_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, [L2TP_CMD_TUNNEL_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, @@ -201,24 +201,14 @@ static const NLType genl_l2tp[] = { [L2TP_CMD_SESSION_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, }; -static const NLTypeSystem genl_l2tp_tunnel_session_type_system = { - .count = ELEMENTSOF(genl_l2tp), - .types = genl_l2tp, +static const NLTypeSystem genl_l2tp_cmd_type_system = { + .count = ELEMENTSOF(genl_l2tp_cmd_types), + .types = genl_l2tp_cmd_types, }; /***************** genl macsec type systems *****************/ -static const NLType genl_rxsc_types[] = { - [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, -}; - -static const NLTypeSystem genl_rxsc_config_type_system = { - .count = ELEMENTSOF(genl_rxsc_types), - .types = genl_rxsc_types, -}; - static const NLType genl_macsec_rxsc_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, + [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, }; static const NLTypeSystem genl_macsec_rxsc_type_system = { @@ -226,7 +216,7 @@ static const NLTypeSystem genl_macsec_rxsc_type_system = { .types = genl_macsec_rxsc_types, }; -static const NLType genl_macsec_sa_config_types[] = { +static const NLType genl_macsec_sa_types[] = { [MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 }, [MACSEC_SA_ATTR_ACTIVE] = { .type = NETLINK_TYPE_U8 }, [MACSEC_SA_ATTR_PN] = { .type = NETLINK_TYPE_U32 }, @@ -234,41 +224,31 @@ static const NLType genl_macsec_sa_config_types[] = { [MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN }, }; -static const NLTypeSystem genl_macsec_sa_config_type_system = { - .count = ELEMENTSOF(genl_macsec_sa_config_types), - .types = genl_macsec_sa_config_types, -}; - -static const NLType genl_macsec_rxsa_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, -}; - -static const NLTypeSystem genl_macsec_rxsa_type_system = { - .count = ELEMENTSOF(genl_macsec_rxsa_types), - .types = genl_macsec_rxsa_types, -}; - -static const NLType genl_macsec_sa_types[] = { - [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_rxsc_config_type_system }, - [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_config_type_system }, -}; - static const NLTypeSystem genl_macsec_sa_type_system = { .count = ELEMENTSOF(genl_macsec_sa_types), .types = genl_macsec_sa_types, }; -static const NLType genl_macsec[] = { - [MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system }, - [MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsa_type_system}, - [MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, +static const NLType genl_macsec_types[] = { + [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [MACSEC_ATTR_RXSC_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_rxsc_type_system }, + [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, }; -static const NLTypeSystem genl_macsec_device_type_system = { - .count = ELEMENTSOF(genl_macsec), - .types = genl_macsec, +static const NLTypeSystem genl_macsec_type_system = { + .count = ELEMENTSOF(genl_macsec_types), + .types = genl_macsec_types, +}; + +static const NLType genl_macsec_cmd_types[] = { + [MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, + [MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, + [MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, +}; + +static const NLTypeSystem genl_macsec_cmd_type_system = { + .count = ELEMENTSOF(genl_macsec_cmd_types), + .types = genl_macsec_cmd_types, }; /***************** genl nl80211 type systems *****************/ @@ -284,7 +264,7 @@ static const NLTypeSystem genl_nl80211_type_system = { .types = genl_nl80211_types, }; -static const NLType genl_nl80211_cmds[] = { +static const NLType genl_nl80211_cmd_types[] = { [NL80211_CMD_GET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, [NL80211_CMD_SET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, [NL80211_CMD_NEW_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, @@ -299,15 +279,15 @@ static const NLType genl_nl80211_cmds[] = { [NL80211_CMD_DEL_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, }; -static const NLTypeSystem genl_nl80211_cmds_type_system = { - .count = ELEMENTSOF(genl_nl80211_cmds), - .types = genl_nl80211_cmds, +static const NLTypeSystem genl_nl80211_cmd_type_system = { + .count = ELEMENTSOF(genl_nl80211_cmd_types), + .types = genl_nl80211_cmd_types, }; /***************** genl wireguard type systems *****************/ static const NLType genl_wireguard_allowedip_types[] = { - [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, - [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR }, + [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, + [WGALLOWEDIP_A_IPADDR] = { .type = NETLINK_TYPE_IN_ADDR }, [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 }, }; @@ -317,12 +297,12 @@ static const NLTypeSystem genl_wireguard_allowedip_type_system = { }; static const NLType genl_wireguard_peer_types[] = { - [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, - [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, - [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, + [WGPEER_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [WGPEER_A_PRESHARED_KEY] = { .size = WG_KEY_LEN }, [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NETLINK_TYPE_U16 }, - [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR }, - [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, + [WGPEER_A_ENDPOINT] = { .type = NETLINK_TYPE_SOCKADDR }, + [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, }; static const NLTypeSystem genl_wireguard_peer_type_system = { @@ -330,51 +310,52 @@ static const NLTypeSystem genl_wireguard_peer_type_system = { .types = genl_wireguard_peer_types, }; -static const NLType genl_wireguard_set_device_types[] = { - [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 }, - [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, +static const NLType genl_wireguard_types[] = { + [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ-1 }, + [WGDEVICE_A_FLAGS] = { .type = NETLINK_TYPE_U32 }, [WGDEVICE_A_PRIVATE_KEY] = { .size = WG_KEY_LEN }, [WGDEVICE_A_LISTEN_PORT] = { .type = NETLINK_TYPE_U16 }, - [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, - [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, -}; - -static const NLTypeSystem genl_wireguard_set_device_type_system = { - .count = ELEMENTSOF(genl_wireguard_set_device_types), - .types = genl_wireguard_set_device_types, -}; - -static const NLType genl_wireguard_cmds[] = { - [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_set_device_type_system }, + [WGDEVICE_A_FWMARK] = { .type = NETLINK_TYPE_U32 }, + [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, }; static const NLTypeSystem genl_wireguard_type_system = { - .count = ELEMENTSOF(genl_wireguard_cmds), - .types = genl_wireguard_cmds, + .count = ELEMENTSOF(genl_wireguard_types), + .types = genl_wireguard_types, }; +static const NLType genl_wireguard_cmd_types[] = { + [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, +}; + +static const NLTypeSystem genl_wireguard_cmd_type_system = { + .count = ELEMENTSOF(genl_wireguard_cmd_types), + .types = genl_wireguard_cmd_types, +}; + +/***************** genl families *****************/ static const NLType genl_families[] = { - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system }, - [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, - [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmds_type_system }, - [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_tunnel_session_type_system }, - [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_device_type_system }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmds_type_system }, - [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmds_type_system }, + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_cmd_type_system }, + [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_cmd_type_system }, + [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmd_type_system }, + [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_cmd_type_system }, + [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_cmd_type_system }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmd_type_system }, + [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmd_type_system }, }; /* Mainly used when sending message */ -const NLTypeSystem genl_family_type_system_root = { +const NLTypeSystem genl_family_type_system = { .count = ELEMENTSOF(genl_families), .types = genl_families, }; static const NLType genl_types[] = { - [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, [SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmd_type_system, .size = sizeof(struct genlmsghdr) }, }; /* Mainly used when message received */ diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 14a3c7417a..5e2a0efee9 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -35,7 +35,7 @@ typedef struct NLTypeSystemUnion NLTypeSystemUnion; typedef struct NLTypeSystem NLTypeSystem; typedef struct NLType NLType; -extern const NLTypeSystem genl_family_type_system_root; +extern const NLTypeSystem genl_family_type_system; int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret); int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret); From 9270ec60bcdbe6481cf7ab0f0b60a7afad6f932a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 15:11:02 +0900 Subject: [PATCH 12/29] sd-netlink: drop genl type system indexed by command All type systems of currently supported genl families do not depend on commands. Hence, at least tentatively, let's drop the tables. Note that type system for genl ethtool depends on commands. Let's reintroduce a mechanism to support the deps when we support ethtool on netlink. --- src/libsystemd/sd-netlink/netlink-genl.c | 14 +-- .../sd-netlink/netlink-types-genl.c | 101 ++---------------- 2 files changed, 11 insertions(+), 104 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 9330d66fe2..d8a628a683 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -29,8 +29,7 @@ int sd_genl_socket_open(sd_netlink **ret) { static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nlmsg_type, uint8_t cmd, sd_netlink_message **ret) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - const NLType *genl_cmd_type, *nl_type; - const NLTypeSystem *type_system; + const NLType *type; size_t size; int r; @@ -38,7 +37,7 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl assert(nl->protocol == NETLINK_GENERIC); assert(ret); - r = type_system_get_type(&genl_family_type_system, &genl_cmd_type, family); + r = type_system_get_type(&genl_family_type_system, &type, family); if (r < 0) return r; @@ -52,17 +51,10 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl return -ENOMEM; m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - - type_system = type_get_type_system(genl_cmd_type); - - r = type_system_get_type(type_system, &nl_type, cmd); - if (r < 0) - return r; - m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = nlmsg_type; - m->containers[0].type_system = type_get_type_system(nl_type); + m->containers[0].type_system = type_get_type_system(type); *(struct genlmsghdr *) NLMSG_DATA(m->hdr) = (struct genlmsghdr) { .cmd = cmd, diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index a88609c0be..7259d240fa 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -36,15 +36,6 @@ static const NLTypeSystem genl_ctrl_type_system = { .types = genl_ctrl_types, }; -static const NLType genl_ctrl_cmd_types[] = { - [CTRL_CMD_GETFAMILY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, }, -}; - -static const NLTypeSystem genl_ctrl_cmd_type_system = { - .count = ELEMENTSOF(genl_ctrl_cmd_types), - .types = genl_ctrl_cmd_types, -}; - /***************** genl batadv type systems *****************/ static const NLType genl_batadv_types[] = { [BATADV_ATTR_VERSION] = { .type = NETLINK_TYPE_STRING }, @@ -114,15 +105,6 @@ static const NLTypeSystem genl_batadv_type_system = { .types = genl_batadv_types, }; -static const NLType genl_batadv_cmd_types[] = { - [BATADV_CMD_SET_MESH] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, -}; - -static const NLTypeSystem genl_batadv_cmd_type_system = { - .count = ELEMENTSOF(genl_batadv_cmd_types), - .types = genl_batadv_cmd_types, -}; - /***************** genl fou type systems *****************/ static const NLType genl_fou_types[] = { [FOU_ATTR_PORT] = { .type = NETLINK_TYPE_U16 }, @@ -143,17 +125,6 @@ static const NLTypeSystem genl_fou_type_system = { .types = genl_fou_types, }; -static const NLType genl_fou_cmd_types[] = { - [FOU_CMD_ADD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, - [FOU_CMD_DEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, - [FOU_CMD_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, -}; - -static const NLTypeSystem genl_fou_cmd_type_system = { - .count = ELEMENTSOF(genl_fou_cmd_types), - .types = genl_fou_cmd_types, -}; - /***************** genl l2tp type systems *****************/ static const NLType genl_l2tp_types[] = { [L2TP_ATTR_PW_TYPE] = { .type = NETLINK_TYPE_U16 }, @@ -190,22 +161,6 @@ static const NLTypeSystem genl_l2tp_type_system = { .types = genl_l2tp_types, }; -static const NLType genl_l2tp_cmd_types[] = { - [L2TP_CMD_TUNNEL_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_TUNNEL_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_CREATE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_DELETE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_MODIFY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [L2TP_CMD_SESSION_GET] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, -}; - -static const NLTypeSystem genl_l2tp_cmd_type_system = { - .count = ELEMENTSOF(genl_l2tp_cmd_types), - .types = genl_l2tp_cmd_types, -}; - /***************** genl macsec type systems *****************/ static const NLType genl_macsec_rxsc_types[] = { [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, @@ -240,17 +195,6 @@ static const NLTypeSystem genl_macsec_type_system = { .types = genl_macsec_types, }; -static const NLType genl_macsec_cmd_types[] = { - [MACSEC_CMD_ADD_RXSC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, - [MACSEC_CMD_ADD_TXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, - [MACSEC_CMD_ADD_RXSA] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, -}; - -static const NLTypeSystem genl_macsec_cmd_type_system = { - .count = ELEMENTSOF(genl_macsec_cmd_types), - .types = genl_macsec_cmd_types, -}; - /***************** genl nl80211 type systems *****************/ static const NLType genl_nl80211_types[] = { [NL80211_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, @@ -264,26 +208,6 @@ static const NLTypeSystem genl_nl80211_type_system = { .types = genl_nl80211_types, }; -static const NLType genl_nl80211_cmd_types[] = { - [NL80211_CMD_GET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_WIPHY] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_GET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_INTERFACE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_GET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_SET_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_NEW_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [NL80211_CMD_DEL_STATION] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, -}; - -static const NLTypeSystem genl_nl80211_cmd_type_system = { - .count = ELEMENTSOF(genl_nl80211_cmd_types), - .types = genl_nl80211_cmd_types, -}; - /***************** genl wireguard type systems *****************/ static const NLType genl_wireguard_allowedip_types[] = { [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, @@ -325,24 +249,15 @@ static const NLTypeSystem genl_wireguard_type_system = { .types = genl_wireguard_types, }; -static const NLType genl_wireguard_cmd_types[] = { - [WG_CMD_SET_DEVICE] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, -}; - -static const NLTypeSystem genl_wireguard_cmd_type_system = { - .count = ELEMENTSOF(genl_wireguard_cmd_types), - .types = genl_wireguard_cmd_types, -}; - /***************** genl families *****************/ static const NLType genl_families[] = { - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_cmd_type_system }, - [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_cmd_type_system }, - [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_cmd_type_system }, - [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_cmd_type_system }, - [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_cmd_type_system }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmd_type_system }, - [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_cmd_type_system }, + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system }, + [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, + [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, + [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, + [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, + [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, }; /* Mainly used when sending message */ @@ -355,7 +270,7 @@ static const NLType genl_types[] = { [SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_cmd_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, }; /* Mainly used when message received */ From d757e6bdf0934466580f0c099c1ea7889904db5f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 15:27:56 +0900 Subject: [PATCH 13/29] sd-netlink: unify two spurious type system root for genl --- src/libsystemd/sd-netlink/netlink-genl.c | 2 +- .../sd-netlink/netlink-types-genl.c | 42 +++++-------------- src/libsystemd/sd-netlink/netlink-types.h | 2 - 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index d8a628a683..06406add49 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -37,7 +37,7 @@ static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nl assert(nl->protocol == NETLINK_GENERIC); assert(ret); - r = type_system_get_type(&genl_family_type_system, &type, family); + r = type_system_root_get_type(nl, &type, nlmsg_type); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index 7259d240fa..10d073f325 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -250,30 +250,18 @@ static const NLTypeSystem genl_wireguard_type_system = { }; /***************** genl families *****************/ -static const NLType genl_families[] = { - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system }, - [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system }, - [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system }, - [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system }, - [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system }, - [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system }, -}; - -/* Mainly used when sending message */ -const NLTypeSystem genl_family_type_system = { - .count = ELEMENTSOF(genl_families), - .types = genl_families, -}; - static const NLType genl_types[] = { - [SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, - [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, + [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system, .size = sizeof(struct genlmsghdr) }, }; -/* Mainly used when message received */ static const NLTypeSystem genl_type_system = { .count = ELEMENTSOF(genl_types), .types = genl_types, @@ -281,21 +269,11 @@ static const NLTypeSystem genl_type_system = { int genl_get_type(sd_netlink *genl, uint16_t nlmsg_type, const NLType **ret) { sd_genl_family_t family; - const NLType *nl_type; int r; r = nlmsg_type_to_genl_family(genl, nlmsg_type, &family); if (r < 0) return r; - if (family >= genl_type_system.count) - return -EOPNOTSUPP; - - nl_type = &genl_type_system.types[family]; - - if (nl_type->type == NETLINK_TYPE_UNSPEC) - return -EOPNOTSUPP; - - *ret = nl_type; - return 0; + return type_system_get_type(&genl_type_system, ret, family); } diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 5e2a0efee9..baab1dbdb0 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -35,8 +35,6 @@ typedef struct NLTypeSystemUnion NLTypeSystemUnion; typedef struct NLTypeSystem NLTypeSystem; typedef struct NLType NLType; -extern const NLTypeSystem genl_family_type_system; - int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret); int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret); int genl_get_type(sd_netlink *genl, uint16_t nlmsg_type, const NLType **ret); From aee6309b975fac5b8ef08934b05e7d4e5afa966a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 15:40:17 +0900 Subject: [PATCH 14/29] sd-netlink: introduce basic_type_system Preparation for later commits. --- src/libsystemd/sd-netlink/netlink-message.c | 6 +++--- src/libsystemd/sd-netlink/netlink-types-genl.c | 2 -- .../sd-netlink/netlink-types-internal.h | 3 --- src/libsystemd/sd-netlink/netlink-types-nfnl.c | 2 -- src/libsystemd/sd-netlink/netlink-types-rtnl.c | 2 -- src/libsystemd/sd-netlink/netlink-types.c | 18 ++++++++++++++---- src/libsystemd/sd-netlink/test-netlink.c | 8 ++++---- src/systemd/sd-netlink.h | 2 +- 8 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 169e9cd957..fe4c2950c1 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -1302,14 +1302,14 @@ static int netlink_message_parse_error(sd_netlink_message *m) { NLMSG_PAYLOAD(m->hdr, hlen)); } -int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) { +int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *nl) { const NLType *nl_type; uint16_t type; size_t size; int r; assert_return(m, -EINVAL); - assert_return(genl || m->protocol != NETLINK_GENERIC, -EINVAL); + assert_return(nl, -EINVAL); /* don't allow appending to message once parsed */ message_seal(m); @@ -1325,7 +1325,7 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) { assert(m->hdr); - r = type_system_root_get_type(genl, &nl_type, m->hdr->nlmsg_type); + r = type_system_root_get_type(nl, &nl_type, m->hdr->nlmsg_type); if (r < 0) return r; diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index 10d073f325..4af1c71c2f 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -251,8 +251,6 @@ static const NLTypeSystem genl_wireguard_type_system = { /***************** genl families *****************/ static const NLType genl_types[] = { - [SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, - [SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system, .size = sizeof(struct genlmsghdr) }, [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system, .size = sizeof(struct genlmsghdr) }, diff --git a/src/libsystemd/sd-netlink/netlink-types-internal.h b/src/libsystemd/sd-netlink/netlink-types-internal.h index 66a25a4dfb..2bd42a12f8 100644 --- a/src/libsystemd/sd-netlink/netlink-types-internal.h +++ b/src/libsystemd/sd-netlink/netlink-types-internal.h @@ -24,9 +24,6 @@ struct NLTypeSystemUnion { const NLTypeSystem *type_systems; }; -extern const NLTypeSystem empty_type_system; -extern const NLTypeSystem error_type_system; - typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_BOND, NL_UNION_LINK_INFO_DATA_BRIDGE, diff --git a/src/libsystemd/sd-netlink/netlink-types-nfnl.c b/src/libsystemd/sd-netlink/netlink-types-nfnl.c index ba6c076e39..0c54f83d11 100644 --- a/src/libsystemd/sd-netlink/netlink-types-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-nfnl.c @@ -234,8 +234,6 @@ static const NLTypeSystem nfnl_msg_batch_type_system = { }; static const NLType nfnl_types[] = { - [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, - [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, [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) }, diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index 7f7f4150b6..8f0b766440 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -1008,8 +1008,6 @@ static const NLTypeSystem rtnl_mdb_type_system = { }; static const NLType rtnl_types[] = { - [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, - [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 83ba725fd8..d5a4a017c4 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -9,7 +9,7 @@ static const NLType empty_types[1] = { /* fake array to avoid .types==NULL, which denotes invalid type-systems */ }; -const NLTypeSystem empty_type_system = { +static const NLTypeSystem empty_type_system = { .count = 0, .types = empty_types, }; @@ -19,11 +19,21 @@ static const NLType error_types[] = { [NLMSGERR_ATTR_OFFS] = { .type = NETLINK_TYPE_U32 }, }; -const NLTypeSystem error_type_system = { +static const NLTypeSystem error_type_system = { .count = ELEMENTSOF(error_types), .types = error_types, }; +static const NLType basic_types[] = { + [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, + [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, +}; + +const NLTypeSystem basic_type_system = { + .count = ELEMENTSOF(basic_types), + .types = basic_types, +}; + uint16_t type_get_type(const NLType *type) { assert(type); return type->type; @@ -54,8 +64,8 @@ uint16_t type_system_get_count(const NLTypeSystem *type_system) { } int type_system_root_get_type(sd_netlink *nl, const NLType **ret, uint16_t type) { - if (!nl) - return rtnl_get_type(type, ret); + if (!nl || IN_SET(type, NLMSG_DONE, NLMSG_ERROR)) + return type_system_get_type(&basic_type_system, ret, type); switch(nl->protocol) { case NETLINK_ROUTE: diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 1076ec55a4..a87fe11069 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -29,7 +29,7 @@ static void test_message_link_bridge(sd_netlink *rtnl) { assert_se(sd_netlink_message_append_u32(message, IFLA_BRPORT_COST, 10) >= 0); assert_se(sd_netlink_message_close_container(message) >= 0); - assert_se(sd_netlink_message_rewind(message, NULL) >= 0); + assert_se(sd_netlink_message_rewind(message, rtnl) >= 0); assert_se(sd_netlink_message_enter_container(message, IFLA_PROTINFO) >= 0); assert_se(sd_netlink_message_read_u32(message, IFLA_BRPORT_COST, &cost) >= 0); @@ -131,7 +131,7 @@ static void test_route(sd_netlink *rtnl) { return; } - assert_se(sd_netlink_message_rewind(req, NULL) >= 0); + assert_se(sd_netlink_message_rewind(req, rtnl) >= 0); assert_se(sd_netlink_message_read_in_addr(req, RTA_GATEWAY, &addr_data) >= 0); assert_se(addr_data.s_addr == addr.s_addr); @@ -431,7 +431,7 @@ static void test_container(sd_netlink *rtnl) { assert_se(sd_netlink_message_close_container(m) >= 0); assert_se(sd_netlink_message_close_container(m) == -EINVAL); - assert_se(sd_netlink_message_rewind(m, NULL) >= 0); + assert_se(sd_netlink_message_rewind(m, rtnl) >= 0); assert_se(sd_netlink_message_enter_container(m, IFLA_LINKINFO) >= 0); assert_se(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0); @@ -571,7 +571,7 @@ static void test_strv(sd_netlink *rtnl) { assert_se(sd_netlink_message_close_container(m) >= 0); message_seal(m); - assert_se(sd_netlink_message_rewind(m, NULL) >= 0); + assert_se(sd_netlink_message_rewind(m, rtnl) >= 0); assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0); assert_se(strv_equal(names_in, names_out)); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index f2f2541284..c513d26071 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -128,7 +128,7 @@ int sd_netlink_message_exit_container(sd_netlink_message *m); int sd_netlink_message_open_array(sd_netlink_message *m, uint16_t type); int sd_netlink_message_cancel_array(sd_netlink_message *m); -int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl); +int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *nl); sd_netlink_message *sd_netlink_message_next(sd_netlink_message *m); From 1370925bc770d94ce27533fbf5dc2e7595c7c54a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 29 Jun 2021 17:26:19 +0900 Subject: [PATCH 15/29] basic: copy genetlink.h to repository --- src/basic/linux/genetlink.h | 102 ++++++++++++++++++++++++++++++++++++ src/basic/meson.build | 1 + 2 files changed, 103 insertions(+) create mode 100644 src/basic/linux/genetlink.h diff --git a/src/basic/linux/genetlink.h b/src/basic/linux/genetlink.h new file mode 100644 index 0000000000..d83f214b41 --- /dev/null +++ b/src/basic/linux/genetlink.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI__LINUX_GENERIC_NETLINK_H +#define _UAPI__LINUX_GENERIC_NETLINK_H + +#include +#include + +#define GENL_NAMSIZ 16 /* length of family name */ + +#define GENL_MIN_ID NLMSG_MIN_TYPE +#define GENL_MAX_ID 1023 + +struct genlmsghdr { + __u8 cmd; + __u8 version; + __u16 reserved; +}; + +#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr)) + +#define GENL_ADMIN_PERM 0x01 +#define GENL_CMD_CAP_DO 0x02 +#define GENL_CMD_CAP_DUMP 0x04 +#define GENL_CMD_CAP_HASPOL 0x08 +#define GENL_UNS_ADMIN_PERM 0x10 + +/* + * List of reserved static generic netlink identifiers: + */ +#define GENL_ID_CTRL NLMSG_MIN_TYPE +#define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) +#define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) +/* must be last reserved + 1 */ +#define GENL_START_ALLOC (NLMSG_MIN_TYPE + 3) + +/************************************************************************** + * Controller + **************************************************************************/ + +enum { + CTRL_CMD_UNSPEC, + CTRL_CMD_NEWFAMILY, + CTRL_CMD_DELFAMILY, + CTRL_CMD_GETFAMILY, + CTRL_CMD_NEWOPS, + CTRL_CMD_DELOPS, + CTRL_CMD_GETOPS, + CTRL_CMD_NEWMCAST_GRP, + CTRL_CMD_DELMCAST_GRP, + CTRL_CMD_GETMCAST_GRP, /* unused */ + CTRL_CMD_GETPOLICY, + __CTRL_CMD_MAX, +}; + +#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1) + +enum { + CTRL_ATTR_UNSPEC, + CTRL_ATTR_FAMILY_ID, + CTRL_ATTR_FAMILY_NAME, + CTRL_ATTR_VERSION, + CTRL_ATTR_HDRSIZE, + CTRL_ATTR_MAXATTR, + CTRL_ATTR_OPS, + CTRL_ATTR_MCAST_GROUPS, + CTRL_ATTR_POLICY, + CTRL_ATTR_OP_POLICY, + CTRL_ATTR_OP, + __CTRL_ATTR_MAX, +}; + +#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1) + +enum { + CTRL_ATTR_OP_UNSPEC, + CTRL_ATTR_OP_ID, + CTRL_ATTR_OP_FLAGS, + __CTRL_ATTR_OP_MAX, +}; + +#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1) + +enum { + CTRL_ATTR_MCAST_GRP_UNSPEC, + CTRL_ATTR_MCAST_GRP_NAME, + CTRL_ATTR_MCAST_GRP_ID, + __CTRL_ATTR_MCAST_GRP_MAX, +}; + +enum { + CTRL_ATTR_POLICY_UNSPEC, + CTRL_ATTR_POLICY_DO, + CTRL_ATTR_POLICY_DUMP, + + __CTRL_ATTR_POLICY_DUMP_MAX, + CTRL_ATTR_POLICY_DUMP_MAX = __CTRL_ATTR_POLICY_DUMP_MAX - 1 +}; + +#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1) + + +#endif /* _UAPI__LINUX_GENERIC_NETLINK_H */ diff --git a/src/basic/meson.build b/src/basic/meson.build index 666537868b..6d755ab646 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -83,6 +83,7 @@ basic_sources = files(''' linux/can/vxcan.h linux/fib_rules.h linux/fou.h + linux/genetlink.h linux/hdlc/ioctl.h linux/if.h linux/if_addr.h From 9a9c8f3fcc9654b1e211bf4d4b0d895381649a41 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 15:51:33 +0900 Subject: [PATCH 16/29] sd-netlink: add several missing attributes --- .../sd-netlink/netlink-types-genl.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index 4af1c71c2f..c39db47b19 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -25,10 +25,29 @@ static const NLTypeSystem genl_ctrl_mcast_group_type_system = { .types = genl_ctrl_mcast_group_types, }; +static const NLType genl_ctrl_ops_types[] = { + [CTRL_ATTR_OP_ID] = { .type = NETLINK_TYPE_U32 }, + [CTRL_ATTR_OP_FLAGS] = { .type = NETLINK_TYPE_U32 }, +}; + +static const NLTypeSystem genl_ctrl_ops_type_system = { + .count = ELEMENTSOF(genl_ctrl_ops_types), + .types = genl_ctrl_ops_types, +}; + static const NLType genl_ctrl_types[] = { [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING }, + [CTRL_ATTR_VERSION] = { .type = NETLINK_TYPE_U32 }, + [CTRL_ATTR_HDRSIZE] = { .type = NETLINK_TYPE_U32 }, + [CTRL_ATTR_MAXATTR] = { .type = NETLINK_TYPE_U32 }, + [CTRL_ATTR_OPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_ops_type_system }, [CTRL_ATTR_MCAST_GROUPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_mcast_group_type_system }, + /* + [CTRL_ATTR_POLICY] = { .type = NETLINK_TYPE_NESTED, }, + [CTRL_ATTR_OP_POLICY] = { .type = NETLINK_TYPE_NESTED, } + */ + [CTRL_ATTR_OP] = { .type = NETLINK_TYPE_U32 }, }; static const NLTypeSystem genl_ctrl_type_system = { From c08ab4a013e96151dea9639f2fc90de504f526b7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 3 Jul 2021 12:38:52 +0900 Subject: [PATCH 17/29] sd-netlink: wrap long function declarations --- .../sd-netlink/netlink-message-nfnl.c | 90 ++++++++++++++----- 1 file changed, 67 insertions(+), 23 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-message-nfnl.c b/src/libsystemd/sd-netlink/netlink-message-nfnl.c index e55b480402..03f70f606f 100644 --- a/src/libsystemd/sd-netlink/netlink-message-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-nfnl.c @@ -90,11 +90,16 @@ int sd_nfnl_message_batch_end(sd_netlink *nfnl, sd_netlink_message **ret) { return nfnl_message_batch(nfnl, ret, NFNL_MSG_BATCH_END); } -int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret, - int family, - const char *table, const char *chain, - const char *type, - uint8_t hook, int prio) { +int sd_nfnl_nft_message_new_basechain( + sd_netlink *nfnl, + sd_netlink_message **ret, + int family, + const char *table, + const char *chain, + const char *type, + uint8_t hook, + int prio) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -134,8 +139,12 @@ int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret return 0; } -int sd_nfnl_nft_message_del_table(sd_netlink *nfnl, sd_netlink_message **ret, - int family, const char *table) { +int sd_nfnl_nft_message_del_table( + sd_netlink *nfnl, + sd_netlink_message **ret, + int family, + const char *table) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -151,8 +160,13 @@ int sd_nfnl_nft_message_del_table(sd_netlink *nfnl, sd_netlink_message **ret, return r; } -int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret, - int family, const char *table, uint16_t flags) { +int sd_nfnl_nft_message_new_table( + sd_netlink *nfnl, + sd_netlink_message **ret, + int family, + const char *table, + uint16_t flags) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -168,8 +182,13 @@ int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret, return r; } -int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret, - int family, const char *table, const char *chain) { +int sd_nfnl_nft_message_new_rule( + sd_netlink *nfnl, + sd_netlink_message **ret, + int family, + const char *table, + const char *chain) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -189,9 +208,15 @@ int sd_nfnl_nft_message_new_rule(sd_netlink *nfnl, sd_netlink_message **ret, return r; } -int sd_nfnl_nft_message_new_set(sd_netlink *nfnl, sd_netlink_message **ret, - int family, const char *table, const char *set_name, - uint32_t set_id, uint32_t klen) { +int sd_nfnl_nft_message_new_set( + sd_netlink *nfnl, + sd_netlink_message **ret, + int family, + const char *table, + const char *set_name, + uint32_t set_id, + uint32_t klen) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -214,12 +239,18 @@ int sd_nfnl_nft_message_new_set(sd_netlink *nfnl, sd_netlink_message **ret, r = sd_netlink_message_append_u32(m, NFTA_SET_KEY_LEN, htobe32(klen)); if (r < 0) return r; + *ret = TAKE_PTR(m); return r; } -int sd_nfnl_nft_message_new_setelems_begin(sd_netlink *nfnl, sd_netlink_message **ret, - int family, const char *table, const char *set_name) { +int sd_nfnl_nft_message_new_setelems_begin( + sd_netlink *nfnl, + sd_netlink_message **ret, + int family, + const char *table, + const char *set_name) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -243,8 +274,13 @@ int sd_nfnl_nft_message_new_setelems_begin(sd_netlink *nfnl, sd_netlink_message return r; } -int sd_nfnl_nft_message_del_setelems_begin(sd_netlink *nfnl, sd_netlink_message **ret, - int family, const char *table, const char *set_name) { +int sd_nfnl_nft_message_del_setelems_begin( + sd_netlink *nfnl, + sd_netlink_message **ret, + int family, + const char *table, + const char *set_name) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; int r; @@ -269,7 +305,9 @@ int sd_nfnl_nft_message_del_setelems_begin(sd_netlink *nfnl, sd_netlink_message } static int sd_nfnl_add_data(sd_netlink_message *m, uint16_t attr, const void *data, uint32_t dlen) { - int r = sd_netlink_message_open_container(m, attr); + int r; + + r = sd_netlink_message_open_container(m, attr); if (r < 0) return r; @@ -280,9 +318,14 @@ static int sd_nfnl_add_data(sd_netlink_message *m, uint16_t attr, const void *da return sd_netlink_message_close_container(m); /* attr */ } -int sd_nfnl_nft_message_add_setelem(sd_netlink_message *m, uint32_t num, - const void *key, uint32_t klen, - const void *data, uint32_t dlen) { +int sd_nfnl_nft_message_add_setelem( + sd_netlink_message *m, + uint32_t num, + const void *key, + uint32_t klen, + const void *data, + uint32_t dlen) { + int r; r = sd_netlink_message_open_array(m, num); @@ -299,7 +342,8 @@ int sd_nfnl_nft_message_add_setelem(sd_netlink_message *m, uint32_t num, goto cancel; } - return r; + return 0; + cancel: sd_netlink_message_cancel_array(m); return r; From 07acd0d90b34d452b31492239fcaac6faad45acb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 3 Jul 2021 12:42:08 +0900 Subject: [PATCH 18/29] sd-netlink: drop 'flags' argument from sd_nfnl_nft_message_new_table() --- src/libsystemd/sd-netlink/netlink-message-nfnl.c | 5 ++--- src/shared/firewall-util-nft.c | 2 +- src/systemd/sd-netlink.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-message-nfnl.c b/src/libsystemd/sd-netlink/netlink-message-nfnl.c index 03f70f606f..ffcffb82f8 100644 --- a/src/libsystemd/sd-netlink/netlink-message-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-nfnl.c @@ -164,13 +164,12 @@ int sd_nfnl_nft_message_new_table( sd_netlink *nfnl, sd_netlink_message **ret, int family, - const char *table, - uint16_t flags) { + const char *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 | flags); + r = nft_message_new(nfnl, &m, family, NFT_MSG_NEWTABLE, NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); if (r < 0) return r; diff --git a/src/shared/firewall-util-nft.c b/src/shared/firewall-util-nft.c index e68978d777..d6beaf20d8 100644 --- a/src/shared/firewall-util-nft.c +++ b/src/shared/firewall-util-nft.c @@ -649,7 +649,7 @@ static int fw_nftables_init_family(sd_netlink *nfnl, int family) { msgcnt++; assert(msgcnt < NFT_INIT_MSGS); /* Set F_EXCL so table add fails if the table already exists. */ - r = sd_nfnl_nft_message_new_table(nfnl, &batch[msgcnt], family, NFT_SYSTEMD_TABLE_NAME, NLM_F_EXCL | NLM_F_ACK); + r = sd_nfnl_nft_message_new_table(nfnl, &batch[msgcnt], family, NFT_SYSTEMD_TABLE_NAME); if (r < 0) goto out_unref; diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index c513d26071..c67ea87540 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -229,7 +229,7 @@ int sd_nfnl_message_batch_end(sd_netlink *nfnl, sd_netlink_message **ret); int sd_nfnl_nft_message_del_table(sd_netlink *nfnl, sd_netlink_message **ret, int family, const char *table); int sd_nfnl_nft_message_new_table(sd_netlink *nfnl, sd_netlink_message **ret, - int family, const char *table, uint16_t nl_flags); + int family, const char *table); int sd_nfnl_nft_message_new_basechain(sd_netlink *nfnl, sd_netlink_message **ret, int family, const char *table, const char *chain, const char *type, uint8_t hook, int prio); From fae9ee25a4999633a7adfa941d0c49ce95e3e8c0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 16:10:49 +0900 Subject: [PATCH 19/29] 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. --- .../sd-netlink/netlink-message-nfnl.c | 54 +++++-------------- .../sd-netlink/netlink-types-nfnl.c | 30 ++++++++--- 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-message-nfnl.c b/src/libsystemd/sd-netlink/netlink-message-nfnl.c index ffcffb82f8..9b24f74042 100644 --- a/src/libsystemd/sd-netlink/netlink-message-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-message-nfnl.c @@ -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; diff --git a/src/libsystemd/sd-netlink/netlink-types-nfnl.c b/src/libsystemd/sd-netlink/netlink-types-nfnl.c index 0c54f83d11..dbc55c4782 100644 --- a/src/libsystemd/sd-netlink/netlink-types-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-nfnl.c @@ -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)); } From e6dd2989358b22bdddc8e4a79c9c1ec45c84f14c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 16:39:38 +0900 Subject: [PATCH 20/29] sd-netlink: drop redundant string table lookup functions to handle type system union --- .../sd-netlink/netlink-types-internal.h | 92 +----- .../sd-netlink/netlink-types-nfnl.c | 60 ++-- .../sd-netlink/netlink-types-rtnl.c | 310 +++++++++--------- src/libsystemd/sd-netlink/netlink-types.c | 36 +- 4 files changed, 201 insertions(+), 297 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-types-internal.h b/src/libsystemd/sd-netlink/netlink-types-internal.h index 2bd42a12f8..adbc189c88 100644 --- a/src/libsystemd/sd-netlink/netlink-types-internal.h +++ b/src/libsystemd/sd-netlink/netlink-types-internal.h @@ -16,89 +16,17 @@ struct NLTypeSystem { const NLType *types; }; +typedef struct NLTypeSystemUnionElement { + union { + int protocol; + const char *name; + }; + NLTypeSystem type_system; +} NLTypeSystemUnionElement; + struct NLTypeSystemUnion { - int num; + size_t count; + const NLTypeSystemUnionElement *elements; NLMatchType match_type; uint16_t match_attribute; - int (*lookup)(const char *); - const NLTypeSystem *type_systems; }; - -typedef enum NLUnionLinkInfoData { - NL_UNION_LINK_INFO_DATA_BOND, - NL_UNION_LINK_INFO_DATA_BRIDGE, - NL_UNION_LINK_INFO_DATA_VLAN, - NL_UNION_LINK_INFO_DATA_VETH, - NL_UNION_LINK_INFO_DATA_DUMMY, - NL_UNION_LINK_INFO_DATA_MACVLAN, - NL_UNION_LINK_INFO_DATA_MACVTAP, - NL_UNION_LINK_INFO_DATA_IPVLAN, - NL_UNION_LINK_INFO_DATA_IPVTAP, - NL_UNION_LINK_INFO_DATA_VXLAN, - NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL, - NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL, - NL_UNION_LINK_INFO_DATA_ERSPAN, - NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL, - NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL, - NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL, - NL_UNION_LINK_INFO_DATA_SIT_TUNNEL, - NL_UNION_LINK_INFO_DATA_VTI_TUNNEL, - NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL, - NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL, - NL_UNION_LINK_INFO_DATA_VRF, - NL_UNION_LINK_INFO_DATA_VCAN, - NL_UNION_LINK_INFO_DATA_GENEVE, - NL_UNION_LINK_INFO_DATA_VXCAN, - NL_UNION_LINK_INFO_DATA_WIREGUARD, - NL_UNION_LINK_INFO_DATA_NETDEVSIM, - NL_UNION_LINK_INFO_DATA_CAN, - NL_UNION_LINK_INFO_DATA_MACSEC, - NL_UNION_LINK_INFO_DATA_NLMON, - NL_UNION_LINK_INFO_DATA_XFRM, - NL_UNION_LINK_INFO_DATA_IFB, - NL_UNION_LINK_INFO_DATA_BAREUDP, - NL_UNION_LINK_INFO_DATA_BATADV, - _NL_UNION_LINK_INFO_DATA_MAX, - _NL_UNION_LINK_INFO_DATA_INVALID = -EINVAL, -} NLUnionLinkInfoData; - -const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_; -NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_; - -typedef enum NLUnionTCAOptionData { - NL_UNION_TCA_OPTION_DATA_CAKE, - NL_UNION_TCA_OPTION_DATA_CODEL, - NL_UNION_TCA_OPTION_DATA_DRR, - NL_UNION_TCA_OPTION_DATA_ETS, - NL_UNION_TCA_OPTION_DATA_FQ, - NL_UNION_TCA_OPTION_DATA_FQ_CODEL, - NL_UNION_TCA_OPTION_DATA_FQ_PIE, - NL_UNION_TCA_OPTION_DATA_GRED, - NL_UNION_TCA_OPTION_DATA_HHF, - NL_UNION_TCA_OPTION_DATA_HTB, - NL_UNION_TCA_OPTION_DATA_PIE, - NL_UNION_TCA_OPTION_DATA_QFQ, - NL_UNION_TCA_OPTION_DATA_SFB, - NL_UNION_TCA_OPTION_DATA_TBF, - _NL_UNION_TCA_OPTION_DATA_MAX, - _NL_UNION_TCA_OPTION_DATA_INVALID = -EINVAL, -} NLUnionTCAOptionData; - -const char *nl_union_tca_option_data_to_string(NLUnionTCAOptionData p) _const_; -NLUnionTCAOptionData nl_union_tca_option_data_from_string(const char *p) _pure_; - -typedef enum NLUnionNFTExprData { - NL_UNION_NFT_EXPR_DATA_BITWISE, - NL_UNION_NFT_EXPR_DATA_CMP, - NL_UNION_NFT_EXPR_DATA_FIB, - NL_UNION_NFT_EXPR_DATA_LOOKUP, - NL_UNION_NFT_EXPR_DATA_PAYLOAD, - NL_UNION_NFT_EXPR_DATA_MASQ, - NL_UNION_NFT_EXPR_DATA_META, - NL_UNION_NFT_EXPR_DATA_NAT, - _NL_UNION_NFT_EXPR_DATA_MAX, - _NL_UNION_NFT_EXPR_DATA_INVALID = -EINVAL, -} NLUnionNFTExprData; - -const char *nl_union_nft_expr_data_to_string(NLUnionNFTExprData p) _const_; -NLUnionNFTExprData nl_union_nft_expr_data_from_string(const char *p) _pure_; diff --git a/src/libsystemd/sd-netlink/netlink-types-nfnl.c b/src/libsystemd/sd-netlink/netlink-types-nfnl.c index dbc55c4782..799e80fe32 100644 --- a/src/libsystemd/sd-netlink/netlink-types-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-nfnl.c @@ -108,42 +108,36 @@ static const NLType nfnl_nft_expr_masq_types[] = { [NFTA_MASQ_REG_PROTO_MAX] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem nfnl_expr_data_type_systems[] = { - [NL_UNION_NFT_EXPR_DATA_BITWISE] = { .count = ELEMENTSOF(nfnl_nft_expr_bitwise_types), - .types = nfnl_nft_expr_bitwise_types }, - [NL_UNION_NFT_EXPR_DATA_CMP] = { .count = ELEMENTSOF(nfnl_nft_expr_cmp_types), - .types = nfnl_nft_expr_cmp_types }, - [NL_UNION_NFT_EXPR_DATA_FIB] = { .count = ELEMENTSOF(nfnl_nft_expr_fib_types), - .types = nfnl_nft_expr_fib_types }, - [NL_UNION_NFT_EXPR_DATA_LOOKUP] = { .count = ELEMENTSOF(nfnl_nft_expr_lookup_types), - .types = nfnl_nft_expr_lookup_types }, - [NL_UNION_NFT_EXPR_DATA_MASQ] = { .count = ELEMENTSOF(nfnl_nft_expr_masq_types), - .types = nfnl_nft_expr_masq_types }, - [NL_UNION_NFT_EXPR_DATA_META] = { .count = ELEMENTSOF(nfnl_nft_expr_meta_types), - .types = nfnl_nft_expr_meta_types }, - [NL_UNION_NFT_EXPR_DATA_NAT] = { .count = ELEMENTSOF(nfnl_nft_expr_nat_types), - .types = nfnl_nft_expr_nat_types }, - [NL_UNION_NFT_EXPR_DATA_PAYLOAD] = { .count = ELEMENTSOF(nfnl_nft_expr_payload_types), - .types = nfnl_nft_expr_payload_types }, +static const NLTypeSystemUnionElement nfnl_expr_data_type_systems[] = { + { .name = "bitwise", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_bitwise_types), + .types = nfnl_nft_expr_bitwise_types } }, + { .name = "cmp", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_cmp_types), + .types = nfnl_nft_expr_cmp_types } }, + { .name = "fib", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_fib_types), + .types = nfnl_nft_expr_fib_types } }, + { .name = "lookup", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_lookup_types), + .types = nfnl_nft_expr_lookup_types } }, + { .name = "masq", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_masq_types), + .types = nfnl_nft_expr_masq_types } }, + { .name = "meta", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_meta_types), + .types = nfnl_nft_expr_meta_types } }, + { .name = "nat", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_nat_types), + .types = nfnl_nft_expr_nat_types } }, + { .name = "payload", .type_system = { + .count = ELEMENTSOF(nfnl_nft_expr_payload_types), + .types = nfnl_nft_expr_payload_types } }, }; -static const char* const nl_union_nft_expr_data_table[] = { - [NL_UNION_NFT_EXPR_DATA_BITWISE] = "bitwise", - [NL_UNION_NFT_EXPR_DATA_CMP] = "cmp", - [NL_UNION_NFT_EXPR_DATA_LOOKUP] = "lookup", - [NL_UNION_NFT_EXPR_DATA_META] = "meta", - [NL_UNION_NFT_EXPR_DATA_FIB] = "fib", - [NL_UNION_NFT_EXPR_DATA_MASQ] = "masq", - [NL_UNION_NFT_EXPR_DATA_NAT] = "nat", - [NL_UNION_NFT_EXPR_DATA_PAYLOAD] = "payload", -}; - -DEFINE_STRING_TABLE_LOOKUP(nl_union_nft_expr_data, NLUnionNFTExprData); - static const NLTypeSystemUnion nfnl_nft_data_expr_type_system_union = { - .num = _NL_UNION_NFT_EXPR_DATA_MAX, - .lookup = nl_union_nft_expr_data_from_string, - .type_systems = nfnl_expr_data_type_systems, + .count = ELEMENTSOF(nfnl_expr_data_type_systems), + .elements = nfnl_expr_data_type_systems, .match_type = NL_MATCH_SIBLING, .match_attribute = NFTA_EXPR_NAME, }; diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index 8f0b766440..275045fc2a 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -345,106 +345,99 @@ static const NLType rtnl_link_info_data_bareudp_types[] = { [IFLA_BAREUDP_MULTIPROTO_MODE] = { .type = NETLINK_TYPE_FLAG }, }; -/* these strings must match the .kind entries in the kernel */ -static const char* const nl_union_link_info_data_table[] = { - [NL_UNION_LINK_INFO_DATA_BOND] = "bond", - [NL_UNION_LINK_INFO_DATA_BRIDGE] = "bridge", - [NL_UNION_LINK_INFO_DATA_VLAN] = "vlan", - [NL_UNION_LINK_INFO_DATA_VETH] = "veth", - [NL_UNION_LINK_INFO_DATA_DUMMY] = "dummy", - [NL_UNION_LINK_INFO_DATA_MACVLAN] = "macvlan", - [NL_UNION_LINK_INFO_DATA_MACVTAP] = "macvtap", - [NL_UNION_LINK_INFO_DATA_IPVLAN] = "ipvlan", - [NL_UNION_LINK_INFO_DATA_IPVTAP] = "ipvtap", - [NL_UNION_LINK_INFO_DATA_VXLAN] = "vxlan", - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = "ipip", - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = "gre", - [NL_UNION_LINK_INFO_DATA_ERSPAN] = "erspan", - [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = "gretap", - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = "ip6gre", - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = "ip6gretap", - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = "sit", - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti", - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6", - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl", - [NL_UNION_LINK_INFO_DATA_VRF] = "vrf", - [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan", - [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve", - [NL_UNION_LINK_INFO_DATA_VXCAN] = "vxcan", - [NL_UNION_LINK_INFO_DATA_WIREGUARD] = "wireguard", - [NL_UNION_LINK_INFO_DATA_NETDEVSIM] = "netdevsim", - [NL_UNION_LINK_INFO_DATA_CAN] = "can", - [NL_UNION_LINK_INFO_DATA_MACSEC] = "macsec", - [NL_UNION_LINK_INFO_DATA_NLMON] = "nlmon", - [NL_UNION_LINK_INFO_DATA_XFRM] = "xfrm", - [NL_UNION_LINK_INFO_DATA_IFB] = "ifb", - [NL_UNION_LINK_INFO_DATA_BAREUDP] = "bareudp", - [NL_UNION_LINK_INFO_DATA_BATADV] = "batadv", -}; - -DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); - -static const NLTypeSystem rtnl_link_info_data_type_systems[] = { - [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), - .types = rtnl_link_info_data_bond_types }, - [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), - .types = rtnl_link_info_data_bridge_types }, - [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), - .types = rtnl_link_info_data_vlan_types }, - [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), - .types = rtnl_link_info_data_veth_types }, - [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), - .types = rtnl_link_info_data_vxlan_types }, - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_ERSPAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), - .types = rtnl_link_info_data_ip6tnl_types }, - [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), - .types = rtnl_link_info_data_vrf_types }, - [NL_UNION_LINK_INFO_DATA_GENEVE] = { .count = ELEMENTSOF(rtnl_link_info_data_geneve_types), - .types = rtnl_link_info_data_geneve_types }, - [NL_UNION_LINK_INFO_DATA_VXCAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types), - .types = rtnl_link_info_data_vxcan_types }, - [NL_UNION_LINK_INFO_DATA_CAN] = { .count = ELEMENTSOF(rtnl_link_info_data_can_types), - .types = rtnl_link_info_data_can_types }, - [NL_UNION_LINK_INFO_DATA_MACSEC] = { .count = ELEMENTSOF(rtnl_link_info_data_macsec_types), - .types = rtnl_link_info_data_macsec_types }, - [NL_UNION_LINK_INFO_DATA_XFRM] = { .count = ELEMENTSOF(rtnl_link_info_data_xfrm_types), - .types = rtnl_link_info_data_xfrm_types }, - [NL_UNION_LINK_INFO_DATA_BAREUDP] = { .count = ELEMENTSOF(rtnl_link_info_data_bareudp_types), - .types = rtnl_link_info_data_bareudp_types }, - [NL_UNION_LINK_INFO_DATA_BATADV] = { .count = ELEMENTSOF(rtnl_link_info_data_batadv_types), - .types = rtnl_link_info_data_batadv_types }, +static const NLTypeSystemUnionElement rtnl_link_info_data_type_systems[] = { + { .name = "bareudp", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_bareudp_types), + .types = rtnl_link_info_data_bareudp_types } }, + { .name = "batadv", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_batadv_types), + .types = rtnl_link_info_data_batadv_types } }, + { .name = "bond", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_bond_types), + .types = rtnl_link_info_data_bond_types } }, + { .name = "bridge", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), + .types = rtnl_link_info_data_bridge_types } }, + { .name = "can", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_can_types), + .types = rtnl_link_info_data_can_types } }, + { .name = "dummy", }, + { .name = "erspan", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types } }, + { .name = "geneve", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_geneve_types), + .types = rtnl_link_info_data_geneve_types } }, + { .name = "gre", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types } }, + { .name = "gretap", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types } }, + { .name = "ifb", }, + { .name = "ip6gre", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types } }, + { .name = "ip6gretap", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types } }, + { .name = "ip6tnl", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), + .types = rtnl_link_info_data_ip6tnl_types } }, + { .name = "ipip", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types } }, + { .name = "ipvlan", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), + .types = rtnl_link_info_data_ipvlan_types } }, + { .name = "ipvtap", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), + .types = rtnl_link_info_data_ipvlan_types } }, + { .name = "macsec", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_macsec_types), + .types = rtnl_link_info_data_macsec_types } }, + { .name = "macvlan", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types } }, + { .name = "macvtap", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types } }, + { .name = "netdevsim", }, + { .name = "nlmon", }, + { .name = "sit", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types } }, + { .name = "vcan", }, + { .name = "veth", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_veth_types), + .types = rtnl_link_info_data_veth_types } }, + { .name = "vlan", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), + .types = rtnl_link_info_data_vlan_types } }, + { .name = "vrf", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), + .types = rtnl_link_info_data_vrf_types } }, + { .name = "vti", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types } }, + { .name = "vti6", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types } }, + { .name = "vxcan", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types), + .types = rtnl_link_info_data_vxcan_types } }, + { .name = "vxlan", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), + .types = rtnl_link_info_data_vxlan_types } }, + { .name = "wireguard", }, + { .name = "xfrm", .type_system = { + .count = ELEMENTSOF(rtnl_link_info_data_xfrm_types), + .types = rtnl_link_info_data_xfrm_types } }, }; static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { - .num = _NL_UNION_LINK_INFO_DATA_MAX, - .lookup = nl_union_link_info_data_from_string, - .type_systems = rtnl_link_info_data_type_systems, + .count = ELEMENTSOF(rtnl_link_info_data_type_systems), + .elements = rtnl_link_info_data_type_systems, .match_type = NL_MATCH_SIBLING, .match_attribute = IFLA_INFO_KIND, }; @@ -501,14 +494,15 @@ static const struct NLType rtnl_prot_info_bridge_port_types[] = { [IFLA_BRPORT_BACKUP_PORT] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem rtnl_prot_info_type_systems[] = { - [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), - .types = rtnl_prot_info_bridge_port_types }, +static const NLTypeSystemUnionElement rtnl_prot_info_type_systems[] = { + { .protocol = AF_BRIDGE, .type_system = { + .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), + .types = rtnl_prot_info_bridge_port_types } }, }; static const NLTypeSystemUnion rtnl_prot_info_type_system_union = { - .num = AF_MAX, - .type_systems = rtnl_prot_info_type_systems, + .count = ELEMENTSOF(rtnl_prot_info_type_systems), + .elements = rtnl_prot_info_type_systems, .match_type = NL_MATCH_PROTOCOL, }; @@ -539,16 +533,18 @@ static const NLType rtnl_af_spec_bridge_types[] = { [IFLA_BRIDGE_VLAN_INFO] = { .size = sizeof(struct bridge_vlan_info) }, }; -static const NLTypeSystem rtnl_af_spec_type_systems[] = { - [AF_UNSPEC] = { .count = ELEMENTSOF(rtnl_af_spec_unspec_types), - .types = rtnl_af_spec_unspec_types }, - [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_af_spec_bridge_types), - .types = rtnl_af_spec_bridge_types }, +static const NLTypeSystemUnionElement rtnl_af_spec_type_systems[] = { + { .protocol = AF_UNSPEC, .type_system = { + .count = ELEMENTSOF(rtnl_af_spec_unspec_types), + .types = rtnl_af_spec_unspec_types } }, + { .protocol = AF_BRIDGE, .type_system = { + .count = ELEMENTSOF(rtnl_af_spec_bridge_types), + .types = rtnl_af_spec_bridge_types } }, }; static const NLTypeSystemUnion rtnl_af_spec_type_system_union = { - .num = AF_MAX, - .type_systems = rtnl_af_spec_type_systems, + .count = ELEMENTSOF(rtnl_af_spec_type_systems), + .elements = rtnl_af_spec_type_systems, .match_type = NL_MATCH_PROTOCOL, }; @@ -928,60 +924,54 @@ static const NLType rtnl_tca_option_data_tbf_types[] = { [TCA_TBF_PBURST] = { .type = NETLINK_TYPE_U32 }, }; -static const char* const nl_union_tca_option_data_table[] = { - [NL_UNION_TCA_OPTION_DATA_CAKE] = "cake", - [NL_UNION_TCA_OPTION_DATA_CODEL] = "codel", - [NL_UNION_TCA_OPTION_DATA_DRR] = "drr", - [NL_UNION_TCA_OPTION_DATA_ETS] = "ets", - [NL_UNION_TCA_OPTION_DATA_FQ] = "fq", - [NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel", - [NL_UNION_TCA_OPTION_DATA_FQ_PIE] = "fq_pie", - [NL_UNION_TCA_OPTION_DATA_GRED] = "gred", - [NL_UNION_TCA_OPTION_DATA_HHF] = "hhf", - [NL_UNION_TCA_OPTION_DATA_HTB] = "htb", - [NL_UNION_TCA_OPTION_DATA_PIE] = "pie", - [NL_UNION_TCA_OPTION_DATA_QFQ] = "qfq", - [NL_UNION_TCA_OPTION_DATA_SFB] = "sfb", - [NL_UNION_TCA_OPTION_DATA_TBF] = "tbf", -}; - -DEFINE_STRING_TABLE_LOOKUP(nl_union_tca_option_data, NLUnionTCAOptionData); - -static const NLTypeSystem rtnl_tca_option_data_type_systems[] = { - [NL_UNION_TCA_OPTION_DATA_CAKE] = { .count = ELEMENTSOF(rtnl_tca_option_data_cake_types), - .types = rtnl_tca_option_data_cake_types }, - [NL_UNION_TCA_OPTION_DATA_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_codel_types), - .types = rtnl_tca_option_data_codel_types }, - [NL_UNION_TCA_OPTION_DATA_DRR] = { .count = ELEMENTSOF(rtnl_tca_option_data_drr_types), - .types = rtnl_tca_option_data_drr_types }, - [NL_UNION_TCA_OPTION_DATA_ETS] = { .count = ELEMENTSOF(rtnl_tca_option_data_ets_types), - .types = rtnl_tca_option_data_ets_types }, - [NL_UNION_TCA_OPTION_DATA_FQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_types), - .types = rtnl_tca_option_data_fq_types }, - [NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types), - .types = rtnl_tca_option_data_fq_codel_types }, - [NL_UNION_TCA_OPTION_DATA_FQ_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_pie_types), - .types = rtnl_tca_option_data_fq_pie_types }, - [NL_UNION_TCA_OPTION_DATA_GRED] = { .count = ELEMENTSOF(rtnl_tca_option_data_gred_types), - .types = rtnl_tca_option_data_gred_types }, - [NL_UNION_TCA_OPTION_DATA_HHF] = { .count = ELEMENTSOF(rtnl_tca_option_data_hhf_types), - .types = rtnl_tca_option_data_hhf_types }, - [NL_UNION_TCA_OPTION_DATA_HTB] = { .count = ELEMENTSOF(rtnl_tca_option_data_htb_types), - .types = rtnl_tca_option_data_htb_types }, - [NL_UNION_TCA_OPTION_DATA_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_pie_types), - .types = rtnl_tca_option_data_pie_types }, - [NL_UNION_TCA_OPTION_DATA_QFQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_qfq_types), - .types = rtnl_tca_option_data_qfq_types }, - [NL_UNION_TCA_OPTION_DATA_SFB] = { .count = ELEMENTSOF(rtnl_tca_option_data_sfb_types), - .types = rtnl_tca_option_data_sfb_types }, - [NL_UNION_TCA_OPTION_DATA_TBF] = { .count = ELEMENTSOF(rtnl_tca_option_data_tbf_types), - .types = rtnl_tca_option_data_tbf_types }, +static const NLTypeSystemUnionElement rtnl_tca_option_data_type_systems[] = { + { .name = "cake", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_cake_types), + .types = rtnl_tca_option_data_cake_types } }, + { .name = "codel", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_codel_types), + .types = rtnl_tca_option_data_codel_types } }, + { .name = "drr", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_drr_types), + .types = rtnl_tca_option_data_drr_types } }, + { .name = "ets", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_ets_types), + .types = rtnl_tca_option_data_ets_types } }, + { .name = "fq", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_fq_types), + .types = rtnl_tca_option_data_fq_types } }, + { .name = "fq_codel", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types), + .types = rtnl_tca_option_data_fq_codel_types } }, + { .name = "fq_pie", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_fq_pie_types), + .types = rtnl_tca_option_data_fq_pie_types } }, + { .name = "gred", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_gred_types), + .types = rtnl_tca_option_data_gred_types } }, + { .name = "hhf", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_hhf_types), + .types = rtnl_tca_option_data_hhf_types } }, + { .name = "htb", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_htb_types), + .types = rtnl_tca_option_data_htb_types } }, + { .name = "pie", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_pie_types), + .types = rtnl_tca_option_data_pie_types } }, + { .name = "qfq", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_qfq_types), + .types = rtnl_tca_option_data_qfq_types } }, + { .name = "sfb", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_sfb_types), + .types = rtnl_tca_option_data_sfb_types } }, + { .name = "tbf", .type_system = { + .count = ELEMENTSOF(rtnl_tca_option_data_tbf_types), + .types = rtnl_tca_option_data_tbf_types } }, }; static const NLTypeSystemUnion rtnl_tca_option_data_type_system_union = { - .num = _NL_UNION_TCA_OPTION_DATA_MAX, - .lookup = nl_union_tca_option_data_from_string, - .type_systems = rtnl_tca_option_data_type_systems, + .count = ELEMENTSOF(rtnl_tca_option_data_type_systems), + .elements = rtnl_tca_option_data_type_systems, .match_type = NL_MATCH_SIBLING, .match_attribute = TCA_KIND, }; diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index d5a4a017c4..0ae0fc6e99 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -138,40 +138,32 @@ uint16_t type_system_union_get_match_attribute(const NLTypeSystemUnion *type_sys } int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) { - int type; - assert(type_system_union); + assert(type_system_union->elements); assert(type_system_union->match_type == NL_MATCH_SIBLING); - assert(type_system_union->lookup); - assert(type_system_union->type_systems); assert(ret); assert(key); - type = type_system_union->lookup(key); - if (type < 0) - return -EOPNOTSUPP; + for (size_t i = 0; i < type_system_union->count; i++) + if (streq(type_system_union->elements[i].name, key)) { + *ret = &type_system_union->elements[i].type_system; + return 0; + } - assert(type < type_system_union->num); - - *ret = &type_system_union->type_systems[type]; - return 0; + return -EOPNOTSUPP; } int type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) { - const NLTypeSystem *type_system; - assert(type_system_union); - assert(type_system_union->type_systems); + assert(type_system_union->elements); assert(type_system_union->match_type == NL_MATCH_PROTOCOL); assert(ret); - if (protocol >= type_system_union->num) - return -EOPNOTSUPP; + for (size_t i = 0; i < type_system_union->count; i++) + if (type_system_union->elements[i].protocol == protocol) { + *ret = &type_system_union->elements[i].type_system; + return 0; + } - type_system = &type_system_union->type_systems[protocol]; - if (!type_system->types) - return -EOPNOTSUPP; - - *ret = type_system; - return 0; + return -EOPNOTSUPP; } From 699c3708dfcb77279fe9a2a8c50587d5ef7f2dcc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 17:06:41 +0900 Subject: [PATCH 21/29] sd-netlink: introduce several macros to define type system --- .../sd-netlink/netlink-types-genl.c | 82 +--- .../sd-netlink/netlink-types-internal.h | 17 + .../sd-netlink/netlink-types-nfnl.c | 117 ++--- .../sd-netlink/netlink-types-rtnl.c | 402 +++++------------- src/libsystemd/sd-netlink/netlink-types.c | 15 +- 5 files changed, 183 insertions(+), 450 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index c39db47b19..33e80a1745 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -20,20 +20,14 @@ static const NLType genl_ctrl_mcast_group_types[] = { [CTRL_ATTR_MCAST_GRP_ID] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem genl_ctrl_mcast_group_type_system = { - .count = ELEMENTSOF(genl_ctrl_mcast_group_types), - .types = genl_ctrl_mcast_group_types, -}; +DEFINE_TYPE_SYSTEM(genl_ctrl_mcast_group); static const NLType genl_ctrl_ops_types[] = { [CTRL_ATTR_OP_ID] = { .type = NETLINK_TYPE_U32 }, [CTRL_ATTR_OP_FLAGS] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem genl_ctrl_ops_type_system = { - .count = ELEMENTSOF(genl_ctrl_ops_types), - .types = genl_ctrl_ops_types, -}; +DEFINE_TYPE_SYSTEM(genl_ctrl_ops); static const NLType genl_ctrl_types[] = { [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 }, @@ -50,10 +44,7 @@ static const NLType genl_ctrl_types[] = { [CTRL_ATTR_OP] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem genl_ctrl_type_system = { - .count = ELEMENTSOF(genl_ctrl_types), - .types = genl_ctrl_types, -}; +DEFINE_TYPE_SYSTEM(genl_ctrl); /***************** genl batadv type systems *****************/ static const NLType genl_batadv_types[] = { @@ -119,10 +110,7 @@ static const NLType genl_batadv_types[] = { [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem genl_batadv_type_system = { - .count = ELEMENTSOF(genl_batadv_types), - .types = genl_batadv_types, -}; +DEFINE_TYPE_SYSTEM(genl_batadv); /***************** genl fou type systems *****************/ static const NLType genl_fou_types[] = { @@ -139,10 +127,7 @@ static const NLType genl_fou_types[] = { [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32}, }; -static const NLTypeSystem genl_fou_type_system = { - .count = ELEMENTSOF(genl_fou_types), - .types = genl_fou_types, -}; +DEFINE_TYPE_SYSTEM(genl_fou); /***************** genl l2tp type systems *****************/ static const NLType genl_l2tp_types[] = { @@ -175,20 +160,14 @@ static const NLType genl_l2tp_types[] = { [L2TP_ATTR_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_FLAG }, }; -static const NLTypeSystem genl_l2tp_type_system = { - .count = ELEMENTSOF(genl_l2tp_types), - .types = genl_l2tp_types, -}; +DEFINE_TYPE_SYSTEM(genl_l2tp); /***************** genl macsec type systems *****************/ static const NLType genl_macsec_rxsc_types[] = { [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, }; -static const NLTypeSystem genl_macsec_rxsc_type_system = { - .count = ELEMENTSOF(genl_macsec_rxsc_types), - .types = genl_macsec_rxsc_types, -}; +DEFINE_TYPE_SYSTEM(genl_macsec_rxsc); static const NLType genl_macsec_sa_types[] = { [MACSEC_SA_ATTR_AN] = { .type = NETLINK_TYPE_U8 }, @@ -198,10 +177,7 @@ static const NLType genl_macsec_sa_types[] = { [MACSEC_SA_ATTR_KEY] = { .size = MACSEC_MAX_KEY_LEN }, }; -static const NLTypeSystem genl_macsec_sa_type_system = { - .count = ELEMENTSOF(genl_macsec_sa_types), - .types = genl_macsec_sa_types, -}; +DEFINE_TYPE_SYSTEM(genl_macsec_sa); static const NLType genl_macsec_types[] = { [MACSEC_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, @@ -209,10 +185,7 @@ static const NLType genl_macsec_types[] = { [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, }; -static const NLTypeSystem genl_macsec_type_system = { - .count = ELEMENTSOF(genl_macsec_types), - .types = genl_macsec_types, -}; +DEFINE_TYPE_SYSTEM(genl_macsec); /***************** genl nl80211 type systems *****************/ static const NLType genl_nl80211_types[] = { @@ -222,10 +195,7 @@ static const NLType genl_nl80211_types[] = { [NL80211_ATTR_IFTYPE] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem genl_nl80211_type_system = { - .count = ELEMENTSOF(genl_nl80211_types), - .types = genl_nl80211_types, -}; +DEFINE_TYPE_SYSTEM(genl_nl80211); /***************** genl wireguard type systems *****************/ static const NLType genl_wireguard_allowedip_types[] = { @@ -234,10 +204,7 @@ static const NLType genl_wireguard_allowedip_types[] = { [WGALLOWEDIP_A_CIDR_MASK] = { .type = NETLINK_TYPE_U8 }, }; -static const NLTypeSystem genl_wireguard_allowedip_type_system = { - .count = ELEMENTSOF(genl_wireguard_allowedip_types), - .types = genl_wireguard_allowedip_types, -}; +DEFINE_TYPE_SYSTEM(genl_wireguard_allowedip); static const NLType genl_wireguard_peer_types[] = { [WGPEER_A_PUBLIC_KEY] = { .size = WG_KEY_LEN }, @@ -248,10 +215,7 @@ static const NLType genl_wireguard_peer_types[] = { [WGPEER_A_ALLOWEDIPS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_allowedip_type_system }, }; -static const NLTypeSystem genl_wireguard_peer_type_system = { - .count = ELEMENTSOF(genl_wireguard_peer_types), - .types = genl_wireguard_peer_types, -}; +DEFINE_TYPE_SYSTEM(genl_wireguard_peer); static const NLType genl_wireguard_types[] = { [WGDEVICE_A_IFINDEX] = { .type = NETLINK_TYPE_U32 }, @@ -263,26 +227,20 @@ static const NLType genl_wireguard_types[] = { [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, }; -static const NLTypeSystem genl_wireguard_type_system = { - .count = ELEMENTSOF(genl_wireguard_types), - .types = genl_wireguard_types, -}; +DEFINE_TYPE_SYSTEM(genl_wireguard); /***************** genl families *****************/ static const NLType genl_types[] = { - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, + [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system, .size = sizeof(struct genlmsghdr) }, }; -static const NLTypeSystem genl_type_system = { - .count = ELEMENTSOF(genl_types), - .types = genl_types, -}; +DEFINE_TYPE_SYSTEM(genl); int genl_get_type(sd_netlink *genl, uint16_t nlmsg_type, const NLType **ret) { sd_genl_family_t family; diff --git a/src/libsystemd/sd-netlink/netlink-types-internal.h b/src/libsystemd/sd-netlink/netlink-types-internal.h index adbc189c88..16da6aad0e 100644 --- a/src/libsystemd/sd-netlink/netlink-types-internal.h +++ b/src/libsystemd/sd-netlink/netlink-types-internal.h @@ -30,3 +30,20 @@ struct NLTypeSystemUnion { NLMatchType match_type; uint16_t match_attribute; }; + +#define TYPE_SYSTEM_FROM_TYPE(name) \ + { .count = ELEMENTSOF(name##_types), .types = name##_types } +#define DEFINE_TYPE_SYSTEM(name) \ + static const NLTypeSystem name##_type_system = TYPE_SYSTEM_FROM_TYPE(name) + +#define _DEFINE_TYPE_SYSTEM_UNION(name, type, attr) \ + static const NLTypeSystemUnion name##_type_system_union = { \ + .count = ELEMENTSOF(name##_type_systems), \ + .elements = name##_type_systems, \ + .match_type = type, \ + .match_attribute = attr, \ + } +#define DEFINE_TYPE_SYSTEM_UNION_MATCH_PROTOCOL(name) \ + _DEFINE_TYPE_SYSTEM_UNION(name, NL_MATCH_PROTOCOL, 0) +#define DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(name, attr) \ + _DEFINE_TYPE_SYSTEM_UNION(name, NL_MATCH_SIBLING, attr) diff --git a/src/libsystemd/sd-netlink/netlink-types-nfnl.c b/src/libsystemd/sd-netlink/netlink-types-nfnl.c index 799e80fe32..68e5395fea 100644 --- a/src/libsystemd/sd-netlink/netlink-types-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-nfnl.c @@ -14,10 +14,7 @@ static const NLType nfnl_nft_table_types[] = { [NFTA_TABLE_FLAGS] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem nfnl_nft_table_type_system = { - .count = ELEMENTSOF(nfnl_nft_table_types), - .types = nfnl_nft_table_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_table); static const NLType nfnl_nft_chain_hook_types[] = { [NFTA_HOOK_HOOKNUM] = { .type = NETLINK_TYPE_U32 }, @@ -25,10 +22,7 @@ static const NLType nfnl_nft_chain_hook_types[] = { [NFTA_HOOK_DEV] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, }; -static const NLTypeSystem nfnl_nft_chain_hook_type_system = { - .count = ELEMENTSOF(nfnl_nft_chain_hook_types), - .types = nfnl_nft_chain_hook_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_chain_hook); static const NLType nfnl_nft_chain_types[] = { [NFTA_CHAIN_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, @@ -38,10 +32,7 @@ static const NLType nfnl_nft_chain_types[] = { [NFTA_CHAIN_FLAGS] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem nfnl_nft_chain_type_system = { - .count = ELEMENTSOF(nfnl_nft_chain_types), - .types = nfnl_nft_chain_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_chain); static const NLType nfnl_nft_expr_meta_types[] = { [NFTA_META_DREG] = { .type = NETLINK_TYPE_U32 }, @@ -70,10 +61,7 @@ static const NLType nfnl_nft_data_types[] = { [NFTA_DATA_VALUE] = { .type = NETLINK_TYPE_BINARY }, }; -static const NLTypeSystem nfnl_nft_data_type_system = { - .count = ELEMENTSOF(nfnl_nft_data_types), - .types = nfnl_nft_data_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_data); static const NLType nfnl_nft_expr_bitwise_types[] = { [NFTA_BITWISE_SREG] = { .type = NETLINK_TYPE_U32 }, @@ -109,49 +97,24 @@ static const NLType nfnl_nft_expr_masq_types[] = { }; static const NLTypeSystemUnionElement nfnl_expr_data_type_systems[] = { - { .name = "bitwise", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_bitwise_types), - .types = nfnl_nft_expr_bitwise_types } }, - { .name = "cmp", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_cmp_types), - .types = nfnl_nft_expr_cmp_types } }, - { .name = "fib", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_fib_types), - .types = nfnl_nft_expr_fib_types } }, - { .name = "lookup", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_lookup_types), - .types = nfnl_nft_expr_lookup_types } }, - { .name = "masq", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_masq_types), - .types = nfnl_nft_expr_masq_types } }, - { .name = "meta", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_meta_types), - .types = nfnl_nft_expr_meta_types } }, - { .name = "nat", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_nat_types), - .types = nfnl_nft_expr_nat_types } }, - { .name = "payload", .type_system = { - .count = ELEMENTSOF(nfnl_nft_expr_payload_types), - .types = nfnl_nft_expr_payload_types } }, + { .name = "bitwise", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_bitwise), }, + { .name = "cmp", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_cmp), }, + { .name = "fib", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_fib), }, + { .name = "lookup", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_lookup), }, + { .name = "masq", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_masq), }, + { .name = "meta", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_meta), }, + { .name = "nat", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_nat), }, + { .name = "payload", .type_system = TYPE_SYSTEM_FROM_TYPE(nfnl_nft_expr_payload), }, }; -static const NLTypeSystemUnion nfnl_nft_data_expr_type_system_union = { - .count = ELEMENTSOF(nfnl_expr_data_type_systems), - .elements = nfnl_expr_data_type_systems, - .match_type = NL_MATCH_SIBLING, - .match_attribute = NFTA_EXPR_NAME, -}; +DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(nfnl_expr_data, NFTA_EXPR_NAME); static const NLType nfnl_nft_rule_expr_types[] = { [NFTA_EXPR_NAME] = { .type = NETLINK_TYPE_STRING, .size = 16 }, - [NFTA_EXPR_DATA] = { .type = NETLINK_TYPE_UNION, - .type_system_union = &nfnl_nft_data_expr_type_system_union }, + [NFTA_EXPR_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &nfnl_expr_data_type_system_union }, }; -static const NLTypeSystem nfnl_nft_rule_expr_type_system = { - .count = ELEMENTSOF(nfnl_nft_rule_expr_types), - .types = nfnl_nft_rule_expr_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_rule_expr); static const NLType nfnl_nft_rule_types[] = { [NFTA_RULE_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, @@ -159,10 +122,7 @@ static const NLType nfnl_nft_rule_types[] = { [NFTA_RULE_EXPRESSIONS] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_rule_expr_type_system } }; -static const NLTypeSystem nfnl_nft_rule_type_system = { - .count = ELEMENTSOF(nfnl_nft_rule_types), - .types = nfnl_nft_rule_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_rule); static const NLType nfnl_nft_set_types[] = { [NFTA_SET_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, @@ -176,10 +136,7 @@ static const NLType nfnl_nft_set_types[] = { [NFTA_SET_ID] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem nfnl_nft_set_type_system = { - .count = ELEMENTSOF(nfnl_nft_set_types), - .types = nfnl_nft_set_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_set); static const NLType nfnl_nft_setelem_types[] = { [NFTA_SET_ELEM_KEY] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_data_type_system }, @@ -187,10 +144,7 @@ static const NLType nfnl_nft_setelem_types[] = { [NFTA_SET_ELEM_FLAGS] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem nfnl_nft_setelem_type_system = { - .count = ELEMENTSOF(nfnl_nft_setelem_types), - .types = nfnl_nft_setelem_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_setelem); static const NLType nfnl_nft_setelem_list_types[] = { [NFTA_SET_ELEM_LIST_TABLE] = { .type = NETLINK_TYPE_STRING, .size = NFT_TABLE_MAXNAMELEN - 1 }, @@ -198,54 +152,39 @@ static const NLType nfnl_nft_setelem_list_types[] = { [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_setelem_type_system }, }; -static const NLTypeSystem nfnl_nft_setelem_list_type_system = { - .count = ELEMENTSOF(nfnl_nft_setelem_list_types), - .types = nfnl_nft_setelem_list_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_nft_setelem_list); 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_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_rule_type_system, .size = sizeof(struct nfgenmsg) }, - [NFT_MSG_NEWSET] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_set_type_system, .size = sizeof(struct nfgenmsg) }, + [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_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_rule_type_system, .size = sizeof(struct nfgenmsg) }, + [NFT_MSG_NEWSET] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_set_type_system, .size = sizeof(struct nfgenmsg) }, [NFT_MSG_NEWSETELEM] = { .type = NETLINK_TYPE_NESTED, .type_system = &nfnl_nft_setelem_list_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_subsys_nft_type_system = { - .count = ELEMENTSOF(nfnl_subsys_nft_types), - .types = nfnl_subsys_nft_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_subsys_nft); static const NLType nfnl_msg_batch_types [] = { [NFNL_BATCH_GENID] = { .type = NETLINK_TYPE_U32 } }; -static const NLTypeSystem nfnl_msg_batch_type_system = { - .count = ELEMENTSOF(nfnl_msg_batch_types), - .types = nfnl_msg_batch_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_msg_batch); 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) }, }; -static const NLTypeSystem nfnl_subsys_none_type_system = { - .count = ELEMENTSOF(nfnl_subsys_none_types), - .types = nfnl_subsys_none_types, -}; +DEFINE_TYPE_SYSTEM(nfnl_subsys_none); 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 = { - .count = ELEMENTSOF(nfnl_types), - .types = nfnl_types, -}; +DEFINE_TYPE_SYSTEM(nfnl); int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret) { const NLTypeSystem *subsys; diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index 275045fc2a..dacd7517a0 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -74,10 +74,7 @@ static const NLType rtnl_macvlan_macaddr_types[] = { [IFLA_MACVLAN_MACADDR] = { .type = NETLINK_TYPE_ETHER_ADDR }, }; -static const NLTypeSystem rtnl_macvlan_macaddr_type_system = { - .count = ELEMENTSOF(rtnl_macvlan_macaddr_types), - .types = rtnl_macvlan_macaddr_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_macvlan_macaddr); static const NLType rtnl_link_info_data_macvlan_types[] = { [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 }, @@ -134,10 +131,7 @@ static const NLType rtnl_vlan_qos_map_types[] = { [IFLA_VLAN_QOS_MAPPING] = { .size = sizeof(struct ifla_vlan_qos_mapping) }, }; -static const NLTypeSystem rtnl_vlan_qos_map_type_system = { - .count = ELEMENTSOF(rtnl_vlan_qos_map_types), - .types = rtnl_vlan_qos_map_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_vlan_qos_map); static const NLType rtnl_link_info_data_vlan_types[] = { [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, @@ -198,10 +192,7 @@ static const NLType rtnl_bond_arp_target_types[] = { [BOND_ARP_TARGETS_MAX] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem rtnl_bond_arp_type_system = { - .count = ELEMENTSOF(rtnl_bond_arp_target_types), - .types = rtnl_bond_arp_target_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_bond_arp_target); static const NLType rtnl_link_info_data_bond_types[] = { [IFLA_BOND_MODE] = { .type = NETLINK_TYPE_U8 }, @@ -211,7 +202,7 @@ static const NLType rtnl_link_info_data_bond_types[] = { [IFLA_BOND_DOWNDELAY] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_USE_CARRIER] = { .type = NETLINK_TYPE_U8 }, [IFLA_BOND_ARP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, - [IFLA_BOND_ARP_IP_TARGET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_type_system }, + [IFLA_BOND_ARP_IP_TARGET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_target_type_system }, [IFLA_BOND_ARP_VALIDATE] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NETLINK_TYPE_U32 }, [IFLA_BOND_PRIMARY] = { .type = NETLINK_TYPE_U32 }, @@ -346,101 +337,42 @@ static const NLType rtnl_link_info_data_bareudp_types[] = { }; static const NLTypeSystemUnionElement rtnl_link_info_data_type_systems[] = { - { .name = "bareudp", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_bareudp_types), - .types = rtnl_link_info_data_bareudp_types } }, - { .name = "batadv", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_batadv_types), - .types = rtnl_link_info_data_batadv_types } }, - { .name = "bond", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_bond_types), - .types = rtnl_link_info_data_bond_types } }, - { .name = "bridge", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), - .types = rtnl_link_info_data_bridge_types } }, - { .name = "can", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_can_types), - .types = rtnl_link_info_data_can_types } }, - { .name = "dummy", }, - { .name = "erspan", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types } }, - { .name = "geneve", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_geneve_types), - .types = rtnl_link_info_data_geneve_types } }, - { .name = "gre", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types } }, - { .name = "gretap", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types } }, - { .name = "ifb", }, - { .name = "ip6gre", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types } }, - { .name = "ip6gretap", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types } }, - { .name = "ip6tnl", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), - .types = rtnl_link_info_data_ip6tnl_types } }, - { .name = "ipip", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types } }, - { .name = "ipvlan", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types } }, - { .name = "ipvtap", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types } }, - { .name = "macsec", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_macsec_types), - .types = rtnl_link_info_data_macsec_types } }, - { .name = "macvlan", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types } }, - { .name = "macvtap", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types } }, - { .name = "netdevsim", }, - { .name = "nlmon", }, - { .name = "sit", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types } }, - { .name = "vcan", }, - { .name = "veth", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_veth_types), - .types = rtnl_link_info_data_veth_types } }, - { .name = "vlan", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), - .types = rtnl_link_info_data_vlan_types } }, - { .name = "vrf", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), - .types = rtnl_link_info_data_vrf_types } }, - { .name = "vti", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types } }, - { .name = "vti6", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types } }, - { .name = "vxcan", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_vxcan_types), - .types = rtnl_link_info_data_vxcan_types } }, - { .name = "vxlan", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), - .types = rtnl_link_info_data_vxlan_types } }, - { .name = "wireguard", }, - { .name = "xfrm", .type_system = { - .count = ELEMENTSOF(rtnl_link_info_data_xfrm_types), - .types = rtnl_link_info_data_xfrm_types } }, + { .name = "bareudp", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_bareudp), }, + { .name = "batadv", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_batadv), }, + { .name = "bond", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_bond), }, + { .name = "bridge", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_bridge), }, + { .name = "can", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_can), }, + { .name = "dummy", }, + { .name = "erspan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, + { .name = "geneve", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_geneve), }, + { .name = "gre", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, + { .name = "gretap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, + { .name = "ifb", }, + { .name = "ip6gre", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, + { .name = "ip6gretap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipgre), }, + { .name = "ip6tnl", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ip6tnl), }, + { .name = "ipip", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_iptun), }, + { .name = "ipvlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvlan), }, + { .name = "ipvtap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvlan), }, + { .name = "macsec", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_macsec), }, + { .name = "macvlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_macvlan), }, + { .name = "macvtap", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_macvlan), }, + { .name = "netdevsim", }, + { .name = "nlmon", }, + { .name = "sit", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_iptun), }, + { .name = "vcan", }, + { .name = "veth", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_veth), }, + { .name = "vlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vlan), }, + { .name = "vrf", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vrf), }, + { .name = "vti", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvti), }, + { .name = "vti6", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_ipvti), }, + { .name = "vxcan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vxcan), }, + { .name = "vxlan", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_vxlan), }, + { .name = "wireguard", }, + { .name = "xfrm", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_link_info_data_xfrm), }, }; -static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { - .count = ELEMENTSOF(rtnl_link_info_data_type_systems), - .elements = rtnl_link_info_data_type_systems, - .match_type = NL_MATCH_SIBLING, - .match_attribute = IFLA_INFO_KIND, -}; +DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(rtnl_link_info_data, IFLA_INFO_KIND); static const NLType rtnl_link_info_types[] = { [IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING }, @@ -452,10 +384,7 @@ static const NLType rtnl_link_info_types[] = { */ }; -static const NLTypeSystem rtnl_link_info_type_system = { - .count = ELEMENTSOF(rtnl_link_info_types), - .types = rtnl_link_info_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_link_info); static const struct NLType rtnl_prot_info_bridge_port_types[] = { [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 }, @@ -495,16 +424,10 @@ static const struct NLType rtnl_prot_info_bridge_port_types[] = { }; static const NLTypeSystemUnionElement rtnl_prot_info_type_systems[] = { - { .protocol = AF_BRIDGE, .type_system = { - .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), - .types = rtnl_prot_info_bridge_port_types } }, + { .protocol = AF_BRIDGE, .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_prot_info_bridge_port), }, }; -static const NLTypeSystemUnion rtnl_prot_info_type_system_union = { - .count = ELEMENTSOF(rtnl_prot_info_type_systems), - .elements = rtnl_prot_info_type_systems, - .match_type = NL_MATCH_PROTOCOL, -}; +DEFINE_TYPE_SYSTEM_UNION_MATCH_PROTOCOL(rtnl_prot_info); static const struct NLType rtnl_af_spec_inet6_types[] = { [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 }, @@ -519,10 +442,7 @@ static const struct NLType rtnl_af_spec_inet6_types[] = { [IFLA_INET6_ADDR_GEN_MODE] = { .type = NETLINK_TYPE_U8 }, }; -static const NLTypeSystem rtnl_af_spec_inet6_type_system = { - .count = ELEMENTSOF(rtnl_af_spec_inet6_types), - .types = rtnl_af_spec_inet6_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_af_spec_inet6); static const NLType rtnl_af_spec_unspec_types[] = { [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system }, @@ -534,42 +454,28 @@ static const NLType rtnl_af_spec_bridge_types[] = { }; static const NLTypeSystemUnionElement rtnl_af_spec_type_systems[] = { - { .protocol = AF_UNSPEC, .type_system = { - .count = ELEMENTSOF(rtnl_af_spec_unspec_types), - .types = rtnl_af_spec_unspec_types } }, - { .protocol = AF_BRIDGE, .type_system = { - .count = ELEMENTSOF(rtnl_af_spec_bridge_types), - .types = rtnl_af_spec_bridge_types } }, + { .protocol = AF_UNSPEC, .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_af_spec_unspec), }, + { .protocol = AF_BRIDGE, .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_af_spec_bridge), }, }; -static const NLTypeSystemUnion rtnl_af_spec_type_system_union = { - .count = ELEMENTSOF(rtnl_af_spec_type_systems), - .elements = rtnl_af_spec_type_systems, - .match_type = NL_MATCH_PROTOCOL, -}; +DEFINE_TYPE_SYSTEM_UNION_MATCH_PROTOCOL(rtnl_af_spec); static const NLType rtnl_prop_list_types[] = { [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, }; -static const NLTypeSystem rtnl_prop_list_type_system = { - .count = ELEMENTSOF(rtnl_prop_list_types), - .types = rtnl_prop_list_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_prop_list); static const NLType rtnl_vf_vlan_list_types[] = { [IFLA_VF_VLAN_INFO] = { .size = sizeof(struct ifla_vf_vlan_info) }, }; -static const NLTypeSystem rtnl_vf_vlan_type_system = { - .count = ELEMENTSOF(rtnl_vf_vlan_list_types), - .types = rtnl_vf_vlan_list_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_vf_vlan_list); -static const NLType rtnl_vf_vlan_info_types[] = { +static const NLType rtnl_vf_info_types[] = { [IFLA_VF_MAC] = { .size = sizeof(struct ifla_vf_mac) }, [IFLA_VF_VLAN] = { .size = sizeof(struct ifla_vf_vlan) }, - [IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_type_system}, + [IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_list_type_system}, [IFLA_VF_TX_RATE] = { .size = sizeof(struct ifla_vf_tx_rate) }, [IFLA_VF_SPOOFCHK] = { .size = sizeof(struct ifla_vf_spoofchk) }, [IFLA_VF_RATE] = { .size = sizeof(struct ifla_vf_rate) }, @@ -580,19 +486,13 @@ static const NLType rtnl_vf_vlan_info_types[] = { [IFLA_VF_IB_PORT_GUID] = { .size = sizeof(struct ifla_vf_guid) }, }; -static const NLTypeSystem rtnl_vf_vlan_info_type_system = { - .count = ELEMENTSOF(rtnl_vf_vlan_info_types), - .types = rtnl_vf_vlan_info_types, +DEFINE_TYPE_SYSTEM(rtnl_vf_info); + +static const NLType rtnl_vfinfo_list_types[] = { + [IFLA_VF_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_info_type_system }, }; -static const NLType rtnl_link_io_srv_types[] = { - [IFLA_VF_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_info_type_system }, -}; - -static const NLTypeSystem rtnl_io_srv_type_system = { - .count = ELEMENTSOF(rtnl_link_io_srv_types), - .types = rtnl_link_io_srv_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_vfinfo_list); static const NLType rtnl_link_types[] = { [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR }, @@ -622,7 +522,7 @@ static const NLType rtnl_link_types[] = { [IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 }, [IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 }, [IFLA_NUM_VF] = { .type = NETLINK_TYPE_U32 }, - [IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_io_srv_type_system }, + [IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vfinfo_list_type_system }, [IFLA_STATS64] = { .size = sizeof(struct rtnl_link_stats64) }, /* [IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED }, @@ -651,10 +551,7 @@ static const NLType rtnl_link_types[] = { [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 }, }; -static const NLTypeSystem rtnl_link_type_system = { - .count = ELEMENTSOF(rtnl_link_types), - .types = rtnl_link_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_link); /* IFA_FLAGS was defined in kernel 3.14, but we still support older * kernels where IFA_MAX is lower. */ @@ -671,10 +568,7 @@ static const NLType rtnl_address_types[] = { [IFA_TARGET_NETNSID] = { .type = NETLINK_TYPE_S32 }, }; -static const NLTypeSystem rtnl_address_type_system = { - .count = ELEMENTSOF(rtnl_address_types), - .types = rtnl_address_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_address); /* RTM_METRICS --- array of struct rtattr with types of RTAX_* */ @@ -697,10 +591,7 @@ static const NLType rtnl_route_metrics_types[] = { [RTAX_FASTOPEN_NO_COOKIE] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem rtnl_route_metrics_type_system = { - .count = ELEMENTSOF(rtnl_route_metrics_types), - .types = rtnl_route_metrics_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_route_metrics); static const NLType rtnl_route_types[] = { [RTA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ @@ -731,10 +622,7 @@ static const NLType rtnl_route_types[] = { [RTA_NH_ID] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem rtnl_route_type_system = { - .count = ELEMENTSOF(rtnl_route_types), - .types = rtnl_route_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_route); static const NLType rtnl_neigh_types[] = { [NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, @@ -747,20 +635,14 @@ static const NLType rtnl_neigh_types[] = { [NDA_IFINDEX] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem rtnl_neigh_type_system = { - .count = ELEMENTSOF(rtnl_neigh_types), - .types = rtnl_neigh_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_neigh); static const NLType rtnl_addrlabel_types[] = { [IFAL_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) }, [IFAL_LABEL] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem rtnl_addrlabel_type_system = { - .count = ELEMENTSOF(rtnl_addrlabel_types), - .types = rtnl_addrlabel_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_addrlabel); static const NLType rtnl_routing_policy_rule_types[] = { [FRA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, @@ -785,10 +667,7 @@ static const NLType rtnl_routing_policy_rule_types[] = { [FRA_DPORT_RANGE] = { .size = sizeof(struct fib_rule_port_range) }, }; -static const NLTypeSystem rtnl_routing_policy_rule_type_system = { - .count = ELEMENTSOF(rtnl_routing_policy_rule_types), - .types = rtnl_routing_policy_rule_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_routing_policy_rule); static const NLType rtnl_nexthop_types[] = { [NHA_ID] = { .type = NETLINK_TYPE_U32 }, @@ -804,10 +683,7 @@ static const NLType rtnl_nexthop_types[] = { [NHA_FDB] = { .type = NETLINK_TYPE_FLAG }, }; -static const NLTypeSystem rtnl_nexthop_type_system = { - .count = ELEMENTSOF(rtnl_nexthop_types), - .types = rtnl_nexthop_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_nexthop); static const NLType rtnl_tca_option_data_cake_types[] = { [TCA_CAKE_BASE_RATE64] = { .type = NETLINK_TYPE_U64 }, @@ -831,19 +707,13 @@ static const NLType rtnl_tca_option_data_ets_quanta_types[] = { [TCA_ETS_QUANTA_BAND] = { .type = NETLINK_TYPE_U32, }, }; -static const NLTypeSystem rtnl_tca_option_data_ets_quanta_type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_ets_quanta_types), - .types = rtnl_tca_option_data_ets_quanta_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_tca_option_data_ets_quanta); static const NLType rtnl_tca_option_data_ets_prio_types[] = { [TCA_ETS_PRIOMAP_BAND] = { .type = NETLINK_TYPE_U8, }, }; -static const NLTypeSystem rtnl_tca_option_data_ets_prio_type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_ets_prio_types), - .types = rtnl_tca_option_data_ets_prio_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_tca_option_data_ets_prio); static const NLType rtnl_tca_option_data_ets_types[] = { [TCA_ETS_NBANDS] = { .type = NETLINK_TYPE_U8 }, @@ -925,56 +795,23 @@ static const NLType rtnl_tca_option_data_tbf_types[] = { }; static const NLTypeSystemUnionElement rtnl_tca_option_data_type_systems[] = { - { .name = "cake", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_cake_types), - .types = rtnl_tca_option_data_cake_types } }, - { .name = "codel", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_codel_types), - .types = rtnl_tca_option_data_codel_types } }, - { .name = "drr", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_drr_types), - .types = rtnl_tca_option_data_drr_types } }, - { .name = "ets", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_ets_types), - .types = rtnl_tca_option_data_ets_types } }, - { .name = "fq", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_fq_types), - .types = rtnl_tca_option_data_fq_types } }, - { .name = "fq_codel", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types), - .types = rtnl_tca_option_data_fq_codel_types } }, - { .name = "fq_pie", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_fq_pie_types), - .types = rtnl_tca_option_data_fq_pie_types } }, - { .name = "gred", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_gred_types), - .types = rtnl_tca_option_data_gred_types } }, - { .name = "hhf", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_hhf_types), - .types = rtnl_tca_option_data_hhf_types } }, - { .name = "htb", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_htb_types), - .types = rtnl_tca_option_data_htb_types } }, - { .name = "pie", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_pie_types), - .types = rtnl_tca_option_data_pie_types } }, - { .name = "qfq", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_qfq_types), - .types = rtnl_tca_option_data_qfq_types } }, - { .name = "sfb", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_sfb_types), - .types = rtnl_tca_option_data_sfb_types } }, - { .name = "tbf", .type_system = { - .count = ELEMENTSOF(rtnl_tca_option_data_tbf_types), - .types = rtnl_tca_option_data_tbf_types } }, + { .name = "cake", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_cake), }, + { .name = "codel", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_codel), }, + { .name = "drr", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_drr), }, + { .name = "ets", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_ets), }, + { .name = "fq", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_fq), }, + { .name = "fq_codel", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_fq_codel), }, + { .name = "fq_pie", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_fq_pie), }, + { .name = "gred", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_gred), }, + { .name = "hhf", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_hhf), }, + { .name = "htb", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_htb), }, + { .name = "pie", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_pie), }, + { .name = "qfq", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_qfq), }, + { .name = "sfb", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_sfb), }, + { .name = "tbf", .type_system = TYPE_SYSTEM_FROM_TYPE(rtnl_tca_option_data_tbf), }, }; -static const NLTypeSystemUnion rtnl_tca_option_data_type_system_union = { - .count = ELEMENTSOF(rtnl_tca_option_data_type_systems), - .elements = rtnl_tca_option_data_type_systems, - .match_type = NL_MATCH_SIBLING, - .match_attribute = TCA_KIND, -}; +DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(rtnl_tca_option_data, TCA_KIND); static const NLType rtnl_tca_types[] = { [TCA_KIND] = { .type = NETLINK_TYPE_STRING }, @@ -983,61 +820,52 @@ static const NLType rtnl_tca_types[] = { [TCA_EGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem rtnl_tca_type_system = { - .count = ELEMENTSOF(rtnl_tca_types), - .types = rtnl_tca_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_tca); -static const NLType mdb_types[] = { +static const NLType rtnl_mdb_types[] = { [MDBA_SET_ENTRY] = { .size = sizeof(struct br_port_msg) }, }; -static const NLTypeSystem rtnl_mdb_type_system = { - .count = ELEMENTSOF(mdb_types), - .types = mdb_types, -}; +DEFINE_TYPE_SYSTEM(rtnl_mdb); static const NLType rtnl_types[] = { - [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, - [RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, - [RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, + [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, + [RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, + [RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) }, [RTM_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, [RTM_DELRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, [RTM_GETRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct fib_rule_hdr) }, - [RTM_NEWNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, - [RTM_DELNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, - [RTM_GETNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, - [RTM_NEWQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_DELQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_GETQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_NEWTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_DELTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_GETTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, - [RTM_NEWMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, - [RTM_DELMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, - [RTM_GETMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, + [RTM_NEWNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, + [RTM_DELNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, + [RTM_GETNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) }, + [RTM_NEWQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_DELQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_GETQDISC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_NEWTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_DELTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_GETTCLASS] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_tca_type_system, .size = sizeof(struct tcmsg) }, + [RTM_NEWMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, + [RTM_DELMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, + [RTM_GETMDB] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_mdb_type_system, .size = sizeof(struct br_port_msg) }, }; -static const NLTypeSystem rtnl_type_system = { - .count = ELEMENTSOF(rtnl_types), - .types = rtnl_types, -}; +DEFINE_TYPE_SYSTEM(rtnl); int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret) { return type_system_get_type(&rtnl_type_system, ret, nlmsg_type); diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 0ae0fc6e99..0f17e7e8ad 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -9,30 +9,21 @@ static const NLType empty_types[1] = { /* fake array to avoid .types==NULL, which denotes invalid type-systems */ }; -static const NLTypeSystem empty_type_system = { - .count = 0, - .types = empty_types, -}; +DEFINE_TYPE_SYSTEM(empty); static const NLType error_types[] = { [NLMSGERR_ATTR_MSG] = { .type = NETLINK_TYPE_STRING }, [NLMSGERR_ATTR_OFFS] = { .type = NETLINK_TYPE_U32 }, }; -static const NLTypeSystem error_type_system = { - .count = ELEMENTSOF(error_types), - .types = error_types, -}; +DEFINE_TYPE_SYSTEM(error); static const NLType basic_types[] = { [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system }, [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) }, }; -const NLTypeSystem basic_type_system = { - .count = ELEMENTSOF(basic_types), - .types = basic_types, -}; +DEFINE_TYPE_SYSTEM(basic); uint16_t type_get_type(const NLType *type) { assert(type); From 1cedca05e4fadeef0bb88fb58cf9a989ab8e6af2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 17:41:14 +0900 Subject: [PATCH 22/29] sd-netlink: split message_new() into two parts and introduces message_new_full() --- src/libsystemd/sd-netlink/netlink-internal.h | 8 ++- src/libsystemd/sd-netlink/netlink-message.c | 62 ++++++++++++-------- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index d85b4a0774..e19b460bcd 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -126,8 +126,14 @@ struct sd_netlink_message { sd_netlink_message *next; /* next in a chain of multi-part messages */ }; -int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type); int message_new_empty(sd_netlink *nl, sd_netlink_message **ret); +int message_new_full( + sd_netlink *nl, + uint16_t nlmsg_type, + const NLTypeSystem *type_system, + size_t header_size, + sd_netlink_message **ret); +int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type); int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret); uint32_t message_get_serial(sd_netlink_message *m); void message_seal(sd_netlink_message *m); diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index fe4c2950c1..325c570b2e 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -23,7 +23,8 @@ int message_new_empty(sd_netlink *nl, sd_netlink_message **ret) { sd_netlink_message *m; - assert_return(ret, -EINVAL); + assert(nl); + assert(ret); /* Note that 'nl' is currently unused, if we start using it internally we must take care to * avoid problems due to mutual references between buses and their queued messages. See sd-bus. */ @@ -39,17 +40,51 @@ int message_new_empty(sd_netlink *nl, sd_netlink_message **ret) { }; *ret = m; + return 0; +} +int message_new_full( + sd_netlink *nl, + uint16_t nlmsg_type, + const NLTypeSystem *type_system, + size_t header_size, + sd_netlink_message **ret) { + + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + size_t size; + int r; + + assert(nl); + assert(type_system); + assert(ret); + + size = NLMSG_SPACE(header_size); + assert(size >= sizeof(struct nlmsghdr)); + + r = message_new_empty(nl, &m); + if (r < 0) + return r; + + m->containers[0].type_system = type_system; + + m->hdr = malloc0(size); + if (!m->hdr) + return -ENOMEM; + + m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + m->hdr->nlmsg_len = size; + m->hdr->nlmsg_type = nlmsg_type; + + *ret = TAKE_PTR(m); return 0; } int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const NLType *nl_type; - size_t size; int r; assert_return(nl, -EINVAL); + assert_return(ret, -EINVAL); r = type_system_root_get_type(nl, &nl_type, type); if (r < 0) @@ -58,26 +93,7 @@ int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type) { if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) return -EINVAL; - r = message_new_empty(nl, &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 | NLM_F_ACK; - - m->containers[0].type_system = type_get_type_system(nl_type); - m->hdr->nlmsg_len = size; - m->hdr->nlmsg_type = type; - - *ret = TAKE_PTR(m); - - return 0; + return message_new_full(nl, type, type_get_type_system(nl_type), type_get_size(nl_type), ret); } int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret) { From 56fdc16da81aa1608d0ab49e76cc124a579382ec Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 24 Aug 2021 18:11:20 +0900 Subject: [PATCH 23/29] sd-netlink: drop sd_genl_family_t and introduce GenericNetlinkFamily Kernel manages each genl family by its name, e.g. "nlctrl" or WG_GENL_NAME, and its ID (used for nlmsg_type) is determined dynamically when the corresponding module is loaded. This commit makes sd-netlink follow the same way; now, sd_genl_family_t is dropped, and sd_genl_message_new() takes a genl family name. Each genl family is resolved when it is used first time, and its information is stored in GenericNetlinkFamily. --- src/libsystemd/sd-netlink/netlink-genl.c | 349 +++++++++++++----- src/libsystemd/sd-netlink/netlink-genl.h | 4 +- src/libsystemd/sd-netlink/netlink-internal.h | 4 +- src/libsystemd/sd-netlink/netlink-message.c | 38 +- src/libsystemd/sd-netlink/netlink-socket.c | 6 +- .../sd-netlink/netlink-types-genl.c | 44 +-- src/libsystemd/sd-netlink/netlink-types.c | 48 ++- src/libsystemd/sd-netlink/netlink-types.h | 14 +- src/libsystemd/sd-netlink/sd-netlink.c | 4 +- src/libsystemd/sd-netlink/test-netlink.c | 22 +- src/network/netdev/batadv.c | 2 +- src/network/netdev/fou-tunnel.c | 2 +- src/network/netdev/l2tp-tunnel.c | 4 +- src/network/netdev/macsec.c | 2 +- src/network/netdev/wireguard.c | 2 +- src/network/test-network-tables.c | 1 - src/shared/wifi-util.c | 21 +- src/systemd/sd-netlink.h | 19 +- 18 files changed, 375 insertions(+), 211 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 06406add49..1aeca0c5cf 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -7,91 +7,196 @@ #include "alloc-util.h" #include "netlink-genl.h" #include "netlink-internal.h" +#include "netlink-types.h" -typedef struct { - const char* name; - uint8_t version; -} genl_family; +typedef struct GenericNetlinkFamily { + sd_netlink *genl; -static const genl_family genl_families[] = { - [SD_GENL_ID_CTRL] = { .name = "", .version = 1 }, - [SD_GENL_WIREGUARD] = { .name = "wireguard", .version = 1 }, - [SD_GENL_FOU] = { .name = "fou", .version = 1 }, - [SD_GENL_L2TP] = { .name = "l2tp", .version = 1 }, - [SD_GENL_MACSEC] = { .name = "macsec", .version = 1 }, - [SD_GENL_NL80211] = { .name = "nl80211", .version = 1 }, - [SD_GENL_BATADV] = { .name = "batadv", .version = 1 }, + const NLTypeSystem *type_system; + + uint16_t id; /* a.k.a nlmsg_type */ + char *name; +} GenericNetlinkFamily; + +static const GenericNetlinkFamily nlctrl_static = { + .id = GENL_ID_CTRL, + .name = (char*) CTRL_GENL_NAME, }; -int sd_genl_socket_open(sd_netlink **ret) { - return netlink_open_family(ret, NETLINK_GENERIC); +static GenericNetlinkFamily *genl_family_free(GenericNetlinkFamily *f) { + if (!f) + return NULL; + + if (f->genl) { + if (f->id > 0) + hashmap_remove(f->genl->genl_family_by_id, UINT_TO_PTR(f->id)); + if (f->name) + hashmap_remove(f->genl->genl_family_by_name, f->name); + } + + free(f->name); + + return mfree(f); } -static int genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint16_t nlmsg_type, uint8_t cmd, sd_netlink_message **ret) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - const NLType *type; - size_t size; +DEFINE_TRIVIAL_CLEANUP_FUNC(GenericNetlinkFamily*, genl_family_free); + +void genl_clear_family(sd_netlink *nl) { + assert(nl); + + nl->genl_family_by_name = hashmap_free_with_destructor(nl->genl_family_by_name, genl_family_free); + nl->genl_family_by_id = hashmap_free_with_destructor(nl->genl_family_by_id, genl_family_free); +} + +static int genl_family_new( + sd_netlink *nl, + const char *expected_family_name, + const NLTypeSystem *type_system, + sd_netlink_message *message, + const GenericNetlinkFamily **ret) { + + _cleanup_(genl_family_freep) GenericNetlinkFamily *f = NULL; + const char *family_name; int r; assert(nl); - assert(nl->protocol == NETLINK_GENERIC); + assert(expected_family_name); + assert(type_system); + assert(message); assert(ret); - r = type_system_root_get_type(nl, &type, nlmsg_type); - if (r < 0) - return r; - - r = message_new_empty(nl, &m); - if (r < 0) - return r; - - size = NLMSG_SPACE(sizeof(struct genlmsghdr)); - m->hdr = malloc0(size); - if (!m->hdr) + f = new(GenericNetlinkFamily, 1); + if (!f) return -ENOMEM; - m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - m->hdr->nlmsg_len = size; - m->hdr->nlmsg_type = nlmsg_type; - - m->containers[0].type_system = type_get_type_system(type); - - *(struct genlmsghdr *) NLMSG_DATA(m->hdr) = (struct genlmsghdr) { - .cmd = cmd, - .version = genl_families[family].version, + *f = (GenericNetlinkFamily) { + .type_system = type_system, }; - *ret = TAKE_PTR(m); + if (sd_netlink_message_is_error(message)) { + int e; + /* Kernel does not support the genl family? To prevent from resolving the family name + * again, let's store the family with zero id to indicate that. */ + + e = sd_netlink_message_get_errno(message); + if (e >= 0) /* Huh? */ + e = -EOPNOTSUPP; + + f->name = strdup(expected_family_name); + if (!f->name) + return e; + + if (hashmap_ensure_put(&nl->genl_family_by_name, &string_hash_ops, f->name, f) < 0) + return e; + + f->genl = nl; + TAKE_PTR(f); + return e; + } + + r = sd_genl_message_get_family_name(nl, message, &family_name); + if (r < 0) + return r; + + if (!streq(family_name, CTRL_GENL_NAME)) + return -EINVAL; + + r = sd_netlink_message_read_u16(message, CTRL_ATTR_FAMILY_ID, &f->id); + if (r < 0) + return r; + + r = sd_netlink_message_read_string_strdup(message, CTRL_ATTR_FAMILY_NAME, &f->name); + if (r < 0) + return r; + + if (!streq(f->name, expected_family_name)) + return -EINVAL; + + r = hashmap_ensure_put(&nl->genl_family_by_id, NULL, UINT_TO_PTR(f->id), f); + if (r < 0) + return r; + + r = hashmap_ensure_put(&nl->genl_family_by_name, &string_hash_ops, f->name, f); + if (r < 0) { + hashmap_remove(nl->genl_family_by_id, UINT_TO_PTR(f->id)); + return r; + } + + f->genl = nl; + *ret = TAKE_PTR(f); return 0; } -static int lookup_nlmsg_type(sd_netlink *nl, sd_genl_family_t family, uint16_t *ret) { - _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; - uint16_t u; - void *v; +static int genl_family_get_type_system(const GenericNetlinkFamily *family, const NLTypeSystem **ret) { + assert(family); + assert(ret); + + if (family->type_system) { + *ret = family->type_system; + return 0; + } + + return genl_get_type_system_by_name(family->name, ret); +} + +static int genl_message_new( + sd_netlink *nl, + const GenericNetlinkFamily *family, + uint8_t cmd, + sd_netlink_message **ret) { + + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + const NLTypeSystem *type_system; int r; assert(nl); assert(nl->protocol == NETLINK_GENERIC); + assert(family); assert(ret); - if (family == SD_GENL_ID_CTRL) { - *ret = GENL_ID_CTRL; - return 0; - } - - v = hashmap_get(nl->genl_family_to_nlmsg_type, INT_TO_PTR(family)); - if (v) { - *ret = PTR_TO_UINT(v); - return 0; - } - - r = genl_message_new(nl, SD_GENL_ID_CTRL, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &req); + r = genl_family_get_type_system(family, &type_system); if (r < 0) return r; - r = sd_netlink_message_append_string(req, CTRL_ATTR_FAMILY_NAME, genl_families[family].name); + r = message_new_full(nl, family->id, type_system, sizeof(struct genlmsghdr), &m); + if (r < 0) + return r; + + *(struct genlmsghdr *) NLMSG_DATA(m->hdr) = (struct genlmsghdr) { + .cmd = cmd, + .version = 1, + }; + + *ret = TAKE_PTR(m); + return 0; +} + +static int genl_family_get_by_name_internal( + sd_netlink *nl, + const GenericNetlinkFamily *ctrl, + const char *name, + const GenericNetlinkFamily **ret) { + + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; + const NLTypeSystem *type_system; + int r; + + assert(nl); + assert(nl->protocol == NETLINK_GENERIC); + assert(ctrl); + assert(name); + assert(ret); + + r = genl_get_type_system_by_name(name, &type_system); + if (r < 0) + return r; + + r = genl_message_new(nl, ctrl, CTRL_CMD_GETFAMILY, &req); + if (r < 0) + return r; + + r = sd_netlink_message_append_string(req, CTRL_ATTR_FAMILY_NAME, name); if (r < 0) return r; @@ -99,62 +204,105 @@ static int lookup_nlmsg_type(sd_netlink *nl, sd_genl_family_t family, uint16_t * if (r < 0) return r; - r = sd_netlink_message_read_u16(reply, CTRL_ATTR_FAMILY_ID, &u); - if (r < 0) - return r; - - r = hashmap_ensure_put(&nl->genl_family_to_nlmsg_type, NULL, INT_TO_PTR(family), UINT_TO_PTR(u)); - if (r < 0) - return r; - - r = hashmap_ensure_put(&nl->nlmsg_type_to_genl_family, NULL, UINT_TO_PTR(u), INT_TO_PTR(family)); - if (r < 0) - return r; - - *ret = u; - return 0; + return genl_family_new(nl, name, type_system, reply, ret); } -int sd_genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret) { - uint16_t nlmsg_type = 0; /* Unnecessary initialization to appease gcc */ +static int genl_family_get_by_name(sd_netlink *nl, const char *name, const GenericNetlinkFamily **ret) { + const GenericNetlinkFamily *f, *ctrl; int r; - assert_return(nl, -EINVAL); - assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL); - assert_return(ret, -EINVAL); + assert(nl); + assert(nl->protocol == NETLINK_GENERIC); + assert(name); + assert(ret); - r = lookup_nlmsg_type(nl, family, &nlmsg_type); - if (r < 0) - return r; + f = hashmap_get(nl->genl_family_by_name, name); + if (f) { + if (f->id == 0) /* kernel does not support the family. */ + return -EOPNOTSUPP; - return genl_message_new(nl, family, nlmsg_type, cmd, ret); + *ret = f; + return 0; + } + + if (streq(name, CTRL_GENL_NAME)) + return genl_family_get_by_name_internal(nl, &nlctrl_static, CTRL_GENL_NAME, ret); + + ctrl = hashmap_get(nl->genl_family_by_name, CTRL_GENL_NAME); + if (!ctrl) { + r = genl_family_get_by_name_internal(nl, &nlctrl_static, CTRL_GENL_NAME, &ctrl); + if (r < 0) + return r; + } + + return genl_family_get_by_name_internal(nl, ctrl, name, ret); } -int nlmsg_type_to_genl_family(const sd_netlink *nl, uint16_t nlmsg_type, sd_genl_family_t *ret) { - void *p; +static int genl_family_get_by_id(sd_netlink *nl, uint16_t id, const GenericNetlinkFamily **ret) { + const GenericNetlinkFamily *f; assert(nl); assert(nl->protocol == NETLINK_GENERIC); assert(ret); - if (nlmsg_type == NLMSG_ERROR) - *ret = SD_GENL_ERROR; - else if (nlmsg_type == NLMSG_DONE) - *ret = SD_GENL_DONE; - else if (nlmsg_type == GENL_ID_CTRL) - *ret = SD_GENL_ID_CTRL; - else { - p = hashmap_get(nl->nlmsg_type_to_genl_family, UINT_TO_PTR(nlmsg_type)); - if (!p) - return -EOPNOTSUPP; - - *ret = PTR_TO_INT(p); + f = hashmap_get(nl->genl_family_by_id, UINT_TO_PTR(id)); + if (f) { + *ret = f; + return 0; } + if (id == GENL_ID_CTRL) { + *ret = &nlctrl_static; + return 0; + } + + return -ENOENT; +} + +int genl_get_type_system_and_header_size( + sd_netlink *nl, + uint16_t id, + const NLTypeSystem **ret_type_system, + size_t *ret_header_size) { + + const GenericNetlinkFamily *f; + int r; + + assert(nl); + assert(nl->protocol == NETLINK_GENERIC); + + r = genl_family_get_by_id(nl, id, &f); + if (r < 0) + return r; + + if (ret_type_system) { + r = genl_family_get_type_system(f, ret_type_system); + if (r < 0) + return r; + } + if (ret_header_size) + *ret_header_size = sizeof(struct genlmsghdr); return 0; } -int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *ret) { +int sd_genl_message_new(sd_netlink *nl, const char *family_name, uint8_t cmd, sd_netlink_message **ret) { + const GenericNetlinkFamily *family; + int r; + + assert_return(nl, -EINVAL); + assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL); + assert_return(family_name, -EINVAL); + assert_return(ret, -EINVAL); + + r = genl_family_get_by_name(nl, family_name, &family); + if (r < 0) + return r; + + return genl_message_new(nl, family, cmd, ret); +} + +int sd_genl_message_get_family_name(sd_netlink *nl, sd_netlink_message *m, const char **ret) { + const GenericNetlinkFamily *family; uint16_t nlmsg_type; int r; @@ -167,5 +315,14 @@ int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_fa if (r < 0) return r; - return nlmsg_type_to_genl_family(nl, nlmsg_type, ret); + r = genl_family_get_by_id(nl, nlmsg_type, &family); + if (r < 0) + return r; + + *ret = family->name; + return 0; +} + +int sd_genl_socket_open(sd_netlink **ret) { + return netlink_open_family(ret, NETLINK_GENERIC); } diff --git a/src/libsystemd/sd-netlink/netlink-genl.h b/src/libsystemd/sd-netlink/netlink-genl.h index fd0461426b..b06be05952 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.h +++ b/src/libsystemd/sd-netlink/netlink-genl.h @@ -3,4 +3,6 @@ #include "sd-netlink.h" -int nlmsg_type_to_genl_family(const sd_netlink *nl, uint16_t type, sd_genl_family_t *ret); +#define CTRL_GENL_NAME "nlctrl" + +void genl_clear_family(sd_netlink *nl); diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index e19b460bcd..2594885fe6 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -95,8 +95,8 @@ struct sd_netlink { sd_event_source *exit_event_source; sd_event *event; - Hashmap *genl_family_to_nlmsg_type; - Hashmap *nlmsg_type_to_genl_family; + Hashmap *genl_family_by_name; + Hashmap *genl_family_by_id; }; struct netlink_attribute { diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 325c570b2e..0c9b5454b6 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -80,20 +80,18 @@ int message_new_full( } int message_new(sd_netlink *nl, sd_netlink_message **ret, uint16_t type) { - const NLType *nl_type; + const NLTypeSystem *type_system; + size_t size; int r; assert_return(nl, -EINVAL); assert_return(ret, -EINVAL); - r = type_system_root_get_type(nl, &nl_type, type); + r = type_system_root_get_type_system_and_header_size(nl, type, &type_system, &size); if (r < 0) return r; - if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) - return -EINVAL; - - return message_new_full(nl, type, type_get_type_system(nl_type), type_get_size(nl_type), ret); + return message_new_full(nl, type, type_system, size, ret); } int message_new_synthetic_error(sd_netlink *nl, int error, uint32_t serial, sd_netlink_message **ret) { @@ -1319,8 +1317,6 @@ static int netlink_message_parse_error(sd_netlink_message *m) { } int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *nl) { - const NLType *nl_type; - uint16_t type; size_t size; int r; @@ -1341,28 +1337,18 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *nl) { assert(m->hdr); - r = type_system_root_get_type(nl, &nl_type, m->hdr->nlmsg_type); + r = type_system_root_get_type_system_and_header_size(nl, m->hdr->nlmsg_type, + &m->containers[0].type_system, &size); if (r < 0) return r; - type = type_get_type(nl_type); - size = type_get_size(nl_type); + if (sd_netlink_message_is_error(m)) + return netlink_message_parse_error(m); - if (type == NETLINK_TYPE_NESTED) { - m->containers[0].type_system = type_get_type_system(nl_type); - - if (sd_netlink_message_is_error(m)) - r = netlink_message_parse_error(m); - else - r = netlink_container_parse(m, - &m->containers[m->n_containers], - (struct rtattr*)((uint8_t*) NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), - NLMSG_PAYLOAD(m->hdr, size)); - if (r < 0) - return r; - } - - return 0; + return netlink_container_parse(m, + &m->containers[0], + (struct rtattr*)((uint8_t*) NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), + NLMSG_PAYLOAD(m->hdr, size)); } void message_seal(sd_netlink_message *m) { diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 1168f4edc0..15c2789bee 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -326,7 +326,7 @@ int socket_read_message(sd_netlink *nl) { for (struct nlmsghdr *new_msg = nl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; - const NLType *nl_type; + size_t size; if (!group && new_msg->nlmsg_pid != nl->sockaddr.nl.nl_pid) /* not broadcast and not for us */ @@ -346,7 +346,7 @@ int socket_read_message(sd_netlink *nl) { } /* check that we support this message type */ - r = type_system_root_get_type(nl, &nl_type, new_msg->nlmsg_type); + r = type_system_root_get_type_system_and_header_size(nl, new_msg->nlmsg_type, NULL, &size); if (r < 0) { if (r == -EOPNOTSUPP) log_debug("sd-netlink: ignored message with unknown type: %i", @@ -356,7 +356,7 @@ int socket_read_message(sd_netlink *nl) { } /* check that the size matches the message type */ - if (new_msg->nlmsg_len < NLMSG_LENGTH(type_get_size(nl_type))) { + if (new_msg->nlmsg_len < NLMSG_LENGTH(size)) { log_debug("sd-netlink: message is shorter than expected, dropping"); continue; } diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index 33e80a1745..dde682f626 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -44,8 +44,6 @@ static const NLType genl_ctrl_types[] = { [CTRL_ATTR_OP] = { .type = NETLINK_TYPE_U32 }, }; -DEFINE_TYPE_SYSTEM(genl_ctrl); - /***************** genl batadv type systems *****************/ static const NLType genl_batadv_types[] = { [BATADV_ATTR_VERSION] = { .type = NETLINK_TYPE_STRING }, @@ -110,8 +108,6 @@ static const NLType genl_batadv_types[] = { [BATADV_ATTR_THROUGHPUT_OVERRIDE] = { .type = NETLINK_TYPE_U32 }, }; -DEFINE_TYPE_SYSTEM(genl_batadv); - /***************** genl fou type systems *****************/ static const NLType genl_fou_types[] = { [FOU_ATTR_PORT] = { .type = NETLINK_TYPE_U16 }, @@ -127,8 +123,6 @@ static const NLType genl_fou_types[] = { [FOU_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32}, }; -DEFINE_TYPE_SYSTEM(genl_fou); - /***************** genl l2tp type systems *****************/ static const NLType genl_l2tp_types[] = { [L2TP_ATTR_PW_TYPE] = { .type = NETLINK_TYPE_U16 }, @@ -160,8 +154,6 @@ static const NLType genl_l2tp_types[] = { [L2TP_ATTR_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_FLAG }, }; -DEFINE_TYPE_SYSTEM(genl_l2tp); - /***************** genl macsec type systems *****************/ static const NLType genl_macsec_rxsc_types[] = { [MACSEC_RXSC_ATTR_SCI] = { .type = NETLINK_TYPE_U64 }, @@ -185,8 +177,6 @@ static const NLType genl_macsec_types[] = { [MACSEC_ATTR_SA_CONFIG] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_sa_type_system }, }; -DEFINE_TYPE_SYSTEM(genl_macsec); - /***************** genl nl80211 type systems *****************/ static const NLType genl_nl80211_types[] = { [NL80211_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 }, @@ -195,8 +185,6 @@ static const NLType genl_nl80211_types[] = { [NL80211_ATTR_IFTYPE] = { .type = NETLINK_TYPE_U32 }, }; -DEFINE_TYPE_SYSTEM(genl_nl80211); - /***************** genl wireguard type systems *****************/ static const NLType genl_wireguard_allowedip_types[] = { [WGALLOWEDIP_A_FAMILY] = { .type = NETLINK_TYPE_U16 }, @@ -227,28 +215,20 @@ static const NLType genl_wireguard_types[] = { [WGDEVICE_A_PEERS] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_peer_type_system }, }; -DEFINE_TYPE_SYSTEM(genl_wireguard); - /***************** genl families *****************/ -static const NLType genl_types[] = { - [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_WIREGUARD] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_wireguard_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_FOU] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_fou_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_L2TP] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_l2tp_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_MACSEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_macsec_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) }, - [SD_GENL_BATADV] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_batadv_type_system, .size = sizeof(struct genlmsghdr) }, +static const NLTypeSystemUnionElement genl_type_systems[] = { + { .name = CTRL_GENL_NAME, .type_system = TYPE_SYSTEM_FROM_TYPE(genl_ctrl), }, + { .name = BATADV_NL_NAME, .type_system = TYPE_SYSTEM_FROM_TYPE(genl_batadv), }, + { .name = FOU_GENL_NAME, .type_system = TYPE_SYSTEM_FROM_TYPE(genl_fou), }, + { .name = L2TP_GENL_NAME, .type_system = TYPE_SYSTEM_FROM_TYPE(genl_l2tp), }, + { .name = MACSEC_GENL_NAME, .type_system = TYPE_SYSTEM_FROM_TYPE(genl_macsec), }, + { .name = NL80211_GENL_NAME, .type_system = TYPE_SYSTEM_FROM_TYPE(genl_nl80211), }, + { .name = WG_GENL_NAME, .type_system = TYPE_SYSTEM_FROM_TYPE(genl_wireguard), }, }; -DEFINE_TYPE_SYSTEM(genl); +/* This is the root type system union, so match_attribute is not necessary. */ +DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(genl, 0); -int genl_get_type(sd_netlink *genl, uint16_t nlmsg_type, const NLType **ret) { - sd_genl_family_t family; - int r; - - r = nlmsg_type_to_genl_family(genl, nlmsg_type, &family); - if (r < 0) - return r; - - return type_system_get_type(&genl_type_system, ret, family); +int genl_get_type_system_by_name(const char *name, const NLTypeSystem **ret) { + return type_system_union_get_type_system_by_string(&genl_type_system_union, ret, name); } diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 0f17e7e8ad..7d6caf004b 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -2,6 +2,7 @@ #include +#include "netlink-genl.h" #include "netlink-internal.h" #include "netlink-types-internal.h" @@ -54,20 +55,43 @@ uint16_t type_system_get_count(const NLTypeSystem *type_system) { return type_system->count; } -int type_system_root_get_type(sd_netlink *nl, const NLType **ret, uint16_t type) { - if (!nl || IN_SET(type, NLMSG_DONE, NLMSG_ERROR)) - return type_system_get_type(&basic_type_system, ret, type); +int type_system_root_get_type_system_and_header_size( + sd_netlink *nl, + uint16_t type, + const NLTypeSystem **ret_type_system, + size_t *ret_header_size) { - switch(nl->protocol) { - case NETLINK_ROUTE: - return rtnl_get_type(type, ret); - case NETLINK_NETFILTER: - return nfnl_get_type(type, ret); - case NETLINK_GENERIC: - return genl_get_type(nl, type, ret); - default: + const NLType *nl_type; + int r; + + assert(nl); + + if (IN_SET(type, NLMSG_DONE, NLMSG_ERROR)) + r = type_system_get_type(&basic_type_system, &nl_type, type); + else + switch(nl->protocol) { + case NETLINK_ROUTE: + r = rtnl_get_type(type, &nl_type); + break; + case NETLINK_NETFILTER: + r = nfnl_get_type(type, &nl_type); + break; + case NETLINK_GENERIC: + return genl_get_type_system_and_header_size(nl, type, ret_type_system, ret_header_size); + default: + return -EOPNOTSUPP; + } + if (r < 0) + return r; + + if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) return -EOPNOTSUPP; - } + + if (ret_type_system) + *ret_type_system = type_get_type_system(nl_type); + if (ret_header_size) + *ret_header_size = type_get_size(nl_type); + return 0; } int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index baab1dbdb0..f8261b681c 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -37,15 +37,25 @@ typedef struct NLType NLType; int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret); int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret); -int genl_get_type(sd_netlink *genl, uint16_t nlmsg_type, const NLType **ret); +int genl_get_type_system_by_name(const char *name, const NLTypeSystem **ret); +int genl_get_type_system_and_header_size( + sd_netlink *nl, + uint16_t id, + const NLTypeSystem **ret_type_system, + size_t *ret_header_size); uint16_t type_get_type(const NLType *type); size_t type_get_size(const NLType *type); const NLTypeSystem *type_get_type_system(const NLType *type); const NLTypeSystemUnion *type_get_type_system_union(const NLType *type); +int type_system_root_get_type_system_and_header_size( + sd_netlink *nl, + uint16_t type, + const NLTypeSystem **ret_type_system, + size_t *ret_header_size); + uint16_t type_system_get_count(const NLTypeSystem *type_system); -int type_system_root_get_type(sd_netlink *nl, const NLType **ret, uint16_t type); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index 22697aa992..2305333575 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -9,6 +9,7 @@ #include "hashmap.h" #include "io-util.h" #include "macro.h" +#include "netlink-genl.h" #include "netlink-internal.h" #include "netlink-slot.h" #include "process-util.h" @@ -196,8 +197,7 @@ static sd_netlink *netlink_free(sd_netlink *nl) { hashmap_free(nl->broadcast_group_refs); - hashmap_free(nl->genl_family_to_nlmsg_type); - hashmap_free(nl->nlmsg_type_to_genl_family); + genl_clear_family(nl); safe_close(nl->fd); return mfree(nl); diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index a87fe11069..6cc6cdad45 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -9,6 +9,7 @@ #include "alloc-util.h" #include "ether-addr-util.h" #include "macro.h" +#include "netlink-genl.h" #include "netlink-internal.h" #include "netlink-util.h" #include "socket-util.h" @@ -514,7 +515,7 @@ static void test_array(void) { log_debug("/* %s */", __func__); assert_se(sd_genl_socket_open(&genl) >= 0); - assert_se(sd_genl_message_new(genl, SD_GENL_ID_CTRL, CTRL_CMD_GETFAMILY, &m) >= 0); + assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0); assert_se(sd_netlink_message_open_container(m, CTRL_ATTR_MCAST_GROUPS) >= 0); for (unsigned i = 0; i < 10; i++) { @@ -582,6 +583,23 @@ static void test_strv(sd_netlink *rtnl) { assert_se(sd_netlink_message_exit_container(m) >= 0); } +static void test_genl(void) { + _cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; + const char *name; + + log_debug("/* %s */", __func__); + + assert_se(sd_genl_socket_open(&genl) >= 0); + assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0); + assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0); + assert_se(streq(name, CTRL_GENL_NAME)); + + m = sd_netlink_message_unref(m); + assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) < 0); + assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) == -EOPNOTSUPP); +} + int main(void) { sd_netlink *rtnl; sd_netlink_message *m; @@ -642,5 +660,7 @@ int main(void) { assert_se((r = sd_netlink_message_unref(r)) == NULL); assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL); + test_genl(); + return EXIT_SUCCESS; } diff --git a/src/network/netdev/batadv.c b/src/network/netdev/batadv.c index 1f899e90f6..1d12fc79cc 100644 --- a/src/network/netdev/batadv.c +++ b/src/network/netdev/batadv.c @@ -122,7 +122,7 @@ static int netdev_batadv_post_create(NetDev *netdev, Link *link, sd_netlink_mess b = BATADV(netdev); assert(b); - r = sd_genl_message_new(netdev->manager->genl, SD_GENL_BATADV, BATADV_CMD_SET_MESH, &message); + r = sd_genl_message_new(netdev->manager->genl, BATADV_NL_NAME, BATADV_CMD_SET_MESH, &message); if (r < 0) return log_netdev_error_errno(netdev, r, "Failed to allocate generic netlink message: %m"); diff --git a/src/network/netdev/fou-tunnel.c b/src/network/netdev/fou-tunnel.c index e01de0f151..bc4c108a22 100644 --- a/src/network/netdev/fou-tunnel.c +++ b/src/network/netdev/fou-tunnel.c @@ -36,7 +36,7 @@ static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message **r assert(t); - r = sd_genl_message_new(netdev->manager->genl, SD_GENL_FOU, FOU_CMD_ADD, &m); + r = sd_genl_message_new(netdev->manager->genl, FOU_GENL_NAME, FOU_CMD_ADD, &m); if (r < 0) return log_netdev_error_errno(netdev, r, "Failed to allocate generic netlink message: %m"); diff --git a/src/network/netdev/l2tp-tunnel.c b/src/network/netdev/l2tp-tunnel.c index f651b2f7bf..a04fa6ac46 100644 --- a/src/network/netdev/l2tp-tunnel.c +++ b/src/network/netdev/l2tp-tunnel.c @@ -104,7 +104,7 @@ static int netdev_l2tp_fill_message_tunnel(NetDev *netdev, union in_addr_union * assert(t); - r = sd_genl_message_new(netdev->manager->genl, SD_GENL_L2TP, L2TP_CMD_TUNNEL_CREATE, &m); + r = sd_genl_message_new(netdev->manager->genl, L2TP_GENL_NAME, L2TP_CMD_TUNNEL_CREATE, &m); if (r < 0) return log_netdev_error_errno(netdev, r, "Failed to create generic netlink message: %m"); @@ -195,7 +195,7 @@ static int netdev_l2tp_fill_message_session(NetDev *netdev, L2tpSession *session assert(session); assert(session->tunnel); - r = sd_genl_message_new(netdev->manager->genl, SD_GENL_L2TP, L2TP_CMD_SESSION_CREATE, &m); + r = sd_genl_message_new(netdev->manager->genl, L2TP_GENL_NAME, L2TP_CMD_SESSION_CREATE, &m); if (r < 0) return log_netdev_error_errno(netdev, r, "Failed to create generic netlink message: %m"); diff --git a/src/network/netdev/macsec.c b/src/network/netdev/macsec.c index 74e9fdd10b..3b0c940804 100644 --- a/src/network/netdev/macsec.c +++ b/src/network/netdev/macsec.c @@ -224,7 +224,7 @@ static int netdev_macsec_fill_message(NetDev *netdev, int command, sd_netlink_me assert(netdev); assert(netdev->ifindex > 0); - r = sd_genl_message_new(netdev->manager->genl, SD_GENL_MACSEC, command, &m); + r = sd_genl_message_new(netdev->manager->genl, MACSEC_GENL_NAME, command, &m); if (r < 0) return log_netdev_error_errno(netdev, r, "Failed to create generic netlink message: %m"); diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index b8fc492d4f..1e90cad2e7 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -229,7 +229,7 @@ static int wireguard_set_interface(NetDev *netdev) { message = sd_netlink_message_unref(message); - r = sd_genl_message_new(netdev->manager->genl, SD_GENL_WIREGUARD, WG_CMD_SET_DEVICE, &message); + r = sd_genl_message_new(netdev->manager->genl, WG_GENL_NAME, WG_CMD_SET_DEVICE, &message); if (r < 0) return log_netdev_error_errno(netdev, r, "Failed to allocate generic netlink message: %m"); diff --git a/src/network/test-network-tables.c b/src/network/test-network-tables.c index f687a1a370..b7b536f3b5 100644 --- a/src/network/test-network-tables.c +++ b/src/network/test-network-tables.c @@ -46,7 +46,6 @@ int main(int argc, char **argv) { assert_cc(sizeof(sd_lldp_event_t) == sizeof(int64_t)); assert_cc(sizeof(sd_ndisc_event_t) == sizeof(int64_t)); assert_cc(sizeof(sd_dhcp_lease_server_type_t) == sizeof(int64_t)); - assert_cc(sizeof(sd_genl_family_t) == sizeof(int64_t)); return EXIT_SUCCESS; } diff --git a/src/shared/wifi-util.c b/src/shared/wifi-util.c index b05e1aa0df..5891208076 100644 --- a/src/shared/wifi-util.c +++ b/src/shared/wifi-util.c @@ -1,17 +1,18 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "log.h" +#include "string-util.h" #include "wifi-util.h" int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftype, char **ssid) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL; - sd_genl_family_t family; + const char *family; int r; assert(genl); assert(ifindex > 0); - r = sd_genl_message_new(genl, SD_GENL_NL80211, NL80211_CMD_GET_INTERFACE, &m); + r = sd_genl_message_new(genl, NL80211_GENL_NAME, NL80211_CMD_GET_INTERFACE, &m); if (r < 0) return log_debug_errno(r, "Failed to create generic netlink message: %m"); @@ -38,11 +39,11 @@ int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftyp if (r < 0) return log_debug_errno(r, "Failed to get information about wifi interface %d: %m", ifindex); - r = sd_genl_message_get_family(genl, reply, &family); + r = sd_genl_message_get_family_name(genl, reply, &family); if (r < 0) return log_debug_errno(r, "Failed to determine genl family: %m"); - if (family != SD_GENL_NL80211) { - log_debug("Received message of unexpected genl family %" PRIi64 ", ignoring.", family); + if (!streq(family, NL80211_GENL_NAME)) { + log_debug("Received message of unexpected genl family '%s', ignoring.", family); goto nodata; } @@ -75,14 +76,14 @@ nodata: int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *bssid) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL; - sd_genl_family_t family; + const char *family; int r; assert(genl); assert(ifindex > 0); assert(bssid); - r = sd_genl_message_new(genl, SD_GENL_NL80211, NL80211_CMD_GET_STATION, &m); + r = sd_genl_message_new(genl, NL80211_GENL_NAME, NL80211_CMD_GET_STATION, &m); if (r < 0) return log_debug_errno(r, "Failed to create generic netlink message: %m"); @@ -106,11 +107,11 @@ int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *bssid) { if (r < 0) return log_debug_errno(r, "Failed to get information about wifi station: %m"); - r = sd_genl_message_get_family(genl, reply, &family); + r = sd_genl_message_get_family_name(genl, reply, &family); if (r < 0) return log_debug_errno(r, "Failed to determine genl family: %m"); - if (family != SD_GENL_NL80211) { - log_debug("Received message of unexpected genl family %" PRIi64 ", ignoring.", family); + if (!streq(family, NL80211_GENL_NAME)) { + log_debug("Received message of unexpected genl family '%s', ignoring.", family); goto nodata; } diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index c67ea87540..6bb93fdf17 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -34,21 +34,6 @@ typedef struct sd_netlink sd_netlink; typedef struct sd_netlink_message sd_netlink_message; typedef struct sd_netlink_slot sd_netlink_slot; -typedef enum sd_genl_family_t { - SD_GENL_ERROR, - SD_GENL_DONE, - SD_GENL_ID_CTRL, - SD_GENL_WIREGUARD, - SD_GENL_FOU, - SD_GENL_L2TP, - SD_GENL_MACSEC, - SD_GENL_NL80211, - SD_GENL_BATADV, - _SD_GENL_FAMILY_MAX, - _SD_GENL_FAMILY_INVALID = -EINVAL, - _SD_ENUM_FORCE_S64(GENL_FAMILY) -} sd_genl_family_t; - /* callback */ typedef int (*sd_netlink_message_handler_t)(sd_netlink *nl, sd_netlink_message *m, void *userdata); typedef _sd_destroy_t sd_netlink_destroy_t; @@ -250,8 +235,8 @@ int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m); /* genl */ int sd_genl_socket_open(sd_netlink **ret); -int sd_genl_message_new(sd_netlink *genl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **ret); -int sd_genl_message_get_family(sd_netlink *genl, sd_netlink_message *m, sd_genl_family_t *ret); +int sd_genl_message_new(sd_netlink *genl, const char *family_name, uint8_t cmd, sd_netlink_message **ret); +int sd_genl_message_get_family_name(sd_netlink *genl, sd_netlink_message *m, const char **ret); /* slot */ sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *slot); From 52313394ba4f2e57156d0ba1a4c4ddc669dbf7f0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 4 Jul 2021 20:05:35 +0900 Subject: [PATCH 24/29] sd-netlink: read protocol version of each genl family --- src/libsystemd/sd-netlink/netlink-genl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 1aeca0c5cf..f454dbd837 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -16,11 +16,13 @@ typedef struct GenericNetlinkFamily { uint16_t id; /* a.k.a nlmsg_type */ char *name; + uint32_t version; } GenericNetlinkFamily; static const GenericNetlinkFamily nlctrl_static = { .id = GENL_ID_CTRL, .name = (char*) CTRL_GENL_NAME, + .version = 0x01, }; static GenericNetlinkFamily *genl_family_free(GenericNetlinkFamily *f) { @@ -113,6 +115,10 @@ static int genl_family_new( if (!streq(f->name, expected_family_name)) return -EINVAL; + r = sd_netlink_message_read_u32(message, CTRL_ATTR_VERSION, &f->version); + if (r < 0) + return r; + r = hashmap_ensure_put(&nl->genl_family_by_id, NULL, UINT_TO_PTR(f->id), f); if (r < 0) return r; @@ -165,7 +171,7 @@ static int genl_message_new( *(struct genlmsghdr *) NLMSG_DATA(m->hdr) = (struct genlmsghdr) { .cmd = cmd, - .version = 1, + .version = family->version, }; *ret = TAKE_PTR(m); From 44f1072a9ddf9ad33a1fe76bae3d16f4a818ea79 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 3 Jul 2021 06:53:08 +0900 Subject: [PATCH 25/29] sd-netlink: determine header size of genl message by using CTRL_ATTR_HDRSIZE attribute Fortunately, all genl families we currently use do not require additional header size. --- src/libsystemd/sd-netlink/netlink-genl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index f454dbd837..8537e13316 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -17,6 +17,7 @@ typedef struct GenericNetlinkFamily { uint16_t id; /* a.k.a nlmsg_type */ char *name; uint32_t version; + uint32_t additional_header_size; } GenericNetlinkFamily; static const GenericNetlinkFamily nlctrl_static = { @@ -119,6 +120,10 @@ static int genl_family_new( if (r < 0) return r; + r = sd_netlink_message_read_u32(message, CTRL_ATTR_HDRSIZE, &f->additional_header_size); + if (r < 0) + return r; + r = hashmap_ensure_put(&nl->genl_family_by_id, NULL, UINT_TO_PTR(f->id), f); if (r < 0) return r; @@ -165,7 +170,8 @@ static int genl_message_new( if (r < 0) return r; - r = message_new_full(nl, family->id, type_system, sizeof(struct genlmsghdr), &m); + r = message_new_full(nl, family->id, type_system, + sizeof(struct genlmsghdr) + family->additional_header_size, &m); if (r < 0) return r; @@ -287,7 +293,7 @@ int genl_get_type_system_and_header_size( return r; } if (ret_header_size) - *ret_header_size = sizeof(struct genlmsghdr); + *ret_header_size = sizeof(struct genlmsghdr) + f->additional_header_size; return 0; } From ef90beb1c5c4041db8c33e28cea236567d40d1fd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 3 Jul 2021 06:21:45 +0900 Subject: [PATCH 26/29] sd-netlink: introduce sd_genl_message_get_command() --- src/libsystemd/sd-netlink/netlink-genl.c | 38 ++++++++++++++++++++++++ src/libsystemd/sd-netlink/test-netlink.c | 3 ++ src/systemd/sd-netlink.h | 1 + 3 files changed, 42 insertions(+) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 8537e13316..9f0ebba3df 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -60,6 +60,7 @@ static int genl_family_new( _cleanup_(genl_family_freep) GenericNetlinkFamily *f = NULL; const char *family_name; + uint8_t cmd; int r; assert(nl); @@ -105,6 +106,13 @@ static int genl_family_new( if (!streq(family_name, CTRL_GENL_NAME)) return -EINVAL; + r = sd_genl_message_get_command(nl, message, &cmd); + if (r < 0) + return r; + + if (cmd != CTRL_CMD_NEWFAMILY) + return -EINVAL; + r = sd_netlink_message_read_u16(message, CTRL_ATTR_FAMILY_ID, &f->id); if (r < 0) return r; @@ -335,6 +343,36 @@ int sd_genl_message_get_family_name(sd_netlink *nl, sd_netlink_message *m, const return 0; } +int sd_genl_message_get_command(sd_netlink *nl, sd_netlink_message *m, uint8_t *ret) { + struct genlmsghdr *h; + uint16_t nlmsg_type; + size_t size; + int r; + + assert_return(nl, -EINVAL); + assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL); + assert_return(m, -EINVAL); + assert_return(m->protocol == NETLINK_GENERIC, -EINVAL); + assert_return(m->hdr, -EINVAL); + assert_return(ret, -EINVAL); + + r = sd_netlink_message_get_type(m, &nlmsg_type); + if (r < 0) + return r; + + r = genl_get_type_system_and_header_size(nl, nlmsg_type, NULL, &size); + if (r < 0) + return r; + + if (m->hdr->nlmsg_len < NLMSG_LENGTH(size)) + return -EBADMSG; + + h = NLMSG_DATA(m->hdr); + + *ret = h->cmd; + return 0; +} + int sd_genl_socket_open(sd_netlink **ret) { return netlink_open_family(ret, NETLINK_GENERIC); } diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 6cc6cdad45..945f5b7bd5 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -587,6 +587,7 @@ static void test_genl(void) { _cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const char *name; + uint8_t cmd; log_debug("/* %s */", __func__); @@ -594,6 +595,8 @@ static void test_genl(void) { assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0); assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0); assert_se(streq(name, CTRL_GENL_NAME)); + assert_se(sd_genl_message_get_command(genl, m, &cmd) >= 0); + assert_se(cmd == CTRL_CMD_GETFAMILY); m = sd_netlink_message_unref(m); assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) < 0); diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index 6bb93fdf17..d7565d41e9 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -237,6 +237,7 @@ int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m); int sd_genl_socket_open(sd_netlink **ret); int sd_genl_message_new(sd_netlink *genl, const char *family_name, uint8_t cmd, sd_netlink_message **ret); int sd_genl_message_get_family_name(sd_netlink *genl, sd_netlink_message *m, const char **ret); +int sd_genl_message_get_command(sd_netlink *genl, sd_netlink_message *m, uint8_t *ret); /* slot */ sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *slot); From 3f60e4488c5d52d01af07523cae6fa2f325014c9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 30 Jun 2021 01:11:07 +0900 Subject: [PATCH 27/29] sd-netlink: split sd_netlink_add_match() into two parts This also makes netlink_slot_disconnect() correctly unref multicast groups. --- src/libsystemd/sd-netlink/netlink-internal.h | 13 ++ src/libsystemd/sd-netlink/netlink-slot.c | 22 +-- src/libsystemd/sd-netlink/sd-netlink.c | 147 +++++++++++-------- 3 files changed, 99 insertions(+), 83 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 2594885fe6..9025286add 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -25,6 +25,8 @@ struct reply_callback { struct match_callback { sd_netlink_message_handler_t callback; + uint32_t *groups; + size_t n_groups; uint16_t type; LIST_FIELDS(struct match_callback, match_callbacks); @@ -151,6 +153,17 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m); int socket_writev_message(sd_netlink *nl, sd_netlink_message **m, size_t msgcount); int socket_read_message(sd_netlink *nl); +int netlink_add_match_internal( + sd_netlink *nl, + sd_netlink_slot **ret_slot, + const uint32_t *groups, + size_t n_groups, + uint16_t type, + sd_netlink_message_handler_t callback, + sd_netlink_destroy_t destroy_callback, + void *userdata, + const char *description); + /* Make sure callbacks don't destroy the netlink connection */ #define NETLINK_DONT_DESTROY(nl) \ _cleanup_(sd_netlink_unrefp) _unused_ sd_netlink *_dont_destroy_##nl = sd_netlink_ref(nl) diff --git a/src/libsystemd/sd-netlink/netlink-slot.c b/src/libsystemd/sd-netlink/netlink-slot.c index 76b4ccaa96..34f527d07f 100644 --- a/src/libsystemd/sd-netlink/netlink-slot.c +++ b/src/libsystemd/sd-netlink/netlink-slot.c @@ -70,25 +70,11 @@ void netlink_slot_disconnect(sd_netlink_slot *slot, bool unref) { case NETLINK_MATCH_CALLBACK: LIST_REMOVE(match_callbacks, nl->match_callbacks, &slot->match_callback); - switch (slot->match_callback.type) { - case RTM_NEWLINK: - case RTM_DELLINK: - (void) socket_broadcast_group_unref(nl, RTNLGRP_LINK); + for (size_t i = 0; i < slot->match_callback.n_groups; i++) + (void) socket_broadcast_group_unref(nl, slot->match_callback.groups[i]); - break; - case RTM_NEWADDR: - case RTM_DELADDR: - (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV4_IFADDR); - (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV6_IFADDR); - - break; - case RTM_NEWROUTE: - case RTM_DELROUTE: - (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV4_ROUTE); - (void) socket_broadcast_group_unref(nl, RTNLGRP_IPV6_ROUTE); - - break; - } + slot->match_callback.n_groups = 0; + slot->match_callback.groups = mfree(slot->match_callback.groups); break; default: diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index 2305333575..8ea3b2f1a0 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -895,9 +895,11 @@ int sd_netlink_detach_event(sd_netlink *nl) { return 0; } -int sd_netlink_add_match( - sd_netlink *rtnl, +int netlink_add_match_internal( + sd_netlink *nl, sd_netlink_slot **ret_slot, + const uint32_t *groups, + size_t n_groups, uint16_t type, sd_netlink_message_handler_t callback, sd_netlink_destroy_t destroy_callback, @@ -907,75 +909,29 @@ int sd_netlink_add_match( _cleanup_free_ sd_netlink_slot *slot = NULL; int r; - assert_return(rtnl, -EINVAL); - assert_return(callback, -EINVAL); - assert_return(!netlink_pid_changed(rtnl), -ECHILD); + assert(groups); + assert(n_groups > 0); - r = netlink_slot_allocate(rtnl, !ret_slot, NETLINK_MATCH_CALLBACK, sizeof(struct match_callback), userdata, description, &slot); + for (size_t i = 0; i < n_groups; i++) { + r = socket_broadcast_group_ref(nl, groups[i]); + if (r < 0) + return r; + } + + r = netlink_slot_allocate(nl, !ret_slot, NETLINK_MATCH_CALLBACK, sizeof(struct match_callback), + userdata, description, &slot); if (r < 0) return r; + slot->match_callback.groups = newdup(uint32_t, groups, n_groups); + if (!slot->match_callback.groups) + return -ENOMEM; + + slot->match_callback.n_groups = n_groups; slot->match_callback.callback = callback; slot->match_callback.type = type; - switch (type) { - case RTM_NEWLINK: - case RTM_DELLINK: - r = socket_broadcast_group_ref(rtnl, RTNLGRP_LINK); - if (r < 0) - return r; - - break; - case RTM_NEWADDR: - case RTM_DELADDR: - r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_IFADDR); - if (r < 0) - return r; - - r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_IFADDR); - if (r < 0) - return r; - - break; - case RTM_NEWNEIGH: - case RTM_DELNEIGH: - r = socket_broadcast_group_ref(rtnl, RTNLGRP_NEIGH); - if (r < 0) - return r; - - break; - case RTM_NEWROUTE: - case RTM_DELROUTE: - r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_ROUTE); - if (r < 0) - return r; - - r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_ROUTE); - if (r < 0) - return r; - break; - case RTM_NEWRULE: - case RTM_DELRULE: - r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_RULE); - if (r < 0) - return r; - - r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_RULE); - if (r < 0) - return r; - break; - case RTM_NEWNEXTHOP: - case RTM_DELNEXTHOP: - r = socket_broadcast_group_ref(rtnl, RTNLGRP_NEXTHOP); - if (r < 0) - return r; - break; - - default: - return -EOPNOTSUPP; - } - - LIST_PREPEND(match_callbacks, rtnl->match_callbacks, &slot->match_callback); + LIST_PREPEND(match_callbacks, nl->match_callbacks, &slot->match_callback); /* Set this at last. Otherwise, some failures in above call the destroy callback but some do not. */ slot->destroy_callback = destroy_callback; @@ -984,6 +940,67 @@ int sd_netlink_add_match( *ret_slot = slot; TAKE_PTR(slot); - return 0; } + +int sd_netlink_add_match( + sd_netlink *rtnl, + sd_netlink_slot **ret_slot, + uint16_t type, + sd_netlink_message_handler_t callback, + sd_netlink_destroy_t destroy_callback, + void *userdata, + const char *description) { + + static const uint32_t + address_groups[] = { RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, }, + link_groups[] = { RTNLGRP_LINK, }, + neighbor_groups[] = { RTNLGRP_NEIGH, }, + nexthop_groups[] = { RTNLGRP_NEXTHOP, }, + route_groups[] = { RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE, }, + rule_groups[] = { RTNLGRP_IPV4_RULE, RTNLGRP_IPV6_RULE, }; + const uint32_t *groups; + size_t n_groups; + + assert_return(rtnl, -EINVAL); + assert_return(callback, -EINVAL); + assert_return(!netlink_pid_changed(rtnl), -ECHILD); + + switch (type) { + case RTM_NEWLINK: + case RTM_DELLINK: + groups = link_groups; + n_groups = ELEMENTSOF(link_groups); + break; + case RTM_NEWADDR: + case RTM_DELADDR: + groups = address_groups; + n_groups = ELEMENTSOF(address_groups); + break; + case RTM_NEWNEIGH: + case RTM_DELNEIGH: + groups = neighbor_groups; + n_groups = ELEMENTSOF(neighbor_groups); + break; + case RTM_NEWROUTE: + case RTM_DELROUTE: + groups = route_groups; + n_groups = ELEMENTSOF(route_groups); + break; + case RTM_NEWRULE: + case RTM_DELRULE: + groups = rule_groups; + n_groups = ELEMENTSOF(rule_groups); + break; + case RTM_NEWNEXTHOP: + case RTM_DELNEXTHOP: + groups = nexthop_groups; + n_groups = ELEMENTSOF(nexthop_groups); + break; + default: + return -EOPNOTSUPP; + } + + return netlink_add_match_internal(rtnl, ret_slot, groups, n_groups, type, callback, + destroy_callback, userdata, description); +} From e1578f608b7a35fbcc3da0016c87900fc3c700a7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 30 Jun 2021 01:16:45 +0900 Subject: [PATCH 28/29] sd-netlink: introduce sd_genl_add_match() By using this, we can listen multicast messages for generic netlink. --- src/libsystemd/sd-netlink/netlink-genl.c | 94 ++++++++++++++++++++ src/libsystemd/sd-netlink/netlink-internal.h | 2 + src/libsystemd/sd-netlink/sd-netlink.c | 19 +++- src/libsystemd/sd-netlink/test-netlink.c | 63 +++++++++++++ src/systemd/sd-netlink.h | 5 ++ 5 files changed, 180 insertions(+), 3 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 9f0ebba3df..3564ece7f4 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -18,6 +18,7 @@ typedef struct GenericNetlinkFamily { char *name; uint32_t version; uint32_t additional_header_size; + Hashmap *multicast_group_by_name; } GenericNetlinkFamily; static const GenericNetlinkFamily nlctrl_static = { @@ -38,6 +39,7 @@ static GenericNetlinkFamily *genl_family_free(GenericNetlinkFamily *f) { } free(f->name); + hashmap_free(f->multicast_group_by_name); return mfree(f); } @@ -132,6 +134,48 @@ static int genl_family_new( if (r < 0) return r; + r = sd_netlink_message_enter_container(message, CTRL_ATTR_MCAST_GROUPS); + if (r >= 0) { + for (uint16_t i = 0; i < UINT16_MAX; i++) { + _cleanup_free_ char *group_name = NULL; + uint32_t group_id; + + r = sd_netlink_message_enter_array(message, i + 1); + if (r == -ENODATA) + break; + if (r < 0) + return r; + + r = sd_netlink_message_read_u32(message, CTRL_ATTR_MCAST_GRP_ID, &group_id); + if (r < 0) + return r; + + r = sd_netlink_message_read_string_strdup(message, CTRL_ATTR_MCAST_GRP_NAME, &group_name); + if (r < 0) + return r; + + r = sd_netlink_message_exit_container(message); + if (r < 0) + return r; + + if (group_id == 0) { + log_debug("sd-netlink: received multicast group '%s' for generic netlink family '%s' with id == 0, ignoring", + group_name, f->name); + continue; + } + + r = hashmap_ensure_put(&f->multicast_group_by_name, &string_hash_ops_free, group_name, UINT32_TO_PTR(group_id)); + if (r < 0) + return r; + + TAKE_PTR(group_name); + } + + r = sd_netlink_message_exit_container(message); + if (r < 0) + return r; + } + r = hashmap_ensure_put(&nl->genl_family_by_id, NULL, UINT_TO_PTR(f->id), f); if (r < 0) return r; @@ -373,6 +417,56 @@ int sd_genl_message_get_command(sd_netlink *nl, sd_netlink_message *m, uint8_t * return 0; } +static int genl_family_get_multicast_group_id_by_name(const GenericNetlinkFamily *f, const char *name, uint32_t *ret) { + void *p; + + assert(f); + assert(name); + + p = hashmap_get(f->multicast_group_by_name, name); + if (!p) + return -ENOENT; + + if (ret) + *ret = PTR_TO_UINT32(p); + return 0; +} + +int sd_genl_add_match( + sd_netlink *nl, + sd_netlink_slot **ret_slot, + const char *family_name, + const char *multicast_group_name, + uint8_t command, + sd_netlink_message_handler_t callback, + sd_netlink_destroy_t destroy_callback, + void *userdata, + const char *description) { + + const GenericNetlinkFamily *f; + uint32_t multicast_group_id; + int r; + + assert_return(nl, -EINVAL); + assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL); + assert_return(callback, -EINVAL); + assert_return(family_name, -EINVAL); + assert_return(multicast_group_name, -EINVAL); + + /* If command == 0, then all commands belonging to the multicast group trigger the callback. */ + + r = genl_family_get_by_name(nl, family_name, &f); + if (r < 0) + return r; + + r = genl_family_get_multicast_group_id_by_name(f, multicast_group_name, &multicast_group_id); + if (r < 0) + return r; + + return netlink_add_match_internal(nl, ret_slot, &multicast_group_id, 1, f->id, command, + callback, destroy_callback, userdata, description); +} + int sd_genl_socket_open(sd_netlink **ret) { return netlink_open_family(ret, NETLINK_GENERIC); } diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 9025286add..050edaec78 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -28,6 +28,7 @@ struct match_callback { uint32_t *groups; size_t n_groups; uint16_t type; + uint8_t cmd; /* used by genl */ LIST_FIELDS(struct match_callback, match_callbacks); }; @@ -159,6 +160,7 @@ int netlink_add_match_internal( const uint32_t *groups, size_t n_groups, uint16_t type, + uint8_t cmd, sd_netlink_message_handler_t callback, sd_netlink_destroy_t destroy_callback, void *userdata, diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c index 8ea3b2f1a0..2d0c940b5a 100644 --- a/src/libsystemd/sd-netlink/sd-netlink.c +++ b/src/libsystemd/sd-netlink/sd-netlink.c @@ -426,8 +426,8 @@ static int process_reply(sd_netlink *nl, sd_netlink_message *m) { static int process_match(sd_netlink *nl, sd_netlink_message *m) { struct match_callback *c; - sd_netlink_slot *slot; uint16_t type; + uint8_t cmd; int r; assert(nl); @@ -437,8 +437,19 @@ static int process_match(sd_netlink *nl, sd_netlink_message *m) { if (r < 0) return r; + if (m->protocol == NETLINK_GENERIC) { + r = sd_genl_message_get_command(nl, m, &cmd); + if (r < 0) + return r; + } else + cmd = 0; + LIST_FOREACH(match_callbacks, c, nl->match_callbacks) { - if (type != c->type) + sd_netlink_slot *slot; + + if (c->type != type) + continue; + if (c->cmd != 0 && c->cmd != cmd) continue; slot = container_of(c, sd_netlink_slot, match_callback); @@ -901,6 +912,7 @@ int netlink_add_match_internal( const uint32_t *groups, size_t n_groups, uint16_t type, + uint8_t cmd, sd_netlink_message_handler_t callback, sd_netlink_destroy_t destroy_callback, void *userdata, @@ -930,6 +942,7 @@ int netlink_add_match_internal( slot->match_callback.n_groups = n_groups; slot->match_callback.callback = callback; slot->match_callback.type = type; + slot->match_callback.cmd = cmd; LIST_PREPEND(match_callbacks, nl->match_callbacks, &slot->match_callback); @@ -1001,6 +1014,6 @@ int sd_netlink_add_match( return -EOPNOTSUPP; } - return netlink_add_match_internal(rtnl, ret_slot, groups, n_groups, type, callback, + return netlink_add_match_internal(rtnl, ret_slot, groups, n_groups, type, 0, callback, destroy_callback, userdata, description); } diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c index 945f5b7bd5..c5a5e512a2 100644 --- a/src/libsystemd/sd-netlink/test-netlink.c +++ b/src/libsystemd/sd-netlink/test-netlink.c @@ -2,7 +2,12 @@ #include #include +#include +#include #include +#include +#include +#include #include "sd-netlink.h" @@ -583,24 +588,82 @@ static void test_strv(sd_netlink *rtnl) { assert_se(sd_netlink_message_exit_container(m) >= 0); } +static int genl_ctrl_match_callback(sd_netlink *genl, sd_netlink_message *m, void *userdata) { + const char *name; + uint16_t id; + uint8_t cmd; + + assert(genl); + assert(m); + + assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0); + assert_se(streq(name, CTRL_GENL_NAME)); + + assert_se(sd_genl_message_get_command(genl, m, &cmd) >= 0); + + switch (cmd) { + case CTRL_CMD_NEWFAMILY: + case CTRL_CMD_DELFAMILY: + assert_se(sd_netlink_message_read_string(m, CTRL_ATTR_FAMILY_NAME, &name) >= 0); + assert_se(sd_netlink_message_read_u16(m, CTRL_ATTR_FAMILY_ID, &id) >= 0); + log_debug("%s: %s (id=%"PRIu16") family is %s.", + __func__, name, id, cmd == CTRL_CMD_NEWFAMILY ? "added" : "removed"); + break; + case CTRL_CMD_NEWMCAST_GRP: + case CTRL_CMD_DELMCAST_GRP: + assert_se(sd_netlink_message_read_string(m, CTRL_ATTR_FAMILY_NAME, &name) >= 0); + assert_se(sd_netlink_message_read_u16(m, CTRL_ATTR_FAMILY_ID, &id) >= 0); + log_debug("%s: multicast group for %s (id=%"PRIu16") family is %s.", + __func__, name, id, cmd == CTRL_CMD_NEWMCAST_GRP ? "added" : "removed"); + break; + default: + log_debug("%s: received nlctrl message with unknown command '%"PRIu8"'.", __func__, cmd); + } + + return 0; +} + static void test_genl(void) { + _cleanup_(sd_event_unrefp) sd_event *event = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; const char *name; uint8_t cmd; + int r; log_debug("/* %s */", __func__); assert_se(sd_genl_socket_open(&genl) >= 0); + assert_se(sd_event_default(&event) >= 0); + assert_se(sd_netlink_attach_event(genl, event, 0) >= 0); + assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0); assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0); assert_se(streq(name, CTRL_GENL_NAME)); assert_se(sd_genl_message_get_command(genl, m, &cmd) >= 0); assert_se(cmd == CTRL_CMD_GETFAMILY); + assert_se(sd_genl_add_match(genl, NULL, CTRL_GENL_NAME, "notify", 0, genl_ctrl_match_callback, NULL, NULL, "genl-ctrl-notify") >= 0); + m = sd_netlink_message_unref(m); assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) < 0); assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) == -EOPNOTSUPP); + + /* These families may not be supported by kernel. Hence, ignore results. */ + (void) sd_genl_message_new(genl, FOU_GENL_NAME, 0, &m); + m = sd_netlink_message_unref(m); + (void) sd_genl_message_new(genl, L2TP_GENL_NAME, 0, &m); + m = sd_netlink_message_unref(m); + (void) sd_genl_message_new(genl, MACSEC_GENL_NAME, 0, &m); + m = sd_netlink_message_unref(m); + (void) sd_genl_message_new(genl, NL80211_GENL_NAME, 0, &m); + + for (;;) { + r = sd_event_run(event, 500 * USEC_PER_MSEC); + assert_se(r >= 0); + if (r == 0) + return; + } } int main(void) { diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h index d7565d41e9..5965780fbb 100644 --- a/src/systemd/sd-netlink.h +++ b/src/systemd/sd-netlink.h @@ -238,6 +238,11 @@ int sd_genl_socket_open(sd_netlink **ret); int sd_genl_message_new(sd_netlink *genl, const char *family_name, uint8_t cmd, sd_netlink_message **ret); int sd_genl_message_get_family_name(sd_netlink *genl, sd_netlink_message *m, const char **ret); int sd_genl_message_get_command(sd_netlink *genl, sd_netlink_message *m, uint8_t *ret); +int sd_genl_add_match(sd_netlink *nl, sd_netlink_slot **ret_slot, const char *family_name, + const char *multicast_group_name, uint8_t command, + sd_netlink_message_handler_t callback, + sd_netlink_destroy_t destroy_callback, + void *userdata, const char *description); /* slot */ sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *slot); From 98be429243ba1d0505c98c7f64f89076ed5deb85 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 29 Aug 2021 17:59:17 +0900 Subject: [PATCH 29/29] sd-netlink: make type_system_get_*() and friends return value directly --- src/libsystemd/sd-netlink/netlink-genl.c | 33 ++--- src/libsystemd/sd-netlink/netlink-message.c | 121 +++++++++--------- .../sd-netlink/netlink-types-genl.c | 4 +- .../sd-netlink/netlink-types-nfnl.c | 11 +- .../sd-netlink/netlink-types-rtnl.c | 4 +- src/libsystemd/sd-netlink/netlink-types.c | 76 ++++------- src/libsystemd/sd-netlink/netlink-types.h | 17 ++- 7 files changed, 121 insertions(+), 145 deletions(-) diff --git a/src/libsystemd/sd-netlink/netlink-genl.c b/src/libsystemd/sd-netlink/netlink-genl.c index 3564ece7f4..f6f13ae239 100644 --- a/src/libsystemd/sd-netlink/netlink-genl.c +++ b/src/libsystemd/sd-netlink/netlink-genl.c @@ -191,16 +191,13 @@ static int genl_family_new( return 0; } -static int genl_family_get_type_system(const GenericNetlinkFamily *family, const NLTypeSystem **ret) { +static const NLTypeSystem *genl_family_get_type_system(const GenericNetlinkFamily *family) { assert(family); - assert(ret); - if (family->type_system) { - *ret = family->type_system; - return 0; - } + if (family->type_system) + return family->type_system; - return genl_get_type_system_by_name(family->name, ret); + return genl_get_type_system_by_name(family->name); } static int genl_message_new( @@ -218,9 +215,9 @@ static int genl_message_new( assert(family); assert(ret); - r = genl_family_get_type_system(family, &type_system); - if (r < 0) - return r; + type_system = genl_family_get_type_system(family); + if (!type_system) + return -EOPNOTSUPP; r = message_new_full(nl, family->id, type_system, sizeof(struct genlmsghdr) + family->additional_header_size, &m); @@ -252,9 +249,9 @@ static int genl_family_get_by_name_internal( assert(name); assert(ret); - r = genl_get_type_system_by_name(name, &type_system); - if (r < 0) - return r; + type_system = genl_get_type_system_by_name(name); + if (!type_system) + return -EOPNOTSUPP; r = genl_message_new(nl, ctrl, CTRL_CMD_GETFAMILY, &req); if (r < 0) @@ -340,9 +337,13 @@ int genl_get_type_system_and_header_size( return r; if (ret_type_system) { - r = genl_family_get_type_system(f, ret_type_system); - if (r < 0) - return r; + const NLTypeSystem *t; + + t = genl_family_get_type_system(f); + if (!t) + return -EOPNOTSUPP; + + *ret_type_system = t; } if (ret_header_size) *ret_header_size = sizeof(struct genlmsghdr) + f->additional_header_size; diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 0c9b5454b6..e422d5699c 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -215,13 +215,12 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da static int message_attribute_has_type(sd_netlink_message *m, size_t *out_size, uint16_t attribute_type, uint16_t data_type) { const NLType *type; - int r; assert(m); - r = type_system_get_type(m->containers[m->n_containers].type_system, &type, attribute_type); - if (r < 0) - return r; + type = type_system_get_type(m->containers[m->n_containers].type_system, attribute_type); + if (!type) + return -EOPNOTSUPP; if (type_get_type(type) != data_type) return -EINVAL; @@ -584,23 +583,23 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type if (r < 0) return r; - r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); - if (r < 0) - return r; + type_system_union = type_system_get_type_system_union( + m->containers[m->n_containers].type_system, + type); + if (!type_system_union) + return -EOPNOTSUPP; - r = type_system_union_get_type_system_by_protocol( + m->containers[m->n_containers + 1].type_system = + type_system_union_get_type_system_by_protocol( type_system_union, - &m->containers[m->n_containers + 1].type_system, family); - if (r < 0) - return r; - } else { - r = type_system_get_type_system(m->containers[m->n_containers].type_system, - &m->containers[m->n_containers + 1].type_system, - type); - if (r < 0) - return r; - } + } else + m->containers[m->n_containers + 1].type_system = + type_system_get_type_system( + m->containers[m->n_containers].type_system, + type); + if (!m->containers[m->n_containers + 1].type_system) + return -EOPNOTSUPP; r = add_rtattr(m, type | NLA_F_NESTED, NULL, size); if (r < 0) @@ -619,16 +618,18 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor assert_return(!m->sealed, -EPERM); assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -ERANGE); - r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); - if (r < 0) - return r; + type_system_union = type_system_get_type_system_union( + m->containers[m->n_containers].type_system, + type); + if (!type_system_union) + return -EOPNOTSUPP; - r = type_system_union_get_type_system_by_string( + m->containers[m->n_containers + 1].type_system = + type_system_union_get_type_system_by_string( type_system_union, - &m->containers[m->n_containers + 1].type_system, key); - if (r < 0) - return r; + if (!m->containers[m->n_containers + 1].type_system) + return -EOPNOTSUPP; r = sd_netlink_message_append_string(m, type_system_union_get_match_attribute(type_system_union), key); if (r < 0) @@ -1043,24 +1044,24 @@ int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container assert_return(m, -EINVAL); assert_return(m->n_containers < NETLINK_CONTAINER_DEPTH, -EINVAL); - r = type_system_get_type(m->containers[m->n_containers].type_system, - &nl_type, - container_type); - if (r < 0) - return r; + nl_type = type_system_get_type( + m->containers[m->n_containers].type_system, + container_type); + if (!nl_type) + return -EOPNOTSUPP; if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) return -EINVAL; - r = type_system_get_type_system(m->containers[m->n_containers].type_system, - &type_system, - container_type); - if (r < 0) - return r; + type_system = type_system_get_type_system( + m->containers[m->n_containers].type_system, + container_type); + if (!type_system) + return -EOPNOTSUPP; - r = type_system_get_type(type_system, &nl_type, type_id); - if (r < 0) - return r; + nl_type = type_system_get_type(type_system, type_id); + if (!nl_type) + return -EOPNOTSUPP; if (type_get_type(nl_type) != NETLINK_TYPE_STRING) return -EINVAL; @@ -1139,28 +1140,28 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ assert_return(m, -EINVAL); assert_return(m->n_containers < (NETLINK_CONTAINER_DEPTH - 1), -EINVAL); - r = type_system_get_type(m->containers[m->n_containers].type_system, - &nl_type, - type_id); - if (r < 0) - return r; + nl_type = type_system_get_type( + m->containers[m->n_containers].type_system, + type_id); + if (!nl_type) + return -EOPNOTSUPP; type = type_get_type(nl_type); if (type == NETLINK_TYPE_NESTED) { - r = type_system_get_type_system(m->containers[m->n_containers].type_system, - &type_system, - type_id); - if (r < 0) - return r; + type_system = type_system_get_type_system( + m->containers[m->n_containers].type_system, + type_id); + if (!type_system) + return -EOPNOTSUPP; } else if (type == NETLINK_TYPE_UNION) { const NLTypeSystemUnion *type_system_union; - r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, - &type_system_union, - type_id); - if (r < 0) - return r; + type_system_union = type_system_get_type_system_union( + m->containers[m->n_containers].type_system, + type_id); + if (!type_system_union) + return -EOPNOTSUPP; switch (type_system_union_get_match_type(type_system_union)) { case NL_MATCH_SIBLING: { @@ -1173,12 +1174,11 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - r = type_system_union_get_type_system_by_string( + type_system = type_system_union_get_type_system_by_string( type_system_union, - &type_system, key); - if (r < 0) - return r; + if (!type_system) + return -EOPNOTSUPP; break; } @@ -1189,12 +1189,11 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ if (r < 0) return r; - r = type_system_union_get_type_system_by_protocol( + type_system = type_system_union_get_type_system_by_protocol( type_system_union, - &type_system, family); - if (r < 0) - return r; + if (!type_system) + return -EOPNOTSUPP; break; } diff --git a/src/libsystemd/sd-netlink/netlink-types-genl.c b/src/libsystemd/sd-netlink/netlink-types-genl.c index dde682f626..0e8783b498 100644 --- a/src/libsystemd/sd-netlink/netlink-types-genl.c +++ b/src/libsystemd/sd-netlink/netlink-types-genl.c @@ -229,6 +229,6 @@ static const NLTypeSystemUnionElement genl_type_systems[] = { /* This is the root type system union, so match_attribute is not necessary. */ DEFINE_TYPE_SYSTEM_UNION_MATCH_SIBLING(genl, 0); -int genl_get_type_system_by_name(const char *name, const NLTypeSystem **ret) { - return type_system_union_get_type_system_by_string(&genl_type_system_union, ret, name); +const NLTypeSystem *genl_get_type_system_by_name(const char *name) { + return type_system_union_get_type_system_by_string(&genl_type_system_union, name); } diff --git a/src/libsystemd/sd-netlink/netlink-types-nfnl.c b/src/libsystemd/sd-netlink/netlink-types-nfnl.c index 68e5395fea..1ba134a976 100644 --- a/src/libsystemd/sd-netlink/netlink-types-nfnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-nfnl.c @@ -186,13 +186,12 @@ static const NLType nfnl_types[] = { DEFINE_TYPE_SYSTEM(nfnl); -int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret) { +const NLType *nfnl_get_type(uint16_t 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; + subsys = type_system_get_type_system(&nfnl_type_system, nlmsg_type >> 8); + if (!subsys) + return NULL; - return type_system_get_type(subsys, ret, nlmsg_type & ((1U << 8) - 1)); + return type_system_get_type(subsys, nlmsg_type & ((1U << 8) - 1)); } diff --git a/src/libsystemd/sd-netlink/netlink-types-rtnl.c b/src/libsystemd/sd-netlink/netlink-types-rtnl.c index dacd7517a0..75046e98a9 100644 --- a/src/libsystemd/sd-netlink/netlink-types-rtnl.c +++ b/src/libsystemd/sd-netlink/netlink-types-rtnl.c @@ -867,6 +867,6 @@ static const NLType rtnl_types[] = { DEFINE_TYPE_SYSTEM(rtnl); -int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret) { - return type_system_get_type(&rtnl_type_system, ret, nlmsg_type); +const NLType *rtnl_get_type(uint16_t nlmsg_type) { + return type_system_get_type(&rtnl_type_system, nlmsg_type); } diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 7d6caf004b..051dac95c2 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -50,11 +50,6 @@ const NLTypeSystemUnion *type_get_type_system_union(const NLType *nl_type) { return nl_type->type_system_union; } -uint16_t type_system_get_count(const NLTypeSystem *type_system) { - assert(type_system); - return type_system->count; -} - int type_system_root_get_type_system_and_header_size( sd_netlink *nl, uint16_t type, @@ -62,27 +57,26 @@ int type_system_root_get_type_system_and_header_size( size_t *ret_header_size) { const NLType *nl_type; - int r; assert(nl); if (IN_SET(type, NLMSG_DONE, NLMSG_ERROR)) - r = type_system_get_type(&basic_type_system, &nl_type, type); + nl_type = type_system_get_type(&basic_type_system, type); else switch(nl->protocol) { case NETLINK_ROUTE: - r = rtnl_get_type(type, &nl_type); + nl_type = rtnl_get_type(type); break; case NETLINK_NETFILTER: - r = nfnl_get_type(type, &nl_type); + nl_type = nfnl_get_type(type); break; case NETLINK_GENERIC: return genl_get_type_system_and_header_size(nl, type, ret_type_system, ret_header_size); default: return -EOPNOTSUPP; } - if (r < 0) - return r; + if (!nl_type) + return -EOPNOTSUPP; if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) return -EOPNOTSUPP; @@ -94,51 +88,41 @@ int type_system_root_get_type_system_and_header_size( return 0; } -int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { +const NLType *type_system_get_type(const NLTypeSystem *type_system, uint16_t type) { const NLType *nl_type; - assert(ret); assert(type_system); assert(type_system->types); if (type >= type_system->count) - return -EOPNOTSUPP; + return NULL; nl_type = &type_system->types[type]; if (nl_type->type == NETLINK_TYPE_UNSPEC) - return -EOPNOTSUPP; + return NULL; - *ret = nl_type; - return 0; + return nl_type; } -int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type) { +const NLTypeSystem *type_system_get_type_system(const NLTypeSystem *type_system, uint16_t type) { const NLType *nl_type; - int r; - assert(ret); + nl_type = type_system_get_type(type_system, type); + if (!nl_type) + return NULL; - r = type_system_get_type(type_system, &nl_type, type); - if (r < 0) - return r; - - *ret = type_get_type_system(nl_type); - return 0; + return type_get_type_system(nl_type); } -int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type) { +const NLTypeSystemUnion *type_system_get_type_system_union(const NLTypeSystem *type_system, uint16_t type) { const NLType *nl_type; - int r; - assert(ret); + nl_type = type_system_get_type(type_system, type); + if (!nl_type) + return NULL; - r = type_system_get_type(type_system, &nl_type, type); - if (r < 0) - return r; - - *ret = type_get_type_system_union(nl_type); - return 0; + return type_get_type_system_union(nl_type); } NLMatchType type_system_union_get_match_type(const NLTypeSystemUnion *type_system_union) { @@ -152,33 +136,27 @@ uint16_t type_system_union_get_match_attribute(const NLTypeSystemUnion *type_sys return type_system_union->match_attribute; } -int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key) { +const NLTypeSystem *type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const char *key) { assert(type_system_union); assert(type_system_union->elements); assert(type_system_union->match_type == NL_MATCH_SIBLING); - assert(ret); assert(key); for (size_t i = 0; i < type_system_union->count; i++) - if (streq(type_system_union->elements[i].name, key)) { - *ret = &type_system_union->elements[i].type_system; - return 0; - } + if (streq(type_system_union->elements[i].name, key)) + return &type_system_union->elements[i].type_system; - return -EOPNOTSUPP; + return NULL; } -int type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol) { +const NLTypeSystem *type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, uint16_t protocol) { assert(type_system_union); assert(type_system_union->elements); assert(type_system_union->match_type == NL_MATCH_PROTOCOL); - assert(ret); for (size_t i = 0; i < type_system_union->count; i++) - if (type_system_union->elements[i].protocol == protocol) { - *ret = &type_system_union->elements[i].type_system; - return 0; - } + if (type_system_union->elements[i].protocol == protocol) + return &type_system_union->elements[i].type_system; - return -EOPNOTSUPP; + return NULL; } diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index f8261b681c..d481f3072f 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -35,9 +35,9 @@ typedef struct NLTypeSystemUnion NLTypeSystemUnion; typedef struct NLTypeSystem NLTypeSystem; typedef struct NLType NLType; -int rtnl_get_type(uint16_t nlmsg_type, const NLType **ret); -int nfnl_get_type(uint16_t nlmsg_type, const NLType **ret); -int genl_get_type_system_by_name(const char *name, const NLTypeSystem **ret); +const NLType *rtnl_get_type(uint16_t nlmsg_type); +const NLType *nfnl_get_type(uint16_t nlmsg_type); +const NLTypeSystem *genl_get_type_system_by_name(const char *name); int genl_get_type_system_and_header_size( sd_netlink *nl, uint16_t id, @@ -55,11 +55,10 @@ int type_system_root_get_type_system_and_header_size( const NLTypeSystem **ret_type_system, size_t *ret_header_size); -uint16_t type_system_get_count(const NLTypeSystem *type_system); -int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); -int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); -int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); +const NLType *type_system_get_type(const NLTypeSystem *type_system, uint16_t type); +const NLTypeSystem *type_system_get_type_system(const NLTypeSystem *type_system, uint16_t type); +const NLTypeSystemUnion *type_system_get_type_system_union(const NLTypeSystem *type_system, uint16_t type); NLMatchType type_system_union_get_match_type(const NLTypeSystemUnion *type_system_union); uint16_t type_system_union_get_match_attribute(const NLTypeSystemUnion *type_system_union); -int type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, const char *key); -int type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, const NLTypeSystem **ret, uint16_t protocol); +const NLTypeSystem *type_system_union_get_type_system_by_string(const NLTypeSystemUnion *type_system_union, const char *key); +const NLTypeSystem *type_system_union_get_type_system_by_protocol(const NLTypeSystemUnion *type_system_union, uint16_t protocol);