bonding: support custom interface IDs
[vpp.git] / src / vnet / geneve / geneve_packet.h
index 87e5225..ab37f53 100644 (file)
 #define INT_OPT_CLASS    0x0103
 #define VMWARE_OPT_CLASS 0x0104
 
+/*
+ * 0                   1                   2                   3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |          Option Class         |      Type     |R|R|R| Length  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                      Variable Option Data                     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
 typedef struct
 {
   u16 opt_class;
   u8 type;
-  u8 res:3;
-  u8 length:5;
+  /* The 3 reserved bits are for future use;
+   * Need to be 0 on sending and ignored on receipt.
+   */
+  u8 res;
+  /* Length is expressed in 4-bytes multiples excluding the options header. */
+  u8 length;
   u32 opt_data[];
 } geneve_options_t;
 
@@ -87,88 +100,146 @@ typedef struct
 
 typedef struct
 {
-  u8 ver:2;
-  u8 opt_len:6;
-  u8 oam_frame:1;
-  u8 critical_options:1;
-  u8 res1:6;
-  u16 protocol;
-  u32 vni:24;
-  u8 res2;
+  /*
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * |Ver|  Opt Len  |O|C|    Rsvd.  |          Protocol Type        |
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   */
+  u32 first_word;
+
+  /*
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   * |        Virtual Network Identifier (VNI)       |    Reserved   |
+   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   */
+  u32 vni_rsvd;
   geneve_options_t opts[];
 } geneve_header_t;
 
+#define GENEVE_VERSION_SHIFT   30
+#define GENEVE_OPTLEN_SHIFT            24
+#define GENEVE_O_BIT_SHIFT             23
+#define GENEVE_C_BIT_SHIFT             22
+#define GENEVE_6_RESERVED_SHIFT 16
+#define GENEVE_VNI_SHIFT               8
+
+#define GENEVE_VERSION_MASK            0xC0000000
+#define GENEVE_OPTLEN_MASK             0x3F000000
+#define GENEVE_O_BIT_MASK              0x00800000
+#define GENEVE_C_BIT_MASK              0x00400000
+#define GENEVE_6_RESERVED_MASK 0x003F0000
+#define GENEVE_PROTOCOL_MASK   0x0000FFFF
+#define GENEVE_VNI_MASK                        0xFFFFFF00
+
+/*
+ * Return the VNI in host-byte order
+ */
 static inline u32
 vnet_get_geneve_vni (geneve_header_t * h)
 {
-  return (clib_net_to_host_u32 (h->vni) >> 8);
+  return (clib_net_to_host_u32 (h->vni_rsvd & GENEVE_VNI_MASK) >>
+         GENEVE_VNI_SHIFT);
+}
+
+/*
+ * Return the VNI in network-byte order
+ *
+ * To be used in the DECAP phase to create the lookup key (IP + VNI)
+ */
+static inline u32
+vnet_get_geneve_vni_bigendian (geneve_header_t * h)
+{
+  u32 vni_host = vnet_get_geneve_vni (h);
+  return clib_host_to_net_u32 ((vni_host << GENEVE_VNI_SHIFT) &
+                              GENEVE_VNI_MASK);
 }
 
 static inline void
 vnet_set_geneve_vni (geneve_header_t * h, u32 vni)
 {
-  h->vni = clib_host_to_net_u32 (vni << 8);
+  h->vni_rsvd &= ~(GENEVE_VNI_MASK);
+  h->vni_rsvd |=
+    clib_host_to_net_u32 ((vni << GENEVE_VNI_SHIFT) & GENEVE_VNI_MASK);
 }
 
 static inline u8
 vnet_get_geneve_version (geneve_header_t * h)
 {
-  return (clib_net_to_host_u32 (h->ver) >> 30);
+  return ((h->first_word & GENEVE_VERSION_MASK) >> GENEVE_VERSION_SHIFT);
 }
 
 static inline void
 vnet_set_geneve_version (geneve_header_t * h, u8 version)
 {
-  h->ver = clib_host_to_net_u32 (version << 30);
+  h->first_word &= ~(GENEVE_VERSION_MASK);
+  h->first_word |= ((version << GENEVE_VERSION_SHIFT) & GENEVE_VERSION_MASK);
 }
 
 static inline u8
 vnet_get_geneve_options_len (geneve_header_t * h)
 {
-  return (clib_net_to_host_u32 (h->opt_len) >> 24);
+  return ((h->first_word & GENEVE_OPTLEN_MASK) >> GENEVE_OPTLEN_SHIFT);
 }
 
 static inline void
 vnet_set_geneve_options_len (geneve_header_t * h, u8 len)
 {
-  h->opt_len = clib_host_to_net_u32 (len << 24);
+  h->first_word &= ~(GENEVE_OPTLEN_MASK);
+  h->first_word |= ((len << GENEVE_OPTLEN_SHIFT) & GENEVE_OPTLEN_MASK);
 }
 
 static inline u8
 vnet_get_geneve_oamframe_bit (geneve_header_t * h)
 {
-  return (clib_net_to_host_u32 (h->oam_frame) >> 23);
+  return ((h->first_word & GENEVE_O_BIT_MASK) >> GENEVE_O_BIT_SHIFT);
 }
 
 static inline void
 vnet_set_geneve_oamframe_bit (geneve_header_t * h, u8 oam)
 {
-  h->oam_frame = clib_host_to_net_u32 (oam << 23);
+  h->first_word &= ~(GENEVE_O_BIT_MASK);
+  h->first_word |= ((oam << GENEVE_O_BIT_SHIFT) & GENEVE_O_BIT_MASK);
 }
 
 static inline u8
 vnet_get_geneve_critical_bit (geneve_header_t * h)
 {
-  return (clib_net_to_host_u32 (h->critical_options) >> 22);
+  return ((h->first_word & GENEVE_C_BIT_MASK) >> GENEVE_C_BIT_SHIFT);
 }
 
 static inline void
 vnet_set_geneve_critical_bit (geneve_header_t * h, u8 critical_opts)
 {
-  h->critical_options = clib_host_to_net_u32 (critical_opts << 22);
+  h->first_word &= ~(GENEVE_C_BIT_MASK);
+  h->first_word |=
+    ((critical_opts << GENEVE_C_BIT_SHIFT) & GENEVE_C_BIT_MASK);
 }
 
 static inline u16
 vnet_get_geneve_protocol (geneve_header_t * h)
 {
-  return clib_net_to_host_u32 (h->protocol);
+  return (h->first_word & GENEVE_PROTOCOL_MASK);
 }
 
 static inline void
 vnet_set_geneve_protocol (geneve_header_t * h, u16 protocol)
 {
-  h->protocol = clib_host_to_net_u32 (protocol);
+  h->first_word &= ~(GENEVE_PROTOCOL_MASK);
+  h->first_word |= (protocol & GENEVE_PROTOCOL_MASK);
 }
+
+static inline void
+vnet_geneve_hdr_1word_ntoh (geneve_header_t * h)
+{
+  h->first_word = clib_net_to_host_u32 (h->first_word);
+}
+
+static inline void
+vnet_geneve_hdr_1word_hton (geneve_header_t * h)
+{
+  h->first_word = clib_host_to_net_u32 (h->first_word);
+}
+
 #endif
 
 /*