aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2006-03-20 19:54:49 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 19:54:49 -0500
commit073a8e0e154c1c440e0b33aaa887473d5cc843f4 (patch)
treeeb7983e9977b153c3ee67864aca9cc5fedba8194 /net/ipv6
parent955189efb44742890f33c91df478877af25246da (diff)
[IPV6]: ADDRCONF: Split up ipv6_generate_eui64() by device type.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c91
1 files changed, 53 insertions, 38 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index c92f3d6a8f13..8a8895ef09a7 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1299,52 +1299,67 @@ static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
1299 __ipv6_dev_ac_dec(ifp->idev, &addr); 1299 __ipv6_dev_ac_dec(ifp->idev, &addr);
1300} 1300}
1301 1301
1302static int addrconf_ifid_eui48(u8 *eui, struct net_device *dev)
1303{
1304 if (dev->addr_len != ETH_ALEN)
1305 return -1;
1306 memcpy(eui, dev->dev_addr, 3);
1307 memcpy(eui + 5, dev->dev_addr + 3, 3);
1308
1309 /*
1310 * The zSeries OSA network cards can be shared among various
1311 * OS instances, but the OSA cards have only one MAC address.
1312 * This leads to duplicate address conflicts in conjunction
1313 * with IPv6 if more than one instance uses the same card.
1314 *
1315 * The driver for these cards can deliver a unique 16-bit
1316 * identifier for each instance sharing the same card. It is
1317 * placed instead of 0xFFFE in the interface identifier. The
1318 * "u" bit of the interface identifier is not inverted in this
1319 * case. Hence the resulting interface identifier has local
1320 * scope according to RFC2373.
1321 */
1322 if (dev->dev_id) {
1323 eui[3] = (dev->dev_id >> 8) & 0xFF;
1324 eui[4] = dev->dev_id & 0xFF;
1325 } else {
1326 eui[3] = 0xFF;
1327 eui[4] = 0xFE;
1328 eui[0] ^= 2;
1329 }
1330 return 0;
1331}
1332
1333static int addrconf_ifid_arcnet(u8 *eui, struct net_device *dev)
1334{
1335 /* XXX: inherit EUI-64 from other interface -- yoshfuji */
1336 if (dev->addr_len != ARCNET_ALEN)
1337 return -1;
1338 memset(eui, 0, 7);
1339 eui[7] = *(u8*)dev->dev_addr;
1340 return 0;
1341}
1342
1343static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
1344{
1345 if (dev->addr_len != INFINIBAND_ALEN)
1346 return -1;
1347 memcpy(eui, dev->dev_addr + 12, 8);
1348 eui[0] |= 2;
1349 return 0;
1350}
1351
1302static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) 1352static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
1303{ 1353{
1304 switch (dev->type) { 1354 switch (dev->type) {
1305 case ARPHRD_ETHER: 1355 case ARPHRD_ETHER:
1306 case ARPHRD_FDDI: 1356 case ARPHRD_FDDI:
1307 case ARPHRD_IEEE802_TR: 1357 case ARPHRD_IEEE802_TR:
1308 if (dev->addr_len != ETH_ALEN) 1358 return addrconf_ifid_eui48(eui, dev);
1309 return -1;
1310 memcpy(eui, dev->dev_addr, 3);
1311 memcpy(eui + 5, dev->dev_addr + 3, 3);
1312
1313 /*
1314 * The zSeries OSA network cards can be shared among various
1315 * OS instances, but the OSA cards have only one MAC address.
1316 * This leads to duplicate address conflicts in conjunction
1317 * with IPv6 if more than one instance uses the same card.
1318 *
1319 * The driver for these cards can deliver a unique 16-bit
1320 * identifier for each instance sharing the same card. It is
1321 * placed instead of 0xFFFE in the interface identifier. The
1322 * "u" bit of the interface identifier is not inverted in this
1323 * case. Hence the resulting interface identifier has local
1324 * scope according to RFC2373.
1325 */
1326 if (dev->dev_id) {
1327 eui[3] = (dev->dev_id >> 8) & 0xFF;
1328 eui[4] = dev->dev_id & 0xFF;
1329 } else {
1330 eui[3] = 0xFF;
1331 eui[4] = 0xFE;
1332 eui[0] ^= 2;
1333 }
1334 return 0;
1335 case ARPHRD_ARCNET: 1359 case ARPHRD_ARCNET:
1336 /* XXX: inherit EUI-64 from other interface -- yoshfuji */ 1360 return addrconf_ifid_arcnet(eui, dev);
1337 if (dev->addr_len != ARCNET_ALEN)
1338 return -1;
1339 memset(eui, 0, 7);
1340 eui[7] = *(u8*)dev->dev_addr;
1341 return 0;
1342 case ARPHRD_INFINIBAND: 1361 case ARPHRD_INFINIBAND:
1343 if (dev->addr_len != INFINIBAND_ALEN) 1362 return addrconf_ifid_infiniband(eui, dev);
1344 return -1;
1345 memcpy(eui, dev->dev_addr + 12, 8);
1346 eui[0] |= 2;
1347 return 0;
1348 } 1363 }
1349 return -1; 1364 return -1;
1350} 1365}