summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-netlink/netlink-types.c
diff options
context:
space:
mode:
authorJörg Thalheim <joerg@thalheim.io>2017-12-18 15:17:06 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-01-09 14:00:49 +0100
commit05d0c2e3cfb5aac8bc14b68a12a6c3ef3e88e3a3 (patch)
tree02f3d0c19b86bca1579313294746af37878255e3 /src/libsystemd/sd-netlink/netlink-types.c
parent8481e3e71e704a10af0b6d53d4b015b2b8e1e16b (diff)
downloadsystemd-05d0c2e3cfb5aac8bc14b68a12a6c3ef3e88e3a3.tar.gz
sd-netlink: add generic netlink support
This also adds the ability to incorporate arrays into netlink messages and to determine when a netlink message is too big, used by some generic netlink protocols.
Diffstat (limited to 'src/libsystemd/sd-netlink/netlink-types.c')
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 7cc4a14446..6dea62e313 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -36,6 +36,7 @@
#include <linux/if_link.h>
#include <linux/if_tunnel.h>
#include <linux/fib_rules.h>
+#include <linux/genetlink.h>
#if HAVE_VXCAN_INFO_PEER
#include <linux/can/vxcan.h>
@@ -46,6 +47,7 @@
#include "netlink-types.h"
#include "string-table.h"
#include "util.h"
+#include "sd-netlink.h"
/* Maximum ARP IP target defined in kernel */
#define BOND_MAX_ARP_TARGETS 16
@@ -665,11 +667,49 @@ static const NLType rtnl_types[] = {
[RTM_GETRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
};
-const NLTypeSystem type_system_root = {
+const NLTypeSystem rtnl_type_system_root = {
.count = ELEMENTSOF(rtnl_types),
.types = rtnl_types,
};
+
+static const NLType genl_get_family_types[] = {
+ [CTRL_ATTR_FAMILY_NAME] = { .type = NETLINK_TYPE_STRING },
+ [CTRL_ATTR_FAMILY_ID] = { .type = NETLINK_TYPE_U16 },
+};
+
+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_families[] = {
+ [SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_ctrl_id_ctrl_type_system },
+};
+
+const NLTypeSystem genl_family_type_system_root = {
+ .count = ELEMENTSOF(genl_families),
+ .types = genl_families,
+};
+
+static const NLType genl_types[] = {
+ [GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) },
+};
+
+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;
@@ -703,6 +743,15 @@ uint16_t type_system_get_count(const NLTypeSystem *type_system) {
return type_system->count;
}
+const NLTypeSystem *type_system_get_root(int protocol) {
+ switch (protocol) {
+ case NETLINK_GENERIC:
+ return &genl_type_system_root;
+ default: /* NETLINK_ROUTE: */
+ return &rtnl_type_system_root;
+ }
+}
+
int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
const NLType *nl_type;