X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Flibrte_ether%2Frte_ether.h;h=1d62d8e5b7047aaea36ab37cc8444fcd7d3f5720;hb=5544a453b4ac2e3eded876d01423e7bb0739284c;hp=100cc525c3e712c1d77cbff54525ccee8b68df0d;hpb=20f4f53aeac94cdadbb849a8bc817e3c4d90a3b7;p=dpdk.git diff --git a/lib/librte_ether/rte_ether.h b/lib/librte_ether/rte_ether.h index 100cc525c3..1d62d8e5b7 100644 --- a/lib/librte_ether/rte_ether.h +++ b/lib/librte_ether/rte_ether.h @@ -45,9 +45,12 @@ extern "C" { #endif #include +#include #include #include +#include +#include #define ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */ #define ETHER_TYPE_LEN 2 /**< Length of Ethernet type field. */ @@ -142,7 +145,7 @@ static inline int is_zero_ether_addr(const struct ether_addr *ea) */ static inline int is_unicast_ether_addr(const struct ether_addr *ea) { - return ((ea->addr_bytes[0] & ETHER_GROUP_ADDR) == 0); + return (ea->addr_bytes[0] & ETHER_GROUP_ADDR) == 0; } /** @@ -157,7 +160,7 @@ static inline int is_unicast_ether_addr(const struct ether_addr *ea) */ static inline int is_multicast_ether_addr(const struct ether_addr *ea) { - return (ea->addr_bytes[0] & ETHER_GROUP_ADDR); + return ea->addr_bytes[0] & ETHER_GROUP_ADDR; } /** @@ -172,7 +175,7 @@ static inline int is_multicast_ether_addr(const struct ether_addr *ea) */ static inline int is_broadcast_ether_addr(const struct ether_addr *ea) { - const uint16_t *ea_words = (const uint16_t *)ea; + const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea; return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF && ea_words[2] == 0xFFFF); @@ -190,7 +193,7 @@ static inline int is_broadcast_ether_addr(const struct ether_addr *ea) */ static inline int is_universal_ether_addr(const struct ether_addr *ea) { - return ((ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) == 0); + return (ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) == 0; } /** @@ -205,7 +208,7 @@ static inline int is_universal_ether_addr(const struct ether_addr *ea) */ static inline int is_local_admin_ether_addr(const struct ether_addr *ea) { - return ((ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) != 0); + return (ea->addr_bytes[0] & ETHER_LOCAL_ADMIN_ADDR) != 0; } /** @@ -221,7 +224,7 @@ static inline int is_local_admin_ether_addr(const struct ether_addr *ea) */ static inline int is_valid_assigned_ether_addr(const struct ether_addr *ea) { - return (is_unicast_ether_addr(ea) && (! is_zero_ether_addr(ea))); + return is_unicast_ether_addr(ea) && (! is_zero_ether_addr(ea)); } /** @@ -266,6 +269,30 @@ static inline void ether_addr_copy(const struct ether_addr *ea_from, #endif } +#define ETHER_ADDR_FMT_SIZE 18 +/** + * Format 48bits Ethernet address in pattern xx:xx:xx:xx:xx:xx. + * + * @param buf + * A pointer to buffer contains the formatted MAC address. + * @param size + * The format buffer size. + * @param eth_addr + * A pointer to a ether_addr structure. + */ +static inline void +ether_format_addr(char *buf, uint16_t size, + const struct ether_addr *eth_addr) +{ + snprintf(buf, size, "%02X:%02X:%02X:%02X:%02X:%02X", + eth_addr->addr_bytes[0], + eth_addr->addr_bytes[1], + eth_addr->addr_bytes[2], + eth_addr->addr_bytes[3], + eth_addr->addr_bytes[4], + eth_addr->addr_bytes[5]); +} + /** * Ethernet header: Contains the destination address, source address * and frame type. @@ -303,9 +330,84 @@ struct vxlan_hdr { #define ETHER_TYPE_RARP 0x8035 /**< Reverse Arp Protocol. */ #define ETHER_TYPE_VLAN 0x8100 /**< IEEE 802.1Q VLAN tagging. */ #define ETHER_TYPE_1588 0x88F7 /**< IEEE 802.1AS 1588 Precise Time Protocol. */ +#define ETHER_TYPE_SLOW 0x8809 /**< Slow protocols (LACP and Marker). */ +#define ETHER_TYPE_TEB 0x6558 /**< Transparent Ethernet Bridging. */ #define ETHER_VXLAN_HLEN (sizeof(struct udp_hdr) + sizeof(struct vxlan_hdr)) -/**< VxLAN tunnel header length. */ +/**< VXLAN tunnel header length. */ + +/** + * Extract VLAN tag information into mbuf + * + * Software version of VLAN stripping + * + * @param m + * The packet mbuf. + * @return + * - 0: Success + * - 1: not a vlan packet + */ +static inline int rte_vlan_strip(struct rte_mbuf *m) +{ + struct ether_hdr *eh + = rte_pktmbuf_mtod(m, struct ether_hdr *); + + if (eh->ether_type != rte_cpu_to_be_16(ETHER_TYPE_VLAN)) + return -1; + + struct vlan_hdr *vh = (struct vlan_hdr *)(eh + 1); + m->ol_flags |= PKT_RX_VLAN_PKT; + m->vlan_tci = rte_be_to_cpu_16(vh->vlan_tci); + + /* Copy ether header over rather than moving whole packet */ + memmove(rte_pktmbuf_adj(m, sizeof(struct vlan_hdr)), + eh, 2 * ETHER_ADDR_LEN); + + return 0; +} + +/** + * Insert VLAN tag into mbuf. + * + * Software version of VLAN unstripping + * + * @param m + * The packet mbuf. + * @return + * - 0: On success + * -EPERM: mbuf is is shared overwriting would be unsafe + * -ENOSPC: not enough headroom in mbuf + */ +static inline int rte_vlan_insert(struct rte_mbuf **m) +{ + struct ether_hdr *oh, *nh; + struct vlan_hdr *vh; + + /* Can't insert header if mbuf is shared */ + if (rte_mbuf_refcnt_read(*m) > 1) { + struct rte_mbuf *copy; + + copy = rte_pktmbuf_clone(*m, (*m)->pool); + if (unlikely(copy == NULL)) + return -ENOMEM; + rte_pktmbuf_free(*m); + *m = copy; + } + + oh = rte_pktmbuf_mtod(*m, struct ether_hdr *); + nh = (struct ether_hdr *) + rte_pktmbuf_prepend(*m, sizeof(struct vlan_hdr)); + if (nh == NULL) + return -ENOSPC; + + memmove(nh, oh, 2 * ETHER_ADDR_LEN); + nh->ether_type = rte_cpu_to_be_16(ETHER_TYPE_VLAN); + + vh = (struct vlan_hdr *) (nh + 1); + vh->vlan_tci = rte_cpu_to_be_16((*m)->vlan_tci); + + return 0; +} #ifdef __cplusplus }