diff options
Diffstat (limited to 'include/linux/etherdevice.h')
| -rw-r--r-- | include/linux/etherdevice.h | 132 |
1 files changed, 38 insertions, 94 deletions
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 243eea1e33d..05955cf0993 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | * as published by the Free Software Foundation; either version | 18 | * as published by the Free Software Foundation; either version |
| 19 | * 2 of the License, or (at your option) any later version. | 19 | * 2 of the License, or (at your option) any later version. |
| 20 | * | 20 | * |
| 21 | * WARNING: This move may well be temporary. This file will get merged with others RSN. | ||
| 22 | * | ||
| 21 | */ | 23 | */ |
| 22 | #ifndef _LINUX_ETHERDEVICE_H | 24 | #ifndef _LINUX_ETHERDEVICE_H |
| 23 | #define _LINUX_ETHERDEVICE_H | 25 | #define _LINUX_ETHERDEVICE_H |
| @@ -51,33 +53,13 @@ extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, | |||
| 51 | #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) | 53 | #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) |
| 52 | #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) | 54 | #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) |
| 53 | 55 | ||
| 54 | /* Reserved Ethernet Addresses per IEEE 802.1Q */ | ||
| 55 | static const u8 eth_reserved_addr_base[ETH_ALEN] __aligned(2) = | ||
| 56 | { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; | ||
| 57 | |||
| 58 | /** | ||
| 59 | * is_link_local_ether_addr - Determine if given Ethernet address is link-local | ||
| 60 | * @addr: Pointer to a six-byte array containing the Ethernet address | ||
| 61 | * | ||
| 62 | * Return true if address is link local reserved addr (01:80:c2:00:00:0X) per | ||
| 63 | * IEEE 802.1Q 8.6.3 Frame filtering. | ||
| 64 | */ | ||
| 65 | static inline bool is_link_local_ether_addr(const u8 *addr) | ||
| 66 | { | ||
| 67 | __be16 *a = (__be16 *)addr; | ||
| 68 | static const __be16 *b = (const __be16 *)eth_reserved_addr_base; | ||
| 69 | static const __be16 m = cpu_to_be16(0xfff0); | ||
| 70 | |||
| 71 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | 56 | /** |
| 75 | * is_zero_ether_addr - Determine if give Ethernet address is all zeros. | 57 | * is_zero_ether_addr - Determine if give Ethernet address is all zeros. |
| 76 | * @addr: Pointer to a six-byte array containing the Ethernet address | 58 | * @addr: Pointer to a six-byte array containing the Ethernet address |
| 77 | * | 59 | * |
| 78 | * Return true if the address is all zeroes. | 60 | * Return true if the address is all zeroes. |
| 79 | */ | 61 | */ |
| 80 | static inline bool is_zero_ether_addr(const u8 *addr) | 62 | static inline int is_zero_ether_addr(const u8 *addr) |
| 81 | { | 63 | { |
| 82 | return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); | 64 | return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]); |
| 83 | } | 65 | } |
| @@ -89,7 +71,7 @@ static inline bool is_zero_ether_addr(const u8 *addr) | |||
| 89 | * Return true if the address is a multicast address. | 71 | * Return true if the address is a multicast address. |
| 90 | * By definition the broadcast address is also a multicast address. | 72 | * By definition the broadcast address is also a multicast address. |
| 91 | */ | 73 | */ |
| 92 | static inline bool is_multicast_ether_addr(const u8 *addr) | 74 | static inline int is_multicast_ether_addr(const u8 *addr) |
| 93 | { | 75 | { |
| 94 | return 0x01 & addr[0]; | 76 | return 0x01 & addr[0]; |
| 95 | } | 77 | } |
| @@ -100,7 +82,7 @@ static inline bool is_multicast_ether_addr(const u8 *addr) | |||
| 100 | * | 82 | * |
| 101 | * Return true if the address is a local address. | 83 | * Return true if the address is a local address. |
| 102 | */ | 84 | */ |
| 103 | static inline bool is_local_ether_addr(const u8 *addr) | 85 | static inline int is_local_ether_addr(const u8 *addr) |
| 104 | { | 86 | { |
| 105 | return 0x02 & addr[0]; | 87 | return 0x02 & addr[0]; |
| 106 | } | 88 | } |
| @@ -111,7 +93,7 @@ static inline bool is_local_ether_addr(const u8 *addr) | |||
| 111 | * | 93 | * |
| 112 | * Return true if the address is the broadcast address. | 94 | * Return true if the address is the broadcast address. |
| 113 | */ | 95 | */ |
| 114 | static inline bool is_broadcast_ether_addr(const u8 *addr) | 96 | static inline int is_broadcast_ether_addr(const u8 *addr) |
| 115 | { | 97 | { |
| 116 | return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff; | 98 | return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff; |
| 117 | } | 99 | } |
| @@ -122,7 +104,7 @@ static inline bool is_broadcast_ether_addr(const u8 *addr) | |||
| 122 | * | 104 | * |
| 123 | * Return true if the address is a unicast address. | 105 | * Return true if the address is a unicast address. |
| 124 | */ | 106 | */ |
| 125 | static inline bool is_unicast_ether_addr(const u8 *addr) | 107 | static inline int is_unicast_ether_addr(const u8 *addr) |
| 126 | { | 108 | { |
| 127 | return !is_multicast_ether_addr(addr); | 109 | return !is_multicast_ether_addr(addr); |
| 128 | } | 110 | } |
| @@ -136,7 +118,7 @@ static inline bool is_unicast_ether_addr(const u8 *addr) | |||
| 136 | * | 118 | * |
| 137 | * Return true if the address is valid. | 119 | * Return true if the address is valid. |
| 138 | */ | 120 | */ |
| 139 | static inline bool is_valid_ether_addr(const u8 *addr) | 121 | static inline int is_valid_ether_addr(const u8 *addr) |
| 140 | { | 122 | { |
| 141 | /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to | 123 | /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to |
| 142 | * explicitly check for it here. */ | 124 | * explicitly check for it here. */ |
| @@ -144,56 +126,31 @@ static inline bool is_valid_ether_addr(const u8 *addr) | |||
| 144 | } | 126 | } |
| 145 | 127 | ||
| 146 | /** | 128 | /** |
| 147 | * eth_random_addr - Generate software assigned random Ethernet address | 129 | * random_ether_addr - Generate software assigned random Ethernet address |
| 148 | * @addr: Pointer to a six-byte array containing the Ethernet address | 130 | * @addr: Pointer to a six-byte array containing the Ethernet address |
| 149 | * | 131 | * |
| 150 | * Generate a random Ethernet address (MAC) that is not multicast | 132 | * Generate a random Ethernet address (MAC) that is not multicast |
| 151 | * and has the local assigned bit set. | 133 | * and has the local assigned bit set. |
| 152 | */ | 134 | */ |
| 153 | static inline void eth_random_addr(u8 *addr) | 135 | static inline void random_ether_addr(u8 *addr) |
| 154 | { | ||
| 155 | get_random_bytes(addr, ETH_ALEN); | ||
| 156 | addr[0] &= 0xfe; /* clear multicast bit */ | ||
| 157 | addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ | ||
| 158 | } | ||
| 159 | |||
| 160 | #define random_ether_addr(addr) eth_random_addr(addr) | ||
| 161 | |||
| 162 | /** | ||
| 163 | * eth_broadcast_addr - Assign broadcast address | ||
| 164 | * @addr: Pointer to a six-byte array containing the Ethernet address | ||
| 165 | * | ||
| 166 | * Assign the broadcast address to the given address array. | ||
| 167 | */ | ||
| 168 | static inline void eth_broadcast_addr(u8 *addr) | ||
| 169 | { | 136 | { |
| 170 | memset(addr, 0xff, ETH_ALEN); | 137 | get_random_bytes (addr, ETH_ALEN); |
| 138 | addr [0] &= 0xfe; /* clear multicast bit */ | ||
| 139 | addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ | ||
| 171 | } | 140 | } |
| 172 | 141 | ||
| 173 | /** | 142 | /** |
| 174 | * eth_zero_addr - Assign zero address | 143 | * dev_hw_addr_random - Create random MAC and set device flag |
| 175 | * @addr: Pointer to a six-byte array containing the Ethernet address | ||
| 176 | * | ||
| 177 | * Assign the zero address to the given address array. | ||
| 178 | */ | ||
| 179 | static inline void eth_zero_addr(u8 *addr) | ||
| 180 | { | ||
| 181 | memset(addr, 0x00, ETH_ALEN); | ||
| 182 | } | ||
| 183 | |||
| 184 | /** | ||
| 185 | * eth_hw_addr_random - Generate software assigned random Ethernet and | ||
| 186 | * set device flag | ||
| 187 | * @dev: pointer to net_device structure | 144 | * @dev: pointer to net_device structure |
| 145 | * @hwaddr: Pointer to a six-byte array containing the Ethernet address | ||
| 188 | * | 146 | * |
| 189 | * Generate a random Ethernet address (MAC) to be used by a net device | 147 | * Generate random MAC to be used by a device and set addr_assign_type |
| 190 | * and set addr_assign_type so the state can be read by sysfs and be | 148 | * so the state can be read by sysfs and be used by udev. |
| 191 | * used by userspace. | ||
| 192 | */ | 149 | */ |
| 193 | static inline void eth_hw_addr_random(struct net_device *dev) | 150 | static inline void dev_hw_addr_random(struct net_device *dev, u8 *hwaddr) |
| 194 | { | 151 | { |
| 195 | dev->addr_assign_type |= NET_ADDR_RANDOM; | 152 | dev->addr_assign_type |= NET_ADDR_RANDOM; |
| 196 | eth_random_addr(dev->dev_addr); | 153 | random_ether_addr(hwaddr); |
| 197 | } | 154 | } |
| 198 | 155 | ||
| 199 | /** | 156 | /** |
| @@ -201,8 +158,7 @@ static inline void eth_hw_addr_random(struct net_device *dev) | |||
| 201 | * @addr1: Pointer to a six-byte array containing the Ethernet address | 158 | * @addr1: Pointer to a six-byte array containing the Ethernet address |
| 202 | * @addr2: Pointer other six-byte array containing the Ethernet address | 159 | * @addr2: Pointer other six-byte array containing the Ethernet address |
| 203 | * | 160 | * |
| 204 | * Compare two Ethernet addresses, returns 0 if equal, non-zero otherwise. | 161 | * Compare two ethernet addresses, returns 0 if equal |
| 205 | * Unlike memcmp(), it doesn't return a value suitable for sorting. | ||
| 206 | */ | 162 | */ |
| 207 | static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2) | 163 | static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2) |
| 208 | { | 164 | { |
| @@ -213,18 +169,6 @@ static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2) | |||
| 213 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; | 169 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; |
| 214 | } | 170 | } |
| 215 | 171 | ||
| 216 | /** | ||
| 217 | * ether_addr_equal - Compare two Ethernet addresses | ||
| 218 | * @addr1: Pointer to a six-byte array containing the Ethernet address | ||
| 219 | * @addr2: Pointer other six-byte array containing the Ethernet address | ||
| 220 | * | ||
| 221 | * Compare two Ethernet addresses, returns true if equal | ||
| 222 | */ | ||
| 223 | static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2) | ||
| 224 | { | ||
| 225 | return !compare_ether_addr(addr1, addr2); | ||
| 226 | } | ||
| 227 | |||
| 228 | static inline unsigned long zap_last_2bytes(unsigned long value) | 172 | static inline unsigned long zap_last_2bytes(unsigned long value) |
| 229 | { | 173 | { |
| 230 | #ifdef __BIG_ENDIAN | 174 | #ifdef __BIG_ENDIAN |
| @@ -235,34 +179,34 @@ static inline unsigned long zap_last_2bytes(unsigned long value) | |||
| 235 | } | 179 | } |
| 236 | 180 | ||
| 237 | /** | 181 | /** |
| 238 | * ether_addr_equal_64bits - Compare two Ethernet addresses | 182 | * compare_ether_addr_64bits - Compare two Ethernet addresses |
| 239 | * @addr1: Pointer to an array of 8 bytes | 183 | * @addr1: Pointer to an array of 8 bytes |
| 240 | * @addr2: Pointer to an other array of 8 bytes | 184 | * @addr2: Pointer to an other array of 8 bytes |
| 241 | * | 185 | * |
| 242 | * Compare two Ethernet addresses, returns true if equal, false otherwise. | 186 | * Compare two ethernet addresses, returns 0 if equal. |
| 243 | * | 187 | * Same result than "memcmp(addr1, addr2, ETH_ALEN)" but without conditional |
| 244 | * The function doesn't need any conditional branches and possibly uses | 188 | * branches, and possibly long word memory accesses on CPU allowing cheap |
| 245 | * word memory accesses on CPU allowing cheap unaligned memory reads. | 189 | * unaligned memory reads. |
| 246 | * arrays = { byte1, byte2, byte3, byte4, byte5, byte6, pad1, pad2 } | 190 | * arrays = { byte1, byte2, byte3, byte4, byte6, byte7, pad1, pad2} |
| 247 | * | 191 | * |
| 248 | * Please note that alignment of addr1 & addr2 are only guaranteed to be 16 bits. | 192 | * Please note that alignment of addr1 & addr2 is only guaranted to be 16 bits. |
| 249 | */ | 193 | */ |
| 250 | 194 | ||
| 251 | static inline bool ether_addr_equal_64bits(const u8 addr1[6+2], | 195 | static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2], |
| 252 | const u8 addr2[6+2]) | 196 | const u8 addr2[6+2]) |
| 253 | { | 197 | { |
| 254 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | 198 | #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS |
| 255 | unsigned long fold = ((*(unsigned long *)addr1) ^ | 199 | unsigned long fold = ((*(unsigned long *)addr1) ^ |
| 256 | (*(unsigned long *)addr2)); | 200 | (*(unsigned long *)addr2)); |
| 257 | 201 | ||
| 258 | if (sizeof(fold) == 8) | 202 | if (sizeof(fold) == 8) |
| 259 | return zap_last_2bytes(fold) == 0; | 203 | return zap_last_2bytes(fold) != 0; |
| 260 | 204 | ||
| 261 | fold |= zap_last_2bytes((*(unsigned long *)(addr1 + 4)) ^ | 205 | fold |= zap_last_2bytes((*(unsigned long *)(addr1 + 4)) ^ |
| 262 | (*(unsigned long *)(addr2 + 4))); | 206 | (*(unsigned long *)(addr2 + 4))); |
| 263 | return fold == 0; | 207 | return fold != 0; |
| 264 | #else | 208 | #else |
| 265 | return ether_addr_equal(addr1, addr2); | 209 | return compare_ether_addr(addr1, addr2); |
| 266 | #endif | 210 | #endif |
| 267 | } | 211 | } |
| 268 | 212 | ||
| @@ -274,23 +218,23 @@ static inline bool ether_addr_equal_64bits(const u8 addr1[6+2], | |||
| 274 | * Compare passed address with all addresses of the device. Return true if the | 218 | * Compare passed address with all addresses of the device. Return true if the |
| 275 | * address if one of the device addresses. | 219 | * address if one of the device addresses. |
| 276 | * | 220 | * |
| 277 | * Note that this function calls ether_addr_equal_64bits() so take care of | 221 | * Note that this function calls compare_ether_addr_64bits() so take care of |
| 278 | * the right padding. | 222 | * the right padding. |
| 279 | */ | 223 | */ |
| 280 | static inline bool is_etherdev_addr(const struct net_device *dev, | 224 | static inline bool is_etherdev_addr(const struct net_device *dev, |
| 281 | const u8 addr[6 + 2]) | 225 | const u8 addr[6 + 2]) |
| 282 | { | 226 | { |
| 283 | struct netdev_hw_addr *ha; | 227 | struct netdev_hw_addr *ha; |
| 284 | bool res = false; | 228 | int res = 1; |
| 285 | 229 | ||
| 286 | rcu_read_lock(); | 230 | rcu_read_lock(); |
| 287 | for_each_dev_addr(dev, ha) { | 231 | for_each_dev_addr(dev, ha) { |
| 288 | res = ether_addr_equal_64bits(addr, ha->addr); | 232 | res = compare_ether_addr_64bits(addr, ha->addr); |
| 289 | if (res) | 233 | if (!res) |
| 290 | break; | 234 | break; |
| 291 | } | 235 | } |
| 292 | rcu_read_unlock(); | 236 | rcu_read_unlock(); |
| 293 | return res; | 237 | return !res; |
| 294 | } | 238 | } |
| 295 | #endif /* __KERNEL__ */ | 239 | #endif /* __KERNEL__ */ |
| 296 | 240 | ||
| @@ -299,7 +243,7 @@ static inline bool is_etherdev_addr(const struct net_device *dev, | |||
| 299 | * @a: Pointer to Ethernet header | 243 | * @a: Pointer to Ethernet header |
| 300 | * @b: Pointer to Ethernet header | 244 | * @b: Pointer to Ethernet header |
| 301 | * | 245 | * |
| 302 | * Compare two Ethernet headers, returns 0 if equal. | 246 | * Compare two ethernet headers, returns 0 if equal. |
| 303 | * This assumes that the network header (i.e., IP header) is 4-byte | 247 | * This assumes that the network header (i.e., IP header) is 4-byte |
| 304 | * aligned OR the platform can handle unaligned access. This is the | 248 | * aligned OR the platform can handle unaligned access. This is the |
| 305 | * case for all packets coming into netif_receive_skb or similar | 249 | * case for all packets coming into netif_receive_skb or similar |
