mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-03 22:10:14 +01:00
platform: handle missing netlink attribute IFLA_ADDRESS by cache-lookup
Sometimes the netlink event lacks the IFLA_ADDRESS attribute with
the MAC address of the link. In this case, take the value from
the cached link instance. A missing netlink attribute should have the
meaning of reusing the previous value, not clearing the address.
(cherry picked from commit 791cbd0817)
This commit is contained in:
parent
c1353a16b0
commit
5e77626b0f
2 changed files with 26 additions and 17 deletions
|
|
@ -1439,6 +1439,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||
gboolean *completed_from_cache = cache ? &completed_from_cache_val : NULL;
|
||||
const NMPObject *link_cached = NULL;
|
||||
NMPObject *lnk_data = NULL;
|
||||
gboolean address_complete_from_cache = TRUE;
|
||||
gboolean lnk_data_complete_from_cache = TRUE;
|
||||
|
||||
if (!nlmsg_valid_hdr (nlh, sizeof (*ifi)))
|
||||
return NULL;
|
||||
|
|
@ -1503,6 +1505,7 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||
memcpy (obj->link.addr.data, nla_data (tb[IFLA_ADDRESS]), l);
|
||||
obj->link.addr.len = l;
|
||||
}
|
||||
address_complete_from_cache = FALSE;
|
||||
}
|
||||
|
||||
if (tb[IFLA_AF_SPEC]) {
|
||||
|
|
@ -1552,28 +1555,34 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||
lnk_data = _parse_lnk_vxlan (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
default:
|
||||
goto lnk_data_handled;
|
||||
lnk_data_complete_from_cache = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We always try to look into the cache and reuse the object there.
|
||||
* We do that, because we consider the lnk object as immutable and don't
|
||||
* modify it after creating. Hence we can share it and reuse.
|
||||
*
|
||||
* Also, sometimes the info-data is missing for updates. In this case
|
||||
* we want to keep the previously received lnk_data. */
|
||||
if (completed_from_cache) {
|
||||
if ( completed_from_cache
|
||||
&& ( lnk_data_complete_from_cache
|
||||
|| address_complete_from_cache)) {
|
||||
_lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached);
|
||||
if ( link_cached
|
||||
&& link_cached->link.type == obj->link.type
|
||||
&& link_cached->_link.netlink.lnk
|
||||
&& ( !lnk_data
|
||||
|| nmp_object_equal (lnk_data, link_cached->_link.netlink.lnk))) {
|
||||
nmp_object_unref (lnk_data);
|
||||
lnk_data = nmp_object_ref (link_cached->_link.netlink.lnk);
|
||||
if (link_cached) {
|
||||
if ( lnk_data_complete_from_cache
|
||||
&& link_cached->link.type == obj->link.type
|
||||
&& link_cached->_link.netlink.lnk
|
||||
&& ( !lnk_data
|
||||
|| nmp_object_equal (lnk_data, link_cached->_link.netlink.lnk))) {
|
||||
/* We always try to look into the cache and reuse the object there.
|
||||
* We do that, because we consider the lnk object as immutable and don't
|
||||
* modify it after creating. Hence we can share it and reuse.
|
||||
*
|
||||
* Also, sometimes the info-data is missing for updates. In this case
|
||||
* we want to keep the previously received lnk_data. */
|
||||
nmp_object_unref (lnk_data);
|
||||
lnk_data = nmp_object_ref (link_cached->_link.netlink.lnk);
|
||||
}
|
||||
if (address_complete_from_cache)
|
||||
obj->link.addr = link_cached->link.addr;
|
||||
}
|
||||
}
|
||||
|
||||
lnk_data_handled:
|
||||
obj->_link.netlink.lnk = lnk_data;
|
||||
|
||||
obj->_link.netlink.is_in_netlink = TRUE;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ struct _NMPlatformLink {
|
|||
/* rtnl_link_get_arptype(), ifinfomsg.ifi_type. */
|
||||
guint32 arptype;
|
||||
|
||||
/* rtnl_link_get_addr() */
|
||||
/* rtnl_link_get_addr(), IFLA_ADDRESS */
|
||||
struct {
|
||||
guint8 data[20]; /* NM_UTILS_HWADDR_LEN_MAX */
|
||||
guint8 len;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue