gre: multipoint ingress lookup fix
Type: fix
Change-Id: I170edd62220a63cb19efea3032e173fb87730b1b
Signed-off-by: Neale Ranns <nranns@cisco.com>
diff --git a/src/vnet/gre/gre.h b/src/vnet/gre/gre.h
index 11bcddd..6989cf4 100644
--- a/src/vnet/gre/gre.h
+++ b/src/vnet/gre/gre.h
@@ -96,6 +96,26 @@
} gre_protocol_info_t;
/**
+ * Elements of the GRE key that are common for v6 and v6 addresses
+ */
+typedef struct gre_tunnel_key_common_t_
+{
+ union
+ {
+ struct
+ {
+ u32 fib_index;
+ u16 session_id;
+ gre_tunnel_type_t type;
+ gre_tunnel_mode_t mode;
+ };
+ u64 as_u64;
+ };
+} gre_tunnel_key_common_t;
+
+STATIC_ASSERT_SIZEOF (gre_tunnel_key_common_t, sizeof (u64));
+
+/**
* @brief Key for a IPv4 GRE Tunnel
*/
typedef struct gre_tunnel_key4_t_
@@ -113,15 +133,12 @@
u64 gtk_as_u64;
};
- /**
- * FIB table index, ERSPAN session ID and tunnel type in u32 bit fields:
- * - The FIB table index the src,dst addresses are in, top 20 bits
- * - The Session ID for ERSPAN tunnel type and 0 otherwise, next 10 bits
- * - Tunnel type, bottom 2 bits
- */
- u32 gtk_fidx_ssid_type;
+ /** address independent attributes */
+ gre_tunnel_key_common_t gtk_common;
} __attribute__ ((packed)) gre_tunnel_key4_t;
+STATIC_ASSERT_SIZEOF (gre_tunnel_key4_t, 2 * sizeof (u64));
+
/**
* @brief Key for a IPv6 GRE Tunnel
* We use a different type so that the V4 key hash is as small as possible
@@ -134,22 +151,11 @@
ip6_address_t gtk_src;
ip6_address_t gtk_dst;
- /**
- * FIB table index, ERSPAN session ID and tunnel type in u32 bit fields:
- * - The FIB table index the src,dst addresses are in, top 20 bits
- * - The Session ID for ERSPAN tunnel type and 0 otherwise, next 10 bits
- * - Tunnel type, bottom 2 bits
- */
- u32 gtk_fidx_ssid_type;
+ /** address independent attributes */
+ gre_tunnel_key_common_t gtk_common;
} __attribute__ ((packed)) gre_tunnel_key6_t;
-#define GTK_FIB_INDEX_SHIFT 12
-#define GTK_FIB_INDEX_MASK 0xfffff000
-#define GTK_TYPE_SHIFT 0
-#define GTK_TYPE_MASK 0x3
-#define GTK_SESSION_ID_SHIFT 2
-#define GTK_SESSION_ID_MASK 0xffc
-#define GTK_SESSION_ID_MAX (GTK_SESSION_ID_MASK >> GTK_SESSION_ID_SHIFT)
+STATIC_ASSERT_SIZEOF (gre_tunnel_key6_t, 5 * sizeof (u64));
/**
* Union of the two possible key types
@@ -161,6 +167,11 @@
} gre_tunnel_key_t;
/**
+ * The session ID is only a 10 bit value
+ */
+#define GTK_SESSION_ID_MAX (0x3ff)
+
+/**
* Used for GRE header seq number generation for ERSPAN encap
*/
typedef struct
@@ -190,12 +201,6 @@
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
/**
- * The hash table's key stored in separate memory since the tunnel_t
- * memory can realloc.
- */
- gre_tunnel_key_t *key;
-
- /**
* The tunnel's source/local address
*/
ip46_address_t tunnel_src;
@@ -372,12 +377,16 @@
static inline void
gre_mk_key4 (ip4_address_t src,
ip4_address_t dst,
- u32 fib_index, u8 ttype, u16 session_id, gre_tunnel_key4_t * key)
+ u32 fib_index,
+ gre_tunnel_type_t ttype,
+ gre_tunnel_mode_t tmode, u16 session_id, gre_tunnel_key4_t * key)
{
key->gtk_src = src;
key->gtk_dst = dst;
- key->gtk_fidx_ssid_type = ttype |
- (fib_index << GTK_FIB_INDEX_SHIFT) | (session_id << GTK_SESSION_ID_SHIFT);
+ key->gtk_common.type = ttype;
+ key->gtk_common.mode = tmode;
+ key->gtk_common.fib_index = fib_index;
+ key->gtk_common.session_id = session_id;
}
static inline int
@@ -385,29 +394,31 @@
const gre_tunnel_key4_t * key2)
{
return ((key1->gtk_as_u64 == key2->gtk_as_u64) &&
- (key1->gtk_fidx_ssid_type == key2->gtk_fidx_ssid_type));
+ (key1->gtk_common.as_u64 == key2->gtk_common.as_u64));
}
static inline void
gre_mk_key6 (const ip6_address_t * src,
const ip6_address_t * dst,
- u32 fib_index, u8 ttype, u16 session_id, gre_tunnel_key6_t * key)
+ u32 fib_index,
+ gre_tunnel_type_t ttype,
+ gre_tunnel_mode_t tmode, u16 session_id, gre_tunnel_key6_t * key)
{
key->gtk_src = *src;
key->gtk_dst = *dst;
- key->gtk_fidx_ssid_type = ttype |
- (fib_index << GTK_FIB_INDEX_SHIFT) | (session_id << GTK_SESSION_ID_SHIFT);
+ key->gtk_common.type = ttype;
+ key->gtk_common.mode = tmode;
+ key->gtk_common.fib_index = fib_index;
+ key->gtk_common.session_id = session_id;
}
static inline int
gre_match_key6 (const gre_tunnel_key6_t * key1,
const gre_tunnel_key6_t * key2)
{
- return ((key1->gtk_src.as_u64[0] == key2->gtk_src.as_u64[0]) &&
- (key1->gtk_src.as_u64[1] == key2->gtk_src.as_u64[1]) &&
- (key1->gtk_dst.as_u64[0] == key2->gtk_dst.as_u64[0]) &&
- (key1->gtk_dst.as_u64[1] == key2->gtk_dst.as_u64[1]) &&
- (key1->gtk_fidx_ssid_type == key2->gtk_fidx_ssid_type));
+ return (ip6_address_is_equal (&key1->gtk_src, &key2->gtk_src) &&
+ ip6_address_is_equal (&key1->gtk_dst, &key2->gtk_dst) &&
+ (key1->gtk_common.as_u64 == key2->gtk_common.as_u64));
}
static inline void