Commit b74ac55d authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller

[IPV6]: Fix EUI64 generation on S/390.

 - put a dev_id field in struct net_device, so that it uses space that
   would be wasted by padding otherwise.
 - if this fields is non-null let ipv6_generate_eui64 use the algorithm
   from the QETH code to generate an EUI that's different for each
   OS instance.  See code comments for details.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 86679f6f
...@@ -5033,27 +5033,6 @@ qeth_neigh_setup(struct net_device *dev, struct neigh_parms *np) ...@@ -5033,27 +5033,6 @@ qeth_neigh_setup(struct net_device *dev, struct neigh_parms *np)
return 0; return 0;
} }
#ifdef CONFIG_QETH_IPV6
int
qeth_ipv6_generate_eui64(u8 * eui, struct net_device *dev)
{
switch (dev->type) {
case ARPHRD_ETHER:
case ARPHRD_FDDI:
case ARPHRD_IEEE802_TR:
if (dev->addr_len != ETH_ALEN)
return -1;
memcpy(eui, dev->dev_addr, 3);
memcpy(eui + 5, dev->dev_addr + 3, 3);
eui[3] = (dev->dev_id >> 8) & 0xff;
eui[4] = dev->dev_id & 0xff;
return 0;
}
return -1;
}
#endif
static void static void
qeth_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev) qeth_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
{ {
...@@ -5587,11 +5566,8 @@ qeth_netdev_init(struct net_device *dev) ...@@ -5587,11 +5566,8 @@ qeth_netdev_init(struct net_device *dev)
} }
#ifdef CONFIG_QETH_IPV6 #ifdef CONFIG_QETH_IPV6
/*IPv6 address autoconfiguration stuff*/ /*IPv6 address autoconfiguration stuff*/
card->dev->dev_id = card->info.unique_id & 0xffff;
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
card->dev->generate_eui64 = qeth_ipv6_generate_eui64; card->dev->dev_id = card->info.unique_id & 0xffff;
#endif #endif
dev->hard_header_parse = NULL; dev->hard_header_parse = NULL;
dev->set_mac_address = qeth_layer2_set_mac_address; dev->set_mac_address = qeth_layer2_set_mac_address;
......
...@@ -345,6 +345,7 @@ struct net_device ...@@ -345,6 +345,7 @@ struct net_device
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */ unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
unsigned char addr_len; /* hardware address length */ unsigned char addr_len; /* hardware address length */
unsigned short dev_id; /* for shared network cards */
struct dev_mc_list *mc_list; /* Multicast mac addresses */ struct dev_mc_list *mc_list; /* Multicast mac addresses */
int mc_count; /* Number of installed mcasts */ int mc_count; /* Number of installed mcasts */
......
...@@ -1079,10 +1079,29 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) ...@@ -1079,10 +1079,29 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
if (dev->addr_len != ETH_ALEN) if (dev->addr_len != ETH_ALEN)
return -1; return -1;
memcpy(eui, dev->dev_addr, 3); memcpy(eui, dev->dev_addr, 3);
memcpy(eui + 5, dev->dev_addr+3, 3); memcpy(eui + 5, dev->dev_addr + 3, 3);
/*
* The zSeries OSA network cards can be shared among various
* OS instances, but the OSA cards have only one MAC address.
* This leads to duplicate address conflicts in conjunction
* with IPv6 if more than one instance uses the same card.
*
* The driver for these cards can deliver a unique 16-bit
* identifier for each instance sharing the same card. It is
* placed instead of 0xFFFE in the interface identifier. The
* "u" bit of the interface identifier is not inverted in this
* case. Hence the resulting interface identifier has local
* scope according to RFC2373.
*/
if (dev->dev_id) {
eui[3] = (dev->dev_id >> 8) & 0xFF;
eui[4] = dev->dev_id & 0xFF;
} else {
eui[3] = 0xFF; eui[3] = 0xFF;
eui[4] = 0xFE; eui[4] = 0xFE;
eui[0] ^= 2; eui[0] ^= 2;
}
return 0; return 0;
case ARPHRD_ARCNET: case ARPHRD_ARCNET:
/* XXX: inherit EUI-64 from other interface -- yoshfuji */ /* XXX: inherit EUI-64 from other interface -- yoshfuji */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment