Blame view

include/linux/etherdevice.h 8.74 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  NET  is implemented using the  BSD Socket
   *		interface as the means of communication with the user level.
   *
   *		Definitions for the Ethernet handlers.
   *
   * Version:	@(#)eth.h	1.0.4	05/13/93
   *
02c30a84e   Jesper Juhl   [PATCH] update Ro...
10
   * Authors:	Ross Biro
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
   *
   *		Relocated to include/linux where it belongs by Alan Cox 
   *							<gw4pts@gw4pts.ampr.org>
   *
   *		This program is free software; you can redistribute it and/or
   *		modify it under the terms of the GNU General Public License
   *		as published by the Free Software Foundation; either version
   *		2 of the License, or (at your option) any later version.
   *
   *	WARNING: This move may well be temporary. This file will get merged with others RSN.
   *
   */
  #ifndef _LINUX_ETHERDEVICE_H
  #define _LINUX_ETHERDEVICE_H
  
  #include <linux/if_ether.h>
bcd61272d   Arnd Bergmann   [NET]: Add missin...
28
  #include <linux/netdevice.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  #include <linux/random.h>
1f87e235e   Eric Dumazet   eth: Declare an o...
30
  #include <asm/unaligned.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
  
  #ifdef __KERNEL__
ab611487d   Alexey Dobriyan   [NET]: __be'ify *...
33
  extern __be16		eth_type_trans(struct sk_buff *skb, struct net_device *dev);
3b04ddde0   Stephen Hemminger   [NET]: Move hardw...
34
35
36
37
38
39
40
  extern const struct header_ops eth_header_ops;
  
  extern int eth_header(struct sk_buff *skb, struct net_device *dev,
  		      unsigned short type,
  		      const void *daddr, const void *saddr, unsigned len);
  extern int eth_rebuild_header(struct sk_buff *skb);
  extern int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr);
e69dd336e   David S. Miller   net: Push protoco...
41
  extern int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type);
3b04ddde0   Stephen Hemminger   [NET]: Move hardw...
42
43
44
  extern void eth_header_cache_update(struct hh_cache *hh,
  				    const struct net_device *dev,
  				    const unsigned char *haddr);
ccad637b0   Stephen Hemminger   netdev: expose et...
45
46
47
  extern int eth_mac_addr(struct net_device *dev, void *p);
  extern int eth_change_mtu(struct net_device *dev, int new_mtu);
  extern int eth_validate_addr(struct net_device *dev);
3b04ddde0   Stephen Hemminger   [NET]: Move hardw...
48

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49

36909ea43   Tom Herbert   net: Add alloc_ne...
50
51
  extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
  					    unsigned int rxqs);
f25f4e448   Peter P Waskiewicz Jr   [CORE] Stack chan...
52
  #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
36909ea43   Tom Herbert   net: Add alloc_ne...
53
  #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
  
  /**
c2da8acaf   Stephen Hemminger   [ETHERNET]: Add e...
56
57
58
59
   * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Return true if the address is all zeroes.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
61
62
63
64
65
66
   */
  static inline int is_zero_ether_addr(const u8 *addr)
  {
  	return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
  }
  
  /**
c2da8acaf   Stephen Hemminger   [ETHERNET]: Add e...
67
   * is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
79165121b   Michael Ellerman   [NET]: Add is_mul...
68
69
70
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Return true if the address is a multicast address.
88df8ef59   Stephen Hemminger   [NET]: Don't excl...
71
   * By definition the broadcast address is also a multicast address.
79165121b   Michael Ellerman   [NET]: Add is_mul...
72
73
74
   */
  static inline int is_multicast_ether_addr(const u8 *addr)
  {
a02cec215   Eric Dumazet   net: return opera...
75
  	return 0x01 & addr[0];
79165121b   Michael Ellerman   [NET]: Add is_mul...
76
  }
