struct rte_ipv4_hdr {
uint8_t version_ihl; /**< version and header length */
uint8_t type_of_service; /**< type of service */
- uint16_t total_length; /**< length of packet */
- uint16_t packet_id; /**< packet ID */
- uint16_t fragment_offset; /**< fragmentation offset */
+ rte_be16_t total_length; /**< length of packet */
+ rte_be16_t packet_id; /**< packet ID */
+ rte_be16_t fragment_offset; /**< fragmentation offset */
uint8_t time_to_live; /**< time to live */
uint8_t next_proto_id; /**< protocol ID */
- uint16_t hdr_checksum; /**< header checksum */
- uint32_t src_addr; /**< source address */
- uint32_t dst_addr; /**< destination address */
-} __attribute__((__packed__));
+ rte_be16_t hdr_checksum; /**< header checksum */
+ rte_be32_t src_addr; /**< source address */
+ rte_be32_t dst_addr; /**< destination address */
+} __rte_packed;
/** Create IPv4 address */
#define RTE_IPV4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \
/* Type of Service fields */
#define RTE_IPV4_HDR_DSCP_MASK (0xfc)
#define RTE_IPV4_HDR_ECN_MASK (0x03)
+#define RTE_IPV4_HDR_ECN_CE RTE_IPV4_HDR_ECN_MASK
/* Fragment Offset * Flags. */
#define RTE_IPV4_HDR_DF_SHIFT 14
/* IPv4 default fields values */
#define RTE_IPV4_MIN_IHL (0x5)
-#define RTE_IPV4_VHL_DEF (IPVERSION | RTE_IPV4_MIN_IHL)
+#define RTE_IPV4_VHL_DEF ((IPVERSION << 4) | RTE_IPV4_MIN_IHL)
/**
* @internal Calculate a sum of all words in the buffer.
}
/* if length is in odd bytes */
- if (len == 1)
- sum += *((const uint8_t *)u16_buf);
+ if (len == 1) {
+ uint16_t left = 0;
+ *(uint8_t *)&left = *(const uint8_t *)u16_buf;
+ sum += left;
+ }
return sum;
}
{
uint16_t cksum;
cksum = rte_raw_cksum(ipv4_hdr, sizeof(struct rte_ipv4_hdr));
- return (cksum == 0xffff) ? cksum : (uint16_t)~cksum;
+ return (uint16_t)~cksum;
}
/**
* @param l4_hdr
* The pointer to the beginning of the L4 header.
* @return
- * The complemented checksum to set in the IP packet
- * or 0 on error
+ * The complemented checksum to set in the IP packet.
*/
static inline uint16_t
rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
- if (cksum == 0)
+ /*
+ * Per RFC 768:If the computed checksum is zero for UDP,
+ * it is transmitted as all ones
+ * (the equivalent in one's complement arithmetic).
+ */
+ if (cksum == 0 && ipv4_hdr->next_proto_id == IPPROTO_UDP)
cksum = 0xffff;
return (uint16_t)cksum;
* IPv6 Header
*/
struct rte_ipv6_hdr {
- uint32_t vtc_flow; /**< IP version, traffic class & flow label. */
- uint16_t payload_len; /**< IP packet length - includes sizeof(ip_header). */
- uint8_t proto; /**< Protocol, next header. */
- uint8_t hop_limits; /**< Hop limits. */
- uint8_t src_addr[16]; /**< IP address of source host. */
- uint8_t dst_addr[16]; /**< IP address of destination host(s). */
-} __attribute__((__packed__));
+ rte_be32_t vtc_flow; /**< IP version, traffic class & flow label. */
+ rte_be16_t payload_len; /**< IP packet length - includes header size */
+ uint8_t proto; /**< Protocol, next header. */
+ uint8_t hop_limits; /**< Hop limits. */
+ uint8_t src_addr[16]; /**< IP address of source host. */
+ uint8_t dst_addr[16]; /**< IP address of destination host(s). */
+} __rte_packed;
/* IPv6 vtc_flow: IPv / TC / flow_label */
#define RTE_IPV6_HDR_FL_SHIFT 0
#define RTE_IPV6_HDR_TC_MASK (0xff << RTE_IPV6_HDR_TC_SHIFT)
#define RTE_IPV6_HDR_DSCP_MASK (0xfc << RTE_IPV6_HDR_TC_SHIFT)
#define RTE_IPV6_HDR_ECN_MASK (0x03 << RTE_IPV6_HDR_TC_SHIFT)
+#define RTE_IPV6_HDR_ECN_CE RTE_IPV6_HDR_ECN_MASK
+
+#define RTE_IPV6_MIN_MTU 1280 /**< Minimum MTU for IPv6, see RFC 8200. */
/**
* Process the pseudo-header checksum of an IPv6 header.
{
uint32_t sum;
struct {
- uint32_t len; /* L4 length. */
- uint32_t proto; /* L4 protocol - top 3 bytes must be zero */
+ rte_be32_t len; /* L4 length. */
+ rte_be32_t proto; /* L4 protocol - top 3 bytes must be zero */
} psd_hdr;
psd_hdr.proto = (uint32_t)(ipv6_hdr->proto << 24);
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
- if (cksum == 0)
+ /*
+ * Per RFC 768: If the computed checksum is zero for UDP,
+ * it is transmitted as all ones
+ * (the equivalent in one's complement arithmetic).
+ */
+ if (cksum == 0 && ipv6_hdr->proto == IPPROTO_UDP)
cksum = 0xffff;
return (uint16_t)cksum;
*/
__rte_experimental
static inline int
-rte_ipv6_get_next_ext(uint8_t *p, int proto, size_t *ext_len)
+rte_ipv6_get_next_ext(const uint8_t *p, int proto, size_t *ext_len)
{
int next_proto;