From 813572853e4d644fe4b69d29a3626b75fb23c07b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 26 May 2021 12:33:28 +0900 Subject: [PATCH] network: introduce link_get_master() and use it where applicable --- src/network/networkd-link.c | 75 ++++++++++++++----------------------- src/network/networkd-link.h | 1 + 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 97bbe97305c..4694ddd9fbe 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -178,27 +178,6 @@ static bool link_is_enslaved(Link *link) { return false; } -static void link_update_master_operstate(Link *link, NetDev *netdev) { - Link *master; - - if (!netdev) - return; - - if (netdev->ifindex <= 0) - return; - - /* If an interface is self-mentioned in Bridge= or friends, then it introduces an infinite loop. - * FIXME: there still exits a possibility of an infinite loop when two or more interfaces - * mention each other in Bridge= or so. We need to detect such a loop. */ - if (link->ifindex == netdev->ifindex) - return; - - if (link_get(link->manager, netdev->ifindex, &master) < 0) - return; - - link_update_operstate(master, true); -} - static LinkAddressState address_state_from_scope(uint8_t scope) { if (scope < RT_SCOPE_SITE) /* universally accessible addresses found */ @@ -371,10 +350,11 @@ void link_update_operstate(Link *link, bool also_update_master) { if (changed) link_dirty(link); - if (also_update_master && link->network) { - link_update_master_operstate(link, link->network->batadv); - link_update_master_operstate(link, link->network->bond); - link_update_master_operstate(link, link->network->bridge); + if (also_update_master) { + Link *master; + + if (link_get_master(link, &master) >= 0) + link_update_operstate(master, true); } } @@ -591,6 +571,17 @@ int link_get_by_name(Manager *m, const char *ifname, Link **ret) { return 0; } +int link_get_master(Link *link, Link **ret) { + assert(link); + assert(link->manager); + assert(ret); + + if (link->master_ifindex <= 0 || link->master_ifindex == link->ifindex) + return -ENODEV; + + return link_get(link->manager, link->master_ifindex, ret); +} + void link_set_state(Link *link, LinkState state) { assert(link); @@ -1329,16 +1320,16 @@ static void link_free_carrier_maps(Link *link) { return; } -static int link_append_to_master(Link *link, NetDev *netdev) { +static int link_append_to_master(Link *link) { Link *master; int r; assert(link); - assert(netdev); - r = link_get(link->manager, netdev->ifindex, &master); - if (r < 0) - return r; + /* - The link may have no master. + * - RTM_NEWLINK message about master interface may not be received yet. */ + if (link_get_master(link, &master) < 0) + return 0; r = set_ensure_put(&master->slaves, NULL, link); if (r <= 0) @@ -1348,15 +1339,15 @@ static int link_append_to_master(Link *link, NetDev *netdev) { return 0; } -static void link_drop_from_master(Link *link, NetDev *netdev) { +static void link_drop_from_master(Link *link) { Link *master; assert(link); - if (!link->manager || !netdev) + if (!link->manager) return; - if (link_get(link->manager, netdev->ifindex, &master) < 0) + if (link_get_master(link, &master) < 0) return; link_unref(set_remove(master->slaves, link)); @@ -1391,11 +1382,7 @@ static Link *link_drop(Link *link) { link_free_carrier_maps(link); - if (link->network) { - link_drop_from_master(link, link->network->batadv); - link_drop_from_master(link, link->network->bridge); - link_drop_from_master(link, link->network->bond); - } + link_drop_from_master(link); link_unref(set_remove(link->manager->links_requesting_uuid, link)); @@ -1466,26 +1453,22 @@ static int link_joined(Link *link) { r = link_set_bridge(link); if (r < 0) log_link_error_errno(link, r, "Could not set bridge message: %m"); - - r = link_append_to_master(link, link->network->bridge); - if (r < 0) - log_link_error_errno(link, r, "Failed to add to bridge master's slave list: %m"); } if (link->network->bond) { r = link_set_bond(link); if (r < 0) log_link_error_errno(link, r, "Could not set bond message: %m"); - - r = link_append_to_master(link, link->network->bond); - if (r < 0) - log_link_error_errno(link, r, "Failed to add to bond master's slave list: %m"); } r = link_set_bridge_vlan(link); if (r < 0) log_link_error_errno(link, r, "Could not set bridge vlan: %m"); + r = link_append_to_master(link); + if (r < 0) + return log_link_error_errno(link, r, "Failed to add to master interface's slave list: %m"); + r = link_request_static_configs(link); if (r < 0) return r; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 0d60ac682c1..2305bf8d42d 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -219,6 +219,7 @@ DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_destroy_callback, Link, link_unref); int link_get(Manager *m, int ifindex, Link **ret); int link_get_by_name(Manager *m, const char *ifname, Link **ret); +int link_get_master(Link *link, Link **ret); int link_up(Link *link); int link_down(Link *link, link_netlink_message_handler_t callback); -- 2.47.3