summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/libsystemd.sym8
-rw-r--r--src/libsystemd/sd-bus/GVARIANT-SERIALIZATION4
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.h3
-rw-r--r--src/libsystemd/sd-bus/bus-control.c45
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c14
-rw-r--r--src/libsystemd/sd-bus/bus-message.c17
-rw-r--r--src/libsystemd/sd-bus/bus-objects.c100
-rw-r--r--src/libsystemd/sd-bus/bus-slot.c2
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c20
-rw-r--r--src/libsystemd/sd-bus/busctl.c3
-rw-r--r--src/libsystemd/sd-bus/kdbus.h1
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c11
-rw-r--r--src/libsystemd/sd-bus/test-bus-chat.c4
-rw-r--r--src/libsystemd/sd-bus/test-bus-gvariant.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-marshal.c21
-rw-r--r--src/libsystemd/sd-bus/test-bus-match.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-objects.c21
-rw-r--r--src/libsystemd/sd-bus/test-bus-proxy.c109
-rw-r--r--src/libsystemd/sd-device/sd-device.c8
-rw-r--r--src/libsystemd/sd-id128/libsystemd-id128.pc.in18
-rw-r--r--src/libsystemd/sd-netlink/netlink-internal.h27
-rw-r--r--src/libsystemd/sd-netlink/netlink-message.c291
-rw-r--r--src/libsystemd/sd-netlink/netlink-socket.c4
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c528
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.h61
25 files changed, 831 insertions, 493 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 809db1f6cc..7bf1d66dde 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -459,3 +459,11 @@ global:
sd_event_source_get_signal;
sd_event_source_get_child_pid;
} LIBSYSTEMD_220;
+
+LIBSYSTEMD_222 {
+global:
+ /* sd-bus */
+ sd_bus_emit_object_added;
+ sd_bus_emit_object_removed;
+ sd_bus_flush_close_unref;
+} LIBSYSTEMD_221;
diff --git a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
index 859e2715f9..6aeb11364a 100644
--- a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
+++ b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
@@ -25,8 +25,8 @@ The header consists of the following:
= 12 bytes
-This header is then followed by the the fields array, whose first
-value is a 32bit array size.
+This header is then followed by the fields array, whose first value is
+a 32bit array size.
When using GVariant we keep the basic structure in place, only
slightly alter the header, and define protocol version '2'. The new
diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h
index b17b62ac93..f2092795f4 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.h
+++ b/src/libsystemd/sd-bus/bus-common-errors.h
@@ -46,6 +46,8 @@
#define BUS_ERROR_NO_MACHINE_FOR_PID "org.freedesktop.machine1.NoMachineForPID"
#define BUS_ERROR_MACHINE_EXISTS "org.freedesktop.machine1.MachineExists"
#define BUS_ERROR_NO_PRIVATE_NETWORKING "org.freedesktop.machine1.NoPrivateNetworking"
+#define BUS_ERROR_NO_SUCH_USER_MAPPING "org.freedesktop.machine1.NoSuchUserMapping"
+#define BUS_ERROR_NO_SUCH_GROUP_MAPPING "org.freedesktop.machine1.NoSuchGroupMapping"
#define BUS_ERROR_NO_SUCH_SESSION "org.freedesktop.login1.NoSuchSession"
#define BUS_ERROR_NO_SESSION_FOR_PID "org.freedesktop.login1.NoSessionForPID"
@@ -58,6 +60,7 @@
#define BUS_ERROR_DEVICE_NOT_TAKEN "org.freedesktop.login1.DeviceNotTaken"
#define BUS_ERROR_OPERATION_IN_PROGRESS "org.freedesktop.login1.OperationInProgress"
#define BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED "org.freedesktop.login1.SleepVerbNotSupported"
+#define BUS_ERROR_SESSION_BUSY "org.freedesktop.login1.SessionBusy"
#define BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED "org.freedesktop.timedate1.AutomaticTimeSyncEnabled"
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 7a59702cb2..c53666ddd0 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -1131,7 +1131,7 @@ static int add_name_change_match(sd_bus *bus,
/* If the old name is unset or empty, then
* this can match against added names */
- if (!old_owner || old_owner[0] == 0) {
+ if (isempty(old_owner)) {
item->type = KDBUS_ITEM_NAME_ADD;
r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
@@ -1141,7 +1141,7 @@ static int add_name_change_match(sd_bus *bus,
/* If the new name is unset or empty, then
* this can match against removed names */
- if (!new_owner || new_owner[0] == 0) {
+ if (isempty(new_owner)) {
item->type = KDBUS_ITEM_NAME_REMOVE;
r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
@@ -1185,8 +1185,10 @@ static int add_name_change_match(sd_bus *bus,
/* If the old name is unset or empty, then this can
* match against added ids */
- if (!old_owner || old_owner[0] == 0) {
+ if (isempty(old_owner)) {
item->type = KDBUS_ITEM_ID_ADD;
+ if (!isempty(new_owner))
+ item->id_change.id = new_owner_id;
r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
if (r < 0)
@@ -1195,8 +1197,10 @@ static int add_name_change_match(sd_bus *bus,
/* If thew new name is unset or empty, then this can
* match against removed ids */
- if (!new_owner || new_owner[0] == 0) {
+ if (isempty(new_owner)) {
item->type = KDBUS_ITEM_ID_REMOVE;
+ if (!isempty(old_owner))
+ item->id_change.id = old_owner_id;
r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
if (r < 0)
@@ -1219,7 +1223,7 @@ int bus_add_match_internal_kernel(
size_t sz;
const char *sender = NULL;
size_t sender_length = 0;
- uint64_t src_id = KDBUS_MATCH_ID_ANY;
+ uint64_t src_id = KDBUS_MATCH_ID_ANY, dst_id = KDBUS_MATCH_ID_ANY;
bool using_bloom = false;
unsigned i;
bool matches_name_change = true;
@@ -1332,13 +1336,25 @@ int bus_add_match_internal_kernel(
break;
}
- case BUS_MATCH_DESTINATION:
- /* The bloom filter does not include
- the destination, since it is only
- available for broadcast messages
- which do not carry a destination
- since they are undirected. */
+ case BUS_MATCH_DESTINATION: {
+ /*
+ * Kernel only supports matching on destination IDs, but
+ * not on destination names. So just skip the
+ * destination name restriction and verify it in
+ * user-space on retrieval.
+ */
+ r = bus_kernel_parse_unique_name(c->value_str, &dst_id);
+ if (r < 0)
+ return r;
+ else if (r > 0)
+ sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
+
+ /* if not a broadcast, it cannot be a name-change */
+ if (r <= 0 || dst_id != KDBUS_DST_ID_BROADCAST)
+ matches_name_change = false;
+
break;
+ }
case BUS_MATCH_ROOT:
case BUS_MATCH_VALUE:
@@ -1365,6 +1381,13 @@ int bus_add_match_internal_kernel(
item = KDBUS_ITEM_NEXT(item);
}
+ if (dst_id != KDBUS_MATCH_ID_ANY) {
+ item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
+ item->type = KDBUS_ITEM_DST_ID;
+ item->id = dst_id;
+ item = KDBUS_ITEM_NEXT(item);
+ }
+
if (using_bloom) {
item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
item->type = KDBUS_ITEM_BLOOM_MASK;
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index f08db2da89..6ac5ebc3da 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -1332,8 +1332,7 @@ static int bus_kernel_translate_message(sd_bus *bus, struct kdbus_msg *k) {
KDBUS_ITEM_FOREACH(d, k, items) {
if (d->type == KDBUS_ITEM_TIMESTAMP)
ts = &d->timestamp;
-
- if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
+ else if (d->type >= _KDBUS_ITEM_KERNEL_BASE && d->type < _KDBUS_ITEM_KERNEL_BASE + ELEMENTSOF(translate)) {
if (found)
return -EBADMSG;
found = d;
@@ -1385,15 +1384,16 @@ int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
r = 0;
}
- } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
+ if (r <= 0)
+ close_kdbus_msg(bus, k);
+ } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL) {
r = bus_kernel_translate_message(bus, k);
- else {
+ close_kdbus_msg(bus, k);
+ } else {
log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type);
r = 0;
- }
-
- if (r <= 0)
close_kdbus_msg(bus, k);
+ }
return r < 0 ? r : 1;
}
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 983e2f62cd..18685be8ff 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -2161,6 +2161,7 @@ static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c)
}
static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
+ bool fixed_size = true;
size_t n_variable = 0;
unsigned i = 0;
const char *p;
@@ -2196,6 +2197,8 @@ static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c,
/* We need to add an offset for each item that has a
* variable size and that is not the last one in the
* list */
+ if (r == 0)
+ fixed_size = false;
if (r == 0 && p[n] != 0)
n_variable++;
@@ -2207,7 +2210,19 @@ static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c,
assert(c->need_offsets || n_variable == 0);
if (n_variable <= 0) {
- a = message_extend_body(m, 1, 0, add_offset, false);
+ int alignment = 1;
+
+ /* Structures with fixed-size members only have to be
+ * fixed-size themselves. But gvariant requires all fixed-size
+ * elements to be sized a multiple of their alignment. Hence,
+ * we must *always* add final padding after the last member so
+ * the overall size of the structure is properly aligned. */
+ if (fixed_size)
+ alignment = bus_gvariant_get_alignment(strempty(c->signature));
+
+ assert(alignment > 0);
+
+ a = message_extend_body(m, alignment, 0, add_offset, false);
if (!a)
return -ENOMEM;
} else {
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index e4bbd880e5..c25293e5e9 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -68,6 +68,12 @@ static int node_vtable_get_userdata(
return 1;
}
+static void *vtable_method_convert_userdata(const sd_bus_vtable *p, void *u) {
+ assert(p);
+
+ return (uint8_t*) u + p->x.method.offset;
+}
+
static void *vtable_property_convert_userdata(const sd_bus_vtable *p, void *u) {
assert(p);
@@ -167,6 +173,7 @@ static int add_subtree_to_set(
sd_bus *bus,
const char *prefix,
struct node *n,
+ bool skip_subhierarchies,
Set *s,
sd_bus_error *error) {
@@ -198,11 +205,13 @@ static int add_subtree_to_set(
if (r < 0 && r != -EEXIST)
return r;
- r = add_subtree_to_set(bus, prefix, i, s, error);
- if (r < 0)
- return r;
- if (bus->nodes_modified)
- return 0;
+ if (!skip_subhierarchies || !i->object_managers) {
+ r = add_subtree_to_set(bus, prefix, i, skip_subhierarchies, s, error);
+ if (r < 0)
+ return r;
+ if (bus->nodes_modified)
+ return 0;
+ }
}
return 0;
@@ -212,6 +221,7 @@ static int get_child_nodes(
sd_bus *bus,
const char *prefix,
struct node *n,
+ bool skip_subhierarchies,
Set **_s,
sd_bus_error *error) {
@@ -227,7 +237,7 @@ static int get_child_nodes(
if (!s)
return -ENOMEM;
- r = add_subtree_to_set(bus, prefix, n, s, error);
+ r = add_subtree_to_set(bus, prefix, n, skip_subhierarchies, s, error);
if (r < 0) {
set_free_free(s);
return r;
@@ -360,6 +370,8 @@ static int method_callbacks_run(
if (bus->nodes_modified)
return 0;
+ u = vtable_method_convert_userdata(c->vtable, u);
+
*found_object = true;
if (c->last_iteration == bus->iteration_counter)
@@ -892,7 +904,7 @@ static int process_introspect(
assert(n);
assert(found_object);
- r = get_child_nodes(bus, m->path, n, &s, &error);
+ r = get_child_nodes(bus, m->path, n, false, &s, &error);
if (r < 0)
return bus_maybe_reply_error(m, r, &error);
if (bus->nodes_modified)
@@ -1158,12 +1170,16 @@ static int process_get_managed_objects(
if (require_fallback || !n->object_managers)
return 0;
- r = get_child_nodes(bus, m->path, n, &s, &error);
+ r = get_child_nodes(bus, m->path, n, true, &s, &error);
if (r < 0)
return r;
if (bus->nodes_modified)
return 0;
+ r = set_put_strdup(s, m->path);
+ if (r < 0)
+ return r;
+
r = sd_bus_message_new_method_return(m, &reply);
if (r < 0)
return r;
@@ -1412,7 +1428,7 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
e = strrchr(path, '/');
assert(e);
- p = strndupa(path, MAX(1, path - e));
+ p = strndupa(path, MAX(1, e - path));
parent = bus_node_allocate(bus, p);
if (!parent)
@@ -1463,6 +1479,32 @@ void bus_node_gc(sd_bus *b, struct node *n) {
free(n);
}
+static int bus_find_parent_object_manager(sd_bus *bus, struct node **out, const char *path) {
+ struct node *n;
+
+ assert(bus);
+ assert(path);
+
+ n = hashmap_get(bus->nodes, path);
+ if (!n) {
+ char *prefix;
+
+ prefix = alloca(strlen(path) + 1);
+ OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
+ n = hashmap_get(bus->nodes, prefix);
+ if (n)
+ break;
+ }
+ }
+
+ while (n && !n->object_managers)
+ n = n->parent;
+
+ if (out)
+ *out = n;
+ return !!n;
+}
+
static int bus_add_object(
sd_bus *bus,
sd_bus_slot **slot,
@@ -2261,10 +2303,11 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p
return 0;
}
-int sd_bus_emit_object_added(sd_bus *bus, const char *path) {
+_public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) {
BUS_DONT_DESTROY(bus);
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ struct node *object_manager;
int r;
/*
@@ -2285,11 +2328,17 @@ int sd_bus_emit_object_added(sd_bus *bus, const char *path) {
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
+ r = bus_find_parent_object_manager(bus, &object_manager, path);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ESRCH;
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
- r = sd_bus_message_new_signal(bus, &m, path, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded");
+ r = sd_bus_message_new_signal(bus, &m, object_manager->path, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded");
if (r < 0)
return r;
@@ -2424,10 +2473,11 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char
return 0;
}
-int sd_bus_emit_object_removed(sd_bus *bus, const char *path) {
+_public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) {
BUS_DONT_DESTROY(bus);
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ struct node *object_manager;
int r;
/*
@@ -2448,11 +2498,17 @@ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) {
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
+ r = bus_find_parent_object_manager(bus, &object_manager, path);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ESRCH;
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
- r = sd_bus_message_new_signal(bus, &m, path, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved");
+ r = sd_bus_message_new_signal(bus, &m, object_manager->path, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved");
if (r < 0)
return r;
@@ -2584,6 +2640,7 @@ _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, ch
BUS_DONT_DESTROY(bus);
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ struct node *object_manager;
char **i;
int r;
@@ -2597,11 +2654,17 @@ _public_ int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, ch
if (strv_isempty(interfaces))
return 0;
+ r = bus_find_parent_object_manager(bus, &object_manager, path);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ESRCH;
+
do {
bus->nodes_modified = false;
m = sd_bus_message_unref(m);
- r = sd_bus_message_new_signal(bus, &m, path, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded");
+ r = sd_bus_message_new_signal(bus, &m, object_manager->path, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded");
if (r < 0)
return r;
@@ -2661,6 +2724,7 @@ _public_ int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const c
_public_ int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ struct node *object_manager;
int r;
assert_return(bus, -EINVAL);
@@ -2673,7 +2737,13 @@ _public_ int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path,
if (strv_isempty(interfaces))
return 0;
- r = sd_bus_message_new_signal(bus, &m, path, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved");
+ r = bus_find_parent_object_manager(bus, &object_manager, path);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ESRCH;
+
+ r = sd_bus_message_new_signal(bus, &m, object_manager->path, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved");
if (r < 0)
return r;
diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c
index c452477566..b149ea16da 100644
--- a/src/libsystemd/sd-bus/bus-slot.c
+++ b/src/libsystemd/sd-bus/bus-slot.c
@@ -273,7 +273,7 @@ _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *descript
return free_and_strdup(&slot->description, description);
}
-_public_ int sd_bus_slot_get_description(sd_bus_slot *slot, char **description) {
+_public_ int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description) {
assert_return(slot, -EINVAL);
assert_return(description, -EINVAL);
assert_return(slot->description, -ENXIO);
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 322d57ddbb..735a775cb4 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -264,6 +264,8 @@ static bool line_begins(const char *s, size_t m, const char *word) {
static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
_cleanup_free_ char *token = NULL;
+ size_t len;
+ int r;
if (!b->anonymous_auth)
return 0;
@@ -276,11 +278,12 @@ static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
if (l % 2 != 0)
return 0;
- token = unhexmem(p, l);
- if (!token)
- return -ENOMEM;
- if (memchr(token, 0, l/2))
+ r = unhexmem(p, l, (void **) &token, &len);
+ if (r < 0)
+ return 0;
+
+ if (memchr(token, 0, len))
return 0;
return !!utf8_is_valid(token);
@@ -288,6 +291,7 @@ static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) {
static int verify_external_token(sd_bus *b, const char *p, size_t l) {
_cleanup_free_ char *token = NULL;
+ size_t len;
uid_t u;
int r;
@@ -307,11 +311,11 @@ static int verify_external_token(sd_bus *b, const char *p, size_t l) {
if (l % 2 != 0)
return 0;
- token = unhexmem(p, l);
- if (!token)
- return -ENOMEM;
+ r = unhexmem(p, l, (void**) &token, &len);
+ if (r < 0)
+ return 0;
- if (memchr(token, 0, l/2))
+ if (memchr(token, 0, len))
return 0;
r = parse_uid(token, &u);
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 39caa4e7d6..6aaaf0e5ec 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -1137,6 +1137,7 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL
if (m) {
dump(m, stdout);
+ fflush(stdout);
if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) {
log_info("Connection terminated, exiting.");
@@ -1973,7 +1974,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
- _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+ _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
int r;
log_parse_environment();
diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h
index 00a6e142c9..ecffc6b13c 100644
--- a/src/libsystemd/sd-bus/kdbus.h
+++ b/src/libsystemd/sd-bus/kdbus.h
@@ -374,6 +374,7 @@ enum kdbus_item_type {
KDBUS_ITEM_ATTACH_FLAGS_RECV,
KDBUS_ITEM_ID,
KDBUS_ITEM_NAME,
+ KDBUS_ITEM_DST_ID,
/* keep these item types in sync with KDBUS_ATTACH_* flags */
_KDBUS_ITEM_ATTACH_BASE = 0x1000,
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 5dd6468707..0ca225c617 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -1428,6 +1428,17 @@ _public_ void sd_bus_close(sd_bus *bus) {
* ioctl on the fd when they are freed. */
}
+_public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
+
+ if (!bus)
+ return NULL;
+
+ sd_bus_flush(bus);
+ sd_bus_close(bus);
+
+ return sd_bus_unref(bus);
+}
+
static void bus_enter_closing(sd_bus *bus) {
assert(bus);
diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c
index 046e999008..754335b5e7 100644
--- a/src/libsystemd/sd-bus/test-bus-chat.c
+++ b/src/libsystemd/sd-bus/test-bus-chat.c
@@ -262,7 +262,7 @@ fail:
static void* client1(void*p) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+ _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
const char *hello;
int r;
@@ -361,7 +361,7 @@ static int quit_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_er
static void* client2(void*p) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
- _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+ _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
bool quit = false;
const char *mid;
diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c
index 22ea00c2fb..9b7dd2e499 100644
--- a/src/libsystemd/sd-bus/test-bus-gvariant.c
+++ b/src/libsystemd/sd-bus/test-bus-gvariant.c
@@ -132,7 +132,7 @@ static void test_bus_gvariant_get_alignment(void) {
static void test_marshal(void) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *n = NULL;
- _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+ _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
_cleanup_free_ void *blob;
size_t sz;
int r;
diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c
index a866a56179..59deaea89f 100644
--- a/src/libsystemd/sd-bus/test-bus-marshal.c
+++ b/src/libsystemd/sd-bus/test-bus-marshal.c
@@ -131,6 +131,9 @@ int main(int argc, char *argv[]) {
r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
assert_se(r >= 0);
+ r = sd_bus_message_append(m, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
+ assert_se(r >= 0);
+
r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
assert_se(r >= 0);
@@ -252,6 +255,22 @@ int main(int argc, char *argv[]) {
assert_se(v == 5);
assert_se(streq(y, "waldo"));
+ r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u);
+ assert_se(r > 0);
+ assert_se(v == 8);
+ assert_se(u64 == 777);
+ assert_se(u == 7);
+
+ r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64);
+ assert_se(r > 0);
+ assert_se(v == 9);
+ assert_se(u == 77);
+ assert_se(u64 == 7777);
+
+ r = sd_bus_message_read(m, "y", &v);
+ assert_se(r > 0);
+ assert_se(v == 10);
+
r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
assert_se(r > 0);
assert_se(boolean);
@@ -331,7 +350,7 @@ int main(int argc, char *argv[]) {
assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
- r = sd_bus_message_skip(m, "a{yv}");
+ r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y");
assert_se(r >= 0);
assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
diff --git a/src/libsystemd/sd-bus/test-bus-match.c b/src/libsystemd/sd-bus/test-bus-match.c
index a1687b1c7b..83cb5c62c2 100644
--- a/src/libsystemd/sd-bus/test-bus-match.c
+++ b/src/libsystemd/sd-bus/test-bus-match.c
@@ -92,7 +92,7 @@ int main(int argc, char *argv[]) {
};
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+ _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
enum bus_match_node_type i;
sd_bus_slot slots[19];
int r;
diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c
index 52952603e4..359984c7f3 100644
--- a/src/libsystemd/sd-bus/test-bus-objects.c
+++ b/src/libsystemd/sd-bus/test-bus-objects.c
@@ -115,14 +115,13 @@ static int set_handler(sd_bus *bus, const char *path, const char *interface, con
static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *s = NULL;
- const char *x;
int r;
assert_se(asprintf(&s, "object %p, path %s", userdata, path) >= 0);
r = sd_bus_message_append(reply, "s", s);
assert_se(r >= 0);
- assert_se(x = startswith(path, "/value/"));
+ assert_se(startswith(path, "/value/") != NULL || strcmp(path, "/value") == 0);
assert_se(PTR_TO_UINT(userdata) == 30);
@@ -154,7 +153,7 @@ static int notify_test2(sd_bus_message *m, void *userdata, sd_bus_error *error)
static int emit_interfaces_added(sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
- assert_se(sd_bus_emit_interfaces_added(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.test", NULL) >= 0);
+ assert_se(sd_bus_emit_interfaces_added(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL) >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
@@ -165,7 +164,7 @@ static int emit_interfaces_added(sd_bus_message *m, void *userdata, sd_bus_error
static int emit_interfaces_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
- assert_se(sd_bus_emit_interfaces_removed(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.test", NULL) >= 0);
+ assert_se(sd_bus_emit_interfaces_removed(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL) >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
@@ -176,7 +175,7 @@ static int emit_interfaces_removed(sd_bus_message *m, void *userdata, sd_bus_err
static int emit_object_added(sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
- assert_se(sd_bus_emit_object_added(sd_bus_message_get_bus(m), m->path) >= 0);
+ assert_se(sd_bus_emit_object_added(sd_bus_message_get_bus(m), "/value/a/x") >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
@@ -187,7 +186,7 @@ static int emit_object_added(sd_bus_message *m, void *userdata, sd_bus_error *er
static int emit_object_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
- assert_se(sd_bus_emit_object_removed(sd_bus_message_get_bus(m), m->path) >= 0);
+ assert_se(sd_bus_emit_object_removed(sd_bus_message_get_bus(m), "/value/a/x") >= 0);
r = sd_bus_reply_method_return(m, NULL);
assert_se(r >= 0);
@@ -229,6 +228,14 @@ static int enumerator_callback(sd_bus *bus, const char *path, void *userdata, ch
return 1;
}
+static int enumerator2_callback(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
+
+ if (object_path_startswith("/value/a", path))
+ assert_se(*nodes = strv_new("/value/a/x", "/value/a/y", "/value/a/z", NULL));
+
+ return 1;
+}
+
static void *server(void *p) {
struct context *c = p;
sd_bus *bus = NULL;
@@ -247,7 +254,9 @@ static void *server(void *p) {
assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test2", vtable, c) >= 0);
assert_se(sd_bus_add_fallback_vtable(bus, NULL, "/value", "org.freedesktop.systemd.ValueTest", vtable2, NULL, UINT_TO_PTR(20)) >= 0);
assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value", enumerator_callback, NULL) >= 0);
+ assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value/a", enumerator2_callback, NULL) >= 0);
assert_se(sd_bus_add_object_manager(bus, NULL, "/value") >= 0);
+ assert_se(sd_bus_add_object_manager(bus, NULL, "/value/a") >= 0);
assert_se(sd_bus_start(bus) >= 0);
diff --git a/src/libsystemd/sd-bus/test-bus-proxy.c b/src/libsystemd/sd-bus/test-bus-proxy.c
new file mode 100644
index 0000000000..369c2f331c
--- /dev/null
+++ b/src/libsystemd/sd-bus/test-bus-proxy.c
@@ -0,0 +1,109 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2015 David Herrmann <dh.herrmann@gmail.com>
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include "util.h"
+#include "log.h"
+
+#include "sd-bus.h"
+#include "bus-kernel.h"
+#include "bus-util.h"
+#include "bus-dump.h"
+
+typedef struct {
+ const char *sender;
+ int matched_acquired;
+} TestProxyMatch;
+
+static int test_proxy_acquired(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ TestProxyMatch *match = userdata;
+ const char *name;
+ int r;
+
+ r = sd_bus_message_read(m, "s", &name);
+ assert_se(r >= 0);
+
+ if (!streq_ptr(match->sender, name))
+ return 0;
+
+ ++match->matched_acquired;
+ return 1;
+}
+
+static void test_proxy_matched(void) {
+ _cleanup_bus_flush_close_unref_ sd_bus *a = NULL;
+ TestProxyMatch match = {};
+ int r;
+
+ /* open bus 'a' */
+
+ r = sd_bus_new(&a);
+ assert_se(r >= 0);
+
+ r = sd_bus_set_address(a, "unix:path=/var/run/dbus/system_bus_socket");
+ assert_se(r >= 0);
+
+ r = sd_bus_set_bus_client(a, true);
+ assert_se(r >= 0);
+
+ r = sd_bus_start(a);
+ assert_se(r >= 0);
+
+ r = sd_bus_add_match(a, NULL,
+ "type='signal',"
+ "member='NameAcquired'",
+ test_proxy_acquired, &match);
+ assert_se(r >= 0);
+
+ r = sd_bus_get_unique_name(a, &match.sender);
+ assert_se(r >= 0);
+
+ /* barrier to guarantee proxy/dbus-daemon handled the previous data */
+ r = sd_bus_call_method(a,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetId",
+ NULL, NULL, NULL);
+ assert_se(r >= 0);
+
+ /* now we can be sure the Name* signals were sent */
+ do {
+ r = sd_bus_process(a, NULL);
+ } while (r > 0);
+ assert_se(r == 0);
+
+ assert_se(match.matched_acquired == 1);
+}
+
+int main(int argc, char **argv) {
+ if (access("/var/run/dbus/system_bus_socket", F_OK) < 0)
+ return EXIT_TEST_SKIP;
+
+ log_parse_environment();
+
+ test_proxy_matched();
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index b274f71093..7cea5a0746 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -791,6 +791,9 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
device->subsystem_set = true;
}
+ if (!device->subsystem)
+ return -ENOENT;
+
*ret = device->subsystem;
return 0;
@@ -908,6 +911,9 @@ _public_ int sd_device_get_driver(sd_device *device, const char **ret) {
return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath);
}
+ if (!device->driver)
+ return -ENOENT;
+
*ret = device->driver;
return 0;
@@ -1002,6 +1008,8 @@ _public_ int sd_device_get_sysname(sd_device *device, const char **ret) {
return r;
}
+ assert_return(device->sysname, -ENOENT);
+
*ret = device->sysname;
return 0;
diff --git a/src/libsystemd/sd-id128/libsystemd-id128.pc.in b/src/libsystemd/sd-id128/libsystemd-id128.pc.in
deleted file mode 100644
index bb65ffde33..0000000000
--- a/src/libsystemd/sd-id128/libsystemd-id128.pc.in
+++ /dev/null
@@ -1,18 +0,0 @@
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: systemd
-Description: systemd 128 Bit ID Utility Library
-URL: @PACKAGE_URL@
-Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lsystemd-id128
-Cflags: -I${includedir}
diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h
index 7290f4e875..4026e2c341 100644
--- a/src/libsystemd/sd-netlink/netlink-internal.h
+++ b/src/libsystemd/sd-netlink/netlink-internal.h
@@ -92,18 +92,27 @@ struct sd_netlink {
sd_event *event;
};
+struct netlink_attribute {
+ size_t offset; /* offset from hdr to attribute */
+ bool nested:1;
+ bool net_byteorder:1;
+};
+
+struct netlink_container {
+ const struct NLTypeSystem *type_system; /* the type system of the container */
+ size_t offset; /* offset from hdr to the start of the container */
+ struct netlink_attribute *attributes;
+ unsigned short n_attributes; /* number of attributes in container */
+};
+
struct sd_netlink_message {
RefCount n_ref;
sd_netlink *rtnl;
struct nlmsghdr *hdr;
- const struct NLTypeSystem *(container_type_system[RTNL_CONTAINER_DEPTH]); /* the type of the container and all its parents */
- size_t container_offsets[RTNL_CONTAINER_DEPTH]; /* offset from hdr to each container's start */
+ struct netlink_container containers[RTNL_CONTAINER_DEPTH];
unsigned n_containers; /* number of containers */
- size_t next_rta_offset; /* offset from hdr to next rta */
- size_t *rta_offset_tb[RTNL_CONTAINER_DEPTH];
- unsigned short rta_tb_size[RTNL_CONTAINER_DEPTH];
bool sealed:1;
bool broadcast:1;
@@ -122,14 +131,6 @@ int socket_read_message(sd_netlink *nl);
int rtnl_rqueue_make_room(sd_netlink *rtnl);
int rtnl_rqueue_partial_make_room(sd_netlink *rtnl);
-int rtnl_message_read_internal(sd_netlink_message *m, unsigned short type, void **data);
-int rtnl_message_parse(sd_netlink_message *m,
- size_t **rta_offset_tb,
- unsigned short *rta_tb_size,
- int max,
- struct rtattr *rta,
- unsigned int rt_len);
-
/* Make sure callbacks don't destroy the rtnl connection */
#define RTNL_DONT_DESTROY(rtnl) \
_cleanup_netlink_unref_ _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl)
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index 87324fc2f7..b0ed2f2882 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -34,10 +34,11 @@
#include "netlink-internal.h"
#include "netlink-types.h"
-#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
+#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
#define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
#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) {
sd_netlink_message *m;
@@ -68,15 +69,18 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) {
size_t size;
int r;
- r = type_system_get_type(NULL, &nl_type, type);
+ r = type_system_get_type(&type_system_root, &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);
if (r < 0)
return r;
- size = NLMSG_SPACE(nl_type->size);
+ size = NLMSG_SPACE(type_get_size(nl_type));
assert(size >= sizeof(struct nlmsghdr));
m->hdr = malloc0(size);
@@ -85,7 +89,7 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) {
m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- m->container_type_system[0] = nl_type->type_system;
+ type_get_type_system(nl_type, &m->containers[0].type_system);
m->hdr->nlmsg_len = size;
m->hdr->nlmsg_type = type;
@@ -126,7 +130,7 @@ sd_netlink_message *sd_netlink_message_unref(sd_netlink_message *m) {
free(m->hdr);
for (i = 0; i <= m->n_containers; i++)
- free(m->rta_offset_tb[i]);
+ free(m->containers[i].attributes);
sd_netlink_message_unref(m->next);
@@ -214,18 +218,22 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da
return offset;
}
-static int message_attribute_has_type(sd_netlink_message *m, uint16_t attribute_type, uint16_t data_type) {
+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;
- r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type);
+ assert(m);
+
+ r = type_system_get_type(m->containers[m->n_containers].type_system, &type, attribute_type);
if (r < 0)
return r;
- if (type->type != data_type)
+ if (type_get_type(type) != data_type)
return -EINVAL;
- return type->size;
+ if (out_size)
+ *out_size = type_get_size(type);
+ return 0;
}
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data) {
@@ -236,11 +244,9 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type,
assert_return(!m->sealed, -EPERM);
assert_return(data, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_STRING);
+ r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING);
if (r < 0)
return r;
- else
- size = (size_t)r;
if (size) {
length = strnlen(data, size+1);
@@ -262,7 +268,7 @@ int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uin
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- r = message_attribute_has_type(m, type, NLA_U8);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U8);
if (r < 0)
return r;
@@ -280,7 +286,7 @@ int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, ui
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- r = message_attribute_has_type(m, type, NLA_U16);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U16);
if (r < 0)
return r;
@@ -297,7 +303,7 @@ int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, ui
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- r = message_attribute_has_type(m, type, NLA_U32);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U32);
if (r < 0)
return r;
@@ -315,7 +321,7 @@ int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type
assert_return(!m->sealed, -EPERM);
assert_return(data, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR);
if (r < 0)
return r;
@@ -333,7 +339,7 @@ int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short typ
assert_return(!m->sealed, -EPERM);
assert_return(data, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR);
if (r < 0)
return r;
@@ -351,7 +357,7 @@ int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short t
assert_return(!m->sealed, -EPERM);
assert_return(data, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR);
if (r < 0)
return r;
@@ -369,7 +375,7 @@ int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short t
assert_return(!m->sealed, -EPERM);
assert_return(info, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_CACHE_INFO);
if (r < 0)
return r;
@@ -388,34 +394,31 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type
assert_return(!m->sealed, -EPERM);
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE);
- r = message_attribute_has_type(m, type, NLA_NESTED);
+ r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED);
if (r < 0) {
const NLTypeSystemUnion *type_system_union;
int family;
- r = message_attribute_has_type(m, type, NLA_UNION);
+ r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_UNION);
if (r < 0)
return r;
- size = (size_t) r;
r = sd_rtnl_message_get_family(m, &family);
if (r < 0)
return r;
- r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type);
+ r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
if (r < 0)
return r;
r = type_system_union_protocol_get_type_system(type_system_union,
- &m->container_type_system[m->n_containers + 1],
+ &m->containers[m->n_containers + 1].type_system,
family);
if (r < 0)
return r;
} else {
- size = (size_t)r;
-
- r = type_system_get_type_system(m->container_type_system[m->n_containers],
- &m->container_type_system[m->n_containers + 1],
+ 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;
@@ -425,7 +428,7 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type
if (r < 0)
return r;
- m->container_offsets[m->n_containers ++] = r;
+ m->containers[m->n_containers ++].offset = r;
return 0;
}
@@ -437,12 +440,12 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type);
+ r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type);
if (r < 0)
return r;
r = type_system_union_get_type_system(type_system_union,
- &m->container_type_system[m->n_containers + 1],
+ &m->containers[m->n_containers + 1].type_system,
key);
if (r < 0)
return r;
@@ -452,11 +455,11 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor
return r;
/* do we evere need non-null size */
- r = add_rtattr(m, type, NULL, 0);
+ r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0);
if (r < 0)
return r;
- m->container_offsets[m->n_containers ++] = r;
+ m->containers[m->n_containers ++].offset = r;
return 0;
}
@@ -467,29 +470,35 @@ int sd_netlink_message_close_container(sd_netlink_message *m) {
assert_return(!m->sealed, -EPERM);
assert_return(m->n_containers > 0, -EINVAL);
- m->container_type_system[m->n_containers] = NULL;
+ m->containers[m->n_containers].type_system = NULL;
m->n_containers --;
return 0;
}
-int rtnl_message_read_internal(sd_netlink_message *m, unsigned short type, void **data) {
+static int netlink_message_read_internal(sd_netlink_message *m, unsigned short type, void **data, bool *net_byteorder) {
+ struct netlink_attribute *attribute;
struct rtattr *rta;
assert_return(m, -EINVAL);
assert_return(m->sealed, -EPERM);
assert_return(data, -EINVAL);
assert(m->n_containers <= RTNL_CONTAINER_DEPTH);
- assert(m->rta_offset_tb[m->n_containers]);
- assert(type < m->rta_tb_size[m->n_containers]);
+ assert(m->containers[m->n_containers].attributes);
+ assert(type < m->containers[m->n_containers].n_attributes);
+
+ attribute = &m->containers[m->n_containers].attributes[type];
- if(!m->rta_offset_tb[m->n_containers][type])
+ if(!attribute->offset)
return -ENODATA;
- rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]);
+ rta = (struct rtattr*)((uint8_t *) m->hdr + attribute->offset);
*data = RTA_DATA(rta);
+ if (net_byteorder)
+ *net_byteorder = attribute->net_byteorder;
+
return RTA_PAYLOAD(rta);
}
@@ -499,11 +508,11 @@ int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, c
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_STRING);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_STRING);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, NULL);
if (r < 0)
return r;
else if (strnlen(attr_data, r) >= (size_t) r)
@@ -521,11 +530,11 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_U8);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U8);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, NULL);
if (r < 0)
return r;
else if ((size_t) r < sizeof(uint8_t))
@@ -538,45 +547,55 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8
}
int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data) {
- int r;
void *attr_data;
+ bool net_byteorder;
+ int r;
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_U16);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U16);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, &net_byteorder);
if (r < 0)
return r;
else if ((size_t) r < sizeof(uint16_t))
return -EIO;
- if (data)
- *data = *(uint16_t *) attr_data;
+ if (data) {
+ if (net_byteorder)
+ *data = be16toh(*(uint16_t *) attr_data);
+ else
+ *data = *(uint16_t *) attr_data;
+ }
return 0;
}
int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data) {
- int r;
void *attr_data;
+ bool net_byteorder;
+ int r;
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_U32);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U32);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, &net_byteorder);
if (r < 0)
return r;
else if ((size_t)r < sizeof(uint32_t))
return -EIO;
- if (data)
- *data = *(uint32_t *) attr_data;
+ if (data) {
+ if (net_byteorder)
+ *data = be32toh(*(uint32_t *) attr_data);
+ else
+ *data = *(uint32_t *) attr_data;
+ }
return 0;
}
@@ -587,11 +606,11 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_ETHER_ADDR);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, NULL);
if (r < 0)
return r;
else if ((size_t)r < sizeof(struct ether_addr))
@@ -609,11 +628,11 @@ int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short typ
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_CACHE_INFO);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, NULL);
if (r < 0)
return r;
else if ((size_t)r < sizeof(struct ifa_cacheinfo))
@@ -631,11 +650,11 @@ int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type,
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, NULL);
if (r < 0)
return r;
else if ((size_t)r < sizeof(struct in_addr))
@@ -653,11 +672,11 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type,
assert_return(m, -EINVAL);
- r = message_attribute_has_type(m, type, NLA_IN_ADDR);
+ r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR);
if (r < 0)
return r;
- r = rtnl_message_read_internal(m, type, &attr_data);
+ r = netlink_message_read_internal(m, type, &attr_data, NULL);
if (r < 0)
return r;
else if ((size_t)r < sizeof(struct in6_addr))
@@ -669,34 +688,73 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type,
return 0;
}
-int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type) {
+static int netlink_container_parse(sd_netlink_message *m,
+ struct netlink_container *container,
+ int count,
+ struct rtattr *rta,
+ unsigned int rt_len) {
+ _cleanup_free_ struct netlink_attribute *attributes = NULL;
+
+ attributes = new0(struct netlink_attribute, count);
+ if(!attributes)
+ return -ENOMEM;
+
+ for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
+ unsigned short type;
+
+ type = RTA_TYPE(rta);
+
+ /* if the kernel is newer than the headers we used
+ when building, we ignore out-of-range attributes */
+ if (type >= count)
+ continue;
+
+ if (attributes[type].offset)
+ log_debug("rtnl: message parse - overwriting repeated attribute");
+
+ attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr;
+ attributes[type].nested = RTA_FLAGS(rta) & NLA_F_NESTED;
+ attributes[type].net_byteorder = RTA_FLAGS(rta) & NLA_F_NET_BYTEORDER;
+ }
+
+ container->attributes = attributes;
+ attributes = NULL;
+ container->n_attributes = count;
+
+ return 0;
+}
+
+int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type_id) {
const NLType *nl_type;
const NLTypeSystem *type_system;
void *container;
+ uint16_t type;
size_t size;
int r;
assert_return(m, -EINVAL);
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
- r = type_system_get_type(m->container_type_system[m->n_containers],
+ r = type_system_get_type(m->containers[m->n_containers].type_system,
&nl_type,
- type);
+ type_id);
if (r < 0)
return r;
- if (nl_type->type == NLA_NESTED) {
- r = type_system_get_type_system(m->container_type_system[m->n_containers],
+ 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);
+ type_id);
if (r < 0)
return r;
- } else if (nl_type->type == NLA_UNION) {
+ } else if (type == NETLINK_TYPE_UNION) {
const NLTypeSystemUnion *type_system_union;
- r = type_system_get_type_system_union(m->container_type_system[m->n_containers],
+ r = type_system_get_type_system_union(m->containers[m->n_containers].type_system,
&type_system_union,
- type);
+ type_id);
if (r < 0)
return r;
@@ -739,7 +797,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ
} else
return -EINVAL;
- r = rtnl_message_read_internal(m, type, &container);
+ r = netlink_message_read_internal(m, type_id, &container, NULL);
if (r < 0)
return r;
else
@@ -747,18 +805,17 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ
m->n_containers ++;
- r = rtnl_message_parse(m,
- &m->rta_offset_tb[m->n_containers],
- &m->rta_tb_size[m->n_containers],
- type_system->max,
- container,
- size);
+ r = netlink_container_parse(m,
+ &m->containers[m->n_containers],
+ type_system_get_count(type_system),
+ container,
+ size);
if (r < 0) {
m->n_containers --;
return r;
}
- m->container_type_system[m->n_containers] = type_system;
+ m->containers[m->n_containers].type_system = type_system;
return 0;
}
@@ -768,9 +825,9 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) {
assert_return(m->sealed, -EINVAL);
assert_return(m->n_containers > 0, -EINVAL);
- free(m->rta_offset_tb[m->n_containers]);
- m->rta_offset_tb[m->n_containers] = NULL;
- m->container_type_system[m->n_containers] = NULL;
+ free(m->containers[m->n_containers].attributes);
+ m->containers[m->n_containers].attributes = NULL;
+ m->containers[m->n_containers].type_system = NULL;
m->n_containers --;
@@ -805,43 +862,10 @@ int sd_netlink_message_get_errno(sd_netlink_message *m) {
return err->error;
}
-int rtnl_message_parse(sd_netlink_message *m,
- size_t **rta_offset_tb,
- unsigned short *rta_tb_size,
- int max,
- struct rtattr *rta,
- unsigned int rt_len) {
- unsigned short type;
- size_t *tb;
-
- tb = new0(size_t, max + 1);
- if(!tb)
- return -ENOMEM;
-
- *rta_tb_size = max + 1;
-
- for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
- type = RTA_TYPE(rta);
-
- /* if the kernel is newer than the headers we used
- when building, we ignore out-of-range attributes
- */
- if (type > max)
- continue;
-
- if (tb[type])
- log_debug("rtnl: message parse - overwriting repeated attribute");
-
- tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr;
- }
-
- *rta_offset_tb = tb;
-
- return 0;
-}
-
int sd_netlink_message_rewind(sd_netlink_message *m) {
- const NLType *type;
+ const NLType *nl_type;
+ uint16_t type;
+ size_t size;
unsigned i;
int r;
@@ -852,39 +876,38 @@ int sd_netlink_message_rewind(sd_netlink_message *m) {
rtnl_message_seal(m);
for (i = 1; i <= m->n_containers; i++) {
- free(m->rta_offset_tb[i]);
- m->rta_offset_tb[i] = NULL;
- m->rta_tb_size[i] = 0;
- m->container_type_system[i] = NULL;
+ free(m->containers[i].attributes);
+ m->containers[i].attributes = NULL;
}
m->n_containers = 0;
- if (m->rta_offset_tb[0]) {
+ if (m->containers[0].attributes) {
/* top-level attributes have already been parsed */
return 0;
}
assert(m->hdr);
- r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type);
+ r = type_system_get_type(&type_system_root, &nl_type, m->hdr->nlmsg_type);
if (r < 0)
return r;
- if (type->type == NLA_NESTED) {
- const NLTypeSystem *type_system = type->type_system;
+ type = type_get_type(nl_type);
+ size = type_get_size(nl_type);
+
+ if (type == NETLINK_TYPE_NESTED) {
+ const NLTypeSystem *type_system;
- assert(type_system);
+ type_get_type_system(nl_type, &type_system);
- m->container_type_system[0] = type_system;
+ m->containers[0].type_system = type_system;
- r = rtnl_message_parse(m,
- &m->rta_offset_tb[m->n_containers],
- &m->rta_tb_size[m->n_containers],
- type_system->max,
- (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) +
- NLMSG_ALIGN(type->size)),
- NLMSG_PAYLOAD(m->hdr, type->size));
+ r = netlink_container_parse(m,
+ &m->containers[m->n_containers],
+ type_system_get_count(type_system),
+ (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)),
+ NLMSG_PAYLOAD(m->hdr, size));
if (r < 0)
return r;
}
diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c
index 8136cf36ae..84ff7c38c9 100644
--- a/src/libsystemd/sd-netlink/netlink-socket.c
+++ b/src/libsystemd/sd-netlink/netlink-socket.c
@@ -243,7 +243,7 @@ int socket_read_message(sd_netlink *rtnl) {
}
/* check that we support this message type */
- r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type);
+ r = type_system_get_type(&type_system_root, &nl_type, new_msg->nlmsg_type);
if (r < 0) {
if (r == -EOPNOTSUPP)
log_debug("sd-netlink: ignored message with unknown type: %i",
@@ -253,7 +253,7 @@ int socket_read_message(sd_netlink *rtnl) {
}
/* check that the size matches the message type */
- if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size)) {
+ if (new_msg->nlmsg_len < NLMSG_LENGTH(type_get_size(nl_type))) {
log_debug("sd-netlink: message larger than expected, dropping");
continue;
}
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 273033770f..9b68935245 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -39,152 +39,205 @@
#include "netlink-types.h"
#include "missing.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;
+};
+
static const NLTypeSystem rtnl_link_type_system;
+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,
+};
+
static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = {
- [VETH_INFO_PEER] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [VETH_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_MAX + 1] = {
- [IFLA_IPVLAN_MODE] = { .type = NLA_U16 },
+ [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 },
};
static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = {
- [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
- [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
+ [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 },
};
static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = {
- [IFLA_BRIDGE_FLAGS] = { .type = NLA_U16 },
- [IFLA_BRIDGE_MODE] = { .type = NLA_U16 },
+ [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_BRIDGE_MODE] = { .type = NETLINK_TYPE_U16 },
/*
- [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY,
+ [IFLA_BRIDGE_VLAN_INFO] = { .type = NETLINK_TYPE_BINARY,
.len = sizeof(struct bridge_vlan_info), },
*/
};
static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = {
- [IFLA_VLAN_ID] = { .type = NLA_U16 },
+ [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 },
/*
[IFLA_VLAN_FLAGS] = { .len = sizeof(struct ifla_vlan_flags) },
- [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED },
- [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED },
+ [IFLA_VLAN_EGRESS_QOS] = { .type = NETLINK_TYPE_NESTED },
+ [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED },
*/
- [IFLA_VLAN_PROTOCOL] = { .type = NLA_U16 },
+ [IFLA_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 },
};
static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = {
- [IFLA_VXLAN_ID] = { .type = NLA_U32 },
- [IFLA_VXLAN_GROUP] = {.type = NLA_IN_ADDR },
- [IFLA_VXLAN_LINK] = { .type = NLA_U32 },
- [IFLA_VXLAN_LOCAL] = { .type = NLA_U32},
- [IFLA_VXLAN_TTL] = { .type = NLA_U8 },
- [IFLA_VXLAN_TOS] = { .type = NLA_U8 },
- [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
- [IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
- [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
- [IFLA_VXLAN_PORT_RANGE] = { .type = NLA_U32},
- [IFLA_VXLAN_PROXY] = { .type = NLA_U8 },
- [IFLA_VXLAN_RSC] = { .type = NLA_U8 },
- [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 },
- [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 },
+ [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_U32},
+ [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 },
};
static const NLType rtnl_bond_arp_target_types[BOND_ARP_TARGETS_MAX + 1] = {
- [BOND_ARP_TARGETS_0] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_1] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_2] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_3] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_4] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_5] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_6] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_7] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_8] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_9] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_10] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_11] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_12] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_13] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_14] = { .type = NLA_U32 },
- [BOND_ARP_TARGETS_MAX] = { .type = NLA_U32 },
+ [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 = {
- .max = ELEMENTSOF(rtnl_bond_arp_target_types) - 1,
+ .count = ELEMENTSOF(rtnl_bond_arp_target_types),
.types = rtnl_bond_arp_target_types,
};
static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = {
- [IFLA_BOND_MODE] = { .type = NLA_U8 },
- [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
- [IFLA_BOND_MIIMON] = { .type = NLA_U32 },
- [IFLA_BOND_UPDELAY] = { .type = NLA_U32 },
- [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 },
- [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 },
- [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 },
- [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED, .type_system = &rtnl_bond_arp_type_system },
- [IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 },
- [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NLA_U32 },
- [IFLA_BOND_PRIMARY] = { .type = NLA_U32 },
- [IFLA_BOND_PRIMARY_RESELECT] = { .type = NLA_U8 },
- [IFLA_BOND_FAIL_OVER_MAC] = { .type = NLA_U8 },
- [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NLA_U8 },
- [IFLA_BOND_RESEND_IGMP] = { .type = NLA_U32 },
- [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NLA_U8 },
- [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NLA_U8 },
- [IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 },
- [IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 },
- [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 },
- [IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
- [IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
- [IFLA_BOND_AD_INFO] = { .type = NLA_NESTED },
+ [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 },
};
static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = {
- [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
- [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR },
- [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR },
- [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
- [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
- [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
- [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 },
- [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
- [IFLA_IPTUN_6RD_PREFIX] = { .type = NLA_IN_ADDR },
- [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 },
- [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 },
- [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 },
+ [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_MAX + 1] = {
- [IFLA_GRE_LINK] = { .type = NLA_U32 },
- [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
- [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
- [IFLA_GRE_IKEY] = { .type = NLA_U32 },
- [IFLA_GRE_OKEY] = { .type = NLA_U32 },
- [IFLA_GRE_LOCAL] = { .type = NLA_IN_ADDR },
- [IFLA_GRE_REMOTE] = { .type = NLA_IN_ADDR },
- [IFLA_GRE_TTL] = { .type = NLA_U8 },
- [IFLA_GRE_TOS] = { .type = NLA_U8 },
- [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
+ [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 },
};
static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = {
- [IFLA_VTI_LINK] = { .type = NLA_U32 },
- [IFLA_VTI_IKEY] = { .type = NLA_U32 },
- [IFLA_VTI_OKEY] = { .type = NLA_U32 },
- [IFLA_VTI_LOCAL] = { .type = NLA_IN_ADDR },
- [IFLA_VTI_REMOTE] = { .type = NLA_IN_ADDR },
+ [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_MAX + 1] = {
- [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
- [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR },
- [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR },
- [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
- [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
- [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
- [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
- [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32},
+ [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 },
};
/* these strings must match the .kind entries in the kernel */
@@ -211,37 +264,37 @@ static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_
DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = {
- [NL_UNION_LINK_INFO_DATA_BOND] = { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1,
+ [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_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1,
+ [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_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+ [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_IPGRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1,
+ [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] = { .max = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types) - 1,
+ [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
.types = rtnl_link_info_data_ip6tnl_types },
};
@@ -255,33 +308,36 @@ static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
};
static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = {
- [IFLA_INFO_KIND] = { .type = NLA_STRING },
- [IFLA_INFO_DATA] = { .type = NLA_UNION, .type_system_union = &rtnl_link_info_data_type_system_union},
+ [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 = NLA_STRING },
- [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
+ [IFLA_INFO_SLAVE_KIND] = { .type = NETLINK_TYPE_STRING },
+ [IFLA_INFO_SLAVE_DATA] = { .type = NETLINK_TYPE_NESTED },
*/
};
static const NLTypeSystem rtnl_link_info_type_system = {
- .max = ELEMENTSOF(rtnl_link_info_types) - 1,
+ .count = ELEMENTSOF(rtnl_link_info_types),
.types = rtnl_link_info_types,
};
static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] = {
- [IFLA_BRPORT_STATE] = { .type = NLA_U8 },
- [IFLA_BRPORT_COST] = { .type = NLA_U32 },
- [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 },
- [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
- [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
- [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
- [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 },
- [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 },
+ [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 },
};
static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = {
- [AF_BRIDGE] = { .max = ELEMENTSOF(rtnl_prot_info_bridge_port_types) - 1,
+ [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types),
.types = rtnl_prot_info_bridge_port_types },
};
@@ -292,7 +348,7 @@ static const NLTypeSystemUnion rtnl_prot_info_type_system_union = {
};
static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = {
- [IFLA_INET6_FLAGS] = { .type = NLA_U32 },
+ [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 },
/*
IFLA_INET6_CONF,
IFLA_INET6_STATS,
@@ -300,114 +356,114 @@ static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = {
IFLA_INET6_CACHEINFO,
IFLA_INET6_ICMP6STATS,
*/
- [IFLA_INET6_TOKEN] = { .type = NLA_IN_ADDR },
- [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 },
+ [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 = {
- .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1,
+ .count = ELEMENTSOF(rtnl_af_spec_inet6_types),
.types = rtnl_af_spec_inet6_types,
};
static const NLType rtnl_af_spec_types[AF_MAX + 1] = {
- [AF_INET6] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_inet6_type_system },
+ [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system },
};
static const NLTypeSystem rtnl_af_spec_type_system = {
- .max = ELEMENTSOF(rtnl_af_spec_types) - 1,
+ .count = ELEMENTSOF(rtnl_af_spec_types),
.types = rtnl_af_spec_types,
};
static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
- [IFLA_ADDRESS] = { .type = NLA_ETHER_ADDR, },
- [IFLA_BROADCAST] = { .type = NLA_ETHER_ADDR, },
- [IFLA_IFNAME] = { .type = NLA_STRING, .size = IFNAMSIZ - 1, },
- [IFLA_MTU] = { .type = NLA_U32 },
- [IFLA_LINK] = { .type = NLA_U32 },
+ [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],
[IFLA_STATS],
[IFLA_COST],
[IFLA_PRIORITY],
*/
- [IFLA_MASTER] = { .type = NLA_U32 },
+ [IFLA_MASTER] = { .type = NETLINK_TYPE_U32 },
/*
[IFLA_WIRELESS],
*/
- [IFLA_PROTINFO] = { .type = NLA_UNION, .type_system_union = &rtnl_prot_info_type_system_union },
- [IFLA_TXQLEN] = { .type = NLA_U32 },
+ [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 = NLA_U32 },
- [IFLA_OPERSTATE] = { .type = NLA_U8 },
- [IFLA_LINKMODE] = { .type = NLA_U8 },
- [IFLA_LINKINFO] = { .type = NLA_NESTED, .type_system = &rtnl_link_info_type_system },
- [IFLA_NET_NS_PID] = { .type = NLA_U32 },
- [IFLA_IFALIAS] = { .type = NLA_STRING, .size = IFALIASZ - 1 },
+ [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],
- [IFLA_VFINFO_LIST] = {. type = NLA_NESTED, },
+ [IFLA_VFINFO_LIST] = {. type = NETLINK_TYPE_NESTED, },
[IFLA_STATS64],
- [IFLA_VF_PORTS] = { .type = NLA_NESTED },
- [IFLA_PORT_SELF] = { .type = NLA_NESTED },
+ [IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED },
+ [IFLA_PORT_SELF] = { .type = NETLINK_TYPE_NESTED },
*/
- [IFLA_AF_SPEC] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_type_system },
+ [IFLA_AF_SPEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_type_system },
/*
[IFLA_VF_PORTS],
[IFLA_PORT_SELF],
[IFLA_AF_SPEC],
*/
- [IFLA_GROUP] = { .type = NLA_U32 },
- [IFLA_NET_NS_FD] = { .type = NLA_U32 },
- [IFLA_EXT_MASK] = { .type = NLA_U32 },
- [IFLA_PROMISCUITY] = { .type = NLA_U32 },
- [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
- [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
- [IFLA_CARRIER] = { .type = NLA_U8 },
+ [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_CARRIER] = { .type = NETLINK_TYPE_U8 },
/*
- [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
+ [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
*/
};
static const NLTypeSystem rtnl_link_type_system = {
- .max = ELEMENTSOF(rtnl_link_types) - 1,
+ .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[CONST_MAX(IFA_MAX, IFA_FLAGS) + 1] = {
- [IFA_ADDRESS] = { .type = NLA_IN_ADDR },
- [IFA_LOCAL] = { .type = NLA_IN_ADDR },
- [IFA_LABEL] = { .type = NLA_STRING, .size = IFNAMSIZ - 1 },
- [IFA_BROADCAST] = { .type = NLA_IN_ADDR }, /* 6? */
- [IFA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
+ [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 }, /* 6? */
+ [IFA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
/*
[IFA_ANYCAST],
[IFA_MULTICAST],
*/
- [IFA_FLAGS] = { .type = NLA_U32 },
+ [IFA_FLAGS] = { .type = NETLINK_TYPE_U32 },
};
static const NLTypeSystem rtnl_address_type_system = {
- .max = ELEMENTSOF(rtnl_address_types) - 1,
+ .count = ELEMENTSOF(rtnl_address_types),
.types = rtnl_address_types,
};
static const NLType rtnl_route_types[RTA_MAX + 1] = {
- [RTA_DST] = { .type = NLA_IN_ADDR }, /* 6? */
- [RTA_SRC] = { .type = NLA_IN_ADDR }, /* 6? */
- [RTA_IIF] = { .type = NLA_U32 },
- [RTA_OIF] = { .type = NLA_U32 },
- [RTA_GATEWAY] = { .type = NLA_IN_ADDR },
- [RTA_PRIORITY] = { .type = NLA_U32 },
- [RTA_PREFSRC] = { .type = NLA_IN_ADDR }, /* 6? */
+ [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 = NLA_NESTED },
+ [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED },
[RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
*/
- [RTA_FLOW] = { .type = NLA_U32 }, /* 6? */
+ [RTA_FLOW] = { .type = NETLINK_TYPE_U32 }, /* 6? */
/*
RTA_CACHEINFO,
RTA_TABLE,
@@ -417,65 +473,95 @@ static const NLType rtnl_route_types[RTA_MAX + 1] = {
};
static const NLTypeSystem rtnl_route_type_system = {
- .max = ELEMENTSOF(rtnl_route_types) - 1,
+ .count = ELEMENTSOF(rtnl_route_types),
.types = rtnl_route_types,
};
static const NLType rtnl_neigh_types[NDA_MAX + 1] = {
- [NDA_DST] = { .type = NLA_IN_ADDR },
- [NDA_LLADDR] = { .type = NLA_ETHER_ADDR },
- [NDA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
- [NDA_PROBES] = { .type = NLA_U32 },
- [NDA_VLAN] = { .type = NLA_U16 },
- [NDA_PORT] = { .type = NLA_U16 },
- [NDA_VNI] = { .type = NLA_U32 },
- [NDA_IFINDEX] = { .type = NLA_U32 },
+ [NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR },
+ [NDA_LLADDR] = { .type = NETLINK_TYPE_ETHER_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 = {
- .max = ELEMENTSOF(rtnl_neigh_types) - 1,
+ .count = ELEMENTSOF(rtnl_neigh_types),
.types = rtnl_neigh_types,
};
static const NLType rtnl_types[RTM_MAX + 1] = {
- [NLMSG_DONE] = { .type = NLA_META, .size = 0 },
- [NLMSG_ERROR] = { .type = NLA_META, .size = sizeof(struct nlmsgerr) },
- [RTM_NEWLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_DELLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_GETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_SETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_NEWADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_DELADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_GETADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_NEWNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
- [RTM_DELNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
- [RTM_GETNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
-};
-
-const NLTypeSystem rtnl_type_system = {
- .max = ELEMENTSOF(rtnl_types) - 1,
+ [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
+ [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_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_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) },
+};
+
+const NLTypeSystem type_system_root = {
+ .count = ELEMENTSOF(rtnl_types),
.types = rtnl_types,
};
-int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
- const NLType *nl_type;
+uint16_t type_get_type(const NLType *type) {
+ assert(type);
+ return type->type;
+}
+size_t type_get_size(const NLType *type) {
+ assert(type);
+ return type->size;
+}
+
+void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) {
+ assert(nl_type);
assert(ret);
+ assert(nl_type->type == NETLINK_TYPE_NESTED);
+ assert(nl_type->type_system);
- if (!type_system)
- type_system = &rtnl_type_system;
+ *ret = nl_type->type_system;
+}
+void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion **ret) {
+ assert(nl_type);
+ assert(ret);
+ assert(nl_type->type == NETLINK_TYPE_UNION);
+ assert(nl_type->type_system_union);
+
+ *ret = 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_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) {
+ const NLType *nl_type;
+
+ assert(ret);
+ assert(type_system);
assert(type_system->types);
- if (type > type_system->max)
+ if (type >= type_system->count)
return -EOPNOTSUPP;
nl_type = &type_system->types[type];
- if (nl_type->type == NLA_UNSPEC)
+ if (nl_type->type == NETLINK_TYPE_UNSPEC)
return -EOPNOTSUPP;
*ret = nl_type;
@@ -493,11 +579,7 @@ int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSys
if (r < 0)
return r;
- assert(nl_type->type == NLA_NESTED);
- assert(nl_type->type_system);
-
- *ret = nl_type->type_system;
-
+ type_get_type_system(nl_type, ret);
return 0;
}
@@ -511,11 +593,7 @@ int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLT
if (r < 0)
return r;
- assert(nl_type->type == NLA_UNION);
- assert(nl_type->type_system_union);
-
- *ret = nl_type->type_system_union;
-
+ type_get_type_system_union(nl_type, ret);
return 0;
}
@@ -552,7 +630,7 @@ int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_sys
return -EOPNOTSUPP;
type_system = &type_system_union->type_systems[protocol];
- if (type_system->max == 0)
+ if (!type_system->types)
return -EOPNOTSUPP;
*ret = type_system;
diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h
index de1544bf36..a210163241 100644
--- a/src/libsystemd/sd-netlink/netlink-types.h
+++ b/src/libsystemd/sd-netlink/netlink-types.h
@@ -22,18 +22,17 @@
***/
enum {
- NLA_UNSPEC,
- NLA_META,
- NLA_U8,
- NLA_U16,
- NLA_U32,
- NLA_U64,
- NLA_STRING,
- NLA_IN_ADDR,
- NLA_ETHER_ADDR,
- NLA_CACHE_INFO,
- NLA_NESTED,
- NLA_UNION,
+ NETLINK_TYPE_UNSPEC,
+ NETLINK_TYPE_U8, /* NLA_U8 */
+ NETLINK_TYPE_U16, /* NLA_U16 */
+ NETLINK_TYPE_U32, /* NLA_U32 */
+ NETLINK_TYPE_U64, /* NLA_U64 */
+ NETLINK_TYPE_STRING, /* NLA_STRING */
+ NETLINK_TYPE_IN_ADDR,
+ NETLINK_TYPE_ETHER_ADDR,
+ NETLINK_TYPE_CACHE_INFO,
+ NETLINK_TYPE_NESTED, /* NLA_NESTED */
+ NETLINK_TYPE_UNION,
};
typedef enum NLMatchType {
@@ -53,18 +52,14 @@ struct NLTypeSystemUnion {
const NLTypeSystem *type_systems;
};
-struct NLTypeSystem {
- uint16_t max;
- const NLType *types;
-};
+extern const NLTypeSystem type_system_root;
-struct NLType {
- uint16_t type;
- size_t size;
- const NLTypeSystem *type_system;
- const NLTypeSystemUnion *type_system_union;
-};
+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);
+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);
@@ -95,25 +90,3 @@ typedef enum 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_;
-
-/* Maximum ARP IP target defined in kernel */
-#define BOND_MAX_ARP_TARGETS 16
-
-typedef enum BondArpTargets {
- 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;