first public release
[dpdk.git] / lib / librte_ether / rte_ether.h
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright 
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright 
14  *       notice, this list of conditions and the following disclaimer in 
15  *       the documentation and/or other materials provided with the 
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its 
18  *       contributors may be used to endorse or promote products derived 
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * 
33  *  version: DPDK.L.1.2.3-3
34  */
35
36 #ifndef _RTE_ETHER_H_
37 #define _RTE_ETHER_H_
38
39 /**
40  * @file
41  *
42  * Ethernet Helpers in RTE
43  */
44
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48
49 #include <stdint.h>
50
51 #define ETHER_ADDR_LEN  6 /**< Length of Ethernet address. */
52 #define ETHER_TYPE_LEN  2 /**< Length of Ethernet type field. */
53 #define ETHER_CRC_LEN   4 /**< Length of Ethernet CRC. */
54 #define ETHER_HDR_LEN   \
55         (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) /**< Length of Ethernet header. */
56 #define ETHER_MIN_LEN   64    /**< Minimum frame len, including CRC. */
57 #define ETHER_MAX_LEN   1518  /**< Maximum frame len, including CRC. */
58 #define ETHER_MTU       \
59         (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) /**< Ethernet MTU. */
60
61 #define ETHER_MAX_VLAN_FRAME_LEN \
62         (ETHER_MAX_LEN + 4) /**< Maximum VLAN frame length, including CRC. */
63
64 #define ETHER_MAX_JUMBO_FRAME_LEN \
65         0x3F00 /**< Maximum Jumbo frame length, including CRC. */
66
67 /**
68  * Ethernet address:
69  * A universally administered address is uniquely assigned to a device by its
70  * manufacturer. The first three octets (in transmission order) contain the
71  * Organizationally Unique Identifier (OUI). The following three (MAC-48 and
72  * EUI-48) octets are assigned by that organization with the only constraint
73  * of uniqueness.
74  * A locally administered address is assigned to a device by a network
75  * administrator and does not contain OUIs.
76  * See http://standards.ieee.org/regauth/groupmac/tutorial.html
77  */
78 struct ether_addr {
79         uint8_t addr_bytes[ETHER_ADDR_LEN]; /**< Address bytes in transmission order */
80 } __attribute__((__packed__));
81
82 #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
83 #define ETHER_GROUP_ADDR       0x01 /**< Multicast or broadcast Eth. address. */
84
85 /**
86  * Check if an Ethernet address is filled with zeros.
87  *
88  * @param ea
89  *   A pointer to a ether_addr structure containing the ethernet address
90  *   to check.
91  * @return
92  *   True  (1) if the given ethernet address is filled with zeros;
93  *   false (0) otherwise.
94  */
95 static inline int is_zero_ether_addr(const struct ether_addr *ea)
96 {
97         int i;
98         for (i = 0; i < ETHER_ADDR_LEN; i++)
99                 if (ea->addr_bytes[i] != 0x00)
100                         return 0;
101         return 1;
102 }
103
104 /**
105  * Check if an Ethernet address is a unicast address.
106  *
107  * @param ea
108  *   A pointer to a ether_addr structure containing the ethernet address
109  *   to check.
110  * @return
111  *   True  (1) if the given ethernet address is a unicast address;
112  *   false (0) otherwise.
113  */
114 static inline int is_unicast_ether_addr(const struct ether_addr *ea)
115 {
116         return ((ea->addr_bytes[0] & ETHER_GROUP_ADDR) == 0);
117 }
118
119 /**
120  * Check if an Ethernet address is a multicast address.
121  *
122  * @param ea
123  *   A pointer to a ether_addr structure containing the ethernet address
124  *   to check.
125  * @return
126  *   True  (1) if the given ethernet address is a multicast address;
127  *   false (0) otherwise.
128  */
129 static inline int is_multicast_ether_addr(const struct ether_addr *ea)
130 {
131         return (ea->addr_bytes[0] & ETHER_GROUP_ADDR);
132 }
133
134 /**
135  * Check if an Ethernet address is a broadcast address.
136  *
137  * @param ea
138  *   A pointer to a ether_addr structure containing the ethernet address
139  *   to check.
140  * @return
141  *   True  (1) if the given ethernet address is a broadcast address;
142  *   false (0) otherwise.
143  */
144 static inline int is_broadcast_ether_addr(const struct ether_addr *ea)
145 {
146         const uint16_t *ea_words = (const uint16_t *)ea;
147
148         return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
149                 ea_words[2] == 0xFFFF);
150 }
151
152 /**
153  * Check if an Ethernet address is a universally assigned address.
154  *
155  * @param ea
156  *   A pointer to a ether_addr structure containing the ethernet address
157  *   to check.
158  * @return
159  *   True  (1) if the given ethernet address is a universally assigned address;
160  *   false (0) otherwise.
161  */
162 static inline int is_universal_ether_addr(const struct ether_addr *ea)
163 {
164         return ((ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) == 0);
165 }
166
167 /**
168  * Check if an Ethernet address is a locally assigned address.
169  *
170  * @param ea
171  *   A pointer to a ether_addr structure containing the ethernet address
172  *   to check.
173  * @return
174  *   True  (1) if the given ethernet address is a locally assigned address;
175  *   false (0) otherwise.
176  */
177 static inline int is_local_admin_ether_addr(const struct ether_addr *ea)
178 {
179         return ((ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) == 1);
180 }
181
182 /**
183  * Check if an Ethernet address is a valid address. Checks that the address is a
184  * unicast address and is not filled with zeros.
185  *
186  * @param ea
187  *   A pointer to a ether_addr structure containing the ethernet address
188  *   to check.
189  * @return
190  *   True  (1) if the given ethernet address is valid;
191  *   false (0) otherwise.
192  */
193 static inline int is_valid_assigned_ether_addr(const struct ether_addr *ea)
194 {
195         return (is_unicast_ether_addr(ea) && (! is_zero_ether_addr(ea)));
196 }
197
198 /**
199  * Fast copy an Ethernet address.
200  *
201  * @param ea_from
202  *   A pointer to a ether_addr structure holding the Ethernet address to copy.
203  * @param ea_to
204  *   A pointer to a ether_addr structure where to copy the Ethernet address.
205  */
206 static inline void ether_addr_copy(const struct ether_addr *ea_from,
207                                    struct ether_addr *ea_to)
208 {
209 #ifdef __INTEL_COMPILER
210         uint16_t *from_words = (uint16_t *)(ea_from->addr_bytes);
211         uint16_t *to_words   = (uint16_t *)(ea_to->addr_bytes);
212
213         to_words[0] = from_words[0];
214         to_words[1] = from_words[1];
215         to_words[2] = from_words[2];
216 #else
217         /*
218          * Use the common way, because of a strange gcc warning.
219          */
220         *ea_to = *ea_from;
221 #endif
222 }
223
224 /**
225  * Ethernet header: Contains the destination address, source address
226  * and frame type.
227  */
228 struct ether_hdr {
229         struct ether_addr d_addr; /**< Destination address. */
230         struct ether_addr s_addr; /**< Source address. */
231         uint16_t ether_type;      /**< Frame type. */
232 } __attribute__((__packed__));
233
234 /**
235  * Ethernet VLAN Header.
236  * Contains the 16-bit VLAN Tag Control Identifier and the Ethernet type
237  * of the encapsulated frame.
238  */
239 struct vlan_hdr {
240         uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */
241         uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */
242 } __attribute__((__packed__));
243
244 /* Ethernet frame types */
245 #define ETHER_TYPE_IPv4 0x0800 /**< IPv4 Protocol. */
246 #define ETHER_TYPE_IPv6 0x86DD /**< IPv6 Protocol. */
247 #define ETHER_TYPE_ARP  0x0806 /**< Arp Protocol. */
248 #define ETHER_TYPE_RARP 0x8035 /**< Reverse Arp Protocol. */
249 #define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */
250 #define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time Protocol. */
251
252 #ifdef __cplusplus
253 }
254 #endif
255
256 #endif /* _RTE_ETHER_H_ */