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 8 /** 9 * @file 10 * 11 * Ethernet Helpers in RTE 12 */ 13 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 ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */ 27 #define ETHER_TYPE_LEN 2 /**< Length of Ethernet type field. */ 28 #define ETHER_CRC_LEN 4 /**< Length of Ethernet CRC. */ 29 #define ETHER_HDR_LEN \ 30 (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) /**< Length of Ethernet header. */ 31 #define ETHER_MIN_LEN 64 /**< Minimum frame len, including CRC. */ 32 #define ETHER_MAX_LEN 1518 /**< Maximum frame len, including CRC. */ 33 #define ETHER_MTU \ 34 (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) /**< Ethernet MTU. */ 35 36 #define ETHER_MAX_VLAN_FRAME_LEN \ 37 (ETHER_MAX_LEN + 4) /**< Maximum VLAN frame length, including CRC. */ 38 39 #define ETHER_MAX_JUMBO_FRAME_LEN \ 40 0x3F00 /**< Maximum Jumbo frame length, including CRC. */ 41 42 #define ETHER_MAX_VLAN_ID 4095 /**< Maximum VLAN ID. */ 43 44 #define ETHER_MIN_MTU 68 /**< Minimum MTU for IPv4 packets, see RFC 791. */ 45 46 /** 47 * Ethernet address: 48 * A universally administered address is uniquely assigned to a device by its 49 * manufacturer. The first three octets (in transmission order) contain the 50 * Organizationally Unique Identifier (OUI). The following three (MAC-48 and 51 * EUI-48) octets are assigned by that organization with the only constraint 52 * of uniqueness. 53 * A locally administered address is assigned to a device by a network 54 * administrator and does not contain OUIs. 55 * See http://standards.ieee.org/regauth/groupmac/tutorial.html 56 */ 57 struct ether_addr { 58 uint8_t addr_bytes[ETHER_ADDR_LEN]; /**< Addr bytes in tx order */ 59 } __attribute__((__packed__)); 60 61 #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */ 62 #define ETHER_GROUP_ADDR 0x01 /**< Multicast or broadcast Eth. address. */ 63 64 /** 65 * Check if two Ethernet addresses are the same. 66 * 67 * @param ea1 68 * A pointer to the first ether_addr structure containing 69 * the ethernet address. 70 * @param ea2 71 * A pointer to the second ether_addr structure containing 72 * the ethernet address. 73 * 74 * @return 75 * True (1) if the given two ethernet address are the same; 76 * False (0) otherwise. 77 */ 78 static inline int is_same_ether_addr(const struct ether_addr *ea1, 79 const struct ether_addr *ea2) 80 { 81 int i; 82 for (i = 0; i < ETHER_ADDR_LEN; i++) 83 if (ea1->addr_bytes[i] != ea2->addr_bytes[i]) 84 return 0; 85 return 1; 86 } 87 88 /** 89 * Check if an Ethernet address is filled with zeros. 90 * 91 * @param ea 92 * A pointer to a ether_addr structure containing the ethernet address 93 * to check. 94 * @return 95 * True (1) if the given ethernet address is filled with zeros; 96 * false (0) otherwise. 97 */ 98 static inline int is_zero_ether_addr(const struct ether_addr *ea) 99 { 100 int i; 101 for (i = 0; i < ETHER_ADDR_LEN; i++) 102 if (ea->addr_bytes[i] != 0x00) 103 return 0; 104 return 1; 105 } 106 107 /** 108 * Check if an Ethernet address is a unicast address. 109 * 110 * @param ea 111 * A pointer to a ether_addr structure containing the ethernet address 112 * to check. 113 * @return 114 * True (1) if the given ethernet address is a unicast address; 115 * false (0) otherwise. 116 */ 117 static inline int is_unicast_ether_addr(const struct ether_addr *ea) 118 { 119 return (ea->addr_bytes[0] & ETHER_GROUP_ADDR) == 0; 120 } 121 122 /** 123 * Check if an Ethernet address is a multicast address. 124 * 125 * @param ea 126 * A pointer to a ether_addr structure containing the ethernet address 127 * to check. 128 * @return 129 * True (1) if the given ethernet address is a multicast address; 130 * false (0) otherwise. 131 */ 132 static inline int is_multicast_ether_addr(const struct ether_addr *ea) 133 { 134 return ea->addr_bytes[0] & ETHER_GROUP_ADDR; 135 } 136 137 /** 138 * Check if an Ethernet address is a broadcast address. 139 * 140 * @param ea 141 * A pointer to a ether_addr structure containing the ethernet address 142 * to check. 143 * @return 144 * True (1) if the given ethernet address is a broadcast address; 145 * false (0) otherwise. 146 */ 147 static inline int is_broadcast_ether_addr(const struct ether_addr *ea) 148 { 149 const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea; 150 151 return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF && 152 ea_words[2] == 0xFFFF); 153 } 154 155 /** 156 * Check if an Ethernet address is a universally assigned address. 157 * 158 * @param ea 159 * A pointer to a ether_addr structure containing the ethernet address 160 * to check. 161 * @return 162 * True (1) if the given ethernet address is a universally assigned address; 163 * false (0) otherwise. 164 */ 165 static inline int is_universal_ether_addr(const struct ether_addr *ea) 166 { 167 return (ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) == 0; 168 } 169 170 /** 171 * Check if an Ethernet address is a locally assigned address. 172 * 173 * @param ea 174 * A pointer to a ether_addr structure containing the ethernet address 175 * to check. 176 * @return 177 * True (1) if the given ethernet address is a locally assigned address; 178 * false (0) otherwise. 179 */ 180 static inline int is_local_admin_ether_addr(const struct ether_addr *ea) 181 { 182 return (ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) != 0; 183 } 184 185 /** 186 * Check if an Ethernet address is a valid address. Checks that the address is a 187 * unicast address and is not filled with zeros. 188 * 189 * @param ea 190 * A pointer to a ether_addr structure containing the ethernet address 191 * to check. 192 * @return 193 * True (1) if the given ethernet address is valid; 194 * false (0) otherwise. 195 */ 196 static inline int is_valid_assigned_ether_addr(const struct ether_addr *ea) 197 { 198 return is_unicast_ether_addr(ea) && (!is_zero_ether_addr(ea)); 199 } 200 201 /** 202 * Generate a random Ethernet address that is locally administered 203 * and not multicast. 204 * @param addr 205 * A pointer to Ethernet address. 206 */ 207 static inline void eth_random_addr(uint8_t *addr) 208 { 209 uint64_t rand = rte_rand(); 210 uint8_t *p = (uint8_t *)&rand; 211 212 rte_memcpy(addr, p, ETHER_ADDR_LEN); 213 addr[0] &= (uint8_t)~ETHER_GROUP_ADDR; /* clear multicast bit */ 214 addr[0] |= ETHER_LOCAL_ADMIN_ADDR; /* set local assignment bit */ 215 } 216 217 /** 218 * Fast copy an Ethernet address. 219 * 220 * @param ea_from 221 * A pointer to a ether_addr structure holding the Ethernet address to copy. 222 * @param ea_to 223 * A pointer to a ether_addr structure where to copy the Ethernet address. 224 */ 225 static inline void ether_addr_copy(const struct ether_addr *ea_from, 226 struct ether_addr *ea_to) 227 { 228 #ifdef __INTEL_COMPILER 229 uint16_t *from_words = (uint16_t *)(ea_from->addr_bytes); 230 uint16_t *to_words = (uint16_t *)(ea_to->addr_bytes); 231 232 to_words[0] = from_words[0]; 233 to_words[1] = from_words[1]; 234 to_words[2] = from_words[2]; 235 #else 236 /* 237 * Use the common way, because of a strange gcc warning. 238 */ 239 *ea_to = *ea_from; 240 #endif 241 } 242 243 #define ETHER_ADDR_FMT_SIZE 18 244 /** 245 * Format 48bits Ethernet address in pattern xx:xx:xx:xx:xx:xx. 246 * 247 * @param buf 248 * A pointer to buffer contains the formatted MAC address. 249 * @param size 250 * The format buffer size. 251 * @param eth_addr 252 * A pointer to a ether_addr structure. 253 */ 254 static inline void 255 ether_format_addr(char *buf, uint16_t size, 256 const struct ether_addr *eth_addr) 257 { 258 snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X", 259 eth_addr->addr_bytes[0], 260 eth_addr->addr_bytes[1], 261 eth_addr->addr_bytes[2], 262 eth_addr->addr_bytes[3], 263 eth_addr->addr_bytes[4], 264 eth_addr->addr_bytes[5]); 265 } 266 267 /** 268 * Ethernet header: Contains the destination address, source address 269 * and frame type. 270 */ 271 struct ether_hdr { 272 struct ether_addr d_addr; /**< Destination address. */ 273 struct ether_addr s_addr; /**< Source address. */ 274 uint16_t ether_type; /**< Frame type. */ 275 } __attribute__((__packed__)); 276 277 /** 278 * Ethernet VLAN Header. 279 * Contains the 16-bit VLAN Tag Control Identifier and the Ethernet type 280 * of the encapsulated frame. 281 */ 282 struct vlan_hdr { 283 uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */ 284 uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */ 285 } __attribute__((__packed__)); 286 287 /** 288 * VXLAN protocol header. 289 * Contains the 8-bit flag, 24-bit VXLAN Network Identifier and 290 * Reserved fields (24 bits and 8 bits) 291 */ 292 struct vxlan_hdr { 293 uint32_t vx_flags; /**< flag (8) + Reserved (24). */ 294 uint32_t vx_vni; /**< VNI (24) + Reserved (8). */ 295 } __attribute__((__packed__)); 296 297 /* Ethernet frame types */ 298 #define ETHER_TYPE_IPv4 0x0800 /**< IPv4 Protocol. */ 299 #define ETHER_TYPE_IPv6 0x86DD /**< IPv6 Protocol. */ 300 #define ETHER_TYPE_ARP 0x0806 /**< Arp Protocol. */ 301 #define ETHER_TYPE_RARP 0x8035 /**< Reverse Arp Protocol. */ 302 #define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */ 303 #define ETHER_TYPE_QINQ 0x88A8 /**< IEEE 802.1ad QinQ tagging. */ 304 #define ETHER_TYPE_ETAG 0x893F /**< IEEE 802.1BR E-Tag. */ 305 #define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time Protocol. */ 306 #define ETHER_TYPE_SLOW 0x8809 /**< Slow protocols (LACP and Marker). */ 307 #define ETHER_TYPE_TEB 0x6558 /**< Transparent Ethernet Bridging. */ 308 #define ETHER_TYPE_LLDP 0x88CC /**< LLDP Protocol. */ 309 #define ETHER_TYPE_MPLS 0x8847 /**< MPLS ethertype. */ 310 #define ETHER_TYPE_MPLSM 0x8848 /**< MPLS multicast ethertype. */ 311 312 #define ETHER_VXLAN_HLEN (sizeof(struct udp_hdr) + sizeof(struct vxlan_hdr)) 313 /**< VXLAN tunnel header length. */ 314 315 /** 316 * VXLAN-GPE protocol header (draft-ietf-nvo3-vxlan-gpe-05). 317 * Contains the 8-bit flag, 8-bit next-protocol, 24-bit VXLAN Network 318 * Identifier and Reserved fields (16 bits and 8 bits). 319 */ 320 struct vxlan_gpe_hdr { 321 uint8_t vx_flags; /**< flag (8). */ 322 uint8_t reserved[2]; /**< Reserved (16). */ 323 uint8_t proto; /**< next-protocol (8). */ 324 uint32_t vx_vni; /**< VNI (24) + Reserved (8). */ 325 } __attribute__((__packed__)); 326 327 /* VXLAN-GPE next protocol types */ 328 #define VXLAN_GPE_TYPE_IPV4 1 /**< IPv4 Protocol. */ 329 #define VXLAN_GPE_TYPE_IPV6 2 /**< IPv6 Protocol. */ 330 #define VXLAN_GPE_TYPE_ETH 3 /**< Ethernet Protocol. */ 331 #define VXLAN_GPE_TYPE_NSH 4 /**< NSH Protocol. */ 332 #define VXLAN_GPE_TYPE_MPLS 5 /**< MPLS Protocol. */ 333 #define VXLAN_GPE_TYPE_GBP 6 /**< GBP Protocol. */ 334 #define VXLAN_GPE_TYPE_VBNG 7 /**< vBNG Protocol. */ 335 336 #define ETHER_VXLAN_GPE_HLEN (sizeof(struct udp_hdr) + \ 337 sizeof(struct vxlan_gpe_hdr)) 338 /**< VXLAN-GPE tunnel header length. */ 339 340 /** 341 * Extract VLAN tag information into mbuf 342 * 343 * Software version of VLAN stripping 344 * 345 * @param m 346 * The packet mbuf. 347 * @return 348 * - 0: Success 349 * - 1: not a vlan packet 350 */ 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 357 if (eh->ether_type != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) 358 return -1; 359 360 vh = (struct vlan_hdr *)(eh + 1); 361 m->ol_flags |= PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED; 362 m->vlan_tci = rte_be_to_cpu_16(vh->vlan_tci); 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 371 /** 372 * Insert VLAN tag into mbuf. 373 * 374 * Software version of VLAN unstripping 375 * 376 * @param m 377 * The packet mbuf. 378 * @return 379 * - 0: On success 380 * -EPERM: mbuf is is shared overwriting would be unsafe 381 * -ENOSPC: not enough headroom in mbuf 382 */ 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); 406 nh->ether_type = rte_cpu_to_be_16(ETHER_TYPE_VLAN); 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 | PKT_TX_VLAN); 412 413 return 0; 414 } 415 416 #ifdef __cplusplus 417 } 418 #endif 419 420 #endif /* _RTE_ETHER_H_ */ 421