#endif
NULL};
+static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
+ Manager *m = userdata;
+
+ assert(m);
+
+ log_received_signal(LOG_INFO, si);
+
+ sd_event_exit(m->event, 0);
+ return 0;
+}
+
+static int setup_signals(Manager *m) {
+ sigset_t mask;
+ int r;
+
+ assert(m);
+
+ assert_se(sigemptyset(&mask) == 0);
+ sigset_add_many(&mask, SIGINT, SIGTERM, -1);
+ assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+
+ r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m);
+ if (r < 0)
+ return r;
+
+ r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
int manager_new(Manager **ret) {
_cleanup_manager_free_ Manager *m = NULL;
int r;
sd_event_set_watchdog(m->event, true);
- r = sd_rtnl_open(RTMGRP_LINK | RTMGRP_IPV4_IFADDR, &m->rtnl);
+ r = sd_rtnl_open(&m->rtnl, RTMGRP_LINK | RTMGRP_IPV4_IFADDR);
if (r < 0)
return r;
if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
return r;
+ r = setup_signals(m);
+ if (r < 0)
+ return r;
+
m->udev = udev_new();
if (!m->udev)
return -ENOMEM;
NetDev *netdev;
Link *link;
+ if (!m)
+ return;
+
udev_monitor_unref(m->udev_monitor);
udev_unref(m->udev);
sd_bus_unref(m->bus);
sd_event_source_unref(m->udev_event_source);
+ sd_event_source_unref(m->sigterm_event_source);
+ sd_event_source_unref(m->sigint_event_source);
sd_event_unref(m->event);
while ((network = m->networks))
}
static int manager_process_link(Manager *m, struct udev_device *device) {
- Link *link;
+ Link *link = NULL;
int r;
- if (streq_ptr(udev_device_get_action(device), "remove")) {
- uint64_t ifindex;
+ assert(m);
+ assert(device);
+
+ link_get(m, udev_device_get_ifindex(device), &link);
+ if (streq_ptr(udev_device_get_action(device), "remove")) {
log_debug("%s: link removed", udev_device_get_sysname(device));
- ifindex = udev_device_get_ifindex(device);
- link = hashmap_get(m->links, &ifindex);
- if (!link)
+ if (link)
+ link_free(link);
+ } else {
+ if (link) {
+ log_debug("%s: link already exists, ignoring",
+ link->ifname);
return 0;
+ }
- link_free(link);
- } else {
r = link_add(m, device, &link);
if (r < 0) {
- if (r == -EEXIST)
- log_debug("%s: link already exists, ignoring",
- link->ifname);
- else
- log_error("%s: could not handle link: %s",
- udev_device_get_sysname(device),
- strerror(-r));
+ log_error("%s: could not handle link: %s",
+ udev_device_get_sysname(device),
+ strerror(-r));
} else
log_debug("%s: link (with ifindex %" PRIu64") added",
link->ifname, link->ifindex);
}
r = sd_event_add_io(m->event,
+ &m->udev_event_source,
udev_monitor_get_fd(m->udev_monitor),
EPOLLIN, manager_dispatch_link_udev,
- m, &m->udev_event_source);
+ m);
if (r < 0)
return r;
Manager *m = userdata;
Link *link;
const char *name;
- uint64_t ifindex_64;
int r, ifindex;
+ assert(rtnl);
+ assert(message);
+ assert(m);
+
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
if (r < 0 || ifindex <= 0) {
log_debug("received RTM_NEWLINK message without valid ifindex");
}
}
- ifindex_64 = ifindex;
- link = hashmap_get(m->links, &ifindex_64);
- if (!link) {
+ r = link_get(m, ifindex, &link);
+ if (r < 0) {
log_debug("received RTM_NEWLINK message for untracked ifindex %d", ifindex);
return 0;
}