DPDK  16.11.11
rte_ether.h
Go to the documentation of this file.
1 /*-
2  * BSD LICENSE
3  *
4  * Copyright(c) 2010-2014 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 
34 #ifndef _RTE_ETHER_H_
35 #define _RTE_ETHER_H_
36 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 #include <stdint.h>
48 #include <stdio.h>
49 
50 #include <rte_memcpy.h>
51 #include <rte_random.h>
52 #include <rte_mbuf.h>
53 #include <rte_byteorder.h>
54 
55 #define ETHER_ADDR_LEN 6
56 #define ETHER_TYPE_LEN 2
57 #define ETHER_CRC_LEN 4
58 #define ETHER_HDR_LEN \
59  (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN)
60 #define ETHER_MIN_LEN 64
61 #define ETHER_MAX_LEN 1518
62 #define ETHER_MTU \
63  (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
65 #define ETHER_MAX_VLAN_FRAME_LEN \
66  (ETHER_MAX_LEN + 4)
68 #define ETHER_MAX_JUMBO_FRAME_LEN \
69  0x3F00
71 #define ETHER_MAX_VLAN_ID 4095
73 #define ETHER_MIN_MTU 68
86 struct ether_addr {
87  uint8_t addr_bytes[ETHER_ADDR_LEN];
88 } __attribute__((__packed__));
89 
90 #define ETHER_LOCAL_ADMIN_ADDR 0x02
91 #define ETHER_GROUP_ADDR 0x01
107 static inline int is_same_ether_addr(const struct ether_addr *ea1,
108  const struct ether_addr *ea2)
109 {
110  int i;
111  for (i = 0; i < ETHER_ADDR_LEN; i++)
112  if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
113  return 0;
114  return 1;
115 }
116 
127 static inline int is_zero_ether_addr(const struct ether_addr *ea)
128 {
129  int i;
130  for (i = 0; i < ETHER_ADDR_LEN; i++)
131  if (ea->addr_bytes[i] != 0x00)
132  return 0;
133  return 1;
134 }
135 
146 static inline int is_unicast_ether_addr(const struct ether_addr *ea)
147 {
148  return (ea->addr_bytes[0] & ETHER_GROUP_ADDR) == 0;
149 }
150 
161 static inline int is_multicast_ether_addr(const struct ether_addr *ea)
162 {
163  return ea->addr_bytes[0] & ETHER_GROUP_ADDR;
164 }
165 
176 static inline int is_broadcast_ether_addr(const struct ether_addr *ea)
177 {
178  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
179 
180  return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
181  ea_words[2] == 0xFFFF);
182 }
183 
194 static inline int is_universal_ether_addr(const struct ether_addr *ea)
195 {
196  return (ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) == 0;
197 }
198 
209 static inline int is_local_admin_ether_addr(const struct ether_addr *ea)
210 {
211  return (ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) != 0;
212 }
213 
225 static inline int is_valid_assigned_ether_addr(const struct ether_addr *ea)
226 {
227  return is_unicast_ether_addr(ea) && (!is_zero_ether_addr(ea));
228 }
229 
236 static inline void eth_random_addr(uint8_t *addr)
237 {
238  uint64_t rand = rte_rand();
239  uint8_t *p = (uint8_t *)&rand;
240 
241  rte_memcpy(addr, p, ETHER_ADDR_LEN);
242  addr[0] &= (uint8_t)~ETHER_GROUP_ADDR; /* clear multicast bit */
243  addr[0] |= ETHER_LOCAL_ADMIN_ADDR; /* set local assignment bit */
244 }
245 
254 static inline void ether_addr_copy(const struct ether_addr *ea_from,
255  struct ether_addr *ea_to)
256 {
257 #ifdef __INTEL_COMPILER
258  uint16_t *from_words = (uint16_t *)(ea_from->addr_bytes);
259  uint16_t *to_words = (uint16_t *)(ea_to->addr_bytes);
260 
261  to_words[0] = from_words[0];
262  to_words[1] = from_words[1];
263  to_words[2] = from_words[2];
264 #else
265  /*
266  * Use the common way, because of a strange gcc warning.
267  */
268  *ea_to = *ea_from;
269 #endif
270 }
271 
272 #define ETHER_ADDR_FMT_SIZE 18
273 
283 static inline void
284 ether_format_addr(char *buf, uint16_t size,
285  const struct ether_addr *eth_addr)
286 {
287  snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
288  eth_addr->addr_bytes[0],
289  eth_addr->addr_bytes[1],
290  eth_addr->addr_bytes[2],
291  eth_addr->addr_bytes[3],
292  eth_addr->addr_bytes[4],
293  eth_addr->addr_bytes[5]);
294 }
295 
300 struct ether_hdr {
303  uint16_t ether_type;
304 } __attribute__((__packed__));
305 
311 struct vlan_hdr {
312  uint16_t vlan_tci;
313  uint16_t eth_proto;
314 } __attribute__((__packed__));
315 
321 struct vxlan_hdr {
322  uint32_t vx_flags;
323  uint32_t vx_vni;
324 } __attribute__((__packed__));
325 
326 /* Ethernet frame types */
327 #define ETHER_TYPE_IPv4 0x0800
328 #define ETHER_TYPE_IPv6 0x86DD
329 #define ETHER_TYPE_ARP 0x0806
330 #define ETHER_TYPE_RARP 0x8035
331 #define ETHER_TYPE_VLAN 0x8100
332 #define ETHER_TYPE_QINQ 0x88A8
333 #define ETHER_TYPE_1588 0x88F7
334 #define ETHER_TYPE_SLOW 0x8809
335 #define ETHER_TYPE_TEB 0x6558
337 #define ETHER_VXLAN_HLEN (sizeof(struct udp_hdr) + sizeof(struct vxlan_hdr))
338 
351 static inline int rte_vlan_strip(struct rte_mbuf *m)
352 {
353  struct ether_hdr *eh
354  = rte_pktmbuf_mtod(m, struct ether_hdr *);
355  struct vlan_hdr *vh;
356 
358  return -1;
359 
360  vh = (struct vlan_hdr *)(eh + 1);
363 
364  /* Copy ether header over rather than moving whole packet */
365  memmove(rte_pktmbuf_adj(m, sizeof(struct vlan_hdr)),
366  eh, 2 * ETHER_ADDR_LEN);
367 
368  return 0;
369 }
370 
383 static inline int rte_vlan_insert(struct rte_mbuf **m)
384 {
385  struct ether_hdr *oh, *nh;
386  struct vlan_hdr *vh;
387 
388  /* Can't insert header if mbuf is shared */
389  if (rte_mbuf_refcnt_read(*m) > 1) {
390  struct rte_mbuf *copy;
391 
392  copy = rte_pktmbuf_clone(*m, (*m)->pool);
393  if (unlikely(copy == NULL))
394  return -ENOMEM;
395  rte_pktmbuf_free(*m);
396  *m = copy;
397  }
398 
399  oh = rte_pktmbuf_mtod(*m, struct ether_hdr *);
400  nh = (struct ether_hdr *)
401  rte_pktmbuf_prepend(*m, sizeof(struct vlan_hdr));
402  if (nh == NULL)
403  return -ENOSPC;
404 
405  memmove(nh, oh, 2 * ETHER_ADDR_LEN);
407 
408  vh = (struct vlan_hdr *) (nh + 1);
409  vh->vlan_tci = rte_cpu_to_be_16((*m)->vlan_tci);
410 
411  (*m)->ol_flags &= ~PKT_RX_VLAN_STRIPPED;
412 
413  return 0;
414 }
415 
416 #ifdef __cplusplus
417 }
418 #endif
419 
420 #endif /* _RTE_ETHER_H_ */
uint16_t eth_proto
Definition: rte_ether.h:313
static void rte_pktmbuf_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:1231
uint16_t vlan_tci
Definition: rte_ether.h:312
static struct rte_mbuf * rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
Definition: rte_mbuf.h:1262
static uint64_t rte_rand(void)
Definition: rte_random.h:77
static int is_local_admin_ether_addr(const struct ether_addr *ea)
Definition: rte_ether.h:209
struct ether_addr s_addr
Definition: rte_ether.h:302
static void ether_format_addr(char *buf, uint16_t size, const struct ether_addr *eth_addr)
Definition: rte_ether.h:284
static uint16_t rte_cpu_to_be_16(uint16_t x)
static int is_universal_ether_addr(const struct ether_addr *ea)
Definition: rte_ether.h:194
static int is_multicast_ether_addr(const struct ether_addr *ea)
Definition: rte_ether.h:161
static uint16_t rte_be_to_cpu_16(uint16_t x)
static int rte_vlan_strip(struct rte_mbuf *m)
Definition: rte_ether.h:351
#define unlikely(x)
uint8_t addr_bytes[ETHER_ADDR_LEN]
Definition: rte_ether.h:87
static uint16_t rte_mbuf_refcnt_read(const struct rte_mbuf *m)
Definition: rte_mbuf.h:695
#define PKT_RX_VLAN_PKT
Definition: rte_mbuf.h:90
static char * rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1515
#define ETHER_ADDR_LEN
Definition: rte_ether.h:55
static int is_zero_ether_addr(const struct ether_addr *ea)
Definition: rte_ether.h:127
#define ETHER_GROUP_ADDR
Definition: rte_ether.h:91
static int rte_vlan_insert(struct rte_mbuf **m)
Definition: rte_ether.h:383
uint64_t ol_flags
Definition: rte_mbuf.h:387
#define rte_pktmbuf_mtod(m, t)
Definition: rte_mbuf.h:1393
uint32_t vx_flags
Definition: rte_ether.h:322
uint16_t ether_type
Definition: rte_ether.h:303
static int is_valid_assigned_ether_addr(const struct ether_addr *ea)
Definition: rte_ether.h:225
#define ETHER_LOCAL_ADMIN_ADDR
Definition: rte_ether.h:90
struct rte_mempool * pool
Definition: rte_mbuf.h:455
struct ether_addr d_addr
Definition: rte_ether.h:301
static char * rte_pktmbuf_prepend(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:1451
uint32_t vx_vni
Definition: rte_ether.h:323
#define ETHER_TYPE_VLAN
Definition: rte_ether.h:331
static int is_broadcast_ether_addr(const struct ether_addr *ea)
Definition: rte_ether.h:176
static void * rte_memcpy(void *dst, const void *src, size_t n)
#define PKT_RX_VLAN_STRIPPED
Definition: rte_mbuf.h:120
uint16_t vlan_tci
Definition: rte_mbuf.h:416
static void ether_addr_copy(const struct ether_addr *ea_from, struct ether_addr *ea_to)
Definition: rte_ether.h:254
static int is_unicast_ether_addr(const struct ether_addr *ea)
Definition: rte_ether.h:146
static void eth_random_addr(uint8_t *addr)
Definition: rte_ether.h:236