ip: add support for buffer offload metadata in ip midchain
[vpp.git] / src / vnet / ip / ip_packet.h
old mode 100644 (file)
new mode 100755 (executable)
index 6c86e3e..04cf9f1
 
 #include <vppinfra/byte_order.h>
 #include <vppinfra/error.h>
+#include <vppinfra/format.h>
 
 typedef enum ip_protocol
 {
 #define ip_protocol(n,s) IP_PROTOCOL_##s = n,
 #include "protocols.def"
 #undef ip_protocol
-} ip_protocol_t;
+} __clib_packed ip_protocol_t;
 
 /* TCP/UDP ports. */
 typedef enum
@@ -84,7 +85,69 @@ typedef enum
 #undef _
 } ip_multicast_group_t;
 
-/* IP checksum support. */
+
+/**
+ * The set of RFC defined DSCP values.
+ */
+#define foreach_ip_dscp                       \
+  _(0, CS0)                                   \
+  _(8, CS1)                                   \
+  _(10, AF11)                                 \
+  _(12, AF12)                                 \
+  _(14, AF13)                                 \
+  _(16, CS2)                                  \
+  _(18, AF21)                                 \
+  _(20, AF22)                                 \
+  _(22, AF23)                                 \
+  _(24, CS3)                                  \
+  _(26, AF31)                                 \
+  _(28, AF32)                                 \
+  _(30, AF33)                                 \
+  _(32, CS4)                                  \
+  _(34, AF41)                                 \
+  _(36, AF42)                                 \
+  _(38, AF43)                                 \
+  _(40, CS5)                                  \
+  _(46, EF)                                   \
+  _(48, CS6)                                  \
+  _(50, CS7)
+
+typedef enum ip_dscp_t_
+{
+#define _(n,f) IP_DSCP_##f = n,
+  foreach_ip_dscp
+#undef _
+} __clib_packed ip_dscp_t;
+
+extern u8 *format_ip_dscp (u8 * s, va_list * va);
+unformat_function_t unformat_ip_dscp;
+
+/**
+ * IP DSCP bit shift
+ *  The ECN occupies the 2 least significant bits of the TC field
+ */
+#define IP_PACKET_TC_FIELD_DSCP_BIT_SHIFT 2
+#define IP_PACKET_TC_FIELD_ECN_MASK 0x03
+
+/**
+ * The set of RFC defined DSCP values.
+ */
+#define foreach_ip_ecn                        \
+  _(0, NON_ECN)                               \
+  _(1, ECT_0)                                 \
+  _(2, ECT_1)                                 \
+  _(3, CE)
+
+typedef enum ip_ecn_t_
+{
+#define _(n,f) IP_ECN_##f = n,
+  foreach_ip_ecn
+#undef _
+} __clib_packed ip_ecn_t;
+
+STATIC_ASSERT_SIZEOF (ip_ecn_t, 1);
+
+extern u8 *format_ip_ecn (u8 * s, va_list * va);
 
 /* Incremental checksum update. */
 typedef uword ip_csum_t;
@@ -146,6 +209,20 @@ always_inline u16
 ip_csum_fold (ip_csum_t c)
 {
   /* Reduce to 16 bits. */
+#if defined(__x86_64__) && defined(__BMI2__)
+  u64 tmp;
+  asm volatile(
+    /* using ADC is much faster than mov, shift, add sequence
+     * compiler produces */
+    "mov       %k[sum], %k[tmp]                \n\t"
+    "shr       $32, %[sum]                     \n\t"
+    "add       %k[tmp], %k[sum]                \n\t"
+    "mov       $16, %k[tmp]                    \n\t"
+    "shrx      %k[tmp], %k[sum], %k[tmp]       \n\t"
+    "adc       %w[tmp], %w[sum]                \n\t"
+    "adc       $0, %w[sum]                     \n\t"
+    : [ sum ] "+&r"(c), [ tmp ] "=&r"(tmp));
+#else
 #if uword_bits == 64
   c = (c & (ip_csum_t) 0xffffffff) + (c >> (ip_csum_t) 32);
   c = (c & 0xffff) + (c >> 16);
@@ -153,12 +230,13 @@ ip_csum_fold (ip_csum_t c)
 
   c = (c & 0xffff) + (c >> 16);
   c = (c & 0xffff) + (c >> 16);
-
+#endif
   return c;
 }
 
 extern ip_csum_t (*vnet_incremental_checksum_fp) (ip_csum_t, void *, uword);
 
+/* Checksum routine. */
 always_inline ip_csum_t
 ip_incremental_checksum (ip_csum_t sum, void *_data, uword n_bytes)
 {
@@ -171,9 +249,6 @@ ip_csum_and_memcpy_fold (ip_csum_t sum, void *dst)
   return ip_csum_fold (sum);
 }
 
-/* Checksum routine. */
-ip_csum_t ip_incremental_checksum (ip_csum_t sum, void *data, uword n_bytes);
-
 #endif /* included_ip_packet_h */
 
 /*