- if (mp->del_all)
- ip_del_all_interface_addresses (vm, ntohl(mp->sw_if_index));
- else if (mp->is_ipv6)
- ip6_add_del_interface_address (vm, ntohl(mp->sw_if_index),
- (void *)mp->address,
- mp->address_length, is_del);
- else
- ip4_add_del_interface_address (vm, ntohl(mp->sw_if_index),
- (void *) mp->address,
- mp->address_length, is_del);
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO(VL_API_SW_INTERFACE_ADD_DEL_ADDRESS_REPLY);
-}
-
-static void
-vl_api_sw_interface_set_table_t_handler (vl_api_sw_interface_set_table_t *mp)
-{
- int rv = 0;
- u32 table_id = ntohl(mp->vrf_id);
- u32 sw_if_index = ntohl(mp->sw_if_index);
- vl_api_sw_interface_set_table_reply_t * rmp;
- stats_main_t * sm = &stats_main;
-
- VALIDATE_SW_IF_INDEX(mp);
-
- dslock (sm, 1 /* release hint */, 4 /* tag */);
-
- if (mp->is_ipv6) {
- ip6_main_t * im = &ip6_main;
- ip6_fib_t * fib =
- find_ip6_fib_by_table_index_or_id (im, table_id,
- IP6_ROUTE_FLAG_TABLE_ID);
- if (fib) {
- vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
- im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
- } else {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- }
- } else {
- ip4_main_t * im = &ip4_main;
- ip4_fib_t * fib = find_ip4_fib_by_table_index_or_id
- (im, table_id, IP4_ROUTE_FLAG_TABLE_ID);
-
- /* Truthfully this can't fail */
- if (fib) {
- vec_validate (im->fib_index_by_sw_if_index, sw_if_index);
- im->fib_index_by_sw_if_index[sw_if_index] = fib->index;
- } else {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- }
- }
- dsunlock(sm);
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO(VL_API_SW_INTERFACE_SET_TABLE_REPLY);
-}
-
-static void
-vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t *mp)
-{
- vlib_main_t *vm = vlib_get_main();
- ip4_main_t * im4 = &ip4_main;
- ip6_main_t * im6 = &ip6_main;
- vl_api_sw_interface_set_vpath_reply_t * rmp;
- int rv = 0;
- u32 ci;
- u32 sw_if_index = ntohl(mp->sw_if_index);
- ip4_main_t *ip4m = &ip4_main;
- ip6_main_t *ip6m = &ip6_main;
- ip_lookup_main_t *ip4lm = &ip4m->lookup_main;
- ip_lookup_main_t *ip6lm = &ip6m->lookup_main;
- ip_config_main_t *rx_cm4u = &ip4lm->rx_config_mains[VNET_UNICAST];
- ip_config_main_t *rx_cm4m = &ip4lm->rx_config_mains[VNET_MULTICAST];
- ip_config_main_t *rx_cm6u = &ip6lm->rx_config_mains[VNET_UNICAST];
- ip_config_main_t *rx_cm6m = &ip6lm->rx_config_mains[VNET_MULTICAST];
-
- VALIDATE_SW_IF_INDEX(mp);
-
- l2input_intf_bitmap_enable(sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
- if (mp->enable) {
- ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
- ci = vnet_config_add_feature(vm, &rx_cm4u->config_main,
- ci,
- im4->ip4_unicast_rx_feature_vpath,
- 0, 0);
- rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
- ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
- ci = vnet_config_add_feature(vm, &rx_cm4m->config_main,
- ci,
- im4->ip4_multicast_rx_feature_vpath,
- 0, 0);
- rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
- ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
- ci = vnet_config_add_feature(vm, &rx_cm6u->config_main,
- ci,
- im6->ip6_unicast_rx_feature_vpath,
- 0, 0);
- rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
- ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
- ci = vnet_config_add_feature(vm, &rx_cm6m->config_main,
- ci,
- im6->ip6_multicast_rx_feature_vpath,
- 0, 0);
- rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
- } else {
- ci = rx_cm4u->config_index_by_sw_if_index[sw_if_index]; //IP4 unicast
- ci = vnet_config_del_feature(vm, &rx_cm4u->config_main,
- ci,
- im4->ip4_unicast_rx_feature_vpath,
- 0, 0);
- rx_cm4u->config_index_by_sw_if_index[sw_if_index] = ci;
- ci = rx_cm4m->config_index_by_sw_if_index[sw_if_index]; //IP4 mcast
- ci = vnet_config_del_feature(vm, &rx_cm4m->config_main,
- ci,
- im4->ip4_multicast_rx_feature_vpath,
- 0, 0);
- rx_cm4m->config_index_by_sw_if_index[sw_if_index] = ci;
- ci = rx_cm6u->config_index_by_sw_if_index[sw_if_index]; //IP6 unicast
- ci = vnet_config_del_feature(vm, &rx_cm6u->config_main,
- ci,
- im6->ip6_unicast_rx_feature_vpath,
- 0, 0);
- rx_cm6u->config_index_by_sw_if_index[sw_if_index] = ci;
- ci = rx_cm6m->config_index_by_sw_if_index[sw_if_index]; //IP6 mcast
- ci = vnet_config_del_feature(vm, &rx_cm6m->config_main,
- ci,
- im6->ip6_multicast_rx_feature_vpath,
- 0, 0);
- rx_cm6m->config_index_by_sw_if_index[sw_if_index] = ci;
- }
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO(VL_API_SW_INTERFACE_SET_VPATH_REPLY);
-}
-
-static void
-vl_api_sw_interface_set_l2_xconnect_t_handler (
- vl_api_sw_interface_set_l2_xconnect_t *mp)
-{
- vl_api_sw_interface_set_l2_xconnect_reply_t * rmp;
- int rv = 0;
- u32 rx_sw_if_index = ntohl(mp->rx_sw_if_index);
- u32 tx_sw_if_index = ntohl(mp->tx_sw_if_index);
- vlib_main_t *vm = vlib_get_main();
- vnet_main_t *vnm = vnet_get_main();
-
- VALIDATE_RX_SW_IF_INDEX(mp);
-
- if (mp->enable) {
- VALIDATE_TX_SW_IF_INDEX(mp);
- rv = set_int_l2_mode(vm, vnm, MODE_L2_XC,
- rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
- } else {
- rv = set_int_l2_mode(vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
- }
-
- BAD_RX_SW_IF_INDEX_LABEL;
- BAD_TX_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO(VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
-}
-
-static void
-vl_api_sw_interface_set_l2_bridge_t_handler (
- vl_api_sw_interface_set_l2_bridge_t *mp)
-{
- bd_main_t * bdm = &bd_main;
- vl_api_sw_interface_set_l2_bridge_reply_t * rmp;
- int rv = 0;
- u32 rx_sw_if_index = ntohl(mp->rx_sw_if_index);
- u32 bd_id = ntohl(mp->bd_id);
- u32 bd_index;
- u32 bvi = mp->bvi;
- u8 shg = mp->shg;
- vlib_main_t *vm = vlib_get_main();
- vnet_main_t *vnm = vnet_get_main();
-
- VALIDATE_RX_SW_IF_INDEX(mp);
-
- bd_index = bd_find_or_add_bd_index (bdm, bd_id);
-
- if (mp->enable) {
- //VALIDATE_TX_SW_IF_INDEX(mp);
- rv = set_int_l2_mode(vm, vnm, MODE_L2_BRIDGE,
- rx_sw_if_index, bd_index, bvi, shg, 0);
- } else {
- rv = set_int_l2_mode(vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
+static int
+mpls_route_add_del_t_handler (vnet_main_t * vnm,
+ vl_api_mpls_route_add_del_t * mp)
+{
+ u32 fib_index, next_hop_fib_index;
+ mpls_label_t *label_stack = NULL;
+ int rv, ii, n_labels;;
+
+ fib_prefix_t pfx = {
+ .fp_len = 21,
+ .fp_proto = FIB_PROTOCOL_MPLS,
+ .fp_eos = mp->mr_eos,
+ .fp_label = ntohl (mp->mr_label),
+ };
+ if (pfx.fp_eos)
+ {
+ if (mp->mr_next_hop_proto_is_ip4)
+ {
+ pfx.fp_payload_proto = DPO_PROTO_IP4;
+ }
+ else
+ {
+ pfx.fp_payload_proto = DPO_PROTO_IP6;
+ }
+ }
+ else
+ {
+ pfx.fp_payload_proto = DPO_PROTO_MPLS;
+ }
+
+ rv = add_del_route_check (FIB_PROTOCOL_MPLS,
+ mp->mr_table_id,
+ mp->mr_next_hop_sw_if_index,
+ dpo_proto_to_fib (pfx.fp_payload_proto),
+ mp->mr_next_hop_table_id,
+ mp->mr_create_table_if_needed,
+ &fib_index, &next_hop_fib_index);
+
+ if (0 != rv)
+ return (rv);
+
+ ip46_address_t nh;
+ memset (&nh, 0, sizeof (nh));
+
+ if (mp->mr_next_hop_proto_is_ip4)
+ memcpy (&nh.ip4, mp->mr_next_hop, sizeof (nh.ip4));
+ else
+ memcpy (&nh.ip6, mp->mr_next_hop, sizeof (nh.ip6));
+
+ n_labels = mp->mr_next_hop_n_out_labels;
+ if (n_labels == 0)
+ ;
+ else if (1 == n_labels)
+ vec_add1 (label_stack, ntohl (mp->mr_next_hop_out_label_stack[0]));
+ else
+ {
+ vec_validate (label_stack, n_labels - 1);
+ for (ii = 0; ii < n_labels; ii++)
+ label_stack[ii] = ntohl (mp->mr_next_hop_out_label_stack[ii]);