VLIB_NODE_FN (ip4_lookup_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
- return ip4_lookup_inline (vm, node, frame,
- /* lookup_for_responses_to_locally_received_packets */
- 0);
-
+ return ip4_lookup_inline (vm, node, frame);
}
static u8 *format_ip4_lookup_trace (u8 * s, va_list * args);
*result_ia = result ? ia : 0;
return result;
}
+#endif
static void
ip4_add_subnet_bcast_route (u32 fib_index,
fib_table_entry_delete (fib_index, &pfx, FIB_SOURCE_INTERFACE);
}
+#ifndef CLIB_MARCH_VARIANT
void
ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable)
{
vnet_feature_enable_disable ("ip4-multicast", "ip4-not-enabled",
sw_if_index, !is_enable, 0, 0);
+
+ {
+ ip4_enable_disable_interface_callback_t *cb;
+ vec_foreach (cb, im->enable_disable_interface_callbacks)
+ cb->function (im, cb->function_opaque, sw_if_index, is_enable);
+ }
}
static clib_error_t *
ip4_sw_interface_enable_disable (sw_if_index, !is_del);
- if (is_del)
- ip4_del_interface_routes (im, ip4_af.fib_index, address, address_length);
- else
- ip4_add_interface_routes (sw_if_index,
- im, ip4_af.fib_index,
- pool_elt_at_index
- (lm->if_address_pool, if_address_index));
+ /* intf addr routes are added/deleted on admin up/down */
+ if (vnet_sw_interface_is_admin_up (vnm, sw_if_index))
+ {
+ if (is_del)
+ ip4_del_interface_routes (im, ip4_af.fib_index, address,
+ address_length);
+ else
+ ip4_add_interface_routes (sw_if_index,
+ im, ip4_af.fib_index,
+ pool_elt_at_index
+ (lm->if_address_pool, if_address_index));
+ }
/* If pool did not grow/shrink: add duplicate address. */
if (elts_before != pool_elts (lm->if_address_pool))
}
#endif
+static clib_error_t *
+ip4_sw_interface_admin_up_down (vnet_main_t * vnm, u32 sw_if_index, u32 flags)
+{
+ ip4_main_t *im = &ip4_main;
+ ip_interface_address_t *ia;
+ ip4_address_t *a;
+ u32 is_admin_up, fib_index;
+
+ /* Fill in lookup tables with default table (0). */
+ vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
+
+ vec_validate_init_empty (im->
+ lookup_main.if_address_pool_index_by_sw_if_index,
+ sw_if_index, ~0);
+
+ is_admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
+
+ fib_index = vec_elt (im->fib_index_by_sw_if_index, sw_if_index);
+
+ /* *INDENT-OFF* */
+ foreach_ip_interface_address (&im->lookup_main, ia, sw_if_index,
+ 0 /* honor unnumbered */,
+ ({
+ a = ip_interface_address_get_address (&im->lookup_main, ia);
+ if (is_admin_up)
+ ip4_add_interface_routes (sw_if_index,
+ im, fib_index,
+ ia);
+ else
+ ip4_del_interface_routes (im, fib_index,
+ a, ia->address_length);
+ }));
+ /* *INDENT-ON* */
+
+ return 0;
+}
+
+VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION (ip4_sw_interface_admin_up_down);
+
/* Built-in ip4 unicast rx feature path definition */
/* *INDENT-OFF* */
VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
vnet_buffer (b)->sw_if_index[VLIB_TX] != ~0 ?
vnet_buffer (b)->sw_if_index[VLIB_TX] : vnet_buffer (b)->ip.fib_index;
+ /*
+ * vnet_buffer()->ip.adj_index[VLIB_RX] will be set to the index of the
+ * adjacency for the destination address (the local interface address).
+ * vnet_buffer()->ip.adj_index[VLIB_TX] will be set to the index of the
+ * adjacency for the source address (the remote sender's address)
+ */
if (PREDICT_FALSE (last_check->first ||
(last_check->src.as_u32 != ip0->src_address.as_u32)))
{
leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address, 3);
lbi0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0);
+ vnet_buffer (b)->ip.adj_index[VLIB_RX] =
+ vnet_buffer (b)->ip.adj_index[VLIB_TX];
vnet_buffer (b)->ip.adj_index[VLIB_TX] = lbi0;
- vnet_buffer (b)->ip.adj_index[VLIB_RX] = lbi0;
lb0 = load_balance_get (lbi0);
dpo0 = load_balance_get_bucket_i (lb0, 0);
}
else
{
+ vnet_buffer (b)->ip.adj_index[VLIB_RX] =
+ vnet_buffer (b)->ip.adj_index[VLIB_TX];
vnet_buffer (b)->ip.adj_index[VLIB_TX] = last_check->lbi;
- vnet_buffer (b)->ip.adj_index[VLIB_RX] = last_check->lbi;
*error0 = last_check->error;
last_check->first = 0;
}
vnet_buffer (b[1])->sw_if_index[VLIB_TX] :
vnet_buffer (b[1])->ip.fib_index;
+ /*
+ * vnet_buffer()->ip.adj_index[VLIB_RX] will be set to the index of the
+ * adjacency for the destination address (the local interface address).
+ * vnet_buffer()->ip.adj_index[VLIB_TX] will be set to the index of the
+ * adjacency for the source address (the remote sender's address)
+ */
if (PREDICT_FALSE (not_last_hit))
{
mtrie[0] = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie;
lbi[0] = ip4_fib_mtrie_leaf_get_adj_index (leaf[0]);
lbi[1] = ip4_fib_mtrie_leaf_get_adj_index (leaf[1]);
+ vnet_buffer (b[0])->ip.adj_index[VLIB_RX] =
+ vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = lbi[0];
- vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = lbi[0];
+ vnet_buffer (b[1])->ip.adj_index[VLIB_RX] =
+ vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = lbi[1];
- vnet_buffer (b[1])->ip.adj_index[VLIB_RX] = lbi[1];
lb[0] = load_balance_get (lbi[0]);
lb[1] = load_balance_get (lbi[1]);
}
else
{
+ vnet_buffer (b[0])->ip.adj_index[VLIB_RX] =
+ vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = last_check->lbi;
- vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = last_check->lbi;
+ vnet_buffer (b[1])->ip.adj_index[VLIB_RX] =
+ vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = last_check->lbi;
- vnet_buffer (b[1])->ip.adj_index[VLIB_RX] = last_check->lbi;
error[0] = last_check->error;
error[1] = last_check->error;
lm->local_next_by_ip_protocol[protocol] =
vlib_node_add_next (vm, ip4_local_node.index, node_index);
}
+
+void
+ip4_unregister_protocol (u32 protocol)
+{
+ ip4_main_t *im = &ip4_main;
+ ip_lookup_main_t *lm = &im->lookup_main;
+
+ ASSERT (protocol < ARRAY_LEN (lm->local_next_by_ip_protocol));
+ lm->local_next_by_ip_protocol[protocol] = IP_LOCAL_NEXT_PUNT;
+}
#endif
static clib_error_t *
u32 node_index = vlib_get_node (vm,
ip4_local_node.index)->
next_nodes[lm->local_next_by_ip_protocol[i]];
- vlib_cli_output (vm, "%d: %U", i, format_vlib_node_name, vm,
- node_index);
+ vlib_cli_output (vm, "%U: %U", format_ip_protocol, i,
+ format_vlib_node_name, vm, node_index);
}
}
return 0;
vlib_packet_template_get_packet (vm,
&im->ip4_arp_request_packet_template,
&bi0);
- b0 = vlib_get_buffer (vm, bi0);
-
- /* copy the persistent fields from the original */
- clib_memcpy_fast (b0->opaque2, p0->opaque2, sizeof (p0->opaque2));
-
/* Seems we're out of buffers */
if (PREDICT_FALSE (!h0))
{
continue;
}
+ b0 = vlib_get_buffer (vm, bi0);
+
+ /* copy the persistent fields from the original */
+ clib_memcpy_fast (b0->opaque2, p0->opaque2, sizeof (p0->opaque2));
+
/* Add rewrite/encap string for ARP packet. */
vnet_rewrite_one_header (adj0[0], h0, sizeof (ethernet_header_t));