chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
sd-rtnl: fix broken test cases and add support for tunnel
[elogind.git]
/
src
/
libsystemd
/
sd-rtnl
/
sd-rtnl.c
diff --git
a/src/libsystemd/sd-rtnl/sd-rtnl.c
b/src/libsystemd/sd-rtnl/sd-rtnl.c
index 08b82ab2a94f3f6dca6bb5e21934d90cbb48cfcc..2ab9d90aa790d4f76360d6adc45111d2b6a6fe1b 100644
(file)
--- a/
src/libsystemd/sd-rtnl/sd-rtnl.c
+++ b/
src/libsystemd/sd-rtnl/sd-rtnl.c
@@
-31,7
+31,7
@@
#include "rtnl-util.h"
static int sd_rtnl_new(sd_rtnl **ret) {
#include "rtnl-util.h"
static int sd_rtnl_new(sd_rtnl **ret) {
-
sd_rtnl *rtnl
;
+
_cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL
;
assert_return(ret, -EINVAL);
assert_return(ret, -EINVAL);
@@
-52,12
+52,12
@@
static int sd_rtnl_new(sd_rtnl **ret) {
/* We guarantee that wqueue always has space for at least
* one entry */
rtnl->wqueue = new(sd_rtnl_message*, 1);
/* We guarantee that wqueue always has space for at least
* one entry */
rtnl->wqueue = new(sd_rtnl_message*, 1);
- if (!rtnl->wqueue) {
- free(rtnl);
+ if (!rtnl->wqueue)
return -ENOMEM;
return -ENOMEM;
- }
*ret = rtnl;
*ret = rtnl;
+ rtnl = NULL;
+
return 0;
}
return 0;
}
@@
-70,8
+70,8
@@
static bool rtnl_pid_changed(sd_rtnl *rtnl) {
return rtnl->original_pid != getpid();
}
return rtnl->original_pid != getpid();
}
-int sd_rtnl_open(
uint32_t groups, sd_rtnl **ret
) {
- _cleanup_
sd_
rtnl_unref_ sd_rtnl *rtnl = NULL;
+int sd_rtnl_open(
sd_rtnl **ret, uint32_t groups
) {
+ _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
socklen_t addrlen;
int r;
socklen_t addrlen;
int r;
@@
-104,6
+104,9
@@
int sd_rtnl_open(uint32_t groups, sd_rtnl **ret) {
}
sd_rtnl *sd_rtnl_ref(sd_rtnl *rtnl) {
}
sd_rtnl *sd_rtnl_ref(sd_rtnl *rtnl) {
+ assert_return(rtnl, NULL);
+ assert_return(!rtnl_pid_changed(rtnl), NULL);
+
if (rtnl)
assert_se(REFCNT_INC(rtnl->n_ref) >= 2);
if (rtnl)
assert_se(REFCNT_INC(rtnl->n_ref) >= 2);
@@
-111,8
+114,12
@@
sd_rtnl *sd_rtnl_ref(sd_rtnl *rtnl) {
}
sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) {
}
sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) {
+ if (!rtnl)
+ return NULL;
- if (rtnl && REFCNT_DEC(rtnl->n_ref) <= 0) {
+ assert_return(!rtnl_pid_changed(rtnl), NULL);
+
+ if (REFCNT_DEC(rtnl->n_ref) <= 0) {
struct match_callback *f;
unsigned i;
struct match_callback *f;
unsigned i;
@@
-127,20
+134,36
@@
sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) {
hashmap_free_free(rtnl->reply_callbacks);
prioq_free(rtnl->reply_callbacks_prioq);
hashmap_free_free(rtnl->reply_callbacks);
prioq_free(rtnl->reply_callbacks_prioq);
+ sd_event_source_unref(rtnl->io_event_source);
+ sd_event_source_unref(rtnl->time_event_source);
+ sd_event_source_unref(rtnl->exit_event_source);
+ sd_event_unref(rtnl->event);
+
while ((f = rtnl->match_callbacks)) {
LIST_REMOVE(match_callbacks, rtnl->match_callbacks, f);
free(f);
}
while ((f = rtnl->match_callbacks)) {
LIST_REMOVE(match_callbacks, rtnl->match_callbacks, f);
free(f);
}
- if (rtnl->fd >= 0)
- close_nointr_nofail(rtnl->fd);
-
+ safe_close(rtnl->fd);
free(rtnl);
}
return NULL;
}
free(rtnl);
}
return NULL;
}
+static void rtnl_seal_message(sd_rtnl *rtnl, sd_rtnl_message *m) {
+ assert(rtnl);
+ assert(!rtnl_pid_changed(rtnl));
+ assert(m);
+ assert(m->hdr);
+
+ m->hdr->nlmsg_seq = rtnl->serial++;
+
+ rtnl_message_seal(m);
+
+ return;
+}
+
int sd_rtnl_send(sd_rtnl *nl,
sd_rtnl_message *message,
uint32_t *serial) {
int sd_rtnl_send(sd_rtnl *nl,
sd_rtnl_message *message,
uint32_t *serial) {
@@
-149,10
+172,9
@@
int sd_rtnl_send(sd_rtnl *nl,
assert_return(nl, -EINVAL);
assert_return(!rtnl_pid_changed(nl), -ECHILD);
assert_return(message, -EINVAL);
assert_return(nl, -EINVAL);
assert_return(!rtnl_pid_changed(nl), -ECHILD);
assert_return(message, -EINVAL);
+ assert_return(!message->sealed, -EPERM);
- r = message_seal(nl, message);
- if (r < 0)
- return r;
+ rtnl_seal_message(nl, message);
if (nl->wqueue_size <= 0) {
/* send directly */
if (nl->wqueue_size <= 0) {
/* send directly */
@@
-181,7
+203,7
@@
int sd_rtnl_send(sd_rtnl *nl,
}
if (serial)
}
if (serial)
- *serial = message_get_serial(message);
+ *serial =
rtnl_
message_get_serial(message);
return 1;
}
return 1;
}
@@
-205,10
+227,8
@@
static int dispatch_rqueue(sd_rtnl *rtnl, sd_rtnl_message **message) {
/* Try to read a new message */
r = socket_read_message(rtnl, &z);
/* Try to read a new message */
r = socket_read_message(rtnl, &z);
- if (r < 0)
+ if (r <
=
0)
return r;
return r;
- if (r == 0)
- return 0;
*message = z;
*message = z;
@@
-241,7
+261,7
@@
static int dispatch_wqueue(sd_rtnl *rtnl) {
}
static int process_timeout(sd_rtnl *rtnl) {
}
static int process_timeout(sd_rtnl *rtnl) {
- _cleanup_
sd_
rtnl_message_unref_ sd_rtnl_message *m = NULL;
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
struct reply_callback *c;
usec_t n;
int r;
struct reply_callback *c;
usec_t n;
int r;
@@
-256,7
+276,7
@@
static int process_timeout(sd_rtnl *rtnl) {
if (c->timeout > n)
return 0;
if (c->timeout > n)
return 0;
- r = message_new_synthetic_error(-ETIMEDOUT, c->serial, &m);
+ r =
rtnl_
message_new_synthetic_error(-ETIMEDOUT, c->serial, &m);
if (r < 0)
return r;
if (r < 0)
return r;
@@
-277,7
+297,10
@@
static int process_reply(sd_rtnl *rtnl, sd_rtnl_message *m) {
assert(rtnl);
assert(m);
assert(rtnl);
assert(m);
- serial = message_get_serial(m);
+ if (sd_rtnl_message_is_broadcast(m))
+ return 0;
+
+ serial = rtnl_message_get_serial(m);
c = hashmap_remove(rtnl->reply_callbacks, &serial);
if (!c)
return 0;
c = hashmap_remove(rtnl->reply_callbacks, &serial);
if (!c)
return 0;
@@
-315,7
+338,7
@@
static int process_match(sd_rtnl *rtnl, sd_rtnl_message *m) {
}
static int process_running(sd_rtnl *rtnl, sd_rtnl_message **ret) {
}
static int process_running(sd_rtnl *rtnl, sd_rtnl_message **ret) {
- _cleanup_
sd_
rtnl_message_unref_ sd_rtnl_message *m = NULL;
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
int r;
assert(rtnl);
int r;
assert(rtnl);
@@
-557,7
+580,7
@@
int sd_rtnl_call(sd_rtnl *nl,
for (;;) {
usec_t left;
for (;;) {
usec_t left;
- _cleanup_
sd_
rtnl_message_unref_ sd_rtnl_message *incoming = NULL;
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *incoming = NULL;
if (!room) {
sd_rtnl_message **q;
if (!room) {
sd_rtnl_message **q;
@@
-580,7
+603,7
@@
int sd_rtnl_call(sd_rtnl *nl,
if (r < 0)
return r;
if (incoming) {
if (r < 0)
return r;
if (incoming) {
- uint32_t received_serial = message_get_serial(incoming);
+ uint32_t received_serial =
rtnl_
message_get_serial(incoming);
if (received_serial == serial) {
r = sd_rtnl_message_get_errno(incoming);
if (received_serial == serial) {
r = sd_rtnl_message_get_errno(incoming);
@@
-774,7
+797,7
@@
int sd_rtnl_attach_event(sd_rtnl *rtnl, sd_event *event, int priority) {
return r;
}
return r;
}
- r = sd_event_add_io(rtnl->event,
rtnl->fd, 0, io_callback, rtnl, &rtnl->io_event_source
);
+ r = sd_event_add_io(rtnl->event,
&rtnl->io_event_source, rtnl->fd, 0, io_callback, rtnl
);
if (r < 0)
goto fail;
if (r < 0)
goto fail;
@@
-786,7
+809,7
@@
int sd_rtnl_attach_event(sd_rtnl *rtnl, sd_event *event, int priority) {
if (r < 0)
goto fail;
if (r < 0)
goto fail;
- r = sd_event_add_
monotonic(rtnl->event, 0, 0, time_callback, rtnl, &rtnl->time_event_source
);
+ r = sd_event_add_
time(rtnl->event, &rtnl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, rtnl
);
if (r < 0)
goto fail;
if (r < 0)
goto fail;
@@
-794,7
+817,7
@@
int sd_rtnl_attach_event(sd_rtnl *rtnl, sd_event *event, int priority) {
if (r < 0)
goto fail;
if (r < 0)
goto fail;
- r = sd_event_add_exit(rtnl->event,
exit_callback, rtnl, &rtnl->exit_event_source
);
+ r = sd_event_add_exit(rtnl->event,
&rtnl->exit_event_source, exit_callback, rtnl
);
if (r < 0)
goto fail;
if (r < 0)
goto fail;
@@
-833,7
+856,9
@@
int sd_rtnl_add_match(sd_rtnl *rtnl,
assert_return(rtnl, -EINVAL);
assert_return(callback, -EINVAL);
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
assert_return(rtnl, -EINVAL);
assert_return(callback, -EINVAL);
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
- assert_return(message_type_is_link(type) || message_type_is_addr(type) || message_type_is_route(type), -ENOTSUP);
+ assert_return(rtnl_message_type_is_link(type) ||
+ rtnl_message_type_is_addr(type) ||
+ rtnl_message_type_is_route(type), -ENOTSUP);
c = new0(struct match_callback, 1);
if (!c)
c = new0(struct match_callback, 1);
if (!c)