mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-26 07:20:26 +01:00
core: use dev_id when calculating the interface IPv6 IID (rh #1101809)
Some device types (s390 OSA and ipvlan) can use the same link-layer address for multiple virtual interfaces, and the kernel used the dev_id property to differentiate these devices when constructing the IID. NM should do this too to prevent IID clashes. https://bugzilla.redhat.com/show_bug.cgi?id=1101809
This commit is contained in:
parent
51fd5a9bd7
commit
c4b9f397c8
3 changed files with 18 additions and 4 deletions
|
|
@ -2313,6 +2313,7 @@ get_gre_eui64_u_bit (guint32 addr)
|
|||
* @link_type: the hardware link type
|
||||
* @hwaddr: the hardware address of the interface
|
||||
* @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
|
||||
* zeroed out
|
||||
*
|
||||
|
|
@ -2327,6 +2328,7 @@ gboolean
|
|||
nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
||||
const guint8 *hwaddr,
|
||||
guint hwaddr_len,
|
||||
guint dev_id,
|
||||
NMUtilsIPv6IfaceId *out_iid)
|
||||
{
|
||||
guint32 addr;
|
||||
|
|
@ -2361,13 +2363,20 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
|||
default:
|
||||
if (hwaddr_len == ETH_ALEN) {
|
||||
/* 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[2] = hwaddr[2];
|
||||
out_iid->id_u8[3] = 0xff;
|
||||
out_iid->id_u8[4] = 0xfe;
|
||||
if (dev_id) {
|
||||
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[6] = hwaddr[4];
|
||||
out_iid->id_u8[7] = hwaddr[5];
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ typedef struct {
|
|||
gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
|
||||
const guint8 *hwaddr,
|
||||
guint len,
|
||||
guint dev_id,
|
||||
NMUtilsIPv6IfaceId *out_iid);
|
||||
|
||||
void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr,
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ typedef struct {
|
|||
char * hw_addr;
|
||||
guint hw_addr_len;
|
||||
char * physical_port_id;
|
||||
guint dev_id;
|
||||
|
||||
NMUnmanagedFlags unmanaged_flags;
|
||||
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
|
||||
get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMLinkType link_type;
|
||||
const guint8 *hwaddr = NULL;
|
||||
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,
|
||||
hwaddr,
|
||||
hwaddr_len,
|
||||
priv->dev_id,
|
||||
out_iid);
|
||||
if (!success) {
|
||||
_LOGW (LOGD_HW, "failed to generate interface identifier "
|
||||
|
|
@ -8304,6 +8307,7 @@ constructed (GObject *object)
|
|||
if (priv->ifindex > 0) {
|
||||
priv->is_software = nm_platform_link_is_software (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);
|
||||
}
|
||||
/* Indicate software device in capabilities. */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue