#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
#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;
/* Fold in carry from high bit. */
d -= d > c;
- ASSERT (ip_csum_with_carry (d, x) == c);
+ ip_csum_t t = ip_csum_with_carry (d, x);
+ ASSERT ((t - c == 0) || (t - c == ~0));
return d;
}
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);
c = (c & 0xffff) + (c >> 16);
c = (c & 0xffff) + (c >> 16);
-
+#endif
return c;
}
-/* Copy data and checksum at the same time. */
-ip_csum_t ip_csum_and_memcpy (ip_csum_t sum, void *dst, void *src,
- uword n_bytes);
+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)
+{
+ return (*vnet_incremental_checksum_fp) (sum, _data, n_bytes);
+}
always_inline u16
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 */
/*