Lines Matching defs:rtnl
36 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
40 rtnl = new0(sd_netlink, 1);
41 if (!rtnl)
44 rtnl->n_ref = REFCNT_INIT;
45 rtnl->fd = -1;
46 rtnl->sockaddr.nl.nl_family = AF_NETLINK;
47 rtnl->original_pid = getpid();
49 LIST_HEAD_INIT(rtnl->match_callbacks);
53 if (!greedy_realloc((void**)&rtnl->rbuffer, &rtnl->rbuffer_allocated,
60 rtnl->serial = 1;
62 *ret = rtnl;
63 rtnl = NULL;
69 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
75 r = sd_netlink_new(&rtnl);
79 addrlen = sizeof(rtnl->sockaddr);
81 r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen);
85 if (rtnl->sockaddr.nl.nl_family != AF_NETLINK)
88 rtnl->fd = fd;
90 *ret = rtnl;
91 rtnl = NULL;
96 static bool rtnl_pid_changed(sd_netlink *rtnl) {
97 assert(rtnl);
99 /* We don't support people creating an rtnl connection and
102 return rtnl->original_pid != getpid();
106 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
112 r = sd_netlink_new(&rtnl);
116 rtnl->fd = fd;
118 r = socket_bind(rtnl);
120 rtnl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */
124 *ret = rtnl;
125 rtnl = NULL;
147 int sd_netlink_inc_rcvbuf(const sd_netlink *const rtnl, const int size) {
148 return fd_inc_rcvbuf(rtnl->fd, size);
151 sd_netlink *sd_netlink_ref(sd_netlink *rtnl) {
152 assert_return(rtnl, NULL);
153 assert_return(!rtnl_pid_changed(rtnl), NULL);
155 if (rtnl)
156 assert_se(REFCNT_INC(rtnl->n_ref) >= 2);
158 return rtnl;
161 sd_netlink *sd_netlink_unref(sd_netlink *rtnl) {
162 if (!rtnl)
165 assert_return(!rtnl_pid_changed(rtnl), NULL);
167 if (REFCNT_DEC(rtnl->n_ref) == 0) {
171 for (i = 0; i < rtnl->rqueue_size; i++)
172 sd_netlink_message_unref(rtnl->rqueue[i]);
173 free(rtnl->rqueue);
175 for (i = 0; i < rtnl->rqueue_partial_size; i++)
176 sd_netlink_message_unref(rtnl->rqueue_partial[i]);
177 free(rtnl->rqueue_partial);
179 free(rtnl->rbuffer);
181 hashmap_free_free(rtnl->reply_callbacks);
182 prioq_free(rtnl->reply_callbacks_prioq);
184 sd_event_source_unref(rtnl->io_event_source);
185 sd_event_source_unref(rtnl->time_event_source);
186 sd_event_unref(rtnl->event);
188 while ((f = rtnl->match_callbacks)) {
189 sd_netlink_remove_match(rtnl, f->type, f->callback, f->userdata);
192 hashmap_free(rtnl->broadcast_group_refs);
194 safe_close(rtnl->fd);
195 free(rtnl);
201 static void rtnl_seal_message(sd_netlink *rtnl, sd_netlink_message *m) {
202 assert(rtnl);
203 assert(!rtnl_pid_changed(rtnl));
209 m->hdr->nlmsg_seq = rtnl->serial++ ? : rtnl->serial++;
238 int rtnl_rqueue_make_room(sd_netlink *rtnl) {
239 assert(rtnl);
241 if (rtnl->rqueue_size >= RTNL_RQUEUE_MAX) {
242 log_debug("rtnl: exhausted the read queue size (%d)", RTNL_RQUEUE_MAX);
246 if (!GREEDY_REALLOC(rtnl->rqueue, rtnl->rqueue_allocated, rtnl->rqueue_size + 1))
252 int rtnl_rqueue_partial_make_room(sd_netlink *rtnl) {
253 assert(rtnl);
255 if (rtnl->rqueue_partial_size >= RTNL_RQUEUE_MAX) {
256 log_debug("rtnl: exhausted the partial read queue size (%d)", RTNL_RQUEUE_MAX);
260 if (!GREEDY_REALLOC(rtnl->rqueue_partial, rtnl->rqueue_partial_allocated,
261 rtnl->rqueue_partial_size + 1))
267 static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
270 assert(rtnl);
273 if (rtnl->rqueue_size <= 0) {
275 r = socket_read_message(rtnl);
281 *message = rtnl->rqueue[0];
282 rtnl->rqueue_size --;
283 memmove(rtnl->rqueue, rtnl->rqueue + 1, sizeof(sd_netlink_message*) * rtnl->rqueue_size);
288 static int process_timeout(sd_netlink *rtnl) {
294 assert(rtnl);
296 c = prioq_peek(rtnl->reply_callbacks_prioq);
308 assert_se(prioq_pop(rtnl->reply_callbacks_prioq) == c);
309 hashmap_remove(rtnl->reply_callbacks, &c->serial);
311 r = c->callback(rtnl, m, c->userdata);
320 static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
326 assert(rtnl);
330 c = hashmap_remove(rtnl->reply_callbacks, &serial);
335 prioq_remove(rtnl->reply_callbacks_prioq, c, &c->prioq_idx);
344 r = c->callback(rtnl, m, c->userdata);
351 static int process_match(sd_netlink *rtnl, sd_netlink_message *m) {
356 assert(rtnl);
363 LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks) {
365 r = c->callback(rtnl, m, c->userdata);
378 static int process_running(sd_netlink *rtnl, sd_netlink_message **ret) {
382 assert(rtnl);
384 r = process_timeout(rtnl);
388 r = dispatch_rqueue(rtnl, &m);
395 r = process_match(rtnl, m);
399 r = process_reply(rtnl, m);
420 int sd_netlink_process(sd_netlink *rtnl, sd_netlink_message **ret) {
421 NETLINK_DONT_DESTROY(rtnl);
424 assert_return(rtnl, -EINVAL);
425 assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
426 assert_return(!rtnl->processing, -EBUSY);
428 rtnl->processing = true;
429 r = process_running(rtnl, ret);
430 rtnl->processing = false;
445 static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
451 assert(rtnl);
453 e = sd_netlink_get_events(rtnl);
466 r = sd_netlink_get_timeout(rtnl, &until);
479 p[0].fd = rtnl->fd;
598 int sd_netlink_call(sd_netlink *rtnl,
606 assert_return(rtnl, -EINVAL);
607 assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
610 r = sd_netlink_send(rtnl, message, &serial);
620 for (i = 0; i < rtnl->rqueue_size; i++) {
623 received_serial = rtnl_message_get_serial(rtnl->rqueue[i]);
629 incoming = rtnl->rqueue[i];
632 memmove(rtnl->rqueue + i,rtnl->rqueue + i + 1,
633 sizeof(sd_netlink_message*) * (rtnl->rqueue_size - i - 1));
634 rtnl->rqueue_size--;
658 r = socket_read_message(rtnl);
676 r = rtnl_poll(rtnl, true, left);
684 int sd_netlink_get_events(sd_netlink *rtnl) {
685 assert_return(rtnl, -EINVAL);
686 assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
688 if (rtnl->rqueue_size == 0)
694 int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) {
697 assert_return(rtnl, -EINVAL);
699 assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
701 if (rtnl->rqueue_size > 0) {
706 c = prioq_peek(rtnl->reply_callbacks_prioq);
718 sd_netlink *rtnl = userdata;
721 assert(rtnl);
723 r = sd_netlink_process(rtnl, NULL);
731 sd_netlink *rtnl = userdata;
734 assert(rtnl);
736 r = sd_netlink_process(rtnl, NULL);
744 sd_netlink *rtnl = userdata;
749 assert(rtnl);
751 e = sd_netlink_get_events(rtnl);
755 r = sd_event_source_set_io_events(rtnl->io_event_source, e);
759 r = sd_netlink_get_timeout(rtnl, &until);
765 j = sd_event_source_set_time(rtnl->time_event_source, until);
770 r = sd_event_source_set_enabled(rtnl->time_event_source, r > 0);
777 int sd_netlink_attach_event(sd_netlink *rtnl, sd_event *event, int priority) {
780 assert_return(rtnl, -EINVAL);
781 assert_return(!rtnl->event, -EBUSY);
783 assert(!rtnl->io_event_source);
784 assert(!rtnl->time_event_source);
787 rtnl->event = sd_event_ref(event);
789 r = sd_event_default(&rtnl->event);
794 r = sd_event_add_io(rtnl->event, &rtnl->io_event_source, rtnl->fd, 0, io_callback, rtnl);
798 r = sd_event_source_set_priority(rtnl->io_event_source, priority);
802 r = sd_event_source_set_description(rtnl->io_event_source, "rtnl-receive-message");
806 r = sd_event_source_set_prepare(rtnl->io_event_source, prepare_callback);
810 r = sd_event_add_time(rtnl->event, &rtnl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, rtnl);
814 r = sd_event_source_set_priority(rtnl->time_event_source, priority);
818 r = sd_event_source_set_description(rtnl->time_event_source, "rtnl-timer");
825 sd_netlink_detach_event(rtnl);
829 int sd_netlink_detach_event(sd_netlink *rtnl) {
830 assert_return(rtnl, -EINVAL);
831 assert_return(rtnl->event, -ENXIO);
833 rtnl->io_event_source = sd_event_source_unref(rtnl->io_event_source);
835 rtnl->time_event_source = sd_event_source_unref(rtnl->time_event_source);
837 rtnl->event = sd_event_unref(rtnl->event);
842 int sd_netlink_add_match(sd_netlink *rtnl,
849 assert_return(rtnl, -EINVAL);
851 assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
864 r = socket_broadcast_group_ref(rtnl, RTNLGRP_LINK);
871 r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_IFADDR);
875 r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_IFADDR);
882 r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV4_ROUTE);
886 r = socket_broadcast_group_ref(rtnl, RTNLGRP_IPV6_ROUTE);
894 LIST_PREPEND(match_callbacks, rtnl->match_callbacks, c);
901 int sd_netlink_remove_match(sd_netlink *rtnl,
908 assert_return(rtnl, -EINVAL);
910 assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
912 LIST_FOREACH(match_callbacks, c, rtnl->match_callbacks)
914 LIST_REMOVE(match_callbacks, rtnl->match_callbacks, c);
920 r = socket_broadcast_group_unref(rtnl, RTNLGRP_LINK);
927 r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV4_IFADDR);
931 r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV6_IFADDR);
938 r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV4_ROUTE);
942 r = socket_broadcast_group_unref(rtnl, RTNLGRP_IPV6_ROUTE);