DPDK  19.08.0-rc0
rte_ether.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #ifndef _RTE_ETHER_H_
6 #define _RTE_ETHER_H_
7 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 #include <stdint.h>
19 #include <stdio.h>
20 
21 #include <rte_memcpy.h>
22 #include <rte_random.h>
23 #include <rte_mbuf.h>
24 #include <rte_byteorder.h>
25 
26 #define RTE_ETHER_ADDR_LEN 6
27 #define RTE_ETHER_TYPE_LEN 2
28 #define RTE_ETHER_CRC_LEN 4
29 #define RTE_ETHER_HDR_LEN \
30  (RTE_ETHER_ADDR_LEN * 2 + \
31  RTE_ETHER_TYPE_LEN)
32 #define RTE_ETHER_MIN_LEN 64
33 #define RTE_ETHER_MAX_LEN 1518
34 #define RTE_ETHER_MTU \
35  (RTE_ETHER_MAX_LEN - RTE_ETHER_HDR_LEN - \
36  RTE_ETHER_CRC_LEN)
38 #define RTE_ETHER_MAX_VLAN_FRAME_LEN \
39  (RTE_ETHER_MAX_LEN + 4)
40 
42 #define RTE_ETHER_MAX_JUMBO_FRAME_LEN \
43  0x3F00
45 #define RTE_ETHER_MAX_VLAN_ID 4095
47 #define RTE_ETHER_MIN_MTU 68
60 struct rte_ether_addr {
61  uint8_t addr_bytes[RTE_ETHER_ADDR_LEN];
62 } __attribute__((__packed__));
63 
64 #define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02
65 #define RTE_ETHER_GROUP_ADDR 0x01
81 static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
82  const struct rte_ether_addr *ea2)
83 {
84  int i;
85  for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
86  if (ea1->addr_bytes[i] != ea2->addr_bytes[i])
87  return 0;
88  return 1;
89 }
90 
101 static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
102 {
103  int i;
104  for (i = 0; i < RTE_ETHER_ADDR_LEN; i++)
105  if (ea->addr_bytes[i] != 0x00)
106  return 0;
107  return 1;
108 }
109 
120 static inline int rte_is_unicast_ether_addr(const struct rte_ether_addr *ea)
121 {
122  return (ea->addr_bytes[0] & RTE_ETHER_GROUP_ADDR) == 0;
123 }
124 
135 static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
136 {
137  return ea->addr_bytes[0] & RTE_ETHER_GROUP_ADDR;
138 }
139 
150 static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
151 {
152  const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
153 
154  return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
155  ea_words[2] == 0xFFFF);
156 }
157 
168 static inline int rte_is_universal_ether_addr(const struct rte_ether_addr *ea)
169 {
170  return (ea->addr_bytes[0] & RTE_ETHER_LOCAL_ADMIN_ADDR) == 0;
171 }
172 
183 static inline int rte_is_local_admin_ether_addr(const struct rte_ether_addr *ea)
184 {
185  return (ea->addr_bytes[0] & RTE_ETHER_LOCAL_ADMIN_ADDR) != 0;
186 }
187 
199 static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *ea)
200 {
202 }
203 
210 static inline void rte_eth_random_addr(uint8_t *addr)
211 {
212  uint64_t rand = rte_rand();
213  uint8_t *p = (uint8_t *)&rand;
214 
215  rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN);
216  addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR; /* clear multicast bit */
217  addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; /* set local assignment bit */
218 }
219 
228 static inline void rte_ether_addr_copy(const struct rte_ether_addr *ea_from,
229  struct rte_ether_addr *ea_to)
230 {
231 #ifdef __INTEL_COMPILER
232  uint16_t *from_words = (uint16_t *)(ea_from->addr_bytes);
233  uint16_t *to_words = (uint16_t *)(ea_to->addr_bytes);
234 
235  to_words[0] = from_words[0];
236  to_words[1] = from_words[1];
237  to_words[2] = from_words[2];
238 #else
239  /*
240  * Use the common way, because of a strange gcc warning.
241  */
242  *ea_to = *ea_from;
243 #endif
244 }
245 
246 #define RTE_ETHER_ADDR_FMT_SIZE 18
247 
257 static inline void
258 rte_ether_format_addr(char *buf, uint16_t size,
259  const struct rte_ether_addr *eth_addr)
260 {
261  snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X",
262  eth_addr->addr_bytes[0],
263  eth_addr->addr_bytes[1],
264  eth_addr->addr_bytes[2],
265  eth_addr->addr_bytes[3],
266  eth_addr->addr_bytes[4],
267  eth_addr->addr_bytes[5]);
268 }
269 
277  uint16_t ether_type;
278 } __attribute__((__packed__));
279 
285 struct rte_vlan_hdr {
286  uint16_t vlan_tci;
287  uint16_t eth_proto;
288 } __attribute__((__packed__));
289 
296  uint32_t vx_flags;
297  uint32_t vx_vni;
298 } __attribute__((__packed__));
299 
300 /* Ethernet frame types */
301 #define RTE_ETHER_TYPE_IPV4 0x0800
302 #define RTE_ETHER_TYPE_IPV6 0x86DD
303 #define RTE_ETHER_TYPE_ARP 0x0806
304 #define RTE_ETHER_TYPE_RARP 0x8035
305 #define RTE_ETHER_TYPE_VLAN 0x8100
306 #define RTE_ETHER_TYPE_QINQ 0x88A8
307 #define ETHER_TYPE_PPPOE_DISCOVERY 0x8863
308 #define ETHER_TYPE_PPPOE_SESSION 0x8864
309 #define RTE_ETHER_TYPE_ETAG 0x893F
310 #define RTE_ETHER_TYPE_1588 0x88F7
311 
312 #define RTE_ETHER_TYPE_SLOW 0x8809
313 #define RTE_ETHER_TYPE_TEB 0x6558
314 #define RTE_ETHER_TYPE_LLDP 0x88CC
315 #define RTE_ETHER_TYPE_MPLS 0x8847
316 #define RTE_ETHER_TYPE_MPLSM 0x8848
318 #define RTE_ETHER_VXLAN_HLEN \
319  (sizeof(struct rte_udp_hdr) + sizeof(struct rte_vxlan_hdr))
320 
328  uint8_t vx_flags;
329  uint8_t reserved[2];
330  uint8_t proto;
331  uint32_t vx_vni;
332 } __attribute__((__packed__));
333 
334 /* VXLAN-GPE next protocol types */
335 #define RTE_VXLAN_GPE_TYPE_IPV4 1
336 #define RTE_VXLAN_GPE_TYPE_IPV6 2
337 #define RTE_VXLAN_GPE_TYPE_ETH 3
338 #define RTE_VXLAN_GPE_TYPE_NSH 4
339 #define RTE_VXLAN_GPE_TYPE_MPLS 5
340 #define RTE_VXLAN_GPE_TYPE_GBP 6
341 #define RTE_VXLAN_GPE_TYPE_VBNG 7
343 #define RTE_ETHER_VXLAN_GPE_HLEN (sizeof(struct rte_udp_hdr) + \
344  sizeof(struct rte_vxlan_gpe_hdr))
345 
358 static inline int rte_vlan_strip(struct rte_mbuf *m)
359 {
360  struct rte_ether_hdr *eh
361  = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
362  struct rte_vlan_hdr *vh;
363 
365  return -1;
366 
367  vh = (struct rte_vlan_hdr *)(eh + 1);
370 
371  /* Copy ether header over rather than moving whole packet */
372  memmove(rte_pktmbuf_adj(m, sizeof(struct rte_vlan_hdr)),
373  eh, 2 * RTE_ETHER_ADDR_LEN);
374 
375  return 0;
376 }
377 
390 static inline int rte_vlan_insert(struct rte_mbuf **m)
391 {
392  struct rte_ether_hdr *oh, *nh;
393  struct rte_vlan_hdr *vh;
394 
395  /* Can't insert header if mbuf is shared */
396  if (rte_mbuf_refcnt_read(*m) > 1) {
397  struct rte_mbuf *copy;
398 
399  copy = rte_pktmbuf_clone(*m, (*m)->pool);
400  if (unlikely(copy == NULL))
401  return -ENOMEM;
402  rte_pktmbuf_free(*m);
403  *m = copy;
404  }
405 
406  oh = rte_pktmbuf_mtod(*m, struct rte_ether_hdr *);
407  nh = (struct rte_ether_hdr *)
408  rte_pktmbuf_prepend(*m, sizeof(struct rte_vlan_hdr));
409  if (nh == NULL)
410  return -ENOSPC;
411 
412  memmove(nh, oh, 2 * RTE_ETHER_ADDR_LEN);
414 
415  vh = (struct rte_vlan_hdr *) (nh + 1);
416  vh->vlan_tci = rte_cpu_to_be_16((*m)->vlan_tci);
417 
418  (*m)->ol_flags &= ~(PKT_RX_VLAN_STRIPPED | PKT_TX_VLAN);
419 
420  return 0;
421 }
422 
423 #ifdef __cplusplus
424 }
425 #endif
426 
427 #endif /* _RTE_ETHER_H_ */
#define RTE_ETHER_LOCAL_ADMIN_ADDR
Definition: rte_ether.h:64
static void rte_eth_random_addr(uint8_t *addr)
Definition: rte_ether.h:210
static void rte_pktmbuf_free(struct rte_mbuf *m)
Definition: rte_mbuf.h:1875
uint32_t vx_vni
Definition: rte_ether.h:297
static int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
Definition: rte_ether.h:150
static struct rte_mbuf * rte_pktmbuf_clone(struct rte_mbuf *md, struct rte_mempool *mp)
Definition: rte_mbuf.h:1906
#define RTE_ETHER_TYPE_VLAN
Definition: rte_ether.h:305
#define RTE_ETHER_ADDR_LEN
Definition: rte_ether.h:26
#define PKT_TX_VLAN
Definition: rte_mbuf.h:347
static uint64_t rte_rand(void)
Definition: rte_random.h:48
static int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
Definition: rte_ether.h:101
static int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
Definition: rte_ether.h:135
uint8_t vx_flags
Definition: rte_ether.h:328
uint32_t vx_flags
Definition: rte_ether.h:296
uint16_t vlan_tci
Definition: rte_ether.h:286
static int rte_vlan_strip(struct rte_mbuf *m)
Definition: rte_ether.h:358
static rte_be16_t rte_cpu_to_be_16(uint16_t x)
struct rte_ether_addr d_addr
Definition: rte_ether.h:275
#define unlikely(x)
static uint16_t rte_mbuf_refcnt_read(const struct rte_mbuf *m)
Definition: rte_mbuf.h:1069
#define PKT_RX_VLAN
Definition: rte_mbuf.h:72
#define RTE_ETHER_GROUP_ADDR
Definition: rte_ether.h:65
static char * rte_pktmbuf_adj(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:2166
uint16_t ether_type
Definition: rte_ether.h:277
static int rte_vlan_insert(struct rte_mbuf **m)
Definition: rte_ether.h:390
uint64_t ol_flags
Definition: rte_mbuf.h:575
struct rte_ether_addr s_addr
Definition: rte_ether.h:276
static void rte_ether_addr_copy(const struct rte_ether_addr *ea_from, struct rte_ether_addr *ea_to)
Definition: rte_ether.h:228
static int rte_is_local_admin_ether_addr(const struct rte_ether_addr *ea)
Definition: rte_ether.h:183
#define rte_pktmbuf_mtod(m, t)
Definition: rte_mbuf.h:2037
static void rte_ether_format_addr(char *buf, uint16_t size, const struct rte_ether_addr *eth_addr)
Definition: rte_ether.h:258
uint32_t vx_vni
Definition: rte_ether.h:331
struct rte_mempool * pool
Definition: rte_mbuf.h:685
uint16_t eth_proto
Definition: rte_ether.h:287
static int rte_is_universal_ether_addr(const struct rte_ether_addr *ea)
Definition: rte_ether.h:168
static char * rte_pktmbuf_prepend(struct rte_mbuf *m, uint16_t len)
Definition: rte_mbuf.h:2102
static int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr *ea)
Definition: rte_ether.h:199
static void * rte_memcpy(void *dst, const void *src, size_t n)
#define PKT_RX_VLAN_STRIPPED
Definition: rte_mbuf.h:103
static uint16_t rte_be_to_cpu_16(rte_be16_t x)
uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]
Definition: rte_ether.h:61
uint8_t reserved[2]
Definition: rte_ether.h:329
uint16_t vlan_tci
Definition: rte_mbuf.h:617
static int rte_is_unicast_ether_addr(const struct rte_ether_addr *ea)
Definition: rte_ether.h:120