mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 16:58:02 +02:00
merge: use dev_id when constructing interface identifiers (rh #1101809)
Some devices (s390 and ipvlan) use the same MAC address for different interfaces, but dev_id differentiates them. So we must use dev_id to avoid IID conflicts. https://bugzilla.redhat.com/show_bug.cgi?id=1101809
This commit is contained in:
commit
4df69a5576
7 changed files with 85 additions and 6 deletions
|
|
@ -2313,6 +2313,7 @@ get_gre_eui64_u_bit (guint32 addr)
|
||||||
* @link_type: the hardware link type
|
* @link_type: the hardware link type
|
||||||
* @hwaddr: the hardware address of the interface
|
* @hwaddr: the hardware address of the interface
|
||||||
* @hwaddr_len: the length (in bytes) of @hwaddr
|
* @hwaddr_len: the length (in bytes) of @hwaddr
|
||||||
|
* @dev_id: the device identifier, if any
|
||||||
* @out_iid: on success, filled with the interface identifier; on failure
|
* @out_iid: on success, filled with the interface identifier; on failure
|
||||||
* zeroed out
|
* zeroed out
|
||||||
*
|
*
|
||||||
|
|
@ -2327,6 +2328,7 @@ gboolean
|
||||||
nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
||||||
const guint8 *hwaddr,
|
const guint8 *hwaddr,
|
||||||
guint hwaddr_len,
|
guint hwaddr_len,
|
||||||
|
guint dev_id,
|
||||||
NMUtilsIPv6IfaceId *out_iid)
|
NMUtilsIPv6IfaceId *out_iid)
|
||||||
{
|
{
|
||||||
guint32 addr;
|
guint32 addr;
|
||||||
|
|
@ -2361,13 +2363,20 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
||||||
default:
|
default:
|
||||||
if (hwaddr_len == ETH_ALEN) {
|
if (hwaddr_len == ETH_ALEN) {
|
||||||
/* Translate 48-bit MAC address to a 64-bit Modified EUI-64. See
|
/* Translate 48-bit MAC address to a 64-bit Modified EUI-64. See
|
||||||
* http://tools.ietf.org/html/rfc4291#appendix-A
|
* http://tools.ietf.org/html/rfc4291#appendix-A and the Linux
|
||||||
|
* kernel's net/ipv6/addrconf.c::ipv6_generate_eui64() function.
|
||||||
*/
|
*/
|
||||||
out_iid->id_u8[0] = hwaddr[0] ^ 0x02;
|
out_iid->id_u8[0] = hwaddr[0];
|
||||||
out_iid->id_u8[1] = hwaddr[1];
|
out_iid->id_u8[1] = hwaddr[1];
|
||||||
out_iid->id_u8[2] = hwaddr[2];
|
out_iid->id_u8[2] = hwaddr[2];
|
||||||
out_iid->id_u8[3] = 0xff;
|
if (dev_id) {
|
||||||
out_iid->id_u8[4] = 0xfe;
|
out_iid->id_u8[3] = (dev_id >> 8) & 0xff;
|
||||||
|
out_iid->id_u8[4] = dev_id & 0xff;
|
||||||
|
} else {
|
||||||
|
out_iid->id_u8[0] ^= 0x02;
|
||||||
|
out_iid->id_u8[3] = 0xff;
|
||||||
|
out_iid->id_u8[4] = 0xfe;
|
||||||
|
}
|
||||||
out_iid->id_u8[5] = hwaddr[3];
|
out_iid->id_u8[5] = hwaddr[3];
|
||||||
out_iid->id_u8[6] = hwaddr[4];
|
out_iid->id_u8[6] = hwaddr[4];
|
||||||
out_iid->id_u8[7] = hwaddr[5];
|
out_iid->id_u8[7] = hwaddr[5];
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,7 @@ typedef struct {
|
||||||
gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
||||||
const guint8 *hwaddr,
|
const guint8 *hwaddr,
|
||||||
guint len,
|
guint len,
|
||||||
|
guint dev_id,
|
||||||
NMUtilsIPv6IfaceId *out_iid);
|
NMUtilsIPv6IfaceId *out_iid);
|
||||||
|
|
||||||
void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr,
|
void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr,
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,7 @@ typedef struct {
|
||||||
char * hw_addr;
|
char * hw_addr;
|
||||||
guint hw_addr_len;
|
guint hw_addr_len;
|
||||||
char * physical_port_id;
|
char * physical_port_id;
|
||||||
|
guint dev_id;
|
||||||
|
|
||||||
NMUnmanagedFlags unmanaged_flags;
|
NMUnmanagedFlags unmanaged_flags;
|
||||||
gboolean is_nm_owned; /* whether the device is a device owned and created by NM */
|
gboolean is_nm_owned; /* whether the device is a device owned and created by NM */
|
||||||
|
|
@ -593,6 +594,7 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface)
|
||||||
static gboolean
|
static gboolean
|
||||||
get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
|
get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
|
||||||
{
|
{
|
||||||
|
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||||
NMLinkType link_type;
|
NMLinkType link_type;
|
||||||
const guint8 *hwaddr = NULL;
|
const guint8 *hwaddr = NULL;
|
||||||
size_t hwaddr_len = 0;
|
size_t hwaddr_len = 0;
|
||||||
|
|
@ -613,6 +615,7 @@ get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
|
||||||
success = nm_utils_get_ipv6_interface_identifier (link_type,
|
success = nm_utils_get_ipv6_interface_identifier (link_type,
|
||||||
hwaddr,
|
hwaddr,
|
||||||
hwaddr_len,
|
hwaddr_len,
|
||||||
|
priv->dev_id,
|
||||||
out_iid);
|
out_iid);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
_LOGW (LOGD_HW, "failed to generate interface identifier "
|
_LOGW (LOGD_HW, "failed to generate interface identifier "
|
||||||
|
|
@ -8304,6 +8307,7 @@ constructed (GObject *object)
|
||||||
if (priv->ifindex > 0) {
|
if (priv->ifindex > 0) {
|
||||||
priv->is_software = nm_platform_link_is_software (priv->ifindex);
|
priv->is_software = nm_platform_link_is_software (priv->ifindex);
|
||||||
priv->physical_port_id = nm_platform_link_get_physical_port_id (priv->ifindex);
|
priv->physical_port_id = nm_platform_link_get_physical_port_id (priv->ifindex);
|
||||||
|
priv->dev_id = nm_platform_link_get_dev_id (priv->ifindex);
|
||||||
priv->mtu = nm_platform_link_get_mtu (priv->ifindex);
|
priv->mtu = nm_platform_link_get_mtu (priv->ifindex);
|
||||||
}
|
}
|
||||||
/* Indicate software device in capabilities. */
|
/* Indicate software device in capabilities. */
|
||||||
|
|
|
||||||
|
|
@ -456,6 +456,15 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
link_get_dev_id (NMPlatform *platform, int ifindex)
|
||||||
|
{
|
||||||
|
/* We call link_get just to cause an error to be set if @ifindex is bad. */
|
||||||
|
link_get (platform, ifindex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
link_get_wake_on_lan (NMPlatform *platform, int ifindex)
|
link_get_wake_on_lan (NMPlatform *platform, int ifindex)
|
||||||
{
|
{
|
||||||
|
|
@ -1309,6 +1318,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
|
||||||
platform_class->link_set_mtu = link_set_mtu;
|
platform_class->link_set_mtu = link_set_mtu;
|
||||||
|
|
||||||
platform_class->link_get_physical_port_id = link_get_physical_port_id;
|
platform_class->link_get_physical_port_id = link_get_physical_port_id;
|
||||||
|
platform_class->link_get_dev_id = link_get_dev_id;
|
||||||
platform_class->link_get_wake_on_lan = link_get_wake_on_lan;
|
platform_class->link_get_wake_on_lan = link_get_wake_on_lan;
|
||||||
|
|
||||||
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
||||||
|
|
|
||||||
|
|
@ -2707,6 +2707,30 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
link_get_dev_id (NMPlatform *platform, int ifindex)
|
||||||
|
{
|
||||||
|
const char *ifname;
|
||||||
|
gs_free char *path = NULL, *id = NULL;
|
||||||
|
gint64 int_val;
|
||||||
|
|
||||||
|
ifname = nm_platform_link_get_name (ifindex);
|
||||||
|
if (!ifname)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ifname = ASSERT_VALID_PATH_COMPONENT (ifname);
|
||||||
|
|
||||||
|
path = g_strdup_printf ("/sys/class/net/%s/dev_id", ifname);
|
||||||
|
id = sysctl_get (platform, path);
|
||||||
|
if (!id || !*id)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Value is reported as hex */
|
||||||
|
int_val = nm_utils_ascii_str_to_int64 (id, 16, 0, G_MAXUINT16, 0);
|
||||||
|
|
||||||
|
return errno ? 0 : (int) int_val;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint32 vlan_flags)
|
vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint32 vlan_flags)
|
||||||
{
|
{
|
||||||
|
|
@ -4554,6 +4578,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
||||||
platform_class->link_set_mtu = link_set_mtu;
|
platform_class->link_set_mtu = link_set_mtu;
|
||||||
|
|
||||||
platform_class->link_get_physical_port_id = link_get_physical_port_id;
|
platform_class->link_get_physical_port_id = link_get_physical_port_id;
|
||||||
|
platform_class->link_get_dev_id = link_get_dev_id;
|
||||||
platform_class->link_get_wake_on_lan = link_get_wake_on_lan;
|
platform_class->link_get_wake_on_lan = link_get_wake_on_lan;
|
||||||
|
|
||||||
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
platform_class->link_supports_carrier_detect = link_supports_carrier_detect;
|
||||||
|
|
|
||||||
|
|
@ -963,9 +963,15 @@ nm_platform_link_get_mtu (int ifindex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_platform_link_get_mtu:
|
* nm_platform_link_get_physical_port_id:
|
||||||
* @ifindex: Interface index
|
* @ifindex: Interface index
|
||||||
*
|
*
|
||||||
|
* The physical port ID, if present, indicates some unique identifier of
|
||||||
|
* the parent interface (eg, the physical port of which this link is a child).
|
||||||
|
* Two links that report the same physical port ID can be assumed to be
|
||||||
|
* children of the same physical port and may share resources that limit
|
||||||
|
* their abilities.
|
||||||
|
*
|
||||||
* Returns: physical port ID for the interface, or %NULL on error
|
* Returns: physical port ID for the interface, or %NULL on error
|
||||||
* or if the interface has no physical port ID.
|
* or if the interface has no physical port ID.
|
||||||
*/
|
*/
|
||||||
|
|
@ -980,6 +986,28 @@ nm_platform_link_get_physical_port_id (int ifindex)
|
||||||
return klass->link_get_physical_port_id (platform, ifindex);
|
return klass->link_get_physical_port_id (platform, ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_platform_link_get_dev_id:
|
||||||
|
* @ifindex: Interface index
|
||||||
|
*
|
||||||
|
* In contrast to the physical device ID (which indicates which parent a
|
||||||
|
* child has) the device ID differentiates sibling devices that may share
|
||||||
|
* the same MAC address.
|
||||||
|
*
|
||||||
|
* Returns: device ID for the interface, or 0 on error or if the
|
||||||
|
* interface has no device ID.
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
nm_platform_link_get_dev_id (int ifindex)
|
||||||
|
{
|
||||||
|
reset_error ();
|
||||||
|
|
||||||
|
g_return_val_if_fail (ifindex >= 0, 0);
|
||||||
|
g_return_val_if_fail (klass->link_get_dev_id, 0);
|
||||||
|
|
||||||
|
return klass->link_get_dev_id (platform, ifindex);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_platform_link_get_wake_onlan:
|
* nm_platform_link_get_wake_onlan:
|
||||||
* @ifindex: Interface index
|
* @ifindex: Interface index
|
||||||
|
|
|
||||||
|
|
@ -370,7 +370,8 @@ typedef struct {
|
||||||
guint32 (*link_get_mtu) (NMPlatform *, int ifindex);
|
guint32 (*link_get_mtu) (NMPlatform *, int ifindex);
|
||||||
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
|
gboolean (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu);
|
||||||
|
|
||||||
char * (*link_get_physical_port_id) (NMPlatform *, int ifindex);
|
char * (*link_get_physical_port_id) (NMPlatform *, int ifindex);
|
||||||
|
guint (*link_get_dev_id) (NMPlatform *, int ifindex);
|
||||||
gboolean (*link_get_wake_on_lan) (NMPlatform *, int ifindex);
|
gboolean (*link_get_wake_on_lan) (NMPlatform *, int ifindex);
|
||||||
|
|
||||||
gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex);
|
gboolean (*link_supports_carrier_detect) (NMPlatform *, int ifindex);
|
||||||
|
|
@ -517,6 +518,7 @@ guint32 nm_platform_link_get_mtu (int ifindex);
|
||||||
gboolean nm_platform_link_set_mtu (int ifindex, guint32 mtu);
|
gboolean nm_platform_link_set_mtu (int ifindex, guint32 mtu);
|
||||||
|
|
||||||
char *nm_platform_link_get_physical_port_id (int ifindex);
|
char *nm_platform_link_get_physical_port_id (int ifindex);
|
||||||
|
guint nm_platform_link_get_dev_id (int ifindex);
|
||||||
gboolean nm_platform_link_get_wake_on_lan (int ifindex);
|
gboolean nm_platform_link_get_wake_on_lan (int ifindex);
|
||||||
|
|
||||||
gboolean nm_platform_link_supports_carrier_detect (int ifindex);
|
gboolean nm_platform_link_supports_carrier_detect (int ifindex);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue