_(IP_DUMP, ip_dump) \
_(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
_(IP_ADD_DEL_ROUTE, ip_add_del_route) \
+_(IP_TABLE_ADD_DEL, ip_table_add_del) \
_(SET_IP_FLOW_HASH,set_ip_flow_hash) \
_(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
_(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
int is_ip4;
vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
- if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP4)
+ if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
fp->afi = IP46_TYPE_IP4;
- else if (api_rpath->rpath.frp_proto == FIB_PROTOCOL_IP6)
+ else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
fp->afi = IP46_TYPE_IP6;
else
{
default:
break;
}
- fp->weight = htonl (api_rpath->rpath.frp_weight);
+ fp->weight = api_rpath->rpath.frp_weight;
+ fp->preference = api_rpath->rpath.frp_preference;
fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
copy_fib_next_hop (api_rpath, fp);
fp++;
default:
break;
}
- fp->weight = htonl (api_rpath->rpath.frp_weight);
- fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
+ fp->weight = api_rpath->rpath.frp_weight;
+ fp->preference = api_rpath->rpath.frp_preference;
+ fp->sw_if_index = api_rpath->rpath.frp_sw_if_index;
copy_fib_next_hop (api_rpath, fp);
fp++;
}
REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
}
+void
+ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api)
+{
+ u32 fib_index, mfib_index;
+
+ /*
+ * ignore action on the default table - this is always present
+ * and cannot be added nor deleted from the API
+ */
+ if (0 != table_id)
+ {
+ /*
+ * The API holds only one lock on the table.
+ * i.e. it can be added many times via the API but needs to be
+ * deleted only once.
+ * The FIB index for unicast and multicast is not necessarily the
+ * same, since internal VPP systesm (like LISP and SR) create
+ * their own unicast tables.
+ */
+ fib_index = fib_table_find (fproto, table_id);
+ mfib_index = mfib_table_find (fproto, table_id);
+
+ if (~0 != fib_index)
+ {
+ fib_table_unlock (fib_index, fproto,
+ (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI));
+ }
+ if (~0 != mfib_index)
+ {
+ mfib_table_unlock (mfib_index, fproto,
+ (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI));
+ }
+ }
+}
+
+void
+vl_api_ip_table_add_del_t_handler (vl_api_ip_table_add_del_t * mp)
+{
+ vl_api_ip_table_add_del_reply_t *rmp;
+ fib_protocol_t fproto = (mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
+ u32 table_id = ntohl (mp->table_id);
+ int rv = 0;
+
+ if (mp->is_add)
+ {
+ ip_table_create (fproto, table_id, 1);
+ }
+ else
+ {
+ ip_table_delete (fproto, table_id, 1);
+ }
+
+ REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
+}
+
int
add_del_route_t_handler (u8 is_multipath,
u8 is_add,
u8 is_rpf_id,
u32 fib_index,
const fib_prefix_t * prefix,
- u8 next_hop_proto_is_ip4,
+ dpo_proto_t next_hop_proto,
const ip46_address_t * next_hop,
u32 next_hop_sw_if_index,
u8 next_hop_fib_index,
- u32 next_hop_weight,
+ u16 next_hop_weight,
+ u16 next_hop_preference,
mpls_label_t next_hop_via_label,
mpls_label_t * next_hop_out_label_stack)
{
vnet_classify_main_t *cm = &vnet_classify_main;
fib_route_path_flags_t path_flags = FIB_ROUTE_PATH_FLAG_NONE;
fib_route_path_t path = {
- .frp_proto = (next_hop_proto_is_ip4 ?
- FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6),
+ .frp_proto = next_hop_proto,
.frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
.frp_sw_if_index = next_hop_sw_if_index,
.frp_fib_index = next_hop_fib_index,
.frp_weight = next_hop_weight,
+ .frp_preference = next_hop_preference,
.frp_label_stack = next_hop_out_label_stack,
};
fib_route_path_t *paths = NULL;
if (MPLS_LABEL_INVALID != next_hop_via_label)
{
- path.frp_proto = FIB_PROTOCOL_MPLS;
+ path.frp_proto = DPO_PROTO_MPLS;
path.frp_local_label = next_hop_via_label;
path.frp_eos = MPLS_NON_EOS;
}
add_del_route_check (fib_protocol_t table_proto,
u32 table_id,
u32 next_hop_sw_if_index,
- fib_protocol_t next_hop_table_proto,
+ dpo_proto_t next_hop_table_proto,
u32 next_hop_table_id,
- u8 create_missing_tables,
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));
+ ntohl (table_id),
+ FIB_SOURCE_API);
}
else
{
}
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 (next_hop_table_proto,
+ *next_hop_fib_index = mfib_table_find (fib_nh_proto,
ntohl (next_hop_table_id));
else
- *next_hop_fib_index = fib_table_find (next_hop_table_proto,
+ *next_hop_fib_index = fib_table_find (fib_nh_proto,
ntohl (next_hop_table_id));
if (~0 == *next_hop_fib_index)
{
if (is_rpf_id)
*next_hop_fib_index =
- mfib_table_find_or_create_and_lock (next_hop_table_proto,
+ mfib_table_find_or_create_and_lock (fib_nh_proto,
ntohl
- (next_hop_table_id));
+ (next_hop_table_id),
+ MFIB_SOURCE_API);
else
*next_hop_fib_index =
- fib_table_find_or_create_and_lock (next_hop_table_proto,
+ fib_table_find_or_create_and_lock (fib_nh_proto,
ntohl
- (next_hop_table_id));
+ (next_hop_table_id),
+ FIB_SOURCE_API);
}
else
{
rv = add_del_route_check (FIB_PROTOCOL_IP4,
mp->table_id,
mp->next_hop_sw_if_index,
- FIB_PROTOCOL_IP4,
+ DPO_PROTO_IP4,
mp->next_hop_table_id,
- mp->create_vrf_if_needed, 0,
- &fib_index, &next_hop_fib_index);
+ 0, &fib_index, &next_hop_fib_index);
if (0 != rv)
return (rv);
mp->classify_table_index,
mp->is_resolve_host,
mp->is_resolve_attached, 0, 0,
- fib_index, &pfx, 1,
+ fib_index, &pfx, DPO_PROTO_IP4,
&nh,
ntohl (mp->next_hop_sw_if_index),
next_hop_fib_index,
mp->next_hop_weight,
+ mp->next_hop_preference,
ntohl (mp->next_hop_via_label),
label_stack));
}
rv = add_del_route_check (FIB_PROTOCOL_IP6,
mp->table_id,
mp->next_hop_sw_if_index,
- FIB_PROTOCOL_IP6,
+ DPO_PROTO_IP6,
mp->next_hop_table_id,
- mp->create_vrf_if_needed, 0,
- &fib_index, &next_hop_fib_index);
+ 0, &fib_index, &next_hop_fib_index);
if (0 != rv)
return (rv);
mp->classify_table_index,
mp->is_resolve_host,
mp->is_resolve_attached, 0, 0,
- fib_index, &pfx, 0,
+ fib_index, &pfx, DPO_PROTO_IP6,
&nh, ntohl (mp->next_hop_sw_if_index),
next_hop_fib_index,
mp->next_hop_weight,
+ mp->next_hop_preference,
ntohl (mp->next_hop_via_label),
label_stack));
}
REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
}
+void
+ip_table_create (fib_protocol_t fproto, u32 table_id, u8 is_api)
+{
+ u32 fib_index, mfib_index;
+
+ /*
+ * ignore action on the default table - this is always present
+ * and cannot be added nor deleted from the API
+ */
+ if (0 != table_id)
+ {
+ /*
+ * The API holds only one lock on the table.
+ * i.e. it can be added many times via the API but needs to be
+ * deleted only once.
+ * The FIB index for unicast and multicast is not necessarily the
+ * same, since internal VPP systesm (like LISP and SR) create
+ * their own unicast tables.
+ */
+ fib_index = fib_table_find (fproto, table_id);
+ mfib_index = mfib_table_find (fproto, table_id);
+
+ if (~0 == fib_index)
+ {
+ fib_table_find_or_create_and_lock (fproto, table_id,
+ (is_api ?
+ FIB_SOURCE_API :
+ FIB_SOURCE_CLI));
+ }
+ if (~0 == mfib_index)
+ {
+ mfib_table_find_or_create_and_lock (fproto, table_id,
+ (is_api ?
+ MFIB_SOURCE_API :
+ MFIB_SOURCE_CLI));
+ }
+ }
+}
+
static int
add_del_mroute_check (fib_protocol_t table_proto,
u32 table_id,
- u32 next_hop_sw_if_index,
- u8 is_local, u8 create_missing_tables, u32 * fib_index)
+ u32 next_hop_sw_if_index, u8 is_local, u32 * fib_index)
{
vnet_main_t *vnm = vnet_get_main ();
*fib_index = mfib_table_find (table_proto, ntohl (table_id));
if (~0 == *fib_index)
{
- if (create_missing_tables)
- {
- *fib_index = mfib_table_find_or_create_and_lock (table_proto,
- ntohl (table_id));
- }
- else
- {
- /* No such VRF, and we weren't asked to create one */
- return VNET_API_ERROR_NO_SUCH_FIB;
- }
+ /* No such table */
+ return VNET_API_ERROR_NO_SUCH_FIB;
}
if (~0 != ntohl (next_hop_sw_if_index))
fib_route_path_t path = {
.frp_sw_if_index = next_hop_sw_if_index,
- .frp_proto = prefix->fp_proto,
+ .frp_proto = fib_proto_to_dpo (prefix->fp_proto),
};
if (is_local)
rv = add_del_mroute_check (fproto,
mp->table_id,
mp->next_hop_sw_if_index,
- mp->is_local,
- mp->create_vrf_if_needed, &fib_index);
+ mp->is_local, &fib_index);
if (0 != rv)
return (rv);
set_ip6_flow_hash (vl_api_set_ip_flow_hash_t * mp)
{
vl_api_set_ip_flow_hash_reply_t *rmp;
- int rv = VNET_API_ERROR_UNIMPLEMENTED;
+ int rv;
+ u32 table_id;
+ flow_hash_config_t flow_hash_config = 0;
+
+ table_id = ntohl (mp->vrf_id);
+
+#define _(a,b) if (mp->a) flow_hash_config |= b;
+ foreach_flow_hash_bit;
+#undef _
- clib_warning ("unimplemented...");
+ rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
}