diff options
author | Tom Gundersen <teg@jklm.no> | 2014-04-15 14:21:44 +0200 |
---|---|---|
committer | Tom Gundersen <teg@jklm.no> | 2014-04-19 18:41:58 +0200 |
commit | 505f8da7325591defe5f751f328bd26915267602 (patch) | |
tree | 5f4ff2ad396ab7666ac45ed2e1a9f3ff1f13b62b /src | |
parent | d1ca51b153d7854d49400289ddedc7d493458f71 (diff) |
networkd: tie links to rtnl rather than udev
This essentially swaps the roles of rtnl and udev in networkd. After this
change libudev is only used for waiting for udev to initialize devices and
to get udev-specific information needed for some [Match] attributes.
This in particular simplifies the code in containers where udev is not really
useful, but also simplifies things and reduces round-trips in the non-container
case.
Diffstat (limited to 'src')
-rw-r--r-- | src/libsystemd-network/network-internal.c | 4 | ||||
-rw-r--r-- | src/libsystemd-network/network-internal.h | 2 | ||||
-rw-r--r-- | src/network/networkd-link.c | 253 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 184 | ||||
-rw-r--r-- | src/network/networkd-netdev.c | 72 | ||||
-rw-r--r-- | src/network/networkd-network.c | 30 | ||||
-rw-r--r-- | src/network/networkd.c | 2 | ||||
-rw-r--r-- | src/network/networkd.h | 14 | ||||
-rw-r--r-- | src/network/test-network.c | 14 | ||||
-rw-r--r-- | src/udev/net/link-config.c | 2 |
10 files changed, 270 insertions, 307 deletions
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index 3686267b07..52e614c4ea 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -79,7 +79,7 @@ bool net_match_config(const struct ether_addr *match_mac, Condition *match_virt, Condition *match_kernel, Condition *match_arch, - const char *dev_mac, + const struct ether_addr *dev_mac, const char *dev_path, const char *dev_parent_driver, const char *dev_driver, @@ -98,7 +98,7 @@ bool net_match_config(const struct ether_addr *match_mac, if (match_arch && !condition_test_architecture(match_arch)) return 0; - if (match_mac && (!dev_mac || memcmp(match_mac, ether_aton(dev_mac), ETH_ALEN))) + if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN))) return 0; if (match_path && (!dev_path || fnmatch(match_path, dev_path, 0))) diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index 65cd0d72a0..836472a776 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -37,7 +37,7 @@ bool net_match_config(const struct ether_addr *match_mac, Condition *match_virt, Condition *match_kernel, Condition *match_arch, - const char *dev_mac, + const struct ether_addr *dev_mac, const char *dev_path, const char *dev_parent_driver, const char *dev_driver, diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index f179af332c..319f2904c0 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -24,7 +24,9 @@ #include "networkd.h" #include "libudev-private.h" +#include "udev-util.h" #include "util.h" +#include "virt.h" #include "bus-util.h" #include "network-internal.h" @@ -33,41 +35,53 @@ static int ipv4ll_address_update(Link *link, bool deprecate); static bool ipv4ll_is_bound(sd_ipv4ll *ll); -int link_new(Manager *manager, struct udev_device *device, Link **ret) { +static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) { _cleanup_link_free_ Link *link = NULL; - const char *ifname; - int r; + uint16_t type; + char *ifname; + int r, ifindex; assert(manager); assert(manager->links); - assert(device); + assert(message); assert(ret); + r = sd_rtnl_message_get_type(message, &type); + if (r < 0) + return r; + else if (type != RTM_NEWLINK) + return -EINVAL; + + r = sd_rtnl_message_link_get_ifindex(message, &ifindex); + if (r < 0) + return r; + else if (ifindex <= 0) + return -EINVAL; + + r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &ifname); + if (r < 0) + return r; + link = new0(Link, 1); if (!link) return -ENOMEM; link->manager = manager; - link->state = _LINK_STATE_INVALID; - - link->ifindex = udev_device_get_ifindex(device); - if (link->ifindex <= 0) - return -EINVAL; + link->state = LINK_STATE_INITIALIZING; + link->ifindex = ifindex; + link->ifname = strdup(ifname); + if (!link->ifname) + return -ENOMEM; r = asprintf(&link->state_file, "/run/systemd/network/links/%"PRIu64, link->ifindex); if (r < 0) return -ENOMEM; - ifname = udev_device_get_sysname(device); - link->ifname = strdup(ifname); - r = hashmap_put(manager->links, &link->ifindex, link); if (r < 0) return r; - link->udev_device = udev_device_ref(device); - *ret = link; link = NULL; @@ -1036,7 +1050,6 @@ static int link_update_flags(Link *link, unsigned flags) { int r; assert(link); - assert(link->network); if (link->state == LINK_STATE_FAILED) return 0; @@ -1060,13 +1073,12 @@ static int link_update_flags(Link *link, unsigned flags) { link->flags = flags; - if (flags_added & generic_flags) - log_debug_link(link, "link flags gained: %#.8x", - flags_added & generic_flags); - - if (flags_removed & generic_flags) - log_debug_link(link, "link flags lost: %#.8x", - flags_removed & generic_flags); + if (!link->network) + /* not currently managing this link + we track state changes, but don't log them + they will be logged if and when a network is + applied */ + return 0; if (flags_added & IFF_UP) log_info_link(link, "link is up"); @@ -1083,6 +1095,14 @@ static int link_update_flags(Link *link, unsigned flags) { else if (flags_removed & IFF_RUNNING) log_debug_link(link, "link is not running"); + if (flags_added & generic_flags) + log_debug_link(link, "ignored link flags gained: %#.8x", + flags_added & generic_flags); + + if (flags_removed & generic_flags) + log_debug_link(link, "ignored link flags lost: %#.8x", + flags_removed & generic_flags); + if (carrier_gained) { log_info_link(link, "gained carrier"); @@ -1180,10 +1200,12 @@ static int link_enslaved(Link *link) { assert(link->state == LINK_STATE_ENSLAVING); assert(link->network); - r = link_up(link); - if (r < 0) { - link_enter_failed(link); - return r; + if (!(link->flags & IFF_UP)) { + r = link_up(link); + if (r < 0) { + link_enter_failed(link); + return r; + } } if (!link->network->dhcp && !link->network->ipv4ll) @@ -1231,7 +1253,7 @@ static int link_enter_enslave(Link *link) { assert(link); assert(link->network); - assert(link->state == _LINK_STATE_INVALID); + assert(link->state == LINK_STATE_INITIALIZING); link->state = LINK_STATE_ENSLAVING; @@ -1323,95 +1345,11 @@ static int link_enter_enslave(Link *link) { return 0; } -static int link_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m, - void *userdata) { - Link *link = userdata; - int r; - - assert(link); - assert(link->ifname); - - if (link->state == LINK_STATE_FAILED) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0) { - log_struct_link(LOG_ERR, link, - "MESSAGE=%s: could not get state: %s", - link->ifname, strerror(-r), - "ERRNO=%d", -r, - NULL); - link_enter_failed(link); - return 1; - } - - link_update(link, m); - - return 1; -} - -static int link_getlink(Link *link) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(link); - assert(link->manager); - assert(link->manager->rtnl); - - log_debug_link(link, "requesting link status"); - - r = sd_rtnl_message_new_link(link->manager->rtnl, &req, - RTM_GETLINK, link->ifindex); - if (r < 0) { - log_error_link(link, "Could not allocate RTM_GETLINK message"); - return r; - } - - r = sd_rtnl_call_async(link->manager->rtnl, req, link_getlink_handler, - link, 0, NULL); - if (r < 0) { - log_error_link(link, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - return 0; -} - static int link_configure(Link *link) { int r; assert(link); - assert(link->state == _LINK_STATE_INVALID); - - r = link_getlink(link); - if (r < 0) - return r; - - return link_enter_enslave(link); -} - -int link_add(Manager *m, struct udev_device *device, Link **ret) { - Link *link = NULL; - Network *network; - int r; - - assert(m); - assert(device); - - r = link_new(m, device, &link); - if (r < 0) - return r; - - *ret = link; - - r = network_get(m, device, &network); - if (r < 0) - return r == -ENOENT ? 0 : r; - - r = network_apply(m, network, link); - if (r < 0) - return r; + assert(link->state == LINK_STATE_INITIALIZING); if (link->network->ipv4ll) { uint8_t seed[8]; @@ -1419,11 +1357,13 @@ int link_add(Manager *m, struct udev_device *device, Link **ret) { if (r < 0) return r; - r = net_get_unique_predictable_data(link->udev_device, seed); - if (r >= 0) { - r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed); - if (r < 0) - return r; + if (link->udev_device) { + r = net_get_unique_predictable_data(link->udev_device, seed); + if (r >= 0) { + r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed); + if (r < 0) + return r; + } } r = sd_ipv4ll_attach_event(link->ipv4ll, NULL, 0); @@ -1463,10 +1403,84 @@ int link_add(Manager *m, struct udev_device *device, Link **ret) { } } + return link_enter_enslave(link); +} + +int link_initialized(Link *link, struct udev_device *device) { + Network *network; + unsigned flags; + int r; + + assert(link); + assert(link->ifname); + assert(link->manager); + + if (link->state != LINK_STATE_INITIALIZING) + return 0; + + if (device) + link->udev_device = udev_device_ref(device); + + log_debug_link(link, "link initialized"); + + r = network_get(link->manager, device, link->ifname, &link->mac, &network); + if (r < 0) + return r == -ENOENT ? 0 : r; + + r = network_apply(link->manager, network, link); + if (r < 0) + return r; + r = link_configure(link); if (r < 0) return r; + /* re-trigger all state updates */ + flags = link->flags; + link->flags = 0; + r = link_update_flags(link, flags); + if (r < 0) + return r; + + return 0; +} + +int link_add(Manager *m, sd_rtnl_message *message, Link **ret) { + Link *link; + _cleanup_udev_device_unref_ struct udev_device *device = NULL; + char ifindex_str[2 + DECIMAL_STR_MAX(int)]; + int r; + + assert(m); + assert(message); + assert(ret); + + r = link_new(m, message, ret); + if (r < 0) + return r; + + link = *ret; + + log_info_link(link, "link added"); + + if (detect_container(NULL) <= 0) { + /* not in a container, udev will be around */ + sprintf(ifindex_str, "n%"PRIu64, link->ifindex); + device = udev_device_new_from_device_id(m->udev, ifindex_str); + if (!device) { + log_warning_link(link, "could not find udev device"); + return -errno; + } + + if (udev_device_get_is_initialized(device) <= 0) + /* not yet ready */ + return 0; + } + + r = link_initialized(link, device); + if (r < 0) + return r; + return 0; } @@ -1476,14 +1490,12 @@ int link_update(Link *link, sd_rtnl_message *m) { int r; assert(link); - assert(link->network); assert(m); if (link->state == LINK_STATE_FAILED) return 0; - if (link->network->dhcp && link->network->dhcp_mtu && - !link->original_mtu) { + if (!link->original_mtu) { r = sd_rtnl_message_read_u16(m, IFLA_MTU, &link->original_mtu); if (r >= 0) log_debug_link(link, "saved original MTU: %" @@ -1591,6 +1603,7 @@ finish: } static const char* const link_state_table[_LINK_STATE_MAX] = { + [LINK_STATE_INITIALIZING] = "configuring", [LINK_STATE_ENSLAVING] = "configuring", [LINK_STATE_SETTING_ADDRESSES] = "configuring", [LINK_STATE_SETTING_ROUTES] = "configuring", diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index d903d0d60e..4c1987daa8 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -29,6 +29,8 @@ #include "mkdir.h" #include "virt.h" +#include "sd-rtnl.h" + const char* const network_dirs[] = { "/etc/systemd/network", "/run/systemd/network", @@ -96,18 +98,14 @@ int manager_new(Manager **ret) { if (r < 0) return r; - m->udev = udev_new(); - if (!m->udev) - return -ENOMEM; - /* udev does not initialize devices inside containers, * so we rely on them being already initialized before * entering the container */ - if (detect_container(NULL) > 0) { - m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "kernel"); - if (!m->udev_monitor) + if (detect_container(NULL) <= 0) { + m->udev = udev_new(); + if (!m->udev) return -ENOMEM; - } else { + m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); if (!m->udev_monitor) return -ENOMEM; @@ -182,15 +180,30 @@ bool manager_should_reload(Manager *m) { return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false); } -static int manager_process_link(Manager *m, struct udev_device *device) { +static int manager_udev_process_link(Manager *m, struct udev_device *device) { Link *link = NULL; int r; assert(m); assert(device); - link_get(m, udev_device_get_ifindex(device), &link); + if (!streq_ptr(udev_device_get_action(device), "add")) + return 0; + + r = link_get(m, udev_device_get_ifindex(device), &link); + if (r < 0) + return r; + + if (!link) + return 0; + + r = link_initialized(link, device); + if (r < 0) + return r; + return 0; +} +/* if (streq_ptr(udev_device_get_action(device), "remove")) { log_debug("%s: link removed", udev_device_get_sysname(device)); @@ -215,45 +228,87 @@ static int manager_process_link(Manager *m, struct udev_device *device) { return 0; } +*/ +static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) { + Manager *m = userdata; + Link *link = NULL; + char *name; + int r, ifindex; -int manager_udev_enumerate_links(Manager *m) { - _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; - struct udev_list_entry *item = NULL, *first = NULL; - int r; - + assert(rtnl); + assert(message); assert(m); - e = udev_enumerate_new(m->udev); - if (!e) - return -ENOMEM; + r = sd_rtnl_message_link_get_ifindex(message, &ifindex); + if (r < 0 || ifindex <= 0) { + log_warning("rtnl: received link message without valid ifindex"); + return 0; + } + + link_get(m, ifindex, &link); + if (!link) { + /* link is new, so add it */ + r = link_add(m, message, &link); + if (r < 0) { + log_debug("could not add new link"); + return 0; + } + } - r = udev_enumerate_add_match_subsystem(e, "net"); + r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name); if (r < 0) - return r; + log_warning("rtnl: received link message without valid ifname"); + else { + NetDev *netdev; - /* udev does not initialize devices inside containers, - * so we rely on them being already initialized before - * entering the container */ - if (detect_container(NULL) <= 0) { - r = udev_enumerate_add_match_is_initialized(e); - if (r < 0) - return r; + r = netdev_get(m, name, &netdev); + if (r >= 0) { + r = netdev_set_ifindex(netdev, message); + if (r < 0) { + log_debug("could not set ifindex on netdev"); + return 0; + } + } } - r = udev_enumerate_scan_devices(e); + r = link_update(link, message); + if (r < 0) + return 0; + + return 1; +} + +int manager_rtnl_enumerate_links(Manager *m) { + _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL; + sd_rtnl_message *link; + int r, k; + + assert(m); + assert(m->rtnl); + + r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0); + if (r < 0) + return r; + + r = sd_rtnl_message_request_dump(req, true); if (r < 0) return r; - first = udev_enumerate_get_list_entry(e); - udev_list_entry_foreach(item, first) { - _cleanup_udev_device_unref_ struct udev_device *d = NULL; - int k; + r = sd_rtnl_call(m->rtnl, req, 0, &reply); + if (r < 0) + return r; - d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item)); - if (!d) - return -ENOMEM; + for (link = reply; link; link = sd_rtnl_message_next(link)) { + uint16_t type; + + k = sd_rtnl_message_get_type(link, &type); + if (k < 0) + return k; + + if (type != RTM_NEWLINK) + continue; - k = manager_process_link(m, d); + k = manager_rtnl_process_link(m->rtnl, link, m); if (k < 0) r = k; } @@ -270,13 +325,18 @@ static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t if (!device) return -ENOMEM; - manager_process_link(m, device); + manager_udev_process_link(m, device); return 0; } int manager_udev_listen(Manager *m) { int r; + if (detect_container(NULL) > 0) + return 0; + + assert(m->udev_monitor); + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL); if (r < 0) { log_error("Could not add udev monitor filter: %s", strerror(-r)); @@ -300,56 +360,6 @@ 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; - char *name; - int r, ifindex; - - assert(rtnl); - assert(message); - assert(m); - - r = sd_rtnl_message_link_get_ifindex(message, &ifindex); - if (r < 0 || ifindex <= 0) { - log_warning("received RTM_NEWLINK message without valid ifindex"); - return 0; - } - - r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name); - if (r < 0) - log_warning("received RTM_NEWLINK message without valid ifname"); - else { - NetDev *netdev; - - r = netdev_get(m, name, &netdev); - if (r >= 0) { - netdev_set_ifindex(netdev, message); - r = sd_rtnl_message_rewind(message); - if (r < 0) { - log_debug("could not rewind rtnl message"); - return 0; - } - } - } - - r = link_get(m, ifindex, &link); - if (r < 0) { - log_debug("received RTM_NEWLINK message for untracked ifindex %d", ifindex); - return 0; - } - - /* only track the status of links we want to manage */ - if (link->network) { - r = link_update(link, message); - if (r < 0) - return 0; - } else - log_debug("%s: received RTM_NEWLINK message for unmanaged link", link->ifname); - - return 1; -} - int manager_rtnl_listen(Manager *m) { int r; diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 92548d96f0..b7fc48db94 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -161,67 +161,6 @@ static int netdev_enter_ready(NetDev *netdev) { return 0; } - -static int netdev_getlink_handler(sd_rtnl *rtnl, sd_rtnl_message *m, - void *userdata) { - NetDev *netdev = userdata; - int r; - - assert(netdev); - - if (netdev->state == NETDEV_STATE_FAILED) - return 1; - - r = sd_rtnl_message_get_errno(m); - if (r < 0) { - log_struct_netdev(LOG_ERR, netdev, - "MESSAGE=%s: could not get link: %s", - netdev->name, strerror(-r), - "ERRNO=%d", -r, - NULL); - return 1; - } - - netdev_set_ifindex(netdev, m); - - return 1; -} - -static int netdev_getlink(NetDev *netdev) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - int r; - - assert(netdev->manager); - assert(netdev->manager->rtnl); - assert(netdev->name); - - log_debug_netdev(netdev, "requesting netdev status"); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, - RTM_GETLINK, 0); - if (r < 0) { - log_error_netdev(netdev, "Could not allocate RTM_GETLINK message"); - return r; - } - - r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->name); - if (r < 0) { - log_error_netdev(netdev, "Colud not append ifname to message: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(netdev->manager->rtnl, req, netdev_getlink_handler, - netdev, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - return 0; -} - static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { NetDev *netdev = userdata; int r; @@ -230,9 +169,8 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda r = sd_rtnl_message_get_errno(m); if (r == -EEXIST) - r = netdev_getlink(netdev); - - if (r < 0) { + log_debug_netdev(netdev, "netdev exists, using existing"); + else if (r < 0) { log_warning_netdev(netdev, "netdev failed: %s", strerror(-r)); netdev_enter_failed(netdev); @@ -410,6 +348,12 @@ int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) { return r; } + r = sd_rtnl_message_exit_container(message); + if (r < 0) { + log_error_netdev(netdev, "Could not exit container"); + return r; + } + kind = netdev_kind_to_string(netdev->kind); if (!kind) { log_error_netdev(netdev, "Could not get kind"); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index bdf71e854e..048017e229 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -184,28 +184,28 @@ void network_free(Network *network) { free(network); } -int network_get(Manager *manager, struct udev_device *device, Network **ret) { +int network_get(Manager *manager, struct udev_device *device, + const char *ifname, const struct ether_addr *address, + Network **ret) { Network *network; assert(manager); - assert(device); assert(ret); LIST_FOREACH(networks, network, manager->networks) { if (net_match_config(network->match_mac, network->match_path, - network->match_driver, network->match_type, - network->match_name, network->match_host, - network->match_virt, network->match_kernel, - network->match_arch, - udev_device_get_sysattr_value(device, "address"), - udev_device_get_property_value(device, "ID_PATH"), - udev_device_get_driver(udev_device_get_parent(device)), - udev_device_get_property_value(device, "ID_NET_DRIVER"), - udev_device_get_devtype(device), - udev_device_get_sysname(device))) { - log_debug("%s: found matching network '%s'", - udev_device_get_sysname(device), - network->filename); + network->match_driver, network->match_type, + network->match_name, network->match_host, + network->match_virt, network->match_kernel, + network->match_arch, + address, + udev_device_get_property_value(device, "ID_PATH"), + udev_device_get_driver(udev_device_get_parent(device)), + udev_device_get_property_value(device, "ID_NET_DRIVER"), + udev_device_get_devtype(device), + ifname)) { + log_debug("%s: found matching network '%s'", ifname, + network->filename); *ret = network; return 0; } diff --git a/src/network/networkd.c b/src/network/networkd.c index f0e6ad5201..6b3bf12a4c 100644 --- a/src/network/networkd.c +++ b/src/network/networkd.c @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) { goto out; } - r = manager_udev_enumerate_links(m); + r = manager_rtnl_enumerate_links(m); if (r < 0) { log_error("Could not enumerate links: %s", strerror(-r)); goto out; diff --git a/src/network/networkd.h b/src/network/networkd.h index 36902e3c51..4a62fb8396 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -185,6 +185,7 @@ struct Route { }; typedef enum LinkState { + LINK_STATE_INITIALIZING, LINK_STATE_ENSLAVING, LINK_STATE_SETTING_ADDRESSES, LINK_STATE_SETTING_ROUTES, @@ -246,10 +247,10 @@ void manager_free(Manager *m); int manager_load_config(Manager *m); bool manager_should_reload(Manager *m); -int manager_udev_enumerate_links(Manager *m); -int manager_udev_listen(Manager *m); +int manager_rtnl_enumerate_links(Manager *m); int manager_rtnl_listen(Manager *m); +int manager_udev_listen(Manager *m); int manager_bus_listen(Manager *m); int manager_update_resolv_conf(Manager *m); @@ -292,7 +293,9 @@ void network_free(Network *network); DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_free); #define _cleanup_network_free_ _cleanup_(network_freep) -int network_get(Manager *manager, struct udev_device *device, Network **ret); +int network_get(Manager *manager, struct udev_device *device, + const char *ifname, const struct ether_addr *mac, + Network **ret); int network_apply(Manager *manager, Network *network, Link *link); int config_parse_bridge(const char *unit, const char *filename, unsigned line, @@ -362,13 +365,14 @@ int config_parse_label(const char *unit, const char *filename, unsigned line, /* Link */ -int link_new(Manager *manager, struct udev_device *device, Link **ret); void link_free(Link *link); int link_get(Manager *m, int ifindex, Link **ret); -int link_add(Manager *manager, struct udev_device *device, Link **ret); +int link_add(Manager *manager, sd_rtnl_message *message, Link **ret); int link_update(Link *link, sd_rtnl_message *message); +int link_initialized(Link *link, struct udev_device *device); + int link_save(Link *link); const char* link_state_to_string(LinkState s) _const_; diff --git a/src/network/test-network.c b/src/network/test-network.c index 9c372c7798..38d57cc6a6 100644 --- a/src/network/test-network.c +++ b/src/network/test-network.c @@ -21,13 +21,6 @@ #include "networkd.h" -static void test_link(Manager *manager, struct udev_device *loopback) { - Link *link = NULL; - - assert_se(link_new(manager, loopback, &link) >= 0); - assert_se(link); -} - static void test_load_config(Manager *manager) { /* TODO: should_reload, is false if the config dirs do not exist, so * so we can't do this test here, move it to a test for paths_check_timestamps @@ -41,10 +34,11 @@ static void test_load_config(Manager *manager) { static void test_network_get(Manager *manager, struct udev_device *loopback) { Network *network; + const struct ether_addr mac = {}; /* let's assume that the test machine does not have a .network file that applies to the loopback device... */ - assert_se(network_get(manager, loopback, &network) == -ENOENT); + assert_se(network_get(manager, loopback, "lo", &mac, &network) == -ENOENT); assert_se(!network); } @@ -66,11 +60,9 @@ int main(void) { test_network_get(manager, loopback); - test_link(manager, loopback); - assert_se(manager_udev_listen(manager) >= 0); - assert_se(manager_udev_enumerate_links(manager) >= 0); assert_se(manager_rtnl_listen(manager) >= 0); + assert_se(manager_rtnl_enumerate_links(manager) >= 0); udev_device_unref(loopback); udev_unref(udev); diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 0c563b2db5..8215c40d5d 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -238,7 +238,7 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device, link_confi if (net_match_config(link->match_mac, link->match_path, link->match_driver, link->match_type, NULL, link->match_host, link->match_virt, link->match_kernel, link->match_arch, - udev_device_get_sysattr_value(device, "address"), + ether_aton(udev_device_get_sysattr_value(device, "address")), udev_device_get_property_value(device, "ID_PATH"), udev_device_get_driver(udev_device_get_parent(device)), udev_device_get_property_value(device, "ID_NET_DRIVER"), |