From e024715f5f6250179a31716a898800a48cf23b39 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 6 May 2007 14:51:13 -0700 Subject: 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 Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/net_kern.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'arch/um') diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 20963f106c3..cd466e30af6 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) #endif } -static void setup_etheraddr(char *str, unsigned char *addr) +static void setup_etheraddr(char *str, unsigned char *addr, char *name) { char *end; int i; @@ -302,15 +302,32 @@ static void setup_etheraddr(char *str, unsigned char *addr) } str = end + 1; } - if(addr[0] & 1){ + if (is_multicast_ether_addr(addr)) { printk(KERN_ERR - "Attempt to assign a broadcast ethernet address to a " + "Attempt to assign a multicast ethernet address to a " "device disallowed\n"); goto random; } + if (!is_valid_ether_addr(addr)) { + printk(KERN_ERR + "Attempt to assign an invalid ethernet address to a " + "device disallowed\n"); + goto random; + } + if (!is_local_ether_addr(addr)) { + printk(KERN_WARNING + "Warning: attempt to assign a globally valid ethernet address to a " + "device\n"); + printk(KERN_WARNING "You should better enable the 2nd rightmost bit " + "in the first byte of the MAC, i.e. " + "%02x:%02x:%02x:%02x:%02x:%02x\n", + addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]); + } return; random: + printk(KERN_INFO + "Choosing a random ethernet address for device %s\n", name); random_ether_addr(addr); } @@ -331,6 +348,7 @@ static void eth_configure(int n, void *init, char *mac, struct net_device *dev; struct uml_net_private *lp; int save, err, size; + char name[sizeof(dev->name)]; size = transport->private_size + sizeof(struct uml_net_private) + sizeof(((struct uml_net_private *) 0)->user); @@ -344,7 +362,13 @@ static void eth_configure(int n, void *init, char *mac, INIT_LIST_HEAD(&device->list); device->index = n; - setup_etheraddr(mac, device->mac); + /* If this name ends up conflicting with an existing registered + * netdevice, that is OK, register_netdev{,ice}() will notice this + * and fail. + */ + snprintf(name, sizeof(name), "eth%d", n); + + setup_etheraddr(mac, device->mac, name); printk(KERN_INFO "Netdevice %d ", n); printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", @@ -375,11 +399,7 @@ static void eth_configure(int n, void *init, char *mac, goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); - /* If this name ends up conflicting with an existing registered - * netdevice, that is OK, register_netdev{,ice}() will notice this - * and fail. - */ - snprintf(dev->name, sizeof(dev->name), "eth%d", n); + strcpy(dev->name, name); device->dev = dev; /* -- cgit v1.2.3