From: Filip Tehlar Date: Mon, 16 Oct 2017 12:48:23 +0000 (-0700) Subject: LISP: add P-ITR/P-ETR/xTR API handlers, ONE-24 X-Git-Tag: v18.04-rc0~369 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=0a8840df8ea6d4936d080c111f2b361f575a773d LISP: add P-ITR/P-ETR/xTR API handlers, ONE-24 Change-Id: I25937cd7470c826d1e833e65530ae959c39139d8 Signed-off-by: Filip Tehlar --- diff --git a/src/vat/api_format.c b/src/vat/api_format.c index ddc1f8cfaa4..9f76f8a51ca 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -4238,6 +4238,123 @@ static void vam->result_ready = 1; } +static void + vl_api_one_show_xtr_mode_reply_t_handler + (vl_api_one_show_xtr_mode_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + i32 retval = ntohl (mp->retval); + + if (0 <= retval) + { + print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled"); + } + + vam->retval = retval; + vam->result_ready = 1; +} + +static void + vl_api_one_show_xtr_mode_reply_t_handler_json + (vl_api_one_show_xtr_mode_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t node; + u8 *status = 0; + + status = format (0, "%s", mp->is_en ? "enabled" : "disabled"); + vec_add1 (status, 0); + + vat_json_init_object (&node); + vat_json_object_add_string_copy (&node, "status", status); + + vec_free (status); + + vat_json_print (vam->ofp, &node); + vat_json_free (&node); + + vam->retval = ntohl (mp->retval); + vam->result_ready = 1; +} + +static void + vl_api_one_show_pitr_mode_reply_t_handler + (vl_api_one_show_pitr_mode_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + i32 retval = ntohl (mp->retval); + + if (0 <= retval) + { + print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled"); + } + + vam->retval = retval; + vam->result_ready = 1; +} + +static void + vl_api_one_show_pitr_mode_reply_t_handler_json + (vl_api_one_show_pitr_mode_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t node; + u8 *status = 0; + + status = format (0, "%s", mp->is_en ? "enabled" : "disabled"); + vec_add1 (status, 0); + + vat_json_init_object (&node); + vat_json_object_add_string_copy (&node, "status", status); + + vec_free (status); + + vat_json_print (vam->ofp, &node); + vat_json_free (&node); + + vam->retval = ntohl (mp->retval); + vam->result_ready = 1; +} + +static void + vl_api_one_show_petr_mode_reply_t_handler + (vl_api_one_show_petr_mode_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + i32 retval = ntohl (mp->retval); + + if (0 <= retval) + { + print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled"); + } + + vam->retval = retval; + vam->result_ready = 1; +} + +static void + vl_api_one_show_petr_mode_reply_t_handler_json + (vl_api_one_show_petr_mode_reply_t * mp) +{ + vat_main_t *vam = &vat_main; + vat_json_node_t node; + u8 *status = 0; + + status = format (0, "%s", mp->is_en ? "enabled" : "disabled"); + vec_add1 (status, 0); + + vat_json_init_object (&node); + vat_json_object_add_string_copy (&node, "status", status); + + vec_free (status); + + vat_json_print (vam->ofp, &node); + vat_json_free (&node); + + vam->retval = ntohl (mp->retval); + vam->result_ready = 1; +} + static void vl_api_show_one_use_petr_reply_t_handler (vl_api_show_one_use_petr_reply_t * mp) @@ -5154,6 +5271,9 @@ _(one_stats_enable_disable_reply) \ _(one_add_del_l2_arp_entry_reply) \ _(one_add_del_ndp_entry_reply) \ _(one_stats_flush_reply) \ +_(one_enable_disable_xtr_mode_reply) \ +_(one_enable_disable_pitr_mode_reply) \ +_(one_enable_disable_petr_mode_reply) \ _(gpe_enable_disable_reply) \ _(gpe_set_encap_mode_reply) \ _(gpe_add_del_iface_reply) \ @@ -5416,6 +5536,14 @@ _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply) \ _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply) \ _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply) \ _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply) \ +_(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \ +_(ONE_ENABLE_DISABLE_PITR_MODE_REPLY, \ + one_enable_disable_pitr_mode_reply) \ +_(ONE_ENABLE_DISABLE_PETR_MODE_REPLY, \ + one_enable_disable_petr_mode_reply) \ +_(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply) \ +_(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply) \ +_(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply) \ _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply) \ _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply) \ _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply) \ @@ -16403,6 +16531,189 @@ api_one_enable_disable (vat_main_t * vam) #define api_lisp_enable_disable api_one_enable_disable +static int +api_one_enable_disable_xtr_mode (vat_main_t * vam) +{ + unformat_input_t *input = vam->input; + vl_api_one_enable_disable_xtr_mode_t *mp; + u8 is_set = 0; + u8 is_en = 0; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "enable")) + { + is_set = 1; + is_en = 1; + } + else if (unformat (input, "disable")) + { + is_set = 1; + } + else + break; + } + + if (!is_set) + { + errmsg ("Value not set"); + return -99; + } + + /* Construct the API message */ + M (ONE_ENABLE_DISABLE_XTR_MODE, mp); + + mp->is_en = is_en; + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static int +api_one_show_xtr_mode (vat_main_t * vam) +{ + vl_api_one_show_xtr_mode_t *mp; + int ret; + + /* Construct the API message */ + M (ONE_SHOW_XTR_MODE, mp); + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static int +api_one_enable_disable_pitr_mode (vat_main_t * vam) +{ + unformat_input_t *input = vam->input; + vl_api_one_enable_disable_pitr_mode_t *mp; + u8 is_set = 0; + u8 is_en = 0; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "enable")) + { + is_set = 1; + is_en = 1; + } + else if (unformat (input, "disable")) + { + is_set = 1; + } + else + break; + } + + if (!is_set) + { + errmsg ("Value not set"); + return -99; + } + + /* Construct the API message */ + M (ONE_ENABLE_DISABLE_PITR_MODE, mp); + + mp->is_en = is_en; + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static int +api_one_show_pitr_mode (vat_main_t * vam) +{ + vl_api_one_show_pitr_mode_t *mp; + int ret; + + /* Construct the API message */ + M (ONE_SHOW_PITR_MODE, mp); + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static int +api_one_enable_disable_petr_mode (vat_main_t * vam) +{ + unformat_input_t *input = vam->input; + vl_api_one_enable_disable_petr_mode_t *mp; + u8 is_set = 0; + u8 is_en = 0; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "enable")) + { + is_set = 1; + is_en = 1; + } + else if (unformat (input, "disable")) + { + is_set = 1; + } + else + break; + } + + if (!is_set) + { + errmsg ("Value not set"); + return -99; + } + + /* Construct the API message */ + M (ONE_ENABLE_DISABLE_PETR_MODE, mp); + + mp->is_en = is_en; + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static int +api_one_show_petr_mode (vat_main_t * vam) +{ + vl_api_one_show_petr_mode_t *mp; + int ret; + + /* Construct the API message */ + M (ONE_SHOW_PETR_MODE, mp); + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + static int api_show_one_map_register_state (vat_main_t * vam) { @@ -21996,6 +22307,12 @@ _(one_get_map_request_itr_rlocs, "") \ _(one_map_register_set_ttl, "") \ _(one_set_transport_protocol, "udp|api") \ _(one_get_transport_protocol, "") \ +_(one_enable_disable_xtr_mode, "enable|disable") \ +_(one_show_xtr_mode, "") \ +_(one_enable_disable_pitr_mode, "enable|disable") \ +_(one_show_pitr_mode, "") \ +_(one_enable_disable_petr_mode, "enable|disable") \ +_(one_show_petr_mode, "") \ _(show_one_nsh_mapping, "") \ _(show_one_pitr, "") \ _(show_one_use_petr, "") \ diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c index 907e9a0f677..c12728800c3 100644 --- a/src/vnet/lisp-cp/control.c +++ b/src/vnet/lisp-cp/control.c @@ -221,7 +221,8 @@ ip_fib_get_first_egress_ip_for_dst (lisp_cp_main_t * lcm, ip_address_t * dst, } static int -dp_add_del_iface (lisp_cp_main_t * lcm, u32 vni, u8 is_l2, u8 is_add) +dp_add_del_iface (lisp_cp_main_t * lcm, u32 vni, u8 is_l2, u8 is_add, + u8 with_default_route) { uword *dp_table; @@ -251,7 +252,8 @@ dp_add_del_iface (lisp_cp_main_t * lcm, u32 vni, u8 is_l2, u8 is_add) if (is_l2) lisp_gpe_tenant_l2_iface_add_or_lock (vni, dp_table[0]); else - lisp_gpe_tenant_l3_iface_add_or_lock (vni, dp_table[0]); + lisp_gpe_tenant_l3_iface_add_or_lock (vni, dp_table[0], + with_default_route); } else { @@ -454,8 +456,16 @@ dp_add_fwd_entry (lisp_cp_main_t * lcm, u32 src_map_index, u32 dst_map_index) /* * Determine local mapping and eid */ - if (lcm->lisp_pitr) - lcl_map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index); + if (lcm->flags & LISP_FLAG_PITR_MODE) + { + if (lcm->pitr_map_index != ~0) + lcl_map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index); + else + { + clib_warning ("no PITR mapping configured!"); + return; + } + } else lcl_map = pool_elt_at_index (lcm->mapping_pool, src_map_index); lcl_eid = &lcl_map->eid; @@ -1101,7 +1111,8 @@ vnet_lisp_eid_table_map (u32 vni, u32 dp_id, u8 is_l2, u8 is_add) hash_set (vni_by_dp_table[0], dp_id, vni); /* create dp iface */ - dp_add_del_iface (lcm, vni, is_l2, 1); + dp_add_del_iface (lcm, vni, is_l2, 1 /* is_add */ , + 1 /* with_default_route */ ); } else { @@ -1112,7 +1123,7 @@ vnet_lisp_eid_table_map (u32 vni, u32 dp_id, u8 is_l2, u8 is_add) return -1; } /* remove dp iface */ - dp_add_del_iface (lcm, vni, is_l2, 0); + dp_add_del_iface (lcm, vni, is_l2, 0 /* is_add */ , 0 /* unused */ ); hash_unset (dp_table_by_vni[0], vni); hash_unset (vni_by_dp_table[0], dp_id); @@ -1499,8 +1510,18 @@ vnet_lisp_add_del_adjacency (vnet_lisp_add_del_adjacency_args_t * a) { /* check if source eid has an associated mapping. If pitr mode is on, * just use the pitr's mapping */ - if (lcm->lisp_pitr) - local_mi = lcm->pitr_map_index; + if (lcm->flags & LISP_FLAG_PITR_MODE) + { + if (lcm->pitr_map_index != ~0) + { + local_mi = lcm->pitr_map_index; + } + else + { + /* PITR mode is on, but no mapping is configured */ + return -1; + } + } else { if (gid_address_type (&a->reid) == GID_ADDR_NSH) @@ -1635,17 +1656,12 @@ vnet_lisp_pitr_set_locator_set (u8 * locator_set_name, u8 is_add) m->local = 1; m->pitr_set = 1; lcm->pitr_map_index = m - lcm->mapping_pool; - - /* enable pitr mode */ - lcm->lisp_pitr = 1; } else { /* remove pitr mapping */ pool_put_index (lcm->mapping_pool, lcm->pitr_map_index); - - /* disable pitr mode */ - lcm->lisp_pitr = 0; + lcm->pitr_map_index = ~0; } return 0; } @@ -1731,6 +1747,7 @@ vnet_lisp_use_petr (ip_address_t * ip, u8 is_add) /* Disable use-petr */ lcm->flags &= ~LISP_FLAG_USE_PETR; + lcm->petr_map_index = ~0; } return 0; } @@ -2182,10 +2199,66 @@ vnet_lisp_map_register_enable_disable (u8 is_enable) return 0; } +static void +lisp_cp_register_dst_port (vlib_main_t * vm) +{ + udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp, + lisp_cp_input_node.index, 1 /* is_ip4 */ ); + udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp6, + lisp_cp_input_node.index, 0 /* is_ip4 */ ); +} + +static void +lisp_cp_unregister_dst_port (vlib_main_t * vm) +{ + udp_unregister_dst_port (vm, UDP_DST_PORT_lisp_cp, 0 /* is_ip4 */ ); + udp_unregister_dst_port (vm, UDP_DST_PORT_lisp_cp6, 1 /* is_ip4 */ ); +} + +/** + * lisp_cp_enable_l2_l3_ifaces + * + * Enable all l2 and l3 ifaces + */ +static void +lisp_cp_enable_l2_l3_ifaces (lisp_cp_main_t * lcm, u8 with_default_route) +{ + u32 vni, dp_table; + + /* *INDENT-OFF* */ + hash_foreach(vni, dp_table, lcm->table_id_by_vni, ({ + dp_add_del_iface(lcm, vni, /* is_l2 */ 0, /* is_add */1, + with_default_route); + })); + hash_foreach(vni, dp_table, lcm->bd_id_by_vni, ({ + dp_add_del_iface(lcm, vni, /* is_l2 */ 1, 1, + with_default_route); + })); + /* *INDENT-ON* */ +} + +static void +lisp_cp_disable_l2_l3_ifaces (lisp_cp_main_t * lcm) +{ + u32 **rmts; + + /* clear interface table */ + hash_free (lcm->fwd_entry_by_mapping_index); + pool_free (lcm->fwd_entry_pool); + /* Clear state tracking rmt-lcl fwd entries */ + /* *INDENT-OFF* */ + pool_foreach(rmts, lcm->lcl_to_rmt_adjacencies, + { + vec_free(rmts[0]); + }); + /* *INDENT-ON* */ + hash_free (lcm->lcl_to_rmt_adjs_by_lcl_idx); + pool_free (lcm->lcl_to_rmt_adjacencies); +} + clib_error_t * vnet_lisp_enable_disable (u8 is_enable) { - u32 vni, dp_table, **rmts; clib_error_t *error = 0; lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); vnet_lisp_gpe_enable_disable_args_t _a, *a = &_a; @@ -2198,33 +2271,45 @@ vnet_lisp_enable_disable (u8 is_enable) a->is_en ? "enable" : "disable"); } - if (is_enable) + /* decide what to do based on mode */ + + if (lcm->flags & LISP_FLAG_XTR_MODE) { - /* enable all l2 and l3 ifaces */ + if (is_enable) + { + lisp_cp_register_dst_port (lcm->vlib_main); + lisp_cp_enable_l2_l3_ifaces (lcm, 1 /* with_default_route */ ); + } + else + { + lisp_cp_unregister_dst_port (lcm->vlib_main); + lisp_cp_disable_l2_l3_ifaces (lcm); + } + } - /* *INDENT-OFF* */ - hash_foreach(vni, dp_table, lcm->table_id_by_vni, ({ - dp_add_del_iface(lcm, vni, 0, 1); - })); - hash_foreach(vni, dp_table, lcm->bd_id_by_vni, ({ - dp_add_del_iface(lcm, vni, /* is_l2 */ 1, 1); - })); - /* *INDENT-ON* */ + if (lcm->flags & LISP_FLAG_PETR_MODE) + { + /* if in xTR mode, the LISP ports were already (un)registered above */ + if (!(lcm->flags & LISP_FLAG_XTR_MODE)) + { + if (is_enable) + lisp_cp_register_dst_port (lcm->vlib_main); + else + lisp_cp_unregister_dst_port (lcm->vlib_main); + } } - else + + if (lcm->flags & LISP_FLAG_PITR_MODE) { - /* clear interface table */ - hash_free (lcm->fwd_entry_by_mapping_index); - pool_free (lcm->fwd_entry_pool); - /* Clear state tracking rmt-lcl fwd entries */ - /* *INDENT-OFF* */ - pool_foreach(rmts, lcm->lcl_to_rmt_adjacencies, - { - vec_free(rmts[0]); - }); - /* *INDENT-ON* */ - hash_free (lcm->lcl_to_rmt_adjs_by_lcl_idx); - pool_free (lcm->lcl_to_rmt_adjacencies); + if (is_enable) + { + /* install interfaces, but no default routes */ + lisp_cp_enable_l2_l3_ifaces (lcm, 0 /* with_default_route */ ); + } + else + { + lisp_cp_disable_l2_l3_ifaces (lcm); + } } /* update global flag */ @@ -2980,8 +3065,10 @@ _send_encapsulated_map_request (lisp_cp_main_t * lcm, return 0; } + u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE; + /* get locator-set for seid */ - if (!lcm->lisp_pitr && gid_address_type (deid) != GID_ADDR_NSH) + if (!pitr_mode && gid_address_type (deid) != GID_ADDR_NSH) { map_index = gid_dictionary_lookup (&lcm->mapping_index_by_gid, seid); if (map_index == ~0) @@ -3004,10 +3091,18 @@ _send_encapsulated_map_request (lisp_cp_main_t * lcm, } else { - if (lcm->lisp_pitr) + if (pitr_mode) { - map = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index); - ls_index = map->locator_set_index; + if (lcm->pitr_map_index != ~0) + { + map = + pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index); + ls_index = map->locator_set_index; + } + else + { + return -1; + } } else { @@ -4357,8 +4452,9 @@ lisp_cp_init (vlib_main_t * vm) lcm->vlib_main = vm; lcm->vnet_main = vnet_get_main (); lcm->mreq_itr_rlocs = ~0; - lcm->lisp_pitr = 0; lcm->flags = 0; + lcm->pitr_map_index = ~0; + lcm->petr_map_index = ~0; memset (&lcm->active_map_resolver, 0, sizeof (lcm->active_map_resolver)); memset (&lcm->active_map_server, 0, sizeof (lcm->active_map_server)); @@ -4374,10 +4470,7 @@ lisp_cp_init (vlib_main_t * vm) hash_set (lcm->table_id_by_vni, 0, 0); hash_set (lcm->vni_by_table_id, 0, 0); - udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp, - lisp_cp_input_node.index, 1 /* is_ip4 */ ); - udp_register_dst_port (vm, UDP_DST_PORT_lisp_cp6, - lisp_cp_input_node.index, 0 /* is_ip4 */ ); + lisp_cp_register_dst_port (vm); u64 now = clib_cpu_time_now (); timing_wheel_init (&lcm->wheel, now, vm->clib_time.clocks_per_second); @@ -4386,6 +4479,7 @@ lisp_cp_init (vlib_main_t * vm) lcm->max_expired_map_registers = MAX_EXPIRED_MAP_REGISTERS_DEFAULT; lcm->expired_map_registers = 0; lcm->transport_protocol = LISP_TRANSPORT_PROTOCOL_UDP; + lcm->flags |= LISP_FLAG_XTR_MODE; return 0; } @@ -4775,6 +4869,124 @@ vnet_lisp_get_transport_protocol (void) return lcm->transport_protocol; } +int +vnet_lisp_enable_disable_xtr_mode (u8 is_enabled) +{ + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE; + u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE; + u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE; + + if (pitr_mode && is_enabled) + return VNET_API_ERROR_INVALID_ARGUMENT; + + if (is_enabled && xtr_mode) + return 0; + if (!is_enabled && !xtr_mode) + return 0; + + if (is_enabled) + { + if (!petr_mode) + { + lisp_cp_register_dst_port (lcm->vlib_main); + } + lisp_cp_enable_l2_l3_ifaces (lcm, 1 /* with_default_route */ ); + lcm->flags |= LISP_FLAG_XTR_MODE; + } + else + { + if (!petr_mode) + { + lisp_cp_unregister_dst_port (lcm->vlib_main); + } + lisp_cp_disable_l2_l3_ifaces (lcm); + lcm->flags &= ~LISP_FLAG_XTR_MODE; + } + return 0; +} + +int +vnet_lisp_enable_disable_pitr_mode (u8 is_enabled) +{ + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE; + u8 pitr_mode = lcm->flags & LISP_FLAG_PITR_MODE; + + if (xtr_mode && is_enabled) + return VNET_API_ERROR_INVALID_VALUE; + + if (is_enabled && pitr_mode) + return 0; + if (!is_enabled && !pitr_mode) + return 0; + + if (is_enabled) + { + /* create iface, no default route */ + lisp_cp_enable_l2_l3_ifaces (lcm, 0 /* with_default_route */ ); + lcm->flags |= LISP_FLAG_PITR_MODE; + } + else + { + lisp_cp_disable_l2_l3_ifaces (lcm); + lcm->flags &= ~LISP_FLAG_PITR_MODE; + } + return 0; +} + +int +vnet_lisp_enable_disable_petr_mode (u8 is_enabled) +{ + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + u8 xtr_mode = lcm->flags & LISP_FLAG_XTR_MODE; + u8 petr_mode = lcm->flags & LISP_FLAG_PETR_MODE; + + if (is_enabled && petr_mode) + return 0; + if (!is_enabled && !petr_mode) + return 0; + + if (is_enabled) + { + if (!xtr_mode) + { + lisp_cp_register_dst_port (lcm->vlib_main); + } + lcm->flags |= LISP_FLAG_PETR_MODE; + } + else + { + if (!xtr_mode) + { + lisp_cp_unregister_dst_port (lcm->vlib_main); + } + lcm->flags &= ~LISP_FLAG_PETR_MODE; + } + return 0; +} + +u8 +vnet_lisp_get_xtr_mode (void) +{ + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + return (lcm->flags & LISP_FLAG_XTR_MODE); +} + +u8 +vnet_lisp_get_pitr_mode (void) +{ + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + return (lcm->flags & LISP_FLAG_PITR_MODE); +} + +u8 +vnet_lisp_get_petr_mode (void) +{ + lisp_cp_main_t *lcm = vnet_lisp_cp_get_main (); + return (lcm->flags & LISP_FLAG_PETR_MODE); +} + VLIB_INIT_FUNCTION (lisp_cp_init); /* diff --git a/src/vnet/lisp-cp/control.h b/src/vnet/lisp-cp/control.h index a6da81880db..ac18768f88a 100644 --- a/src/vnet/lisp-cp/control.h +++ b/src/vnet/lisp-cp/control.h @@ -117,7 +117,10 @@ typedef enum } map_request_mode_t; #define foreach_lisp_flag_bit \ - _(USE_PETR, "Use Proxy-ETR") \ + _(USE_PETR, "Use Proxy-ETR") \ + _(XTR_MODE, "ITR/ETR mode") \ + _(PETR_MODE, "Use Proxy-ETR") \ + _(PITR_MODE, "Proxy-ITR mode") \ _(STATS_ENABLED, "Statistics enabled") typedef enum lisp_flag_bits @@ -246,12 +249,10 @@ typedef struct /* Proxy ITR map index */ u32 pitr_map_index; - /** Proxy ETR map index */ + /** Proxy ETR map index used for 'use-petr'. + * Not related to PETR tunnel mode */ u32 petr_map_index; - /* LISP PITR mode */ - u8 lisp_pitr; - /* mapping index for NSH */ u32 nsh_map_index; @@ -416,6 +417,13 @@ lisp_api_ndp_entry_t *vnet_lisp_ndp_entries_get_by_bd (u32 bd); u32 vnet_lisp_set_transport_protocol (u8 protocol); lisp_transport_protocol_t vnet_lisp_get_transport_protocol (void); +extern int vnet_lisp_enable_disable_xtr_mode (u8 is_enabled); +extern int vnet_lisp_enable_disable_pitr_mode (u8 is_enabled); +extern int vnet_lisp_enable_disable_petr_mode (u8 is_enabled); +extern u8 vnet_lisp_get_xtr_mode (void); +extern u8 vnet_lisp_get_pitr_mode (void); +extern u8 vnet_lisp_get_petr_mode (void); + map_records_arg_t *parse_map_reply (vlib_buffer_t * b); always_inline mapping_t * diff --git a/src/vnet/lisp-cp/lisp_api.c b/src/vnet/lisp-cp/lisp_api.c index 58235d046c8..f1b68d477ae 100644 --- a/src/vnet/lisp-cp/lisp_api.c +++ b/src/vnet/lisp-cp/lisp_api.c @@ -1273,7 +1273,10 @@ vl_api_show_lisp_pitr_t_handler (vl_api_show_lisp_pitr_t * mp) return; } - if (!lcm->lisp_pitr) + u8 is_enabled = (lcm->flags & LISP_FLAG_PITR_MODE) + && lcm->pitr_map_index != ~0; + + if (!is_enabled) { tmp_str = format (0, "N/A"); } @@ -1296,7 +1299,7 @@ vl_api_show_lisp_pitr_t_handler (vl_api_show_lisp_pitr_t * mp) /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_SHOW_LISP_PITR_REPLY, ({ - rmp->status = lcm->lisp_pitr; + rmp->status = lcm->flags & LISP_FLAG_PITR_MODE; strncpy((char *) rmp->locator_set_name, (char *) tmp_str, ARRAY_LEN(rmp->locator_set_name) - 1); })); diff --git a/src/vnet/lisp-cp/lisp_cli.c b/src/vnet/lisp-cp/lisp_cli.c index 738dda7044d..07c1c2c2ef3 100644 --- a/src/vnet/lisp-cp/lisp_cli.c +++ b/src/vnet/lisp-cp/lisp_cli.c @@ -705,11 +705,11 @@ lisp_show_pitr_command_fn (vlib_main_t * vm, mapping_t *m; locator_set_t *ls; u8 *tmp_str = 0; + u8 status = lcm->flags & LISP_FLAG_PITR_MODE; - vlib_cli_output (vm, "%=20s%=16s", - "pitr", lcm->lisp_pitr ? "locator-set" : ""); + vlib_cli_output (vm, "%=20s%=16s", "pitr", status ? "locator-set" : ""); - if (!lcm->lisp_pitr) + if (!status) { vlib_cli_output (vm, "%=20s", "disable"); return 0; diff --git a/src/vnet/lisp-cp/one_api.c b/src/vnet/lisp-cp/one_api.c index 33b3a47a352..0def13c6db9 100644 --- a/src/vnet/lisp-cp/one_api.c +++ b/src/vnet/lisp-cp/one_api.c @@ -134,7 +134,14 @@ _(ONE_ADD_DEL_NDP_ENTRY, one_add_del_ndp_entry) \ _(ONE_NDP_BD_GET, one_ndp_bd_get) \ _(ONE_NDP_ENTRIES_GET, one_ndp_entries_get) \ _(ONE_SET_TRANSPORT_PROTOCOL, one_set_transport_protocol) \ -_(ONE_GET_TRANSPORT_PROTOCOL, one_get_transport_protocol) +_(ONE_GET_TRANSPORT_PROTOCOL, one_get_transport_protocol) \ +_(ONE_ENABLE_DISABLE_XTR_MODE, one_enable_disable_xtr_mode) \ +_(ONE_SHOW_XTR_MODE, one_show_xtr_mode) \ +_(ONE_ENABLE_DISABLE_PITR_MODE, one_enable_disable_pitr_mode) \ +_(ONE_SHOW_PITR_MODE, one_show_pitr_mode) \ +_(ONE_ENABLE_DISABLE_PETR_MODE, one_enable_disable_petr_mode) \ +_(ONE_SHOW_PETR_MODE, one_show_petr_mode) \ + static locator_t * unformat_one_locs (vl_api_one_remote_locator_t * rmt_locs, u32 rloc_num) @@ -630,6 +637,7 @@ static void if (!mp->is_add) { vnet_lisp_add_del_adjacency_args_t _a, *a = &_a; + memset (a, 0, sizeof (a[0])); gid_address_copy (&a->reid, eid); a->is_add = 0; rv = vnet_lisp_add_del_adjacency (a); @@ -1444,7 +1452,10 @@ vl_api_show_one_pitr_t_handler (vl_api_show_one_pitr_t * mp) return; } - if (!lcm->lisp_pitr) + u8 is_enabled = (lcm->flags & LISP_FLAG_PITR_MODE) + && lcm->pitr_map_index != ~0; + + if (!is_enabled) { tmp_str = format (0, "N/A"); } @@ -1467,7 +1478,7 @@ vl_api_show_one_pitr_t_handler (vl_api_show_one_pitr_t * mp) /* *INDENT-OFF* */ REPLY_MACRO2(VL_API_SHOW_ONE_PITR_REPLY, ({ - rmp->status = lcm->lisp_pitr; + rmp->status = lcm->flags & LISP_FLAG_PITR_MODE; strncpy((char *) rmp->locator_set_name, (char *) tmp_str, ARRAY_LEN(rmp->locator_set_name) - 1); })); @@ -1769,6 +1780,78 @@ vl_api_one_ndp_entries_get_t_handler (vl_api_one_ndp_entries_get_t * mp) vec_free (entries); } +static void + vl_api_one_enable_disable_xtr_mode_t_handler + (vl_api_one_enable_disable_xtr_mode_t * mp) +{ + vl_api_one_enable_disable_xtr_mode_reply_t *rmp = 0; + int rv = vnet_lisp_enable_disable_xtr_mode (mp->is_en); + + REPLY_MACRO (VL_API_ONE_ENABLE_DISABLE_XTR_MODE_REPLY); +} + +static void +vl_api_one_show_xtr_mode_t_handler (vl_api_one_show_xtr_mode_t * mp) +{ + vl_api_one_show_xtr_mode_reply_t *rmp = 0; + int rv = 0; + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_ONE_SHOW_XTR_MODE_REPLY, + { + rmp->is_en = vnet_lisp_get_xtr_mode (); + }); + /* *INDENT-ON* */ +} + +static void + vl_api_one_enable_disable_pitr_mode_t_handler + (vl_api_one_enable_disable_pitr_mode_t * mp) +{ + vl_api_one_enable_disable_pitr_mode_reply_t *rmp = 0; + int rv = vnet_lisp_enable_disable_pitr_mode (mp->is_en); + + REPLY_MACRO (VL_API_ONE_ENABLE_DISABLE_PITR_MODE_REPLY); +} + +static void +vl_api_one_show_pitr_mode_t_handler (vl_api_one_show_pitr_mode_t * mp) +{ + vl_api_one_show_pitr_mode_reply_t *rmp = 0; + int rv = 0; + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_ONE_SHOW_PITR_MODE_REPLY, + { + rmp->is_en = vnet_lisp_get_pitr_mode (); + }); + /* *INDENT-ON* */ +} + +static void + vl_api_one_enable_disable_petr_mode_t_handler + (vl_api_one_enable_disable_petr_mode_t * mp) +{ + vl_api_one_enable_disable_petr_mode_reply_t *rmp = 0; + int rv = vnet_lisp_enable_disable_petr_mode (mp->is_en); + + REPLY_MACRO (VL_API_ONE_ENABLE_DISABLE_PETR_MODE_REPLY); +} + +static void +vl_api_one_show_petr_mode_t_handler (vl_api_one_show_petr_mode_t * mp) +{ + vl_api_one_show_petr_mode_reply_t *rmp = 0; + int rv = 0; + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_ONE_SHOW_PETR_MODE_REPLY, + { + rmp->is_en = vnet_lisp_get_petr_mode (); + }); + /* *INDENT-ON* */ +} + /* * one_api_hookup * Add vpe's API message handlers to the table. diff --git a/src/vnet/lisp-cp/one_cli.c b/src/vnet/lisp-cp/one_cli.c index 3b6d1b448af..af4a5bdd954 100644 --- a/src/vnet/lisp-cp/one_cli.c +++ b/src/vnet/lisp-cp/one_cli.c @@ -1020,11 +1020,11 @@ lisp_show_pitr_command_fn (vlib_main_t * vm, mapping_t *m; locator_set_t *ls; u8 *tmp_str = 0; + u8 status = lcm->flags & LISP_FLAG_PITR_MODE; - vlib_cli_output (vm, "%=20s%=16s", - "pitr", lcm->lisp_pitr ? "locator-set" : ""); + vlib_cli_output (vm, "%=20s%=16s", "pitr", status ? "locator-set" : ""); - if (!lcm->lisp_pitr) + if (!status) { vlib_cli_output (vm, "%=20s", "disable"); return 0; @@ -1206,6 +1206,165 @@ VLIB_CLI_COMMAND (one_cp_show_eid_table_command) = { }; /* *INDENT-ON* */ +static clib_error_t * +lisp_enable_disable_pitr_mode_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + u8 is_enabled = 0; + u8 is_set = 0; + clib_error_t *error = NULL; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "enable")) + { + is_set = 1; + is_enabled = 1; + } + else if (unformat (line_input, "disable")) + is_set = 1; + else + { + error = clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + goto done; + } + } + + if (!is_set) + { + error = clib_error_return (0, "state not set"); + goto done; + } + + vnet_lisp_enable_disable_pitr_mode (is_enabled); + +done: + unformat_free (line_input); + + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (one_cp_enable_disable_pitr_mode_command) = { + .path = "one pitr mode", + .short_help = "one pitr mode [enable|disable]", + .function = lisp_enable_disable_pitr_mode_command_fn, +}; +/* *INDENT-ON* */ + + +static clib_error_t * +lisp_enable_disable_petr_mode_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + u8 is_enabled = 0; + u8 is_set = 0; + clib_error_t *error = NULL; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "enable")) + { + is_set = 1; + is_enabled = 1; + } + else if (unformat (line_input, "disable")) + is_set = 1; + else + { + error = clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + goto done; + } + } + + if (!is_set) + { + error = clib_error_return (0, "state not set"); + goto done; + } + + vnet_lisp_enable_disable_petr_mode (is_enabled); + +done: + unformat_free (line_input); + + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (one_cp_enable_disable_petr_mode_command) = { + .path = "one petr mode", + .short_help = "one petr mode [enable|disable]", + .function = lisp_enable_disable_petr_mode_command_fn, +}; +/* *INDENT-ON* */ + +static clib_error_t * +lisp_enable_disable_xtr_mode_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + u8 is_enabled = 0; + u8 is_set = 0; + clib_error_t *error = NULL; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "enable")) + { + is_set = 1; + is_enabled = 1; + } + else if (unformat (line_input, "disable")) + is_set = 1; + else + { + error = clib_error_return (0, "parse error: '%U'", + format_unformat_error, line_input); + goto done; + } + } + + if (!is_set) + { + error = clib_error_return (0, "state not set"); + goto done; + } + + vnet_lisp_enable_disable_xtr_mode (is_enabled); + +done: + unformat_free (line_input); + + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (one_cp_enable_disable_xtr_mode_command) = { + .path = "one xtr mode", + .short_help = "one xtr mode [enable|disable]", + .function = lisp_enable_disable_xtr_mode_command_fn, +}; +/* *INDENT-ON* */ static clib_error_t * lisp_enable_disable_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -2155,6 +2314,30 @@ VLIB_CLI_COMMAND (one_stats_flush_command) = { }; /* *INDENT-ON* */ +static clib_error_t * +lisp_show_one_modes_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + u8 pitr_mode = vnet_lisp_get_pitr_mode (); + u8 petr_mode = vnet_lisp_get_petr_mode (); + u8 xtr_mode = vnet_lisp_get_xtr_mode (); + + vlib_cli_output (vm, "xTR: %s\n", xtr_mode ? "enabled" : "disabled"); + vlib_cli_output (vm, "P-ITR: %s\n", pitr_mode ? "enabled" : "disabled"); + vlib_cli_output (vm, "P-ETR: %s\n", petr_mode ? "enabled" : "disabled"); + + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (one_cp_show_one_modes_modes_command) = { + .path = "show one modes", + .short_help = "show one modes", + .function = lisp_show_one_modes_command_fn, +}; +/* *INDENT-ON* */ + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/lisp-gpe/interface.c b/src/vnet/lisp-gpe/interface.c index a0c05e85682..84933ec3987 100644 --- a/src/vnet/lisp-gpe/interface.c +++ b/src/vnet/lisp-gpe/interface.c @@ -575,7 +575,8 @@ lisp_gpe_tenant_add_default_routes (u32 table_id) * @return number of vectors in frame. */ u32 -lisp_gpe_add_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 table_id) +lisp_gpe_add_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 table_id, + u8 with_default_routes) { vnet_main_t *vnm = lgm->vnet_main; tunnel_lookup_t *l3_ifaces = &lgm->l3_ifaces; @@ -603,7 +604,8 @@ lisp_gpe_add_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 table_id) /* insert default routes that point to lisp-cp lookup */ lisp_gpe_iface_set_table (hi->sw_if_index, table_id); - lisp_gpe_tenant_add_default_routes (table_id); + if (with_default_routes) + lisp_gpe_tenant_add_default_routes (table_id); /* enable interface */ vnet_sw_interface_set_flags (vnm, hi->sw_if_index, @@ -908,7 +910,9 @@ lisp_gpe_add_del_iface_command_fn (vlib_main_t * vm, unformat_input_t * input, { if (is_add) { - if (~0 == lisp_gpe_tenant_l3_iface_add_or_lock (vni, table_id)) + if (~0 == lisp_gpe_tenant_l3_iface_add_or_lock (vni, table_id, 1 + /* with_default_route */ + )) { error = clib_error_return (0, "L3 interface not created"); goto done; diff --git a/src/vnet/lisp-gpe/lisp_gpe.h b/src/vnet/lisp-gpe/lisp_gpe.h index fe51ed06eb1..f1fa7715820 100644 --- a/src/vnet/lisp-gpe/lisp_gpe.h +++ b/src/vnet/lisp-gpe/lisp_gpe.h @@ -203,7 +203,8 @@ lisp_gpe_l3_iface_find_or_create (lisp_gpe_main_t * lgm, extern void lisp_gpe_del_l2_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id); extern u32 lisp_gpe_add_l2_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id); extern void lisp_gpe_del_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id); -extern u32 lisp_gpe_add_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id); +extern u32 lisp_gpe_add_l3_iface (lisp_gpe_main_t * lgm, u32 vni, u32 bd_id, + u8 with_default_route); typedef struct diff --git a/src/vnet/lisp-gpe/lisp_gpe_api.c b/src/vnet/lisp-gpe/lisp_gpe_api.c index 4367a7194d9..4ed480c4fd8 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_api.c +++ b/src/vnet/lisp-gpe/lisp_gpe_api.c @@ -405,7 +405,7 @@ vl_api_gpe_add_del_iface_t_handler (vl_api_gpe_add_del_iface_t * mp) { if (mp->is_add) { - if (~0 == lisp_gpe_tenant_l3_iface_add_or_lock (vni, dp_table)) + if (~0 == lisp_gpe_tenant_l3_iface_add_or_lock (vni, dp_table, 1)) rv = 1; } else diff --git a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c index 6e145f527fb..3f56dbea08d 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c +++ b/src/vnet/lisp-gpe/lisp_gpe_sub_interface.c @@ -135,7 +135,8 @@ lisp_gpe_sub_interface_find_or_create_and_lock (const ip_address_t * lrloc, * find the main interface from the VNI */ main_sw_if_index = - lisp_gpe_tenant_l3_iface_add_or_lock (vni, overlay_table_id); + lisp_gpe_tenant_l3_iface_add_or_lock (vni, overlay_table_id, + 1 /* with_default_route */ ); vnet_sw_interface_t sub_itf_template = { .type = VNET_SW_INTERFACE_TYPE_SUB, diff --git a/src/vnet/lisp-gpe/lisp_gpe_tenant.c b/src/vnet/lisp-gpe/lisp_gpe_tenant.c index 2c77739edc8..814b0d316cb 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_tenant.c +++ b/src/vnet/lisp-gpe/lisp_gpe_tenant.c @@ -102,11 +102,13 @@ lisp_gpe_tenant_delete_if_empty (lisp_gpe_tenant_t * lt) * * @paran vni The tenant's VNI * @param table_id the Tenant's L3 table ID. + * @param with_default_route Install default route for the interface * * @return the SW IF index of the L3 interface */ u32 -lisp_gpe_tenant_l3_iface_add_or_lock (u32 vni, u32 table_id) +lisp_gpe_tenant_l3_iface_add_or_lock (u32 vni, u32 table_id, + u8 with_default_route) { lisp_gpe_tenant_t *lt; @@ -121,7 +123,8 @@ lisp_gpe_tenant_l3_iface_add_or_lock (u32 vni, u32 table_id) { /* create the l3 interface since there are currently no users of it */ lt->lt_l3_sw_if_index = - lisp_gpe_add_l3_iface (&lisp_gpe_main, vni, table_id); + lisp_gpe_add_l3_iface (&lisp_gpe_main, vni, table_id, + with_default_route); } lt->lt_locks[LISP_GPE_TENANT_LOCK_L3_IFACE]++; diff --git a/src/vnet/lisp-gpe/lisp_gpe_tenant.h b/src/vnet/lisp-gpe/lisp_gpe_tenant.h index 5db7dde833b..a9271da91f5 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_tenant.h +++ b/src/vnet/lisp-gpe/lisp_gpe_tenant.h @@ -67,7 +67,8 @@ typedef struct lisp_gpe_tenant_t_ extern u32 lisp_gpe_tenant_find_or_create (u32 vni); -extern u32 lisp_gpe_tenant_l3_iface_add_or_lock (u32 vni, u32 vrf); +extern u32 lisp_gpe_tenant_l3_iface_add_or_lock (u32 vni, u32 vrf, + u8 with_default_route); extern void lisp_gpe_tenant_l3_iface_unlock (u32 vni); extern u32 lisp_gpe_tenant_l2_iface_add_or_lock (u32 vni, u32 vrf);