mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-29 09:10:10 +01:00
device: merge branch 'th/preserve-fake-perm-hwaddr-bgo772880'
https://bugzilla.gnome.org/show_bug.cgi?id=772880 https://bugzilla.redhat.com/show_bug.cgi?id=1388286
This commit is contained in:
commit
e2b7da7b82
15 changed files with 516 additions and 286 deletions
|
|
@ -124,7 +124,10 @@ guint32 _nm_setting_get_setting_priority (NMSetting *setting);
|
|||
|
||||
gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value);
|
||||
|
||||
guint _nm_utils_hwaddr_length (const char *asc);
|
||||
#define NM_UTILS_HWADDR_LEN_MAX_STR (NM_UTILS_HWADDR_LEN_MAX * 3)
|
||||
|
||||
guint8 *_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length);
|
||||
const char *nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboolean upper_case, char *buf, gsize buf_len);
|
||||
|
||||
char *_nm_utils_bin2str (gconstpointer addr, gsize length, gboolean upper_case);
|
||||
|
||||
|
|
|
|||
|
|
@ -2995,17 +2995,64 @@ nm_utils_wifi_strength_bars (guint8 strength)
|
|||
gsize
|
||||
nm_utils_hwaddr_len (int type)
|
||||
{
|
||||
g_return_val_if_fail (type == ARPHRD_ETHER || type == ARPHRD_INFINIBAND, 0);
|
||||
|
||||
if (type == ARPHRD_ETHER)
|
||||
return ETH_ALEN;
|
||||
else if (type == ARPHRD_INFINIBAND)
|
||||
return INFINIBAND_ALEN;
|
||||
|
||||
g_assert_not_reached ();
|
||||
g_return_val_if_reached (0);
|
||||
}
|
||||
|
||||
#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)
|
||||
static guint8 *
|
||||
hwaddr_aton (const char *asc, guint8 *buffer, gsize buffer_length, gsize *out_len)
|
||||
{
|
||||
const char *in = asc;
|
||||
guint8 *out = buffer;
|
||||
guint8 delimiter = '\0';
|
||||
|
||||
nm_assert (asc);
|
||||
nm_assert (buffer);
|
||||
nm_assert (buffer_length);
|
||||
nm_assert (out_len);
|
||||
|
||||
while (TRUE) {
|
||||
const guint8 d1 = in[0];
|
||||
guint8 d2;
|
||||
|
||||
if (!g_ascii_isxdigit (d1))
|
||||
return NULL;
|
||||
|
||||
#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - ('A' - 10))
|
||||
|
||||
/* If there's no leading zero (ie "aa:b:cc") then fake it */
|
||||
d2 = in[1];
|
||||
if (d2 && g_ascii_isxdigit (d2)) {
|
||||
*out++ = (HEXVAL (d1) << 4) + HEXVAL (d2);
|
||||
d2 = in[2];
|
||||
in += 3;
|
||||
} else {
|
||||
/* Fake leading zero */
|
||||
*out++ = HEXVAL (d1);
|
||||
in += 2;
|
||||
}
|
||||
|
||||
if (!d2)
|
||||
break;
|
||||
if (--buffer_length == 0)
|
||||
return NULL;
|
||||
|
||||
if (d2 != delimiter) {
|
||||
if ( delimiter == '\0'
|
||||
&& (d2 == ':' || d2 == '-'))
|
||||
delimiter = d2;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*out_len = out - buffer;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_hwaddr_atoba:
|
||||
|
|
@ -3022,18 +3069,52 @@ GByteArray *
|
|||
nm_utils_hwaddr_atoba (const char *asc, gsize length)
|
||||
{
|
||||
GByteArray *ba;
|
||||
gsize l;
|
||||
|
||||
g_return_val_if_fail (asc != NULL, NULL);
|
||||
g_return_val_if_fail (asc, NULL);
|
||||
g_return_val_if_fail (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL);
|
||||
|
||||
ba = g_byte_array_sized_new (length);
|
||||
g_byte_array_set_size (ba, length);
|
||||
if (!nm_utils_hwaddr_aton (asc, ba->data, length)) {
|
||||
g_byte_array_unref (ba);
|
||||
return NULL;
|
||||
}
|
||||
if (!hwaddr_aton (asc, ba->data, length, &l))
|
||||
goto fail;
|
||||
if (length != l)
|
||||
goto fail;
|
||||
|
||||
return ba;
|
||||
fail:
|
||||
g_byte_array_unref (ba);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* _nm_utils_hwaddr_aton:
|
||||
* @asc: the ASCII representation of a hardware address
|
||||
* @buffer: buffer to store the result into. Must have
|
||||
* at least a size of @buffer_length.
|
||||
* @buffer_length: the length of the input buffer @buffer.
|
||||
* The result must fit into that buffer, otherwise
|
||||
* the function fails and returns %NULL.
|
||||
* @out_length: the output length in case of success.
|
||||
*
|
||||
* Parses @asc and converts it to binary form in @buffer.
|
||||
* Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed.
|
||||
*
|
||||
* It is like nm_utils_hwaddr_aton(), but contrary to that it
|
||||
* can parse addresses of any length. That is, you don't need
|
||||
* to know the length before-hand.
|
||||
*
|
||||
* Return value: @buffer, or %NULL if @asc couldn't be parsed.
|
||||
*/
|
||||
guint8 *
|
||||
_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length)
|
||||
{
|
||||
g_return_val_if_fail (asc, NULL);
|
||||
g_return_val_if_fail (buffer, NULL);
|
||||
g_return_val_if_fail (buffer_length > 0, NULL);
|
||||
g_return_val_if_fail (out_length, NULL);
|
||||
|
||||
return hwaddr_aton (asc, buffer, buffer_length, out_length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3052,72 +3133,55 @@ nm_utils_hwaddr_atoba (const char *asc, gsize length)
|
|||
guint8 *
|
||||
nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize length)
|
||||
{
|
||||
const char *in = asc;
|
||||
guint8 *out = (guint8 *)buffer;
|
||||
char delimiter = '\0';
|
||||
gsize l;
|
||||
|
||||
g_return_val_if_fail (asc != NULL, NULL);
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
g_return_val_if_fail (asc, NULL);
|
||||
g_return_val_if_fail (buffer, NULL);
|
||||
g_return_val_if_fail (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL);
|
||||
|
||||
while (length && *in) {
|
||||
guint8 d1 = in[0], d2 = in[1];
|
||||
if (!hwaddr_aton (asc, buffer, length, &l))
|
||||
return NULL;
|
||||
if (length != l)
|
||||
return NULL;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
if (!g_ascii_isxdigit (d1))
|
||||
return NULL;
|
||||
static void
|
||||
_bin2str_buf (gconstpointer addr, gsize length, gboolean upper_case, char *out)
|
||||
{
|
||||
const guint8 *in = addr;
|
||||
const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
|
||||
/* If there's no leading zero (ie "aa:b:cc") then fake it */
|
||||
if (d2 && g_ascii_isxdigit (d2)) {
|
||||
*out++ = (HEXVAL (d1) << 4) + HEXVAL (d2);
|
||||
in += 2;
|
||||
} else {
|
||||
/* Fake leading zero */
|
||||
*out++ = (HEXVAL ('0') << 4) + HEXVAL (d1);
|
||||
in += 1;
|
||||
}
|
||||
nm_assert (addr);
|
||||
nm_assert (out);
|
||||
nm_assert (length > 0);
|
||||
|
||||
/* @out must contain at least @length*3 bytes */
|
||||
|
||||
for (;;) {
|
||||
const guint8 v = *in++;
|
||||
|
||||
*out++ = LOOKUP[v >> 4];
|
||||
*out++ = LOOKUP[v & 0x0F];
|
||||
length--;
|
||||
if (*in) {
|
||||
if (delimiter == '\0') {
|
||||
if (*in == ':' || *in == '-')
|
||||
delimiter = *in;
|
||||
else
|
||||
return NULL;
|
||||
} else {
|
||||
if (*in != delimiter)
|
||||
return NULL;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
if (!length)
|
||||
break;
|
||||
*out++ = ':';
|
||||
}
|
||||
|
||||
if (length == 0 && !*in)
|
||||
return buffer;
|
||||
else
|
||||
return NULL;
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
_bin2str (gconstpointer addr, gsize length, gboolean upper_case)
|
||||
{
|
||||
const guint8 *in = addr;
|
||||
char *out, *result;
|
||||
const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
char *result;
|
||||
|
||||
g_return_val_if_fail (addr != NULL, g_strdup (""));
|
||||
g_return_val_if_fail (length > 0, g_strdup (""));
|
||||
nm_assert (addr);
|
||||
nm_assert (length > 0);
|
||||
|
||||
result = out = g_malloc (length * 3);
|
||||
while (length--) {
|
||||
guint8 v = *in++;
|
||||
|
||||
*out++ = LOOKUP[v >> 4];
|
||||
*out++ = LOOKUP[v & 0x0F];
|
||||
if (length)
|
||||
*out++ = ':';
|
||||
}
|
||||
|
||||
*out = 0;
|
||||
result = g_malloc (length * 3);
|
||||
_bin2str_buf (addr, length, upper_case, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -3133,9 +3197,25 @@ _bin2str (gconstpointer addr, gsize length, gboolean upper_case)
|
|||
char *
|
||||
nm_utils_hwaddr_ntoa (gconstpointer addr, gsize length)
|
||||
{
|
||||
g_return_val_if_fail (addr, g_strdup (""));
|
||||
g_return_val_if_fail (length > 0, g_strdup (""));
|
||||
|
||||
return _bin2str (addr, length, TRUE);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboolean upper_case, char *buf, gsize buf_len)
|
||||
{
|
||||
g_return_val_if_fail (addr, NULL);
|
||||
g_return_val_if_fail (addr_len > 0, NULL);
|
||||
g_return_val_if_fail (buf, NULL);
|
||||
if (buf_len < addr_len * 3)
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
_bin2str_buf (addr, addr_len, TRUE, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* _nm_utils_bin2str:
|
||||
* @addr: (type guint8) (array length=length): a binary hardware address
|
||||
|
|
@ -3149,51 +3229,12 @@ nm_utils_hwaddr_ntoa (gconstpointer addr, gsize length)
|
|||
char *
|
||||
_nm_utils_bin2str (gconstpointer addr, gsize length, gboolean upper_case)
|
||||
{
|
||||
g_return_val_if_fail (addr, g_strdup (""));
|
||||
g_return_val_if_fail (length > 0, g_strdup (""));
|
||||
|
||||
return _bin2str (addr, length, upper_case);
|
||||
}
|
||||
|
||||
static int
|
||||
hwaddr_binary_len (const char *asc)
|
||||
{
|
||||
int octets = 1;
|
||||
|
||||
if (!*asc)
|
||||
return 0;
|
||||
|
||||
for (; *asc; asc++) {
|
||||
if (*asc == ':' || *asc == '-')
|
||||
octets++;
|
||||
}
|
||||
return octets;
|
||||
}
|
||||
|
||||
/**
|
||||
* _nm_utils_hwaddr_length:
|
||||
* @asc: the ASCII representation of the hardware address
|
||||
*
|
||||
* Validates that @asc is a valid representation of a hardware
|
||||
* address up to (including) %NM_UTILS_HWADDR_LEN_MAX bytes.
|
||||
*
|
||||
* Returns: binary length of the hardware address @asc or
|
||||
* 0 on error.
|
||||
*/
|
||||
guint
|
||||
_nm_utils_hwaddr_length (const char *asc)
|
||||
{
|
||||
int l;
|
||||
|
||||
if (!asc)
|
||||
return 0;
|
||||
|
||||
l = hwaddr_binary_len (asc);
|
||||
if (l <= 0 || l > NM_UTILS_HWADDR_LEN_MAX)
|
||||
return 0;
|
||||
|
||||
if (!nm_utils_hwaddr_valid (asc, l))
|
||||
return 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_hwaddr_valid:
|
||||
* @asc: the ASCII representation of a hardware address
|
||||
|
|
@ -3210,17 +3251,18 @@ gboolean
|
|||
nm_utils_hwaddr_valid (const char *asc, gssize length)
|
||||
{
|
||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
gsize l;
|
||||
|
||||
g_return_val_if_fail (asc != NULL, FALSE);
|
||||
g_return_val_if_fail (length == -1 || (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX), FALSE);
|
||||
|
||||
if (length == -1) {
|
||||
length = hwaddr_binary_len (asc);
|
||||
if (length == 0 || length > NM_UTILS_HWADDR_LEN_MAX)
|
||||
if (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX) {
|
||||
if (!hwaddr_aton (asc, buf, length, &l))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return nm_utils_hwaddr_aton (asc, buf, length) != NULL;
|
||||
return length == l;
|
||||
} else if (length == -1) {
|
||||
return !!hwaddr_aton (asc, buf, sizeof (buf), &l);
|
||||
} else
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3240,20 +3282,23 @@ char *
|
|||
nm_utils_hwaddr_canonical (const char *asc, gssize length)
|
||||
{
|
||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
gsize l;
|
||||
|
||||
g_return_val_if_fail (asc != NULL, NULL);
|
||||
g_return_val_if_fail (asc, NULL);
|
||||
g_return_val_if_fail (length == -1 || (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX), NULL);
|
||||
|
||||
if (length == -1) {
|
||||
length = hwaddr_binary_len (asc);
|
||||
if (length == 0 || length > NM_UTILS_HWADDR_LEN_MAX)
|
||||
if (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX) {
|
||||
if (!hwaddr_aton (asc, buf, length, &l))
|
||||
return NULL;
|
||||
}
|
||||
if (l != length)
|
||||
return NULL;
|
||||
} else if (length == -1) {
|
||||
if (!hwaddr_aton (asc, buf, NM_UTILS_HWADDR_LEN_MAX, &l))
|
||||
return NULL;
|
||||
} else
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
if (nm_utils_hwaddr_aton (asc, buf, length) == NULL)
|
||||
return NULL;
|
||||
|
||||
return nm_utils_hwaddr_ntoa (buf, length);
|
||||
return nm_utils_hwaddr_ntoa (buf, l);
|
||||
}
|
||||
|
||||
/* This is used to possibly canonicalize values passed to MAC address property
|
||||
|
|
@ -3317,17 +3362,17 @@ nm_utils_hwaddr_matches (gconstpointer hwaddr1,
|
|||
gssize hwaddr2_len)
|
||||
{
|
||||
guint8 buf1[NM_UTILS_HWADDR_LEN_MAX], buf2[NM_UTILS_HWADDR_LEN_MAX];
|
||||
gsize l;
|
||||
|
||||
if (hwaddr1_len == -1) {
|
||||
g_return_val_if_fail (hwaddr1 != NULL, FALSE);
|
||||
|
||||
hwaddr1_len = hwaddr_binary_len (hwaddr1);
|
||||
if (hwaddr1_len == 0 || hwaddr1_len > NM_UTILS_HWADDR_LEN_MAX)
|
||||
if (!hwaddr_aton (hwaddr1, buf1, sizeof (buf1), &l)) {
|
||||
g_return_val_if_fail ((hwaddr2_len == -1 && hwaddr2) || (hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX), FALSE);
|
||||
return FALSE;
|
||||
if (!nm_utils_hwaddr_aton (hwaddr1, buf1, hwaddr1_len))
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
hwaddr1 = buf1;
|
||||
hwaddr1_len = l;
|
||||
} else {
|
||||
g_return_val_if_fail (hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE);
|
||||
|
||||
|
|
@ -3340,23 +3385,24 @@ nm_utils_hwaddr_matches (gconstpointer hwaddr1,
|
|||
if (hwaddr2_len == -1) {
|
||||
g_return_val_if_fail (hwaddr2 != NULL, FALSE);
|
||||
|
||||
if (!nm_utils_hwaddr_aton (hwaddr2, buf2, hwaddr1_len))
|
||||
if (!hwaddr_aton (hwaddr2, buf2, sizeof (buf2), &l))
|
||||
return FALSE;
|
||||
if (l != hwaddr1_len)
|
||||
return FALSE;
|
||||
|
||||
hwaddr2 = buf2;
|
||||
hwaddr2_len = hwaddr1_len;
|
||||
} else {
|
||||
g_return_val_if_fail (hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE);
|
||||
|
||||
if (hwaddr2_len != hwaddr1_len)
|
||||
return FALSE;
|
||||
|
||||
if (!hwaddr2) {
|
||||
memset (buf2, 0, hwaddr2_len);
|
||||
hwaddr2 = buf2;
|
||||
}
|
||||
}
|
||||
|
||||
if (hwaddr1_len != hwaddr2_len)
|
||||
return FALSE;
|
||||
|
||||
if (hwaddr1_len == INFINIBAND_ALEN) {
|
||||
hwaddr1 = (guint8 *)hwaddr1 + INFINIBAND_ALEN - 8;
|
||||
hwaddr2 = (guint8 *)hwaddr2 + INFINIBAND_ALEN - 8;
|
||||
|
|
@ -3372,16 +3418,11 @@ static GVariant *
|
|||
_nm_utils_hwaddr_to_dbus_impl (const char *str)
|
||||
{
|
||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
int len;
|
||||
gsize len;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
len = _nm_utils_hwaddr_length (str);
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
if (!nm_utils_hwaddr_aton (str, buf, len))
|
||||
if (!hwaddr_aton (str, buf, sizeof (buf), &len))
|
||||
return NULL;
|
||||
|
||||
return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, buf, len, 1);
|
||||
|
|
|
|||
|
|
@ -305,9 +305,11 @@ nm_strdup_not_empty (const char *str)
|
|||
|
||||
#if NM_MORE_ASSERTS
|
||||
#define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END
|
||||
#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } else { g_assert (FALSE && (cond)); } } G_STMT_END
|
||||
#define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END
|
||||
#else
|
||||
#define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END
|
||||
#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } } G_STMT_END
|
||||
#define nm_assert_not_reached() G_STMT_START { ; } G_STMT_END
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||
if (!match_subchans (self, s_wired, &try_mac))
|
||||
return FALSE;
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device, TRUE);
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||
mac = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (perm_hw_addr) {
|
||||
if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
||||
|
|
@ -1344,6 +1344,7 @@ complete_connection (NMDevice *device,
|
|||
NMSettingPppoe *s_pppoe;
|
||||
const char *setting_mac;
|
||||
const char *perm_hw_addr;
|
||||
gboolean perm_hw_addr_is_fake;
|
||||
|
||||
s_pppoe = nm_connection_get_setting_pppoe (connection);
|
||||
|
||||
|
|
@ -1371,8 +1372,8 @@ complete_connection (NMDevice *device,
|
|||
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||
}
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||
if (perm_hw_addr) {
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address_full (device, TRUE, &perm_hw_addr_is_fake);
|
||||
if (perm_hw_addr && !perm_hw_addr_is_fake) {
|
||||
setting_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (setting_mac) {
|
||||
/* Make sure the setting MAC (if any) matches the device's permanent MAC */
|
||||
|
|
@ -1408,7 +1409,7 @@ new_default_connection (NMDevice *self)
|
|||
if (nm_config_get_no_auto_default_for_device (nm_config_get (), self))
|
||||
return NULL;
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (self, TRUE);
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (self);
|
||||
if (!perm_hw_addr)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -1468,7 +1469,8 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE ((NMDeviceEthernet *) device);
|
||||
NMSettingWired *s_wired = nm_connection_get_setting_wired (connection);
|
||||
const char *perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||
gboolean perm_hw_addr_is_fake;
|
||||
const char *perm_hw_addr;
|
||||
const char *mac = nm_device_get_hw_address (device);
|
||||
const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS;
|
||||
GHashTableIter iter;
|
||||
|
|
@ -1487,7 +1489,8 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
/* If the device reports a permanent address, use that for the MAC address
|
||||
* and the current MAC, if different, is the cloned MAC.
|
||||
*/
|
||||
if (perm_hw_addr) {
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address_full (device, TRUE, &perm_hw_addr_is_fake);
|
||||
if (perm_hw_addr && !perm_hw_addr_is_fake) {
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL);
|
||||
|
||||
mac_prop = NULL;
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||
|
||||
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
||||
if (mac) {
|
||||
hw_addr = nm_device_get_permanent_hw_address (device, TRUE);
|
||||
hw_addr = nm_device_get_permanent_hw_address (device);
|
||||
if ( !hw_addr
|
||||
|| !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1))
|
||||
return FALSE;
|
||||
|
|
@ -197,7 +197,7 @@ complete_connection (NMDevice *device,
|
|||
}
|
||||
|
||||
setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband);
|
||||
hw_address = nm_device_get_permanent_hw_address (device, TRUE);
|
||||
hw_address = nm_device_get_permanent_hw_address (device);
|
||||
if (setting_mac) {
|
||||
/* Make sure the setting MAC (if any) matches the device's MAC */
|
||||
if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) {
|
||||
|
|
@ -223,7 +223,7 @@ static void
|
|||
update_connection (NMDevice *device, NMConnection *connection)
|
||||
{
|
||||
NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection);
|
||||
const char *mac = nm_device_get_permanent_hw_address (device, TRUE);
|
||||
const char *mac = nm_device_get_permanent_hw_address (device);
|
||||
const char *transport_mode = "datagram";
|
||||
int ifindex;
|
||||
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw
|
|||
if (!priv->parent)
|
||||
return !fail_if_no_hwaddr;
|
||||
|
||||
parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE);
|
||||
parent_mac = nm_device_get_permanent_hw_address (priv->parent);
|
||||
return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw
|
|||
if (!priv->parent)
|
||||
return !fail_if_no_hwaddr;
|
||||
|
||||
parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE);
|
||||
parent_mac = nm_device_get_permanent_hw_address (priv->parent);
|
||||
return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,10 +227,18 @@ typedef struct _NMDevicePrivate {
|
|||
char * iface; /* may change, could be renamed by user */
|
||||
int ifindex;
|
||||
|
||||
guint hw_addr_len;
|
||||
union {
|
||||
const guint8 hw_addr_len; /* read-only */
|
||||
guint8 hw_addr_len_;
|
||||
};
|
||||
guint8 /*HwAddrType*/ hw_addr_type;
|
||||
|
||||
bool real;
|
||||
bool real:1;
|
||||
|
||||
/* there was a IP config change, but no idle action was scheduled because device
|
||||
* is still not platform-init */
|
||||
bool queued_ip4_config_pending:1;
|
||||
bool queued_ip6_config_pending:1;
|
||||
|
||||
char * ip_iface;
|
||||
int ip_ifindex;
|
||||
|
|
@ -1859,7 +1867,7 @@ device_link_changed (NMDevice *self)
|
|||
had_hw_addr = (priv->hw_addr != NULL);
|
||||
nm_device_update_hw_address (self);
|
||||
got_hw_addr = (!had_hw_addr && priv->hw_addr);
|
||||
nm_device_update_permanent_hw_address (self);
|
||||
nm_device_update_permanent_hw_address (self, FALSE);
|
||||
|
||||
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
|
||||
_LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'",
|
||||
|
|
@ -1871,7 +1879,7 @@ device_link_changed (NMDevice *self)
|
|||
ip_ifname_changed = !priv->ip_iface;
|
||||
|
||||
if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT))
|
||||
nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings));
|
||||
nm_device_set_unmanaged_by_user_settings (self);
|
||||
else
|
||||
update_unmanaged_specs = TRUE;
|
||||
|
||||
|
|
@ -1950,7 +1958,7 @@ device_link_changed (NMDevice *self)
|
|||
}
|
||||
|
||||
if (update_unmanaged_specs)
|
||||
nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings));
|
||||
nm_device_set_unmanaged_by_user_settings (self);
|
||||
|
||||
if ( got_hw_addr
|
||||
&& !priv->up
|
||||
|
|
@ -2320,13 +2328,12 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink)
|
|||
_notify (self, PROP_UDI);
|
||||
}
|
||||
|
||||
/* trigger initial ip config change to initialize ip-config */
|
||||
priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
|
||||
priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
|
||||
priv->queued_ip4_config_pending = TRUE;
|
||||
priv->queued_ip6_config_pending = TRUE;
|
||||
|
||||
nm_device_update_hw_address (self);
|
||||
nm_device_update_initial_hw_address (self);
|
||||
nm_device_update_permanent_hw_address (self);
|
||||
nm_device_update_permanent_hw_address (self, FALSE);
|
||||
|
||||
/* Note: initial hardware address must be read before calling get_ignore_carrier() */
|
||||
config = nm_config_get ();
|
||||
|
|
@ -2516,11 +2523,6 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
|||
g_clear_pointer (&priv->udi, g_free);
|
||||
_notify (self, PROP_UDI);
|
||||
}
|
||||
if (priv->hw_addr) {
|
||||
priv->hw_addr_len = 0;
|
||||
g_clear_pointer (&priv->hw_addr, g_free);
|
||||
_notify (self, PROP_HW_ADDRESS);
|
||||
}
|
||||
if (priv->physical_port_id) {
|
||||
g_clear_pointer (&priv->physical_port_id, g_free);
|
||||
_notify (self, PROP_PHYSICAL_PORT_ID);
|
||||
|
|
@ -2529,9 +2531,12 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
|||
nm_clear_g_source (&priv->stats.timeout_id);
|
||||
_stats_update_counters (self, 0, 0);
|
||||
|
||||
priv->hw_addr_len_ = 0;
|
||||
if (nm_clear_g_free (&priv->hw_addr))
|
||||
_notify (self, PROP_HW_ADDRESS);
|
||||
priv->hw_addr_type = HW_ADDR_TYPE_UNSET;
|
||||
g_clear_pointer (&priv->hw_addr_perm, g_free);
|
||||
_notify (self, PROP_PERM_HW_ADDRESS);
|
||||
if (nm_clear_g_free (&priv->hw_addr_perm))
|
||||
_notify (self, PROP_PERM_HW_ADDRESS);
|
||||
g_clear_pointer (&priv->hw_addr_initial, g_free);
|
||||
|
||||
priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED;
|
||||
|
|
@ -7697,6 +7702,7 @@ _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type)
|
|||
|
||||
if (nm_clear_g_source (&priv->queued_ip4_config_id))
|
||||
_LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
|
||||
priv->queued_ip4_config_pending = FALSE;
|
||||
|
||||
dhcp4_cleanup (self, cleanup_type, FALSE);
|
||||
arp_cleanup (self);
|
||||
|
|
@ -7713,6 +7719,7 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
|
|||
|
||||
if (nm_clear_g_source (&priv->queued_ip6_config_id))
|
||||
_LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
|
||||
priv->queued_ip6_config_pending = FALSE;
|
||||
|
||||
g_clear_object (&priv->dad6_ip6_config);
|
||||
dhcp6_cleanup (self, cleanup_type, FALSE);
|
||||
|
|
@ -9408,6 +9415,7 @@ update_ip4_config (NMDevice *self, gboolean initial)
|
|||
&& activation_source_is_scheduled (self,
|
||||
activate_stage5_ip4_config_commit,
|
||||
AF_INET)) {
|
||||
priv->queued_ip4_config_pending = FALSE;
|
||||
priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
|
||||
_LOGT (LOGD_DEVICE, "IP4 update was postponed");
|
||||
return;
|
||||
|
|
@ -9498,6 +9506,7 @@ update_ip6_config (NMDevice *self, gboolean initial)
|
|||
&& activation_source_is_scheduled (self,
|
||||
activate_stage5_ip6_config_commit,
|
||||
AF_INET6)) {
|
||||
priv->queued_ip6_config_pending = FALSE;
|
||||
priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
|
||||
_LOGT (LOGD_DEVICE, "IP6 update was postponed");
|
||||
return;
|
||||
|
|
@ -9575,6 +9584,8 @@ queued_ip4_config_change (gpointer user_data)
|
|||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (!priv->queued_ip4_config_pending);
|
||||
|
||||
/* Wait for any queued state changes */
|
||||
if (priv->queued_state.id)
|
||||
return TRUE;
|
||||
|
|
@ -9599,6 +9610,8 @@ queued_ip6_config_change (gpointer user_data)
|
|||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
nm_assert (!priv->queued_ip4_config_pending);
|
||||
|
||||
/* Wait for any queued state changes */
|
||||
if (priv->queued_state.id)
|
||||
return TRUE;
|
||||
|
|
@ -9678,7 +9691,11 @@ device_ipx_changed (NMPlatform *platform,
|
|||
switch (obj_type) {
|
||||
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||
if (!priv->queued_ip4_config_id) {
|
||||
if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
|
||||
priv->queued_ip4_config_pending = TRUE;
|
||||
nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id));
|
||||
} else if (!priv->queued_ip4_config_id) {
|
||||
priv->queued_ip4_config_pending = FALSE;
|
||||
priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
|
||||
_LOGD (LOGD_DEVICE, "queued IP4 config change");
|
||||
}
|
||||
|
|
@ -9695,7 +9712,11 @@ device_ipx_changed (NMPlatform *platform,
|
|||
}
|
||||
/* fallthrough */
|
||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||
if (!priv->queued_ip6_config_id) {
|
||||
if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
|
||||
priv->queued_ip6_config_pending = TRUE;
|
||||
nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id));
|
||||
} else if (!priv->queued_ip6_config_id) {
|
||||
priv->queued_ip6_config_pending = FALSE;
|
||||
priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
|
||||
_LOGD (LOGD_DEVICE, "queued IP6 config change");
|
||||
}
|
||||
|
|
@ -9937,6 +9958,33 @@ _set_unmanaged_flags (NMDevice *self,
|
|||
allow_state_transition = FALSE;
|
||||
was_managed = allow_state_transition && nm_device_get_managed (self, FALSE);
|
||||
|
||||
if ( NM_FLAGS_HAS (priv->unmanaged_flags, NM_UNMANAGED_PLATFORM_INIT)
|
||||
&& NM_FLAGS_HAS (flags, NM_UNMANAGED_PLATFORM_INIT)
|
||||
&& NM_IN_SET (set_op, NM_UNMAN_FLAG_OP_SET_MANAGED)) {
|
||||
/* we are clearing the platform-init flags. This triggers additional actions. */
|
||||
if (!NM_FLAGS_HAS (flags, NM_UNMANAGED_USER_SETTINGS)) {
|
||||
gboolean unmanaged;
|
||||
|
||||
unmanaged = nm_device_spec_match_list (self,
|
||||
nm_settings_get_unmanaged_specs (NM_DEVICE_GET_PRIVATE (self)->settings));
|
||||
nm_device_set_unmanaged_flags (self,
|
||||
NM_UNMANAGED_USER_SETTINGS,
|
||||
!!unmanaged);
|
||||
}
|
||||
|
||||
if (priv->queued_ip4_config_pending) {
|
||||
priv->queued_ip4_config_pending = FALSE;
|
||||
nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id));
|
||||
priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self);
|
||||
}
|
||||
|
||||
if (priv->queued_ip6_config_pending) {
|
||||
priv->queued_ip6_config_pending = FALSE;
|
||||
nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id));
|
||||
priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self);
|
||||
}
|
||||
}
|
||||
|
||||
old_flags = priv->unmanaged_flags;
|
||||
old_mask = priv->unmanaged_mask;
|
||||
|
||||
|
|
@ -10051,20 +10099,30 @@ nm_device_set_unmanaged_by_flags_queue (NMDevice *self,
|
|||
}
|
||||
|
||||
void
|
||||
nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs)
|
||||
nm_device_set_unmanaged_by_user_settings (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
gboolean unmanaged;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) {
|
||||
/* the device is already unmanaged due to platform-init.
|
||||
*
|
||||
* We want to delay evaluating the device spec, because it will freeze
|
||||
* the permanent MAC address. That should not be done, before the platform
|
||||
* link is fully initialized (via UDEV).
|
||||
*
|
||||
* Note that when clearing NM_UNMANAGED_PLATFORM_INIT, we will re-evaluate
|
||||
* whether the device is unmanaged by user-settings. */
|
||||
return;
|
||||
}
|
||||
|
||||
unmanaged = nm_device_spec_match_list (self, unmanaged_specs);
|
||||
unmanaged = nm_device_spec_match_list (self,
|
||||
nm_settings_get_unmanaged_specs (NM_DEVICE_GET_PRIVATE (self)->settings));
|
||||
|
||||
nm_device_set_unmanaged_by_flags (self,
|
||||
NM_UNMANAGED_USER_SETTINGS,
|
||||
unmanaged,
|
||||
!!unmanaged,
|
||||
unmanaged
|
||||
? NM_DEVICE_STATE_REASON_NOW_UNMANAGED
|
||||
: NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||
|
|
@ -11587,11 +11645,17 @@ const char *
|
|||
nm_device_get_hw_address (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
char buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
gsize l;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
nm_assert ((!priv->hw_addr) ^ (priv->hw_addr_len > 0));
|
||||
nm_assert ( (!priv->hw_addr && priv->hw_addr_len == 0)
|
||||
|| ( priv->hw_addr
|
||||
&& _nm_utils_hwaddr_aton (priv->hw_addr, buf, sizeof (buf), &l)
|
||||
&& l == priv->hw_addr_len));
|
||||
|
||||
return priv->hw_addr;
|
||||
}
|
||||
|
|
@ -11602,7 +11666,6 @@ nm_device_update_hw_address (NMDevice *self)
|
|||
NMDevicePrivate *priv;
|
||||
const guint8 *hwaddr;
|
||||
gsize hwaddrlen = 0;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
if (priv->ifindex <= 0)
|
||||
|
|
@ -11615,38 +11678,46 @@ nm_device_update_hw_address (NMDevice *self)
|
|||
&& nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth)))
|
||||
hwaddrlen = 0;
|
||||
|
||||
if (hwaddrlen) {
|
||||
priv->hw_addr_len = hwaddrlen;
|
||||
if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) {
|
||||
g_free (priv->hw_addr);
|
||||
priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen);
|
||||
if (!hwaddrlen)
|
||||
return FALSE;
|
||||
|
||||
_LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr);
|
||||
_notify (self, PROP_HW_ADDRESS);
|
||||
if ( priv->hw_addr_len
|
||||
&& priv->hw_addr_len != hwaddrlen) {
|
||||
char s_buf[NM_UTILS_HWADDR_LEN_MAX_STR];
|
||||
|
||||
if ( !priv->hw_addr_initial
|
||||
|| ( priv->hw_addr_type == HW_ADDR_TYPE_UNSET
|
||||
&& priv->state < NM_DEVICE_STATE_PREPARE
|
||||
&& !nm_device_is_activating (self))) {
|
||||
/* when we get a hw_addr the first time or while the device
|
||||
* is not activated (with no explict hw address set), always
|
||||
* update our inital hw-address as well. */
|
||||
nm_device_update_initial_hw_address (self);
|
||||
}
|
||||
changed = TRUE;
|
||||
}
|
||||
} else {
|
||||
/* Invalid or no hardware address */
|
||||
if (priv->hw_addr_len != 0) {
|
||||
_LOGD (LOGD_PLATFORM | LOGD_DEVICE,
|
||||
"hw-addr: failed reading current MAC address (stay with %s)",
|
||||
priv->hw_addr);
|
||||
} else {
|
||||
_LOGD (LOGD_PLATFORM | LOGD_DEVICE,
|
||||
"hw-addr: failed reading current MAC address");
|
||||
}
|
||||
/* we cannot change the address length of a device once it is set (except
|
||||
* unrealizing the device).
|
||||
*
|
||||
* The reason is that the permanent and initial MAC addresses also must have the
|
||||
* same address length, so it's unclear what it would mean that the length changes. */
|
||||
_LOGD (LOGD_PLATFORM | LOGD_DEVICE,
|
||||
"hw-addr: read a MAC address with differing length (%s vs. %s)",
|
||||
priv->hw_addr,
|
||||
nm_utils_hwaddr_ntoa_buf (hwaddr, hwaddrlen, TRUE, s_buf, sizeof (s_buf)));
|
||||
return FALSE;
|
||||
}
|
||||
return changed;
|
||||
|
||||
if ( priv->hw_addr
|
||||
&& nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen))
|
||||
return FALSE;
|
||||
|
||||
g_free (priv->hw_addr);
|
||||
priv->hw_addr_len_ = hwaddrlen;
|
||||
priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen);
|
||||
|
||||
_LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr);
|
||||
_notify (self, PROP_HW_ADDRESS);
|
||||
|
||||
if ( !priv->hw_addr_initial
|
||||
|| ( priv->hw_addr_type == HW_ADDR_TYPE_UNSET
|
||||
&& priv->state < NM_DEVICE_STATE_PREPARE
|
||||
&& !nm_device_is_activating (self))) {
|
||||
/* when we get a hw_addr the first time or while the device
|
||||
* is not activated (with no explict hw address set), always
|
||||
* update our inital hw-address as well. */
|
||||
nm_device_update_initial_hw_address (self);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -11670,12 +11741,14 @@ nm_device_update_initial_hw_address (NMDevice *self)
|
|||
}
|
||||
|
||||
void
|
||||
nm_device_update_permanent_hw_address (NMDevice *self)
|
||||
nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
size_t len = 0;
|
||||
gboolean success_read;
|
||||
int ifindex;
|
||||
const NMPlatformLink *pllink;
|
||||
|
||||
if (priv->hw_addr_perm) {
|
||||
/* the permanent hardware address is only read once and not
|
||||
|
|
@ -11686,35 +11759,82 @@ nm_device_update_permanent_hw_address (NMDevice *self)
|
|||
return;
|
||||
}
|
||||
|
||||
if (priv->ifindex <= 0)
|
||||
ifindex = priv->ifindex;
|
||||
if (ifindex <= 0)
|
||||
return;
|
||||
|
||||
if (!priv->hw_addr_len) {
|
||||
nm_device_update_hw_address (self);
|
||||
if (!priv->hw_addr_len)
|
||||
/* the user is advised to configure stable MAC addresses for software devices via
|
||||
* UDEV. Thus, check whether the link is fully initialized. */
|
||||
pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex);
|
||||
if ( !pllink
|
||||
|| !pllink->initialized) {
|
||||
if (!force_freeze) {
|
||||
/* we can afford to wait. Back off and leave the permanent MAC address
|
||||
* undecided for now. */
|
||||
return;
|
||||
}
|
||||
/* try to refresh the link just to give UDEV a bit more time... */
|
||||
nm_platform_link_refresh (NM_PLATFORM_GET, ifindex);
|
||||
/* maybe the MAC address changed... */
|
||||
nm_device_update_hw_address (self);
|
||||
} else if (!priv->hw_addr_len)
|
||||
nm_device_update_hw_address (self);
|
||||
|
||||
if (!priv->hw_addr_len) {
|
||||
/* we need the current MAC address because we require the permanent MAC address
|
||||
* to have the same length as the current address.
|
||||
*
|
||||
* Abort if there is no current MAC address. */
|
||||
return;
|
||||
}
|
||||
|
||||
success_read = nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len);
|
||||
if (!success_read || len != priv->hw_addr_len) {
|
||||
/* Fall back to current address. We use the fake address and keep it
|
||||
* until the device unrealizes.
|
||||
*
|
||||
* In some cases it might be necessary to know whether this is a "real" or
|
||||
* a temporary address (fake). */
|
||||
_LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use current: %s)",
|
||||
success_read
|
||||
? "read HW addr length of permanent MAC address differs"
|
||||
: "unable to read permanent MAC address",
|
||||
priv->hw_addr);
|
||||
priv->hw_addr_perm_fake = TRUE;
|
||||
priv->hw_addr_perm = g_strdup (priv->hw_addr);
|
||||
} else {
|
||||
success_read = nm_platform_link_get_permanent_address (NM_PLATFORM_GET, ifindex, buf, &len);
|
||||
if (success_read && priv->hw_addr_len == len) {
|
||||
priv->hw_addr_perm_fake = FALSE;
|
||||
priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len);
|
||||
_LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'",
|
||||
priv->hw_addr_perm);
|
||||
goto notify_and_out;
|
||||
}
|
||||
|
||||
/* we failed to read a permanent MAC address, thus we use a fake address,
|
||||
* that is the current MAC address of the device.
|
||||
*
|
||||
* Note that the permanet MAC address of a NMDevice instance does not change
|
||||
* after being set once. Thus, we use now a fake address and stick to that
|
||||
* (until we unrealize the device). */
|
||||
priv->hw_addr_perm_fake = TRUE;
|
||||
|
||||
/* We also persist our choice of the fake address to the device state
|
||||
* file to use the same address on restart of NetworkManager.
|
||||
* First, try to reload the address from the state file. */
|
||||
{
|
||||
gs_free NMConfigDeviceStateData *dev_state = NULL;
|
||||
|
||||
dev_state = nm_config_device_state_load (nm_config_get (), ifindex);
|
||||
if ( dev_state
|
||||
&& dev_state->perm_hw_addr_fake
|
||||
&& nm_utils_hwaddr_aton (dev_state->perm_hw_addr_fake, buf, priv->hw_addr_len)
|
||||
&& !nm_utils_hwaddr_matches (buf, priv->hw_addr_len, priv->hw_addr, -1)) {
|
||||
_LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use from statefile: %s, current: %s)",
|
||||
success_read
|
||||
? "read HW addr length of permanent MAC address differs"
|
||||
: "unable to read permanent MAC address",
|
||||
dev_state->perm_hw_addr_fake,
|
||||
priv->hw_addr);
|
||||
priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, priv->hw_addr_len);
|
||||
goto notify_and_out;
|
||||
}
|
||||
}
|
||||
|
||||
_LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use current: %s)",
|
||||
success_read
|
||||
? "read HW addr length of permanent MAC address differs"
|
||||
: "unable to read permanent MAC address",
|
||||
priv->hw_addr);
|
||||
priv->hw_addr_perm = g_strdup (priv->hw_addr);
|
||||
|
||||
notify_and_out:
|
||||
_notify (self, PROP_PERM_HW_ADDRESS);
|
||||
}
|
||||
|
||||
|
|
@ -11806,25 +11926,25 @@ nm_device_hw_addr_is_explict (NMDevice *self)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
_hw_addr_matches (NMDevice *self, const char *addr)
|
||||
_hw_addr_matches (NMDevice *self, const guint8 *addr, gsize addr_len)
|
||||
{
|
||||
const char *cur_addr;
|
||||
|
||||
cur_addr = nm_device_get_hw_address (self);
|
||||
return cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1);
|
||||
return cur_addr && nm_utils_hwaddr_matches (addr, addr_len, cur_addr, -1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_hw_addr_set (NMDevice *self,
|
||||
const char *addr,
|
||||
const char *operation,
|
||||
const char *detail)
|
||||
const char *const addr,
|
||||
const char *const operation,
|
||||
const char *const detail)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
gboolean success = FALSE;
|
||||
NMPlatformError plerr;
|
||||
guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX];
|
||||
guint hw_addr_len;
|
||||
gsize addr_len;
|
||||
gboolean was_up;
|
||||
|
||||
nm_assert (NM_IS_DEVICE (self));
|
||||
|
|
@ -11833,17 +11953,17 @@ _hw_addr_set (NMDevice *self,
|
|||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (!_nm_utils_hwaddr_aton (addr, addr_bytes, sizeof (addr_bytes), &addr_len))
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
/* Do nothing if current MAC is same */
|
||||
if (_hw_addr_matches (self, addr)) {
|
||||
if (_hw_addr_matches (self, addr_bytes, addr_len)) {
|
||||
_LOGT (LOGD_DEVICE, "set-hw-addr: no MAC address change needed (%s)", addr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
hw_addr_len = priv->hw_addr_len;
|
||||
if (!hw_addr_len)
|
||||
hw_addr_len = _nm_utils_hwaddr_length (addr);
|
||||
if ( !hw_addr_len
|
||||
|| !nm_utils_hwaddr_aton (addr, addr_bytes, hw_addr_len))
|
||||
if ( priv->hw_addr_len
|
||||
&& priv->hw_addr_len != addr_len)
|
||||
g_return_val_if_reached (FALSE);
|
||||
|
||||
_LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s)...", addr, operation, detail);
|
||||
|
|
@ -11854,12 +11974,12 @@ _hw_addr_set (NMDevice *self,
|
|||
nm_device_take_down (self, FALSE);
|
||||
}
|
||||
|
||||
plerr = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, hw_addr_len);
|
||||
plerr = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, addr_len);
|
||||
success = (plerr == NM_PLATFORM_ERROR_SUCCESS);
|
||||
if (success) {
|
||||
/* MAC address succesfully changed; update the current MAC to match */
|
||||
nm_device_update_hw_address (self);
|
||||
if (_hw_addr_matches (self, addr)) {
|
||||
if (_hw_addr_matches (self, addr_bytes, addr_len)) {
|
||||
_LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)",
|
||||
operation, addr, detail);
|
||||
} else {
|
||||
|
|
@ -11889,7 +12009,7 @@ _hw_addr_set (NMDevice *self,
|
|||
goto handle_fail;
|
||||
if (!nm_device_update_hw_address (self))
|
||||
goto handle_wait;
|
||||
if (!_hw_addr_matches (self, addr))
|
||||
if (!_hw_addr_matches (self, addr_bytes, addr_len))
|
||||
goto handle_fail;
|
||||
|
||||
break;
|
||||
|
|
@ -11972,7 +12092,7 @@ nm_device_hw_addr_set_cloned (NMDevice *self, NMConnection *connection, gboolean
|
|||
}
|
||||
|
||||
if (nm_streq (addr, NM_CLONED_MAC_PERMANENT)) {
|
||||
addr = nm_device_get_permanent_hw_address (self, TRUE);
|
||||
addr = nm_device_get_permanent_hw_address (self);
|
||||
if (!addr)
|
||||
return FALSE;
|
||||
priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT;
|
||||
|
|
@ -12016,9 +12136,8 @@ nm_device_hw_addr_set_cloned (NMDevice *self, NMConnection *connection, gboolean
|
|||
addr = hw_addr_generated;
|
||||
} else {
|
||||
/* this must be a valid address. Otherwise, we shouldn't come here. */
|
||||
if (_nm_utils_hwaddr_length (addr) <= 0) {
|
||||
if (!nm_utils_hwaddr_valid (addr, -1))
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
priv->hw_addr_type = HW_ADDR_TYPE_EXPLICIT;
|
||||
}
|
||||
|
||||
|
|
@ -12050,21 +12169,32 @@ nm_device_hw_addr_reset (NMDevice *self, const char *detail)
|
|||
}
|
||||
|
||||
const char *
|
||||
nm_device_get_permanent_hw_address (NMDevice *self, gboolean fallback_fake)
|
||||
nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean force_freeze, gboolean *out_is_fake)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
if (!priv->hw_addr_perm)
|
||||
return NULL;
|
||||
if ( priv->hw_addr_perm_fake
|
||||
&& !fallback_fake)
|
||||
return NULL;
|
||||
|
||||
if ( !priv->hw_addr_perm
|
||||
&& force_freeze) {
|
||||
/* somebody requests a permanent MAC address, but we don't have it set
|
||||
* yet. We cannot delay it any longer and try to get it without waiting
|
||||
* for UDEV. */
|
||||
nm_device_update_permanent_hw_address (self, TRUE);
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_is_fake, priv->hw_addr_perm && priv->hw_addr_perm_fake);
|
||||
return priv->hw_addr_perm;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_device_get_permanent_hw_address (NMDevice *self)
|
||||
{
|
||||
return nm_device_get_permanent_hw_address_full (self, TRUE, NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_device_get_initial_hw_address (NMDevice *self)
|
||||
{
|
||||
|
|
@ -12119,7 +12249,7 @@ spec_match_list (NMDevice *self, const GSList *specs)
|
|||
}
|
||||
}
|
||||
|
||||
hw_addr_perm = nm_device_get_permanent_hw_address (self, TRUE);
|
||||
hw_addr_perm = nm_device_get_permanent_hw_address (self);
|
||||
if (hw_addr_perm) {
|
||||
m = nm_match_spec_hwaddr (specs, hw_addr_perm);
|
||||
matched = MAX (matched, m);
|
||||
|
|
@ -12217,13 +12347,16 @@ constructor (GType type,
|
|||
}
|
||||
|
||||
if (priv->hw_addr_perm) {
|
||||
priv->hw_addr_len = _nm_utils_hwaddr_length (priv->hw_addr_perm);
|
||||
if (!priv->hw_addr_len) {
|
||||
guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
|
||||
gsize l;
|
||||
|
||||
if (!_nm_utils_hwaddr_aton (priv->hw_addr_perm, buf, sizeof (buf), &l)) {
|
||||
g_clear_pointer (&priv->hw_addr_perm, g_free);
|
||||
g_return_val_if_reached (object);
|
||||
}
|
||||
|
||||
priv->hw_addr = g_strdup (priv->hw_addr_perm);
|
||||
priv->hw_addr_len_ = l;
|
||||
priv->hw_addr = nm_utils_hwaddr_ntoa (buf, l);
|
||||
_LOGT (LOGD_DEVICE, "hw-addr: has permanent hw-address '%s'", priv->hw_addr_perm);
|
||||
}
|
||||
|
||||
|
|
@ -12595,10 +12728,15 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_HW_ADDRESS:
|
||||
g_value_set_string (value, priv->hw_addr);
|
||||
break;
|
||||
case PROP_PERM_HW_ADDRESS:
|
||||
case PROP_PERM_HW_ADDRESS: {
|
||||
const char *perm_hw_addr;
|
||||
gboolean perm_hw_addr_is_fake;
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address_full (self, FALSE, &perm_hw_addr_is_fake);
|
||||
/* this property is exposed on D-Bus for NMDeviceEthernet and NMDeviceWifi. */
|
||||
g_value_set_string (value, nm_device_get_permanent_hw_address (self, FALSE));
|
||||
g_value_set_string (value, perm_hw_addr && !perm_hw_addr_is_fake ? perm_hw_addr : NULL);
|
||||
break;
|
||||
}
|
||||
case PROP_HAS_PENDING_ACTION:
|
||||
g_value_set_boolean (value, nm_device_has_pending_action (self));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -362,8 +362,10 @@ guint32 nm_device_get_ip4_route_metric (NMDevice *dev);
|
|||
guint32 nm_device_get_ip6_route_metric (NMDevice *dev);
|
||||
|
||||
const char * nm_device_get_hw_address (NMDevice *dev);
|
||||
const char * nm_device_get_permanent_hw_address (NMDevice *dev,
|
||||
gboolean fallback_fake);
|
||||
const char * nm_device_get_permanent_hw_address (NMDevice *self);
|
||||
const char * nm_device_get_permanent_hw_address_full (NMDevice *self,
|
||||
gboolean force_freeze,
|
||||
gboolean *out_is_fake);
|
||||
const char * nm_device_get_initial_hw_address (NMDevice *dev);
|
||||
|
||||
NMProxyConfig * nm_device_get_proxy_config (NMDevice *dev);
|
||||
|
|
@ -506,7 +508,7 @@ void nm_device_set_unmanaged_by_flags_queue (NMDevice *self,
|
|||
NMUnmanagedFlags flags,
|
||||
NMUnmanFlagOp set_op,
|
||||
NMDeviceStateReason reason);
|
||||
void nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs);
|
||||
void nm_device_set_unmanaged_by_user_settings (NMDevice *self);
|
||||
void nm_device_set_unmanaged_by_user_udev (NMDevice *self);
|
||||
void nm_device_set_unmanaged_by_quitting (NMDevice *device);
|
||||
|
||||
|
|
@ -586,7 +588,7 @@ void nm_device_reactivate_ip6_config (NMDevice *device,
|
|||
|
||||
gboolean nm_device_update_hw_address (NMDevice *self);
|
||||
void nm_device_update_initial_hw_address (NMDevice *self);
|
||||
void nm_device_update_permanent_hw_address (NMDevice *self);
|
||||
void nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze);
|
||||
void nm_device_update_dynamic_ip_setup (NMDevice *self);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DEVICE_H__ */
|
||||
|
|
|
|||
|
|
@ -603,7 +603,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
|
|||
if (!s_wireless)
|
||||
return FALSE;
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||
mac = nm_setting_wireless_get_mac_address (s_wireless);
|
||||
if (perm_hw_addr) {
|
||||
if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1))
|
||||
|
|
@ -895,7 +895,7 @@ complete_connection (NMDevice *device,
|
|||
if (hidden)
|
||||
g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL);
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||
if (perm_hw_addr) {
|
||||
setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
|
||||
if (setting_mac) {
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device)
|
|||
|
||||
priv = NM_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
hw_address = nm_device_get_permanent_hw_address (device, TRUE);
|
||||
hw_address = nm_device_get_permanent_hw_address (device);
|
||||
if (!hw_address)
|
||||
return;
|
||||
|
||||
|
|
@ -1879,6 +1879,7 @@ _nm_config_state_set (NMConfig *self,
|
|||
|
||||
#define DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE "device"
|
||||
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_MANAGED "managed"
|
||||
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_PERM_HW_ADDR_FAKE "perm-hw-addr-fake"
|
||||
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_CONNECTION_UUID "connection-uuid"
|
||||
|
||||
static NMConfigDeviceStateData *
|
||||
|
|
@ -1887,7 +1888,10 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
|
|||
NMConfigDeviceStateData *device_state;
|
||||
NMConfigDeviceStateManagedType managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN;
|
||||
gs_free char *connection_uuid = NULL;
|
||||
gsize len_plus_1;
|
||||
gs_free char *perm_hw_addr_fake = NULL;
|
||||
gsize connection_uuid_len;
|
||||
gsize perm_hw_addr_fake_len;
|
||||
char *p;
|
||||
|
||||
nm_assert (ifindex > 0);
|
||||
|
||||
|
|
@ -1908,21 +1912,42 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf)
|
|||
DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_CONNECTION_UUID,
|
||||
NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
|
||||
}
|
||||
|
||||
perm_hw_addr_fake = nm_config_keyfile_get_value (kf,
|
||||
DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
|
||||
DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_PERM_HW_ADDR_FAKE,
|
||||
NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
|
||||
if (perm_hw_addr_fake) {
|
||||
char *normalized;
|
||||
|
||||
normalized = nm_utils_hwaddr_canonical (perm_hw_addr_fake, -1);
|
||||
g_free (perm_hw_addr_fake);
|
||||
perm_hw_addr_fake = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
len_plus_1 = connection_uuid ? strlen (connection_uuid) + 1 : 0;
|
||||
connection_uuid_len = connection_uuid ? strlen (connection_uuid) + 1 : 0;
|
||||
perm_hw_addr_fake_len = perm_hw_addr_fake ? strlen (perm_hw_addr_fake) + 1 : 0;
|
||||
|
||||
device_state = g_malloc (sizeof (NMConfigDeviceStateData) + len_plus_1);
|
||||
device_state = g_malloc (sizeof (NMConfigDeviceStateData) +
|
||||
connection_uuid_len +
|
||||
perm_hw_addr_fake_len);
|
||||
|
||||
device_state->ifindex = ifindex;
|
||||
device_state->managed = managed_type;
|
||||
device_state->connection_uuid = NULL;
|
||||
if (connection_uuid) {
|
||||
char *device_state_data;
|
||||
device_state->perm_hw_addr_fake = NULL;
|
||||
|
||||
device_state_data = (char *) (&device_state[1]);
|
||||
memcpy (device_state_data, connection_uuid, len_plus_1);
|
||||
device_state->connection_uuid = device_state_data;
|
||||
p = (char *) (&device_state[1]);
|
||||
if (connection_uuid) {
|
||||
memcpy (p, connection_uuid, connection_uuid_len);
|
||||
device_state->connection_uuid = p;
|
||||
p += connection_uuid_len;
|
||||
}
|
||||
if (perm_hw_addr_fake) {
|
||||
memcpy (p, perm_hw_addr_fake, perm_hw_addr_fake_len);
|
||||
device_state->perm_hw_addr_fake = p;
|
||||
p += perm_hw_addr_fake_len;
|
||||
}
|
||||
|
||||
return device_state;
|
||||
|
|
@ -1943,23 +1968,23 @@ nm_config_device_state_load (NMConfig *self,
|
|||
NMConfigDeviceStateData *device_state;
|
||||
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR) + 60];
|
||||
gs_unref_keyfile GKeyFile *kf = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, NULL);
|
||||
|
||||
nm_sprintf_buf (path, "%s/%d", NM_CONFIG_DEVICE_STATE_DIR, ifindex);
|
||||
|
||||
kf = nm_config_create_keyfile ();
|
||||
if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, &error))
|
||||
if (!g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, NULL))
|
||||
g_clear_pointer (&kf, g_key_file_unref);
|
||||
|
||||
device_state = _config_device_state_data_new (ifindex, kf);
|
||||
|
||||
if (kf) {
|
||||
_LOGT ("device-state: read #%d (%s); managed=%d, connection-uuid=%s%s%s",
|
||||
_LOGT ("device-state: read #%d (%s); managed=%d%s%s%s%s%s%s",
|
||||
ifindex, path,
|
||||
device_state->managed,
|
||||
NM_PRINT_FMT_QUOTE_STRING (device_state->connection_uuid));
|
||||
NM_PRINT_FMT_QUOTED (device_state->connection_uuid, ", connection-uuid=", device_state->connection_uuid, "", ""),
|
||||
NM_PRINT_FMT_QUOTED (device_state->perm_hw_addr_fake, ", perm-hw-addr-fake=", device_state->perm_hw_addr_fake, "", ""));
|
||||
} else {
|
||||
_LOGT ("device-state: read #%d (%s); no persistent state",
|
||||
ifindex, path);
|
||||
|
|
@ -1972,6 +1997,7 @@ gboolean
|
|||
nm_config_device_state_write (NMConfig *self,
|
||||
int ifindex,
|
||||
gboolean managed,
|
||||
const char *perm_hw_addr_fake,
|
||||
const char *connection_uuid)
|
||||
{
|
||||
char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR) + 60];
|
||||
|
|
@ -1983,6 +2009,8 @@ nm_config_device_state_write (NMConfig *self,
|
|||
g_return_val_if_fail (!connection_uuid || *connection_uuid, FALSE);
|
||||
g_return_val_if_fail (managed || !connection_uuid, FALSE);
|
||||
|
||||
nm_assert (!perm_hw_addr_fake || nm_utils_hwaddr_valid (perm_hw_addr_fake, -1));
|
||||
|
||||
nm_sprintf_buf (path, "%s/%d", NM_CONFIG_DEVICE_STATE_DIR, ifindex);
|
||||
|
||||
kf = nm_config_create_keyfile ();
|
||||
|
|
@ -1990,6 +2018,12 @@ nm_config_device_state_write (NMConfig *self,
|
|||
DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
|
||||
DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_MANAGED,
|
||||
!!managed);
|
||||
if (perm_hw_addr_fake) {
|
||||
g_key_file_set_string (kf,
|
||||
DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
|
||||
DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_PERM_HW_ADDR_FAKE,
|
||||
perm_hw_addr_fake);
|
||||
}
|
||||
if (connection_uuid) {
|
||||
g_key_file_set_string (kf,
|
||||
DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
|
||||
|
|
@ -2002,10 +2036,11 @@ nm_config_device_state_write (NMConfig *self,
|
|||
g_error_free (local);
|
||||
return FALSE;
|
||||
}
|
||||
_LOGT ("device-state: write #%d (%s); managed=%d, connection-uuid=%s%s%s",
|
||||
_LOGT ("device-state: write #%d (%s); managed=%d%s%s%s%s%s%s",
|
||||
ifindex, path,
|
||||
(bool) managed,
|
||||
NM_PRINT_FMT_QUOTE_STRING (connection_uuid));
|
||||
NM_PRINT_FMT_QUOTED (connection_uuid, ", connection-uuid=", connection_uuid, "", ""),
|
||||
NM_PRINT_FMT_QUOTED (perm_hw_addr_fake, ", perm-hw-addr-fake=", perm_hw_addr_fake, "", ""));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -199,6 +199,8 @@ struct _NMConfigDeviceStateData {
|
|||
/* the UUID of the last settings-connection active
|
||||
* on the device. */
|
||||
const char *connection_uuid;
|
||||
|
||||
const char *perm_hw_addr_fake;
|
||||
};
|
||||
|
||||
NMConfigDeviceStateData *nm_config_device_state_load (NMConfig *self,
|
||||
|
|
@ -206,6 +208,7 @@ NMConfigDeviceStateData *nm_config_device_state_load (NMConfig *self,
|
|||
gboolean nm_config_device_state_write (NMConfig *self,
|
||||
int ifindex,
|
||||
gboolean managed,
|
||||
const char *perm_hw_addr_fake,
|
||||
const char *connection_uuid);
|
||||
void nm_config_device_state_prune_unseen (NMConfig *self, GHashTable *seen_ifindexes);
|
||||
|
||||
|
|
|
|||
|
|
@ -1272,7 +1272,7 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
|
|||
{
|
||||
const GSList *iter;
|
||||
NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH;
|
||||
guint hwaddr_len = 0;
|
||||
gsize hwaddr_len = 0;
|
||||
guint8 hwaddr_bin[NM_UTILS_HWADDR_LEN_MAX];
|
||||
|
||||
nm_assert (nm_utils_hwaddr_valid (hwaddr, -1));
|
||||
|
|
@ -1297,11 +1297,8 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
|
|||
continue;
|
||||
|
||||
if (G_UNLIKELY (hwaddr_len == 0)) {
|
||||
hwaddr_len = _nm_utils_hwaddr_length (hwaddr);
|
||||
if (!hwaddr_len)
|
||||
if (!_nm_utils_hwaddr_aton (hwaddr, hwaddr_bin, sizeof (hwaddr_bin), &hwaddr_len))
|
||||
g_return_val_if_reached (NM_MATCH_SPEC_NO_MATCH);
|
||||
if (!nm_utils_hwaddr_aton (hwaddr, hwaddr_bin, hwaddr_len))
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr_bin, hwaddr_len)) {
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ find_device_by_permanent_hw_addr (NMManager *manager, const char *hwaddr)
|
|||
|
||||
if (nm_utils_hwaddr_valid (hwaddr, -1)) {
|
||||
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
|
||||
device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data), FALSE);
|
||||
device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data));
|
||||
if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1))
|
||||
return NM_DEVICE (iter->data);
|
||||
}
|
||||
|
|
@ -1331,11 +1331,10 @@ system_unmanaged_devices_changed_cb (NMSettings *settings,
|
|||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
const GSList *unmanaged_specs, *iter;
|
||||
const GSList *iter;
|
||||
|
||||
unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
|
||||
for (iter = priv->devices; iter; iter = g_slist_next (iter))
|
||||
nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data), unmanaged_specs);
|
||||
nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2004,7 +2003,7 @@ add_device (NMManager *self, NMDevice *device, GError **error)
|
|||
type_desc = nm_device_get_type_desc (device);
|
||||
g_assert (type_desc);
|
||||
|
||||
nm_device_set_unmanaged_by_user_settings (device, nm_settings_get_unmanaged_specs (priv->settings));
|
||||
nm_device_set_unmanaged_by_user_settings (device);
|
||||
|
||||
nm_device_set_unmanaged_flags (device,
|
||||
NM_UNMANAGED_SLEEPING,
|
||||
|
|
@ -2880,15 +2879,15 @@ unmanaged_to_disconnected (NMDevice *device)
|
|||
|
||||
if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_UNAVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
NM_DEVICE_STATE_UNAVAILABLE,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
}
|
||||
|
||||
if ( nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST)
|
||||
&& (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) {
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4674,6 +4673,8 @@ nm_manager_write_device_state (NMManager *self)
|
|||
gboolean managed;
|
||||
NMConnection *settings_connection;
|
||||
const char *uuid = NULL;
|
||||
const char *perm_hw_addr_fake = NULL;
|
||||
gboolean perm_hw_addr_is_fake;
|
||||
|
||||
ifindex = nm_device_get_ip_ifindex (device);
|
||||
if (ifindex <= 0)
|
||||
|
|
@ -4693,9 +4694,14 @@ nm_manager_write_device_state (NMManager *self)
|
|||
uuid = nm_connection_get_uuid (settings_connection);
|
||||
}
|
||||
|
||||
perm_hw_addr_fake = nm_device_get_permanent_hw_address_full (device, FALSE, &perm_hw_addr_is_fake);
|
||||
if (perm_hw_addr_fake && !perm_hw_addr_is_fake)
|
||||
perm_hw_addr_fake = NULL;
|
||||
|
||||
if (nm_config_device_state_write (priv->config,
|
||||
ifindex,
|
||||
managed,
|
||||
perm_hw_addr_fake,
|
||||
uuid))
|
||||
g_hash_table_add (seen_ifindexes, GINT_TO_POINTER (ifindex));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1883,7 +1883,7 @@ have_connection_for_device (NMSettings *self, NMDevice *device)
|
|||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
|
||||
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE);
|
||||
perm_hw_addr = nm_device_get_permanent_hw_address (device);
|
||||
|
||||
/* Find a wired connection locked to the given MAC address, if any */
|
||||
g_hash_table_iter_init (&iter, priv->connections);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue