- if (is_drop || is_local || is_classify || is_unreach || is_prohibit)
- {
- /*
- * special route types that link directly to the adj
- */
- if (is_add)
- {
- dpo_id_t dpo = DPO_INVALID;
- dpo_proto_t dproto;
-
- dproto = fib_proto_to_dpo (prefix->fp_proto);
-
- if (is_drop)
- ip_null_dpo_add_and_lock (dproto, IP_NULL_ACTION_NONE, &dpo);
- else if (is_local)
- receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo);
- else if (is_unreach)
- ip_null_dpo_add_and_lock (dproto,
- IP_NULL_ACTION_SEND_ICMP_UNREACH, &dpo);
- else if (is_prohibit)
- ip_null_dpo_add_and_lock (dproto,
- IP_NULL_ACTION_SEND_ICMP_PROHIBIT,
- &dpo);
- else if (is_classify)
- {
- if (pool_is_free_index (cm->tables,
- ntohl (classify_table_index)))
- {
- stats_dsunlock ();
- return VNET_API_ERROR_NO_SUCH_TABLE;
- }
-
- dpo_set (&dpo, DPO_CLASSIFY, dproto,
- classify_dpo_create (dproto,
- ntohl (classify_table_index)));
- }
- else
- {
- stats_dsunlock ();
- return VNET_API_ERROR_NO_SUCH_TABLE;
- }
-
- fib_table_entry_special_dpo_update (fib_index,
- prefix,
- FIB_SOURCE_API,
- FIB_ENTRY_FLAG_EXCLUSIVE, &dpo);
- dpo_reset (&dpo);
- }
- else
- {
- fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
- }
- }
- else
- {
- if (is_add)
- {
- vec_add1 (paths, path);
- fib_table_entry_update (fib_index,
- prefix, FIB_SOURCE_API, entry_flags, paths);
- vec_free (paths);
- }
- else
- {
- fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
- }
- }
-
- stats_dsunlock ();
- return (0);
-}
-
-int
-add_del_route_check (fib_protocol_t table_proto,
- u32 table_id,
- u32 next_hop_sw_if_index,
- dpo_proto_t next_hop_table_proto,
- u32 next_hop_table_id,
- u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index)
-{
- vnet_main_t *vnm = vnet_get_main ();
-
- /* Temporaray whilst I do the CSIT dance */
- u8 create_missing_tables = 1;
-
- *fib_index = fib_table_find (table_proto, ntohl (table_id));
- if (~0 == *fib_index)
- {
- if (create_missing_tables)
- {
- *fib_index = fib_table_find_or_create_and_lock (table_proto,
- ntohl (table_id),
- FIB_SOURCE_API);
- }
- else
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
- }
-
- if (!is_rpf_id && ~0 != ntohl (next_hop_sw_if_index))
- {
- if (pool_is_free_index (vnm->interface_main.sw_interfaces,
- ntohl (next_hop_sw_if_index)))
- {
- return VNET_API_ERROR_NO_MATCHING_INTERFACE;
- }
- }
- else
- {
- fib_protocol_t fib_nh_proto;
-
- if (next_hop_table_proto > DPO_PROTO_MPLS)
- return (0);
-
- fib_nh_proto = dpo_proto_to_fib (next_hop_table_proto);
-
- if (is_rpf_id)
- *next_hop_fib_index = mfib_table_find (fib_nh_proto,
- ntohl (next_hop_table_id));
- else
- *next_hop_fib_index = fib_table_find (fib_nh_proto,
- ntohl (next_hop_table_id));
-
- if (~0 == *next_hop_fib_index)
- {
- if (create_missing_tables)
- {
- if (is_rpf_id)
- *next_hop_fib_index =
- mfib_table_find_or_create_and_lock (fib_nh_proto,
- ntohl
- (next_hop_table_id),
- MFIB_SOURCE_API);
- else
- *next_hop_fib_index =
- fib_table_find_or_create_and_lock (fib_nh_proto,
- ntohl
- (next_hop_table_id),
- FIB_SOURCE_API);
- }
- else
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
- }
- }
-
- return (0);
-}
-
-static int
-ip4_add_del_route_t_handler (vl_api_ip_add_del_route_t * mp)
-{
- u32 fib_index, next_hop_fib_index;
- mpls_label_t *label_stack = NULL;
- int rv, ii, n_labels;;