summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libsystemd/sd-netlink/netlink-internal.h1
-rw-r--r--src/libsystemd/sd-netlink/netlink-socket.c25
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c35
-rw-r--r--src/systemd/sd-netlink.h1
4 files changed, 62 insertions, 0 deletions
diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h
index 1240f0d66d..2845700ffb 100644
--- a/src/libsystemd/sd-netlink/netlink-internal.h
+++ b/src/libsystemd/sd-netlink/netlink-internal.h
@@ -139,6 +139,7 @@ int socket_bind(sd_netlink *nl);
int socket_broadcast_group_ref(sd_netlink *nl, unsigned group);
int socket_broadcast_group_unref(sd_netlink *nl, unsigned group);
int socket_write_message(sd_netlink *nl, sd_netlink_message *m);
+int socket_writev_message(sd_netlink *nl, sd_netlink_message *m[], size_t msgcount);
int socket_read_message(sd_netlink *nl);
int rtnl_rqueue_make_room(sd_netlink *rtnl);
diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c
index 228e38df90..a1a839f57a 100644
--- a/src/libsystemd/sd-netlink/netlink-socket.c
+++ b/src/libsystemd/sd-netlink/netlink-socket.c
@@ -238,6 +238,31 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
return k;
}
+int socket_writev_message(sd_netlink *nl, sd_netlink_message *m[], size_t msgcount) {
+ _cleanup_free_ struct iovec *iovs = NULL;
+ ssize_t k;
+ size_t i;
+
+ assert(nl);
+ assert(msgcount);
+
+ iovs = new0(struct iovec, msgcount);
+ if (!iovs)
+ return -ENOMEM;
+
+ for (i = 0; i < msgcount; i++) {
+ assert(m[i]->hdr != NULL);
+ assert(m[i]->hdr->nlmsg_len > 0);
+ iovs[i] = IOVEC_MAKE(m[i]->hdr, m[i]->hdr->nlmsg_len);
+ }
+
+ k = writev(nl->fd, iovs, msgcount);
+ if (k < 0)
+ return -errno;
+
+ return k;
+}
+
static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_group, bool peek) {
union sockaddr_union sender;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct nl_pktinfo))) control;
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 7801101807..5a8b4d9322 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -226,6 +226,41 @@ int sd_netlink_send(sd_netlink *nl,
return 1;
}
+int sd_netlink_sendv(sd_netlink *nl,
+ sd_netlink_message *messages[],
+ size_t msgcount,
+ uint32_t **ret_serial) {
+ _cleanup_free_ uint32_t *serials = NULL;
+ unsigned i;
+ int r;
+
+ assert_return(nl, -EINVAL);
+ assert_return(!rtnl_pid_changed(nl), -ECHILD);
+ assert_return(messages, -EINVAL);
+
+ if (ret_serial) {
+ serials = new0(uint32_t, msgcount);
+ if (!serials)
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < msgcount; i++) {
+ assert_return(!messages[i]->sealed, -EPERM);
+ rtnl_seal_message(nl, messages[i]);
+ if (serials)
+ serials[i] = rtnl_message_get_serial(messages[i]);
+ }
+
+ r = socket_writev_message(nl, messages, msgcount);
+ if (r < 0)
+ return r;
+
+ if (ret_serial)
+ *ret_serial = TAKE_PTR(serials);
+
+ return r;
+}
+
int rtnl_rqueue_make_room(sd_netlink *rtnl) {
assert(rtnl);
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
index 15fa84de28..2b52c4ca88 100644
--- a/src/systemd/sd-netlink.h
+++ b/src/systemd/sd-netlink.h
@@ -60,6 +60,7 @@ sd_netlink *sd_netlink_ref(sd_netlink *nl);
sd_netlink *sd_netlink_unref(sd_netlink *nl);
int sd_netlink_send(sd_netlink *nl, sd_netlink_message *message, uint32_t *serial);
+int sd_netlink_sendv(sd_netlink *nl, sd_netlink_message *messages[], size_t msgcnt, uint32_t **ret_serial);
int sd_netlink_call_async(sd_netlink *nl, sd_netlink_slot **ret_slot, sd_netlink_message *message,
sd_netlink_message_handler_t callback, sd_netlink_destroy_t destoy_callback,
void *userdata, uint64_t usec, const char *description);