X Tutup
Skip to content

Commit fe321d4

Browse files
committed
network: introduce link_get_by_hw_addr()
1 parent 6eab614 commit fe321d4

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

src/network/networkd-link.c

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,21 @@ int link_get_by_name(Manager *m, const char *ifname, Link **ret) {
304304
return 0;
305305
}
306306

307+
int link_get_by_hw_addr(Manager *m, const struct hw_addr_data *hw_addr, Link **ret) {
308+
Link *link;
309+
310+
assert(m);
311+
assert(hw_addr);
312+
313+
link = hashmap_get(m->links_by_hw_addr, hw_addr);
314+
if (!link)
315+
return -ENODEV;
316+
317+
if (ret)
318+
*ret = link;
319+
return 0;
320+
}
321+
307322
int link_get_master(Link *link, Link **ret) {
308323
assert(link);
309324
assert(link->manager);
@@ -961,9 +976,12 @@ static Link *link_drop(Link *link) {
961976

962977
STRV_FOREACH(n, link->alternative_names)
963978
hashmap_remove(link->manager->links_by_name, *n);
964-
965979
hashmap_remove(link->manager->links_by_name, link->ifname);
966980

981+
/* bonding master and its slaves have the same hardware address. */
982+
if (hashmap_get(link->manager->links_by_hw_addr, &link->hw_addr) == link)
983+
hashmap_remove(link->manager->links_by_hw_addr, &link->hw_addr);
984+
967985
/* The following must be called at last. */
968986
assert_se(hashmap_remove(link->manager->links_by_index, INT_TO_PTR(link->ifindex)) == link);
969987
return link_unref(link);
@@ -1974,7 +1992,7 @@ static int link_update_master(Link *link, sd_netlink_message *message) {
19741992
}
19751993

19761994
static int link_update_hardware_address(Link *link, sd_netlink_message *message) {
1977-
struct hw_addr_data hw_addr;
1995+
struct hw_addr_data old;
19781996
int r;
19791997

19801998
assert(link);
@@ -1984,18 +2002,34 @@ static int link_update_hardware_address(Link *link, sd_netlink_message *message)
19842002
if (r < 0 && r != -ENODATA)
19852003
return log_link_debug_errno(link, r, "rtnl: failed to read broadcast address: %m");
19862004

1987-
r = netlink_message_read_hw_addr(message, IFLA_ADDRESS, &hw_addr);
2005+
old = link->hw_addr;
2006+
r = netlink_message_read_hw_addr(message, IFLA_ADDRESS, &link->hw_addr);
19882007
if (r == -ENODATA)
19892008
return 0;
19902009
if (r < 0)
1991-
return log_link_warning_errno(link, r, "rtnl: failed to read hardware address: %m");
2010+
return log_link_debug_errno(link, r, "rtnl: failed to read hardware address: %m");
19922011

1993-
if (hw_addr_equal(&link->hw_addr, &hw_addr))
2012+
if (hw_addr_equal(&link->hw_addr, &old))
19942013
return 0;
19952014

1996-
link->hw_addr = hw_addr;
2015+
if (hw_addr_is_null(&old))
2016+
log_link_debug(link, "Saved hardware address: %s", HW_ADDR_TO_STR(&link->hw_addr));
2017+
else {
2018+
log_link_debug(link, "Hardware address is changed: %s → %s",
2019+
HW_ADDR_TO_STR(&old), HW_ADDR_TO_STR(&link->hw_addr));
19972020

1998-
log_link_debug(link, "Gained new hardware address: %s", HW_ADDR_TO_STR(&hw_addr));
2021+
if (hashmap_get(link->manager->links_by_hw_addr, &old) == link)
2022+
hashmap_remove(link->manager->links_by_hw_addr, &old);
2023+
}
2024+
2025+
if (!hw_addr_is_null(&link->hw_addr)) {
2026+
r = hashmap_ensure_put(&link->manager->links_by_hw_addr, &hw_addr_hash_ops, &link->hw_addr, link);
2027+
if (r == -EEXIST && streq_ptr(link->kind, "bond"))
2028+
/* bonding master and its slaves have the same hardware address. */
2029+
r = hashmap_replace(link->manager->links_by_hw_addr, &link->hw_addr, link);
2030+
if (r < 0)
2031+
log_link_debug_errno(link, r, "Failed to manage link by its new hardware address, ignoring: %m");
2032+
}
19992033

20002034
r = ipv4ll_update_mac(link);
20012035
if (r < 0)

src/network/networkd-link.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_destroy_callback, Link, link_unref);
220220

221221
int link_get_by_index(Manager *m, int ifindex, Link **ret);
222222
int link_get_by_name(Manager *m, const char *ifname, Link **ret);
223+
int link_get_by_hw_addr(Manager *m, const struct hw_addr_data *hw_addr, Link **ret);
223224
int link_get_master(Link *link, Link **ret);
224225

225226
int link_getlink_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);

src/network/networkd-manager.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ Manager* manager_free(Manager *m) {
462462
m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
463463
m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
464464
m->links_by_name = hashmap_free(m->links_by_name);
465+
m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
465466
m->links_by_index = hashmap_free_with_destructor(m->links_by_index, link_unref);
466467

467468
m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);

src/network/networkd-manager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct Manager {
4646

4747
Hashmap *links_by_index;
4848
Hashmap *links_by_name;
49+
Hashmap *links_by_hw_addr;
4950
Hashmap *netdevs;
5051
OrderedHashmap *networks;
5152
Hashmap *dhcp6_prefixes;

0 commit comments

Comments
 (0)
X Tutup