c2da8acaf   Stephen Hemminger   [ETHERNET]: Add e...
77
  /**
bc2cda1eb   Randy Dunlap   docbook: make a n...
78
   * is_local_ether_addr - Determine if the Ethernet address is locally-assigned one (IEEE 802).
e024715f5   Paolo 'Blaisorblade' Giarrusso   uml: improve chec...
79
80
81
82
83
84
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Return true if the address is a local address.
   */
  static inline int is_local_ether_addr(const u8 *addr)
  {
a02cec215   Eric Dumazet   net: return opera...
85
  	return 0x02 & addr[0];
e024715f5   Paolo 'Blaisorblade' Giarrusso   uml: improve chec...
86
87
88
  }
  
  /**
c2da8acaf   Stephen Hemminger   [ETHERNET]: Add e...
89
90
91
92
93
   * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Return true if the address is the broadcast address.
   */
9bd481f85   Jeff Garzik   wireless: fix ipw...
94
95
  static inline int is_broadcast_ether_addr(const u8 *addr)
  {
2407534f8   Stephen Hemminger   [ETHERNET]: Optim...
96
  	return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
9bd481f85   Jeff Garzik   wireless: fix ipw...
97
  }
79165121b   Michael Ellerman   [NET]: Add is_mul...
98
  /**
51e7eed79   Tobias Klauser   etherdevice.h: Ad...
99
100
101
102
103
104
105
106
107
108
109
   * is_unicast_ether_addr - Determine if the Ethernet address is unicast
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Return true if the address is a unicast address.
   */
  static inline int is_unicast_ether_addr(const u8 *addr)
  {
  	return !is_multicast_ether_addr(addr);
  }
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
113
   * is_valid_ether_addr - Determine if the given Ethernet address is valid
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
79165121b   Michael Ellerman   [NET]: Add is_mul...
114
   * a multicast address, and is not FF:FF:FF:FF:FF:FF.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
116
117
118
119
   *
   * Return true if the address is valid.
   */
  static inline int is_valid_ether_addr(const u8 *addr)
  {
79165121b   Michael Ellerman   [NET]: Add is_mul...
120
121
122
  	/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
  	 * explicitly check for it here. */
  	return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  }
  
  /**
   * random_ether_addr - Generate software assigned random Ethernet address
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Generate a random Ethernet address (MAC) that is not multicast
   * and has the local assigned bit set.
   */
  static inline void random_ether_addr(u8 *addr)
  {
  	get_random_bytes (addr, ETH_ALEN);
  	addr [0] &= 0xfe;	/* clear multicast bit */
  	addr [0] |= 0x02;	/* set local assignment bit (IEEE802) */
  }
360ac8e2f   Stephen Hemminger   [ETH]: ether addr...
138
139
  
  /**
c1f79426e   Stefan Assmann   sysfs: add attrib...
140
141
   * dev_hw_addr_random - Create random MAC and set device flag
   * @dev: pointer to net_device structure
7ed24e8da   Randy Dunlap   etherdevice.h: fi...
142
   * @hwaddr: Pointer to a six-byte array containing the Ethernet address
c1f79426e   Stefan Assmann   sysfs: add attrib...
143
144
145
146
147
148
149
150
151
152
153
   *
   * 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);
  }
  
  /**
360ac8e2f   Stephen Hemminger   [ETH]: ether addr...
154
155
   * compare_ether_addr - Compare two Ethernet addresses
   * @addr1: Pointer to a six-byte array containing the Ethernet address
c2da8acaf   Stephen Hemminger   [ETHERNET]: Add e...
156
   * @addr2: Pointer other six-byte array containing the Ethernet address
360ac8e2f   Stephen Hemminger   [ETH]: ether addr...
157
158
159
   *
   * Compare two ethernet addresses, returns 0 if equal
   */
c2da8acaf   Stephen Hemminger   [ETHERNET]: Add e...
160
  static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2)
360ac8e2f   Stephen Hemminger   [ETH]: ether addr...
161
  {
c2da8acaf   Stephen Hemminger   [ETHERNET]: Add e...
162
163
  	const u16 *a = (const u16 *) addr1;
  	const u16 *b = (const u16 *) addr2;
360ac8e2f   Stephen Hemminger   [ETH]: ether addr...
164
165
166
167
  
  	BUILD_BUG_ON(ETH_ALEN != 6);
  	return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
  }
