bpf/arm: add byte swap operations
[dpdk.git] / lib / librte_net / rte_ip.h
index 9b1944b..f82454b 100644 (file)
@@ -16,7 +16,9 @@
  */
 
 #include <stdint.h>
+#include <sys/types.h>
 #include <netinet/in.h>
+#include <netinet/ip.h>
 
 #include <rte_byteorder.h>
 #include <rte_mbuf.h>
@@ -42,7 +44,7 @@ struct rte_ipv4_hdr {
 } __attribute__((__packed__));
 
 /** Create IPv4 address */
-#define RTE_IPv4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \
+#define RTE_IPV4(a, b, c, d) ((uint32_t)(((a) & 0xff) << 24) | \
                                           (((b) & 0xff) << 16) | \
                                           (((c) & 0xff) << 8)  | \
                                           ((d) & 0xff))
@@ -58,6 +60,11 @@ struct rte_ipv4_hdr {
  */
 #define RTE_IPV4_IHL_MULTIPLIER        (4)
 
+/* 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
 #define        RTE_IPV4_HDR_MF_SHIFT   13
@@ -84,14 +91,18 @@ struct rte_ipv4_hdr {
  * IPv4 Multicast-related macros
  */
 #define RTE_IPV4_MIN_MCAST \
-       RTE_IPv4(224, 0, 0, 0)          /**< Minimal IPv4-multicast address */
+       RTE_IPV4(224, 0, 0, 0)          /**< Minimal IPv4-multicast address */
 #define RTE_IPV4_MAX_MCAST \
-       RTE_IPv4(239, 255, 255, 255)    /**< Maximum IPv4 multicast address */
+       RTE_IPV4(239, 255, 255, 255)    /**< Maximum IPv4 multicast address */
 
 #define RTE_IS_IPV4_MCAST(x) \
        ((x) >= RTE_IPV4_MIN_MCAST && (x) <= RTE_IPV4_MAX_MCAST)
        /**< check if IPv4 address is multicast */
 
+/* IPv4 default fields values */
+#define RTE_IPV4_MIN_IHL    (0x5)
+#define RTE_IPV4_VHL_DEF    (IPVERSION | RTE_IPV4_MIN_IHL)
+
 /**
  * @internal Calculate a sum of all words in the buffer.
  * Helper routine for the rte_raw_cksum().
@@ -354,8 +365,11 @@ struct rte_ipv6_hdr {
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20
-#define RTE_IPV6_HDR_FL_MASK ((1u << RTE_IPV6_HDR_TC_SHIFT) - 1)
-#define RTE_IPV6_HDR_TC_MASK (0xf << RTE_IPV6_HDR_TC_SHIFT)
+#define RTE_IPV6_HDR_FL_MASK   ((1u << RTE_IPV6_HDR_TC_SHIFT) - 1)
+#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
 
 /**
  * Process the pseudo-header checksum of an IPv6 header.
@@ -428,6 +442,56 @@ rte_ipv6_udptcp_cksum(const struct rte_ipv6_hdr *ipv6_hdr, const void *l4_hdr)
        return (uint16_t)cksum;
 }
 
+/* IPv6 fragmentation header size */
+#define RTE_IPV6_FRAG_HDR_SIZE 8
+
+/**
+ * Parse next IPv6 header extension
+ *
+ * This function checks if proto number is an IPv6 extensions and parses its
+ * data if so, providing information on next header and extension length.
+ *
+ * @param p
+ *   Pointer to an extension raw data.
+ * @param proto
+ *   Protocol number extracted from the "next header" field from
+ *   the IPv6 header or the previous extension.
+ * @param ext_len
+ *   Extension data length.
+ * @return
+ *   next protocol number if proto is an IPv6 extension, -EINVAL otherwise
+ */
+__rte_experimental
+static inline int
+rte_ipv6_get_next_ext(uint8_t *p, int proto, size_t *ext_len)
+{
+       int next_proto;
+
+       switch (proto) {
+       case IPPROTO_AH:
+               next_proto = *p++;
+               *ext_len = (*p + 2) * sizeof(uint32_t);
+               break;
+
+       case IPPROTO_HOPOPTS:
+       case IPPROTO_ROUTING:
+       case IPPROTO_DSTOPTS:
+               next_proto = *p++;
+               *ext_len = (*p + 1) * sizeof(uint64_t);
+               break;
+
+       case IPPROTO_FRAGMENT:
+               next_proto = *p;
+               *ext_len = RTE_IPV6_FRAG_HDR_SIZE;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return next_proto;
+}
+
 #ifdef __cplusplus
 }
 #endif