X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-manager.c;h=1b5837e42ca4e029681aa8372b7b68d95b6a39b0;hb=7b77ed8cf36e8eca6017791626044b61ae2d68e7;hp=e376d388722811a2c106d0eb88341ae2ff8298f7;hpb=0617ffabe86a6d366252477eafbe59a888b149d4;p=elogind.git diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index e376d3887..1b5837e42 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -22,6 +22,7 @@ #include "path-util.h" #include "networkd.h" #include "libudev-private.h" +#include "udev-util.h" int manager_new(Manager **ret) { _cleanup_manager_free_ Manager *m = NULL; @@ -35,7 +36,9 @@ int manager_new(Manager **ret) { if (r < 0) return r; - r = sd_rtnl_open(0, &m->rtnl); + sd_event_set_watchdog(m->event, true); + + r = sd_rtnl_open(RTMGRP_LINK | RTMGRP_IPV4_IFADDR, &m->rtnl); if (r < 0) return r; @@ -51,6 +54,10 @@ int manager_new(Manager **ret) { if (!m->links) return -ENOMEM; + m->bridges = hashmap_new(string_hash_func, string_compare_func); + if (!m->bridges) + return -ENOMEM; + LIST_HEAD_INIT(m->networks); m->network_dirs = strv_new("/etc/systemd/network/", @@ -74,6 +81,7 @@ int manager_new(Manager **ret) { void manager_free(Manager *m) { Network *network; + Bridge *bridge; Link *link; udev_monitor_unref(m->udev_monitor); @@ -88,12 +96,37 @@ void manager_free(Manager *m) { link_free(link); hashmap_free(m->links); + while ((bridge = hashmap_first(m->bridges))) + bridge_free(bridge); + hashmap_free(m->bridges); + strv_free(m->network_dirs); sd_rtnl_unref(m->rtnl); free(m); } +int manager_load_config(Manager *m) { + int r; + + /* update timestamp */ + paths_check_timestamp(m->network_dirs, &m->network_dirs_ts_usec, true); + + r = bridge_load(m); + if (r < 0) + return r; + + r = network_load(m); + if (r < 0) + return r; + + return 0; +} + +bool manager_should_reload(Manager *m) { + return paths_check_timestamp(m->network_dirs, &m->network_dirs_ts_usec, false); +} + static int manager_process_link(Manager *m, struct udev_device *device) { Link *link; int r; @@ -101,6 +134,8 @@ static int manager_process_link(Manager *m, struct udev_device *device) { if (streq_ptr(udev_device_get_action(device), "remove")) { uint64_t ifindex; + log_debug("Link removed: %s", udev_device_get_sysname(device)); + ifindex = udev_device_get_ifindex(device); link = hashmap_get(m->links, &ifindex); if (!link) @@ -108,6 +143,8 @@ static int manager_process_link(Manager *m, struct udev_device *device) { link_free(link); } else { + log_debug("New link: %s", udev_device_get_sysname(device)); + r = link_add(m, device); if (r < 0) { log_error("Could not handle link %s: %s", @@ -136,10 +173,6 @@ int manager_udev_enumerate_links(Manager *m) { if (r < 0) goto finish; - r = udev_enumerate_add_match_tag(e, "systemd-networkd"); - if (r < 0) - goto finish; - r = udev_enumerate_scan_devices(e); if (r < 0) goto finish; @@ -172,19 +205,13 @@ finish: static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) { Manager *m = userdata; struct udev_monitor *monitor = m->udev_monitor; - struct udev_device *device; - int r; + _cleanup_udev_device_unref_ struct udev_device *device = NULL; device = udev_monitor_receive_device(monitor); if (!device) return -ENOMEM; - r = manager_process_link(m, device); - if (r < 0) - return r; - - udev_device_unref(device); - + manager_process_link(m, device); return 0; } @@ -197,12 +224,6 @@ int manager_udev_listen(Manager *m) { return r; } - r = udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd-networkd"); - if (r < 0) { - log_error("Could not add udev monitor filter: %s", strerror(-r)); - return r; - } - r = udev_monitor_enable_receiving(m->udev_monitor); if (r < 0) { log_error("Could not enable udev monitor"); @@ -219,6 +240,31 @@ int manager_udev_listen(Manager *m) { return 0; } +static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) { + Manager *m = userdata; + Link *link; + unsigned flags; + int r, ifindex; + + r = sd_rtnl_message_link_get_ifindex(message, &ifindex); + if (r < 0) + return 0; + + link = hashmap_get(m->links, &ifindex); + if (!link) + return 0; + + r = sd_rtnl_message_link_get_flags(message, &flags); + if (r < 0) + return 0; + + r = link_update_flags(link, flags); + if (r < 0) + return 0; + + return 1; +} + int manager_rtnl_listen(Manager *m) { int r; @@ -226,5 +272,9 @@ int manager_rtnl_listen(Manager *m) { if (r < 0) return r; + r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, &manager_rtnl_process_link, m); + if (r < 0) + return r; + return 0; }