1f87e235e   Eric Dumazet   eth: Declare an o...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
  
  static inline unsigned long zap_last_2bytes(unsigned long value)
  {
  #ifdef __BIG_ENDIAN
  	return value >> 16;
  #else
  	return value << 16;
  #endif
  }
  
  /**
   * compare_ether_addr_64bits - Compare two Ethernet addresses
   * @addr1: Pointer to an array of 8 bytes
   * @addr2: Pointer to an other array of 8 bytes
   *
   * Compare two ethernet addresses, returns 0 if equal.
   * Same result than "memcmp(addr1, addr2, ETH_ALEN)" but without conditional
   * branches, and possibly long word memory accesses on CPU allowing cheap
   * unaligned memory reads.
   * arrays = { byte1, byte2, byte3, byte4, byte6, byte7, pad1, pad2}
   *
   * Please note that alignment of addr1 & addr2 is only guaranted to be 16 bits.
   */
  
  static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2],
  						 const u8 addr2[6+2])
  {
  #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
  	unsigned long fold = ((*(unsigned long *)addr1) ^
  			      (*(unsigned long *)addr2));
  
  	if (sizeof(fold) == 8)
  		return zap_last_2bytes(fold) != 0;
  
  	fold |= zap_last_2bytes((*(unsigned long *)(addr1 + 4)) ^
  				(*(unsigned long *)(addr2 + 4)));
  	return fold != 0;
  #else
  	return compare_ether_addr(addr1, addr2);
  #endif
  }
f001fde5e   Jiri Pirko   net: introduce a ...
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
  
  /**
   * is_etherdev_addr - Tell if given Ethernet address belongs to the device.
   * @dev: Pointer to a device structure
   * @addr: Pointer to a six-byte array containing the Ethernet address
   *
   * Compare passed address with all addresses of the device. Return true if the
   * address if one of the device addresses.
   *
   * Note that this function calls compare_ether_addr_64bits() so take care of
   * the right padding.
   */
  static inline bool is_etherdev_addr(const struct net_device *dev,
  				    const u8 addr[6 + 2])
  {
  	struct netdev_hw_addr *ha;
  	int res = 1;
  
  	rcu_read_lock();
  	for_each_dev_addr(dev, ha) {
  		res = compare_ether_addr_64bits(addr, ha->addr);
  		if (!res)
  			break;
  	}
  	rcu_read_unlock();
  	return !res;
  }
79165121b   Michael Ellerman   [NET]: Add is_mul...
236
  #endif	/* __KERNEL__ */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237

aa4b9f533   Herbert Xu   gro: Optimise Eth...
238
239
240
241
242
243
244
245
246
247
248
  /**
   * compare_ether_header - Compare two Ethernet headers
   * @a: Pointer to Ethernet header
   * @b: Pointer to Ethernet header
   *
   * Compare two ethernet headers, returns 0 if equal.
   * This assumes that the network header (i.e., IP header) is 4-byte
   * aligned OR the platform can handle unaligned access.  This is the
   * case for all packets coming into netif_receive_skb or similar
   * entry points.
   */
40d0802b3   Eric Dumazet   gro: __napi_gro_r...
249
  static inline unsigned long compare_ether_header(const void *a, const void *b)
aa4b9f533   Herbert Xu   gro: Optimise Eth...
250
  {
40d0802b3   Eric Dumazet   gro: __napi_gro_r...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
  	unsigned long fold;
  
  	/*
  	 * We want to compare 14 bytes:
  	 *  [a0 ... a13] ^ [b0 ... b13]
  	 * Use two long XOR, ORed together, with an overlap of two bytes.
  	 *  [a0  a1  a2  a3  a4  a5  a6  a7 ] ^ [b0  b1  b2  b3  b4  b5  b6  b7 ] |
  	 *  [a6  a7  a8  a9  a10 a11 a12 a13] ^ [b6  b7  b8  b9  b10 b11 b12 b13]
  	 * This means the [a6 a7] ^ [b6 b7] part is done two times.
  	*/
  	fold = *(unsigned long *)a ^ *(unsigned long *)b;
  	fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
  	return fold;
  #else
aa4b9f533   Herbert Xu   gro: Optimise Eth...
266
267
268
269
270
  	u32 *a32 = (u32 *)((u8 *)a + 2);
  	u32 *b32 = (u32 *)((u8 *)b + 2);
  
  	return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
  	       (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
40d0802b3   Eric Dumazet   gro: __napi_gro_r...
271
  #endif
aa4b9f533   Herbert Xu   gro: Optimise Eth...
272
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
  #endif	/* _LINUX_ETHERDEVICE_H */