Commit c1f79426 authored by Stefan Assmann's avatar Stefan Assmann Committed by David S. Miller

sysfs: add attribute to indicate hw address assignment type

Add addr_assign_type to struct net_device and expose it via sysfs.
This new attribute has the purpose of giving user-space the ability to
distinguish between different assignment types of MAC addresses.

For example user-space can treat NICs with randomly generated MAC
addresses differently than NICs that have permanent (locally assigned)
MAC addresses.
For the former udev could write a persistent net rule by matching the
device path instead of the MAC address.
There's also the case of devices that 'steal' MAC addresses from slave
devices. In which it is also be beneficial for user-space to be aware
of the fact.

This patch also introduces a helper function to assist adoption of
drivers that generate MAC addresses randomly.
Signed-off-by: default avatarStefan Assmann <sassmann@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 55bad823
...@@ -126,6 +126,20 @@ static inline void random_ether_addr(u8 *addr) ...@@ -126,6 +126,20 @@ static inline void random_ether_addr(u8 *addr)
addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
} }
/**
* dev_hw_addr_random - Create random MAC and set device flag
* @dev: pointer to net_device structure
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Generate random MAC to be used by a device and set addr_assign_type
* so the state can be read by sysfs and be used by udev.
*/
static inline void dev_hw_addr_random(struct net_device *dev, u8 *hwaddr)
{
dev->addr_assign_type |= NET_ADDR_RANDOM;
random_ether_addr(hwaddr);
}
/** /**
* compare_ether_addr - Compare two Ethernet addresses * compare_ether_addr - Compare two Ethernet addresses
* @addr1: Pointer to a six-byte array containing the Ethernet address * @addr1: Pointer to a six-byte array containing the Ethernet address
......
...@@ -66,6 +66,11 @@ struct wireless_dev; ...@@ -66,6 +66,11 @@ struct wireless_dev;
#define HAVE_FREE_NETDEV /* free_netdev() */ #define HAVE_FREE_NETDEV /* free_netdev() */
#define HAVE_NETDEV_PRIV /* netdev_priv() */ #define HAVE_NETDEV_PRIV /* netdev_priv() */
/* hardware address assignment types */
#define NET_ADDR_PERM 0 /* address is permanent (default) */
#define NET_ADDR_RANDOM 1 /* address is generated randomly */
#define NET_ADDR_STOLEN 2 /* address is stolen from other device */
/* Backlog congestion levels */ /* Backlog congestion levels */
#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */ #define NET_RX_SUCCESS 0 /* keep 'em coming, baby */
#define NET_RX_DROP 1 /* packet dropped */ #define NET_RX_DROP 1 /* packet dropped */
...@@ -919,6 +924,7 @@ struct net_device { ...@@ -919,6 +924,7 @@ struct net_device {
/* Interface address info. */ /* Interface address info. */
unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
unsigned char addr_assign_type; /* hw address assignment type */
unsigned char addr_len; /* hardware address length */ unsigned char addr_len; /* hardware address length */
unsigned short dev_id; /* for shared network cards */ unsigned short dev_id; /* for shared network cards */
......
...@@ -95,6 +95,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, ...@@ -95,6 +95,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
} }
NETDEVICE_SHOW(dev_id, fmt_hex); NETDEVICE_SHOW(dev_id, fmt_hex);
NETDEVICE_SHOW(addr_assign_type, fmt_dec);
NETDEVICE_SHOW(addr_len, fmt_dec); NETDEVICE_SHOW(addr_len, fmt_dec);
NETDEVICE_SHOW(iflink, fmt_dec); NETDEVICE_SHOW(iflink, fmt_dec);
NETDEVICE_SHOW(ifindex, fmt_dec); NETDEVICE_SHOW(ifindex, fmt_dec);
...@@ -295,6 +296,7 @@ static ssize_t show_ifalias(struct device *dev, ...@@ -295,6 +296,7 @@ static ssize_t show_ifalias(struct device *dev,
} }
static struct device_attribute net_class_attributes[] = { static struct device_attribute net_class_attributes[] = {
__ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL),
__ATTR(addr_len, S_IRUGO, show_addr_len, NULL), __ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
__ATTR(dev_id, S_IRUGO, show_dev_id, NULL), __ATTR(dev_id, S_IRUGO, show_dev_id, NULL),
__ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias),
......
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