|
|
be0c12 |
From cd3b4c5345a3500f190941454fff03fc143c6f2e Mon Sep 17 00:00:00 2001
|
|
|
be0c12 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
be0c12 |
Date: Sun, 15 Dec 2019 21:32:25 +0900
|
|
|
be0c12 |
Subject: [PATCH] sd-netlink: introduce sd_netlink_message_read_strv()
|
|
|
be0c12 |
|
|
|
be0c12 |
The combination of sd_netlink_message_enter_container() and
|
|
|
be0c12 |
sd_netlink_message_read_string() only reads the last element if the attribute is
|
|
|
be0c12 |
duplicated, such a situation easily happens for IFLA_ALT_IFNAME.
|
|
|
be0c12 |
The function introduced here reads all matched attributes.
|
|
|
be0c12 |
|
|
|
be0c12 |
(cherry picked from commit 8f3c1859669230c2c8458675f41de13e369b47e7)
|
|
|
be0c12 |
|
|
|
be0c12 |
Related: #2005008
|
|
|
be0c12 |
---
|
|
|
be0c12 |
src/libsystemd/sd-netlink/netlink-message.c | 58 +++++++++++++++++++++
|
|
|
be0c12 |
src/systemd/sd-netlink.h | 1 +
|
|
|
be0c12 |
2 files changed, 59 insertions(+)
|
|
|
be0c12 |
|
|
|
be0c12 |
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
|
|
|
be0c12 |
index db9101c163..5723e1d21c 100644
|
|
|
be0c12 |
--- a/src/libsystemd/sd-netlink/netlink-message.c
|
|
|
be0c12 |
+++ b/src/libsystemd/sd-netlink/netlink-message.c
|
|
|
be0c12 |
@@ -14,6 +14,7 @@
|
|
|
be0c12 |
#include "netlink-util.h"
|
|
|
be0c12 |
#include "refcnt.h"
|
|
|
be0c12 |
#include "socket-util.h"
|
|
|
be0c12 |
+#include "strv.h"
|
|
|
be0c12 |
#include "util.h"
|
|
|
be0c12 |
|
|
|
be0c12 |
#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
|
|
|
be0c12 |
@@ -754,6 +755,63 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type,
|
|
|
be0c12 |
return 0;
|
|
|
be0c12 |
}
|
|
|
be0c12 |
|
|
|
be0c12 |
+int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret) {
|
|
|
be0c12 |
+ _cleanup_strv_free_ char **s = NULL;
|
|
|
be0c12 |
+ const NLTypeSystem *type_system;
|
|
|
be0c12 |
+ const NLType *nl_type;
|
|
|
be0c12 |
+ struct rtattr *rta;
|
|
|
be0c12 |
+ void *container;
|
|
|
be0c12 |
+ unsigned short rt_len;
|
|
|
be0c12 |
+ int r;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ assert_return(m, -EINVAL);
|
|
|
be0c12 |
+ assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ r = type_system_get_type(m->containers[m->n_containers].type_system,
|
|
|
be0c12 |
+ &nl_type,
|
|
|
be0c12 |
+ container_type);
|
|
|
be0c12 |
+ if (r < 0)
|
|
|
be0c12 |
+ return r;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
|
|
|
be0c12 |
+ return -EINVAL;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ r = type_system_get_type_system(m->containers[m->n_containers].type_system,
|
|
|
be0c12 |
+ &type_system,
|
|
|
be0c12 |
+ container_type);
|
|
|
be0c12 |
+ if (r < 0)
|
|
|
be0c12 |
+ return r;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ r = type_system_get_type(type_system, &nl_type, type_id);
|
|
|
be0c12 |
+ if (r < 0)
|
|
|
be0c12 |
+ return r;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ if (type_get_type(nl_type) != NETLINK_TYPE_STRING)
|
|
|
be0c12 |
+ return -EINVAL;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ r = netlink_message_read_internal(m, container_type, &container, NULL);
|
|
|
be0c12 |
+ if (r < 0)
|
|
|
be0c12 |
+ return r;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ rt_len = (unsigned short) r;
|
|
|
be0c12 |
+ rta = container;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
|
|
|
be0c12 |
+ unsigned short type;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ type = RTA_TYPE(rta);
|
|
|
be0c12 |
+ if (type != type_id)
|
|
|
be0c12 |
+ continue;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ r = strv_extend(&s, RTA_DATA(rta));
|
|
|
be0c12 |
+ if (r < 0)
|
|
|
be0c12 |
+ return r;
|
|
|
be0c12 |
+ }
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ *ret = TAKE_PTR(s);
|
|
|
be0c12 |
+ return 0;
|
|
|
be0c12 |
+}
|
|
|
be0c12 |
+
|
|
|
be0c12 |
static int netlink_container_parse(sd_netlink_message *m,
|
|
|
be0c12 |
struct netlink_container *container,
|
|
|
be0c12 |
int count,
|
|
|
be0c12 |
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
|
|
|
be0c12 |
index 51f0fa16b4..1f5c093f11 100644
|
|
|
be0c12 |
--- a/src/systemd/sd-netlink.h
|
|
|
be0c12 |
+++ b/src/systemd/sd-netlink.h
|
|
|
be0c12 |
@@ -82,6 +82,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor
|
|
|
be0c12 |
int sd_netlink_message_close_container(sd_netlink_message *m);
|
|
|
be0c12 |
|
|
|
be0c12 |
int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, const char **data);
|
|
|
be0c12 |
+int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret);
|
|
|
be0c12 |
int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8_t *data);
|
|
|
be0c12 |
int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data);
|
|
|
be0c12 |
int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data);
|