#define foreach_gre_input_next \
_(PUNT, "error-punt") \
_(DROP, "error-drop") \
+_(ETHERNET_INPUT, "ethernet-input") \
_(IP4_INPUT, "ip4-input") \
-_(IP6_INPUT, "ip6-input") \
-_(NSH_INPUT, "nsh-input")
+_(IP6_INPUT, "ip6-input")
typedef enum {
#define _(s,n) GRE_INPUT_NEXT_##s,
/* Sparse vector mapping gre protocol in network byte order
to next index. */
u16 * next_by_protocol;
-
- u32 * sparse_index_by_next_index;
} gre_input_runtime_t;
static uword
{
gre_main_t * gm = &gre_main;
gre_input_runtime_t * rt = (void *) node->runtime_data;
- __attribute__((unused)) u32 n_left_from, next_index, i_next, * from, * to_next;
+ __attribute__((unused)) u32 n_left_from, next_index, * from, * to_next;
u64 cached_tunnel_key = (u64) ~0;
u32 cached_tunnel_sw_if_index = 0, tunnel_sw_if_index;
u32 cached_tunnel_fib_index = 0, tunnel_fib_index;
n_left_from = from_frame->n_vectors;
next_index = node->cached_next_index;
- i_next = vec_elt (rt->sparse_index_by_next_index, next_index);
while (n_left_from > 0)
{
next0 = vec_elt(rt->next_by_protocol, i0);
next1 = vec_elt(rt->next_by_protocol, i1);
- b0->error = node->errors[next0 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
- b1->error = node->errors[next1 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
+ b0->error = node->errors[i0 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
+ b1->error = node->errors[i1 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
version0 = clib_net_to_host_u16 (h0->flags_and_version);
verr0 = version0 & GRE_VERSION_MASK;
: b1->error;
next1 = verr1 ? GRE_INPUT_NEXT_DROP : next1;
+
/* RPF check for ip4/ip6 input */
- if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
- || next0 == GRE_INPUT_NEXT_IP6_INPUT))
+ if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
+ || next0 == GRE_INPUT_NEXT_IP6_INPUT
+ || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT))
{
u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
(u64)(vnet_buffer(b0)->gre.src);
len /* bytes */);
vnet_buffer(b0)->sw_if_index[VLIB_TX] = tunnel_fib_index;
+ vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
}
drop0:
- if (PREDICT_FALSE(next1 == GRE_INPUT_NEXT_IP4_INPUT
- || next1 == GRE_INPUT_NEXT_IP6_INPUT))
+ if (PREDICT_FALSE(next1 == GRE_INPUT_NEXT_IP4_INPUT
+ || next1 == GRE_INPUT_NEXT_IP6_INPUT
+ || next1 == GRE_INPUT_NEXT_ETHERNET_INPUT))
{
u64 key = ((u64)(vnet_buffer(b1)->gre.dst) << 32) |
(u64)(vnet_buffer(b1)->gre.src);
len /* bytes */);
vnet_buffer(b1)->sw_if_index[VLIB_TX] = tunnel_fib_index;
+ vnet_buffer(b1)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
}
drop1:
if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
next0 = vec_elt(rt->next_by_protocol, i0);
b0->error =
- node->errors[next0 == SPARSE_VEC_INVALID_INDEX
+ node->errors[i0 == SPARSE_VEC_INVALID_INDEX
? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
version0 = clib_net_to_host_u16 (h0->flags_and_version);
: b0->error;
next0 = verr0 ? GRE_INPUT_NEXT_DROP : next0;
+
/* For IP payload we need to find source interface
so we can increase counters and help forward node to
pick right FIB */
- if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
- || next0 == GRE_INPUT_NEXT_IP6_INPUT))
+ if (PREDICT_FALSE(next0 == GRE_INPUT_NEXT_IP4_INPUT
+ || next0 == GRE_INPUT_NEXT_IP6_INPUT
+ || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT))
{
u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
(u64)(vnet_buffer(b0)->gre.src);
len /* bytes */);
vnet_buffer(b0)->sw_if_index[VLIB_TX] = tunnel_fib_index;
+ vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
}
drop:
.unformat_buffer = unformat_gre_header,
};
+VLIB_NODE_FUNCTION_MULTIARCH (gre_input_node, gre_input)
+
void
gre_register_input_protocol (vlib_main_t * vm,
gre_protocol_t protocol,
gre_protocol_info_t * pi;
gre_input_runtime_t * rt;
u16 * n;
- u32 i;
{
clib_error_t * error = vlib_call_init_function (vm, gre_input_init);
n = sparse_vec_validate (rt->next_by_protocol,
clib_host_to_net_u16 (protocol));
n[0] = pi->next_index;
-
- /* Rebuild next index -> sparse index inverse mapping when sparse vector
- is updated. */
- vec_validate (rt->sparse_index_by_next_index, pi->next_index);
- for (i = 1; i < vec_len (rt->next_by_protocol); i++)
- rt->sparse_index_by_next_index[rt->next_by_protocol[i]] = i;
}
static void
static clib_error_t * gre_input_init (vlib_main_t * vm)
{
gre_input_runtime_t * rt;
- vlib_node_t *ip4_input, *ip6_input, *mpls_unicast_input;
+ vlib_node_t *ethernet_input, *ip4_input, *ip6_input, *mpls_unicast_input;
{
clib_error_t * error;
(/* elt bytes */ sizeof (rt->next_by_protocol[0]),
/* bits in index */ BITS (((gre_header_t *) 0)->protocol));
- vec_validate (rt->sparse_index_by_next_index, GRE_INPUT_NEXT_DROP);
- vec_validate (rt->sparse_index_by_next_index, GRE_INPUT_NEXT_PUNT);
- rt->sparse_index_by_next_index[GRE_INPUT_NEXT_DROP]
- = SPARSE_VEC_INVALID_INDEX;
- rt->sparse_index_by_next_index[GRE_INPUT_NEXT_PUNT]
- = SPARSE_VEC_INVALID_INDEX;
-
/* These could be moved to the supported protocol input node defn's */
+ ethernet_input = vlib_get_node_by_name (vm, (u8 *)"ethernet-input");
+ ASSERT(ethernet_input);
ip4_input = vlib_get_node_by_name (vm, (u8 *)"ip4-input");
ASSERT(ip4_input);
ip6_input = vlib_get_node_by_name (vm, (u8 *)"ip6-input");
mpls_unicast_input = vlib_get_node_by_name (vm, (u8 *)"mpls-gre-input");
ASSERT(mpls_unicast_input);
+ gre_register_input_protocol (vm, GRE_PROTOCOL_teb,
+ ethernet_input->index);
+
gre_register_input_protocol (vm, GRE_PROTOCOL_ip4,
ip4_input->index);