diff options
author | Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> | 2007-05-06 17:51:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-07 15:13:02 -0400 |
commit | e024715f5f6250179a31716a898800a48cf23b39 (patch) | |
tree | 2cba9702be41ff8263d1fb50825f6f17c9f40171 /arch/um/drivers | |
parent | 85ee2ce8ae7d6716beffc84451dd65cd217dbf7a (diff) |
uml: improve checking and diagnostics of ethernet MACs
Improve checking and diagnostics for broadcast and multicast Ethernet MAC
addresses, and distinguish between those cases in output; also make sure the
device is assigned a MAC address valid only locally to avoid collisions.
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/drivers')
-rw-r--r-- | arch/um/drivers/net_kern.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 20963f106c34..cd466e30af67 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -283,7 +283,7 @@ void uml_net_user_timer_expire(unsigned long _conn) | |||
283 | #endif | 283 | #endif |
284 | } | 284 | } |
285 | 285 | ||
286 | static void setup_etheraddr(char *str, unsigned char *addr) | 286 | static void setup_etheraddr(char *str, unsigned char *addr, char *name) |
287 | { | 287 | { |
288 | char *end; | 288 | char *end; |
289 | int i; | 289 | int i; |
@@ -302,15 +302,32 @@ static void setup_etheraddr(char *str, unsigned char *addr) | |||
302 | } | 302 | } |
303 | str = end + 1; | 303 | str = end + 1; |
304 | } | 304 | } |
305 | if(addr[0] & 1){ | 305 | if (is_multicast_ether_addr(addr)) { |
306 | printk(KERN_ERR | 306 | printk(KERN_ERR |
307 | "Attempt to assign a broadcast ethernet address to a " | 307 | "Attempt to assign a multicast ethernet address to a " |
308 | "device disallowed\n"); | 308 | "device disallowed\n"); |
309 | goto random; | 309 | goto random; |
310 | } | 310 | } |
311 | if (!is_valid_ether_addr(addr)) { | ||
312 | printk(KERN_ERR | ||
313 | "Attempt to assign an invalid ethernet address to a " | ||
314 | "device disallowed\n"); | ||
315 | goto random; | ||
316 | } | ||
317 | if (!is_local_ether_addr(addr)) { | ||
318 | printk(KERN_WARNING | ||
319 | "Warning: attempt to assign a globally valid ethernet address to a " | ||
320 | "device\n"); | ||
321 | printk(KERN_WARNING "You should better enable the 2nd rightmost bit " | ||
322 | "in the first byte of the MAC, i.e. " | ||
323 | "%02x:%02x:%02x:%02x:%02x:%02x\n", | ||
324 | addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]); | ||
325 | } | ||
311 | return; | 326 | return; |
312 | 327 | ||
313 | random: | 328 | random: |
329 | printk(KERN_INFO | ||
330 | "Choosing a random ethernet address for device %s\n", name); | ||
314 | random_ether_addr(addr); | 331 | random_ether_addr(addr); |
315 | } | 332 | } |
316 | 333 | ||
@@ -331,6 +348,7 @@ static void eth_configure(int n, void *init, char *mac, | |||
331 | struct net_device *dev; | 348 | struct net_device *dev; |
332 | struct uml_net_private *lp; | 349 | struct uml_net_private *lp; |
333 | int save, err, size; | 350 | int save, err, size; |
351 | char name[sizeof(dev->name)]; | ||
334 | 352 | ||
335 | size = transport->private_size + sizeof(struct uml_net_private) + | 353 | size = transport->private_size + sizeof(struct uml_net_private) + |
336 | sizeof(((struct uml_net_private *) 0)->user); | 354 | sizeof(((struct uml_net_private *) 0)->user); |
@@ -344,7 +362,13 @@ static void eth_configure(int n, void *init, char *mac, | |||
344 | INIT_LIST_HEAD(&device->list); | 362 | INIT_LIST_HEAD(&device->list); |
345 | device->index = n; | 363 | device->index = n; |
346 | 364 | ||
347 | setup_etheraddr(mac, device->mac); | 365 | /* If this name ends up conflicting with an existing registered |
366 | * netdevice, that is OK, register_netdev{,ice}() will notice this | ||
367 | * and fail. | ||
368 | */ | ||
369 | snprintf(name, sizeof(name), "eth%d", n); | ||
370 | |||
371 | setup_etheraddr(mac, device->mac, name); | ||
348 | 372 | ||
349 | printk(KERN_INFO "Netdevice %d ", n); | 373 | printk(KERN_INFO "Netdevice %d ", n); |
350 | printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", | 374 | printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", |
@@ -375,11 +399,7 @@ static void eth_configure(int n, void *init, char *mac, | |||
375 | goto out_free_netdev; | 399 | goto out_free_netdev; |
376 | SET_NETDEV_DEV(dev,&device->pdev.dev); | 400 | SET_NETDEV_DEV(dev,&device->pdev.dev); |
377 | 401 | ||
378 | /* If this name ends up conflicting with an existing registered | 402 | strcpy(dev->name, name); |
379 | * netdevice, that is OK, register_netdev{,ice}() will notice this | ||
380 | * and fail. | ||
381 | */ | ||
382 | snprintf(dev->name, sizeof(dev->name), "eth%d", n); | ||
383 | device->dev = dev; | 403 | device->dev = dev; |
384 | 404 | ||
385 | /* | 405 | /* |