X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Flisp-cp%2Fcontrol.c;h=a820b9cd28fa8c10bf648828e7e27d5cfd5a5c97;hb=8e39bb402afd5908f5b2747bcbb0cc5ffd06bacf;hp=b6612c44bb422f354684055476cb870cdc0ff078;hpb=8ebb2a1632ccf2079cd6217af2d4045021dc3b9e;p=vpp.git diff --git a/vnet/vnet/lisp-cp/control.c b/vnet/vnet/lisp-cp/control.c index b6612c44bb4..a820b9cd28f 100644 --- a/vnet/vnet/lisp-cp/control.c +++ b/vnet/vnet/lisp-cp/control.c @@ -47,13 +47,13 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a, if (mi != GID_LOOKUP_MISS && !gid_address_cmp (&old_map->eid, &a->deid)) { - clib_warning("eid %U found in the eid-table", format_ip_address, + clib_warning ("eid %U found in the eid-table", format_gid_address, &a->deid); return VNET_API_ERROR_VALUE_EXIST; } pool_get(lcm->mapping_pool, m); - m->eid = a->deid; + gid_address_copy (&m->eid, &a->deid); m->locator_set_index = a->locator_set_index; m->ttl = a->ttl; m->action = a->action; @@ -87,7 +87,7 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a, { if (mi == GID_LOOKUP_MISS) { - clib_warning("eid %U not found in the eid-table", format_ip_address, + clib_warning("eid %U not found in the eid-table", format_gid_address, &a->deid); return VNET_API_ERROR_INVALID_VALUE; } @@ -123,6 +123,7 @@ vnet_lisp_add_del_mapping (vnet_lisp_add_del_mapping_args_t * a, /* remove mapping from dictionary */ gid_dictionary_add_del (&lcm->mapping_index_by_gid, &a->deid, 0, 0); + gid_address_free (&m->eid); pool_put_index (lcm->mapping_pool, mi); } @@ -210,6 +211,7 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input, u8 is_add = 1; gid_address_t eid; ip_prefix_t * prefp = &gid_address_ippref(&eid); + u8 * mac = gid_address_mac(&eid); gid_address_t * eids = 0; clib_error_t * error = 0; u8 * locator_set_name = 0; @@ -217,9 +219,9 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input, uword * p; vnet_lisp_add_del_mapping_args_t _a, * a = &_a; int rv = 0; + u32 vni = 0; - gid_address_type (&eid) = GID_ADDR_IP_PREFIX; - + memset (&eid, 0, sizeof (eid)); /* Get a line of input. */ if (! unformat_user (input, unformat_line_input, line_input)) return 0; @@ -230,8 +232,16 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input, is_add = 1; else if (unformat (line_input, "del")) is_add = 0; + else if (unformat (line_input, "vni %d", &vni)) + gid_address_vni (&eid) = vni; else if (unformat (line_input, "eid %U", unformat_ip_prefix, prefp)) { + gid_address_type (&eid) = GID_ADDR_IP_PREFIX; + vec_add1(eids, eid); + } + else if (unformat (line_input, "eid %U", unformat_mac_address, mac)) + { + gid_address_type (&eid) = GID_ADDR_MAC; vec_add1(eids, eid); } else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name)) @@ -251,8 +261,8 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input, goto done; } } - /* XXX treat batch configuration */ + a->deid = eid; a->is_add = is_add; a->locator_set_index = locator_set_index; @@ -268,15 +278,99 @@ lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input, vec_free(eids); if (locator_set_name) vec_free (locator_set_name); + gid_address_free (&a->deid); return error; } VLIB_CLI_COMMAND (lisp_add_del_local_eid_command) = { .path = "lisp eid-table", - .short_help = "lisp eid-table add/del eid locator-set ", + .short_help = "lisp eid-table add/del [vni ] eid " + "locator-set ", .function = lisp_add_del_local_eid_command_fn, }; +int +vnet_lisp_eid_table_map (u32 vni, u32 vrf, u8 is_add) +{ + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main (); + uword * table_id, * vnip; + + if (vnet_lisp_enable_disable_status () == 0) + { + clib_warning ("LISP is disabled!"); + return -1; + } + + if (vni == 0 || vrf == 0) + { + clib_warning ("can't add/del default vni-vrf mapping!"); + return -1; + } + + table_id = hash_get (lcm->table_id_by_vni, vni); + vnip = hash_get (lcm->vni_by_table_id, vrf); + + if (is_add) + { + if (table_id || vnip) + { + clib_warning ("vni %d or vrf %d already used in any vrf/vni " + "mapping!", vni, vrf); + return -1; + } + hash_set (lcm->table_id_by_vni, vni, vrf); + hash_set (lcm->vni_by_table_id, vrf, vni); + } + else + { + if (!table_id || !vnip) + { + clib_warning ("vni %d or vrf %d not used in any vrf/vni! " + "mapping!", vni, vrf); + return -1; + } + hash_unset (lcm->table_id_by_vni, vni); + hash_unset (lcm->vni_by_table_id, vrf); + } + return 0; +} + +static clib_error_t * +lisp_eid_table_map_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + u8 is_add = 1; + u32 vni = 0, vrf = 0; + unformat_input_t _line_input, * line_input = &_line_input; + + /* 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, "del")) + is_add = 0; + else if (unformat (line_input, "vni %d", &vni)) + ; + else if (unformat (line_input, "vrf %d", &vrf)) + ; + else + { + return unformat_parse_error (line_input); + } + } + vnet_lisp_eid_table_map (vni, vrf, is_add); + return 0; +} + +VLIB_CLI_COMMAND (lisp_eid_table_map_command) = { + .path = "lisp eid-table map", + .short_help = "lisp eid-table map [del] vni vrf ", + .function = lisp_eid_table_map_command_fn, +}; + static int lisp_add_del_negative_static_mapping (gid_address_t * deid, vnet_lisp_add_del_locator_set_args_t * ls, u8 action, u8 is_add) @@ -573,6 +667,8 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, ip_address_t rloc, * rlocs = 0; ip_prefix_t * deid_ippref, * seid_ippref; gid_address_t seid, deid; + u8 * dmac = gid_address_mac (&deid); + u8 * smac = gid_address_mac (&seid); u8 deid_set = 0, seid_set = 0; u8 * s = 0; u32 vni, action = ~0; @@ -587,9 +683,6 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, seid_ippref = &gid_address_ippref(&seid); deid_ippref = &gid_address_ippref(&deid); - gid_address_type (&deid) = GID_ADDR_IP_PREFIX; - gid_address_type (&seid) = GID_ADDR_IP_PREFIX; - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { if (unformat (line_input, "del-all")) @@ -601,16 +694,30 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, else if (unformat (line_input, "deid %U", unformat_ip_prefix, deid_ippref)) { + gid_address_type (&deid) = GID_ADDR_IP_PREFIX; + deid_set = 1; + } + else if (unformat (line_input, "deid %U", + unformat_mac_address, dmac)) + { + gid_address_type (&deid) = GID_ADDR_MAC; deid_set = 1; } else if (unformat (line_input, "vni %u", &vni)) { - gid_address_set_vni (&seid, vni); - gid_address_set_vni (&deid, vni); + gid_address_vni (&seid) = vni; + gid_address_vni (&deid) = vni; } else if (unformat (line_input, "seid %U", unformat_ip_prefix, seid_ippref)) { + gid_address_type (&seid) = GID_ADDR_IP_PREFIX; + seid_set = 1; + } + else if (unformat (line_input, "seid %U", + unformat_mac_address, smac)) + { + gid_address_type (&seid) = GID_ADDR_MAC; seid_set = 1; } else if (unformat (line_input, "rloc %U", unformat_ip_address, &rloc)) @@ -646,18 +753,22 @@ lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm, goto done; } - /* if seid not set, make sure the ip version is the same as that of the - * deid. This ensures the seid to be configured will be either 0/0 or - * ::/0 */ - if (!seid_set) - ip_prefix_version(seid_ippref) = ip_prefix_version(deid_ippref); - - if (is_add && - (ip_prefix_version (deid_ippref) != ip_prefix_version(seid_ippref))) + if (GID_ADDR_IP_PREFIX == gid_address_type (&deid)) { - clib_warning ("source and destination EIDs are not" - " in the same IP family!"); - goto done; + /* if seid not set, make sure the ip version is the same as that + * of the deid. This ensures the seid to be configured will be + * either 0/0 or ::/0 */ + if (!seid_set) + ip_prefix_version(seid_ippref) = ip_prefix_version(deid_ippref); + + if (is_add && + (ip_prefix_version (deid_ippref) + != ip_prefix_version(seid_ippref))) + { + clib_warning ("source and destination EIDs are not" + " in the same IP family!"); + goto done; + } } if (is_add && (~0 == action) @@ -803,32 +914,74 @@ VLIB_CLI_COMMAND (lisp_pitr_set_locator_set_command) = { .function = lisp_pitr_set_locator_set_command_fn, }; + +static u8 * +format_eid_entry (u8 * s, va_list * args) +{ + vnet_main_t * vnm = va_arg (*args, vnet_main_t *); + lisp_cp_main_t * lcm = va_arg (*args, lisp_cp_main_t *); + gid_address_t * gid = va_arg (*args, gid_address_t *); + locator_set_t * ls = va_arg (*args, locator_set_t *); + u32 * loc_index; + u8 first_line = 1; + u8 * loc; + + u8 * type = ls->local ? format(0, "local(%s)", ls->name) + : format(0, "remote"); + + if (vec_len (ls->locator_indices) == 0) + { + s = format (s, "%-35U%-20s", format_gid_address, gid, type); + } + else + { + vec_foreach (loc_index, ls->locator_indices) + { + locator_t * l = pool_elt_at_index (lcm->locator_pool, loc_index[0]); + if (l->local) + loc = format (0, "%U", format_vnet_sw_if_index_name, vnm, + l->sw_if_index); + else + loc = format (0, "%U", format_ip_address, + &gid_address_ip (&l->address)); + + if (first_line) + { + s = format (s, "%-35U%-20s%-v\n", format_gid_address, + gid, type, loc); + first_line = 0; + } + else + s = format (s, "%55s%v\n", "", loc); + } + } + return s; +} + static clib_error_t * -lisp_show_local_eid_table_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) +lisp_show_eid_table_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) { lisp_cp_main_t * lcm = vnet_lisp_cp_get_main(); mapping_t * mapit; - vlib_cli_output (vm, "%=20s%=16s", "EID", "Locator"); + vlib_cli_output (vm, "%-35s%-20s%-s", "EID", "type", "locators"); pool_foreach (mapit, lcm->mapping_pool, ({ - u8 * msg = 0; locator_set_t * ls = pool_elt_at_index (lcm->locator_set_pool, mapit->locator_set_index); - vlib_cli_output (vm, "%-16U%16v", format_gid_address, &mapit->eid, - ls->name); - vec_free (msg); + vlib_cli_output (vm, "%U", format_eid_entry, lcm->vnet_main, + lcm, &mapit->eid, ls); })); return 0; } -VLIB_CLI_COMMAND (lisp_cp_show_local_eid_table_command) = { +VLIB_CLI_COMMAND (lisp_cp_show_eid_table_command) = { .path = "show lisp eid-table", - .short_help = "Shows local EID table", - .function = lisp_show_local_eid_table_command_fn, + .short_help = "Shows EID table", + .function = lisp_show_eid_table_command_fn, }; /* cleans locator to locator-set data and removes locators not part of @@ -1294,6 +1447,28 @@ VLIB_CLI_COMMAND (lisp_show_status_command) = { .short_help = "show lisp status", .function = lisp_show_status_command_fn, }; + +static clib_error_t * +lisp_show_eid_table_map_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + hash_pair_t * p; + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main (); + + vlib_cli_output (vm, "%=10s%=10s", "VNI", "VRF"); + hash_foreach_pair (p, lcm->table_id_by_vni, + { + vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]); + }); + return 0; +} + +VLIB_CLI_COMMAND (lisp_show_eid_table_map_command) = { + .path = "show lisp eid-table map", + .short_help = "show lisp eid-table vni to vrf mappings", + .function = lisp_show_eid_table_map_command_fn, +}; + static clib_error_t * lisp_add_del_locator_set_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -1357,11 +1532,81 @@ lisp_add_del_locator_set_command_fn (vlib_main_t * vm, unformat_input_t * input, VLIB_CLI_COMMAND (lisp_cp_add_del_locator_set_command) = { .path = "lisp locator-set", - .short_help = "lisp locator-set add/del iface " - "p w ", + .short_help = "lisp locator-set add/del [iface " + "p w ]", .function = lisp_add_del_locator_set_command_fn, }; +static clib_error_t * +lisp_add_del_locator_in_set_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + lisp_gpe_main_t * lgm = &lisp_gpe_main; + vnet_main_t * vnm = lgm->vnet_main; + unformat_input_t _line_input, * line_input = &_line_input; + u8 is_add = 1; + clib_error_t * error = 0; + u8 * locator_set_name = 0; + u8 locator_set_name_set = 0; + locator_t locator, * locators = 0; + vnet_lisp_add_del_locator_set_args_t _a, * a = &_a; + u32 ls_index = 0; + + memset(&locator, 0, sizeof(locator)); + memset(a, 0, sizeof(a[0])); + + /* 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, "add")) + is_add = 1; + else if (unformat (line_input, "del")) + is_add = 0; + else if (unformat(line_input, "locator-set %_%v%_", &locator_set_name)) + locator_set_name_set = 1; + else if (unformat (line_input, "iface %U p %d w %d", + unformat_vnet_sw_interface, vnm, &locator.sw_if_index, + &locator.priority, &locator.weight)) + { + locator.local = 1; + vec_add1(locators, locator); + } + else + { + error = unformat_parse_error(line_input); + goto done; + } + } + + if (!locator_set_name_set) + { + error = clib_error_return(0, "locator_set name not set!"); + goto done; + } + + a->name = locator_set_name; + a->locators = locators; + a->is_add = is_add; + a->local = 1; + + vnet_lisp_add_del_locator(a, 0, &ls_index); + + done: + vec_free(locators); + vec_free (locator_set_name); + return error; +} + +VLIB_CLI_COMMAND (lisp_cp_add_del_locator_in_set_command) = { + .path = "lisp locator", + .short_help = "lisp locator add/del locator-set iface " + "p w ", + .function = lisp_add_del_locator_in_set_command_fn, +}; + static clib_error_t * lisp_cp_show_locator_sets_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -1377,16 +1622,23 @@ lisp_cp_show_locator_sets_command_fn (vlib_main_t * vm, pool_foreach (lsit, lcm->locator_set_pool, ({ u8 * msg = 0; - msg = format (msg, "%-16v", lsit->name); + int next_line = 0; + msg = format (msg, "%=16v", lsit->name); vec_foreach (locit, lsit->locator_indices) { + if (next_line) + { + msg = format (msg, "%16s", " "); + } loc = pool_elt_at_index (lcm->locator_pool, locit[0]); if (loc->local) - msg = format (msg, "%16d%16d%16d", loc->sw_if_index, loc->priority, + msg = format (msg, "%16d%16d%16d\n", loc->sw_if_index, loc->priority, loc->weight); else - msg = format (msg, "%16U%16d%16d", format_gid_address, &loc->address, - loc->priority, loc->weight); + msg = format (msg, "%16U%16d%16d\n", format_ip_address, + gid_address_ip(&loc->address), loc->priority, + loc->weight); + next_line = 1; } vlib_cli_output (vm, "%v", msg); vec_free (msg); @@ -1809,6 +2061,7 @@ build_itr_rloc_list (lisp_cp_main_t * lcm, locator_set_t * loc_set) ip_prefix_t * ippref = &gid_address_ippref (gid); ip_address_t * rloc = &ip_prefix_addr (ippref); + memset (gid, 0, sizeof (gid[0])); gid_address_type (gid) = GID_ADDR_IP_PREFIX; for (i = 0; i < vec_len(loc_set->locator_indices); i++) { @@ -1982,6 +2235,43 @@ get_src_and_dst (void *hdr, ip_address_t * src, ip_address_t *dst) } } +static u32 +lisp_get_vni_from_buffer (vlib_buffer_t * b, u8 version) +{ + uword * vnip; + u32 vni = ~0, table_id = ~0, fib_index; + lisp_cp_main_t * lcm = vnet_lisp_cp_get_main (); + + if (version == IP4) + { + ip4_fib_t * fib; + ip4_main_t * im4 = &ip4_main; + fib_index = vec_elt (im4->fib_index_by_sw_if_index, + vnet_buffer (b)->sw_if_index[VLIB_RX]); + fib = find_ip4_fib_by_table_index_or_id (im4, fib_index, + IP4_ROUTE_FLAG_FIB_INDEX); + table_id = fib->table_id; + } + else + { + ip6_fib_t * fib; + ip6_main_t * im6 = &ip6_main; + fib_index = vec_elt (im6->fib_index_by_sw_if_index, + vnet_buffer (b)->sw_if_index[VLIB_RX]); + fib = find_ip6_fib_by_table_index_or_id (im6, fib_index, + IP6_ROUTE_FLAG_FIB_INDEX); + table_id = fib->table_id; + } + + vnip = hash_get (lcm->vni_by_table_id, table_id); + if (vnip) + vni = vnip[0]; + else + clib_warning ("vrf %d is not mapped to any vni!", table_id); + + return vni; +} + static uword lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * from_frame) @@ -2001,7 +2291,7 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node, while (n_left_from > 0 && n_left_to_next_drop > 0) { - u32 pi0; + u32 pi0, vni; vlib_buffer_t * p0; ip4_header_t * ip0; gid_address_t src, dst; @@ -2028,6 +2318,10 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node, ip_prefix_len(spref) = ip_address_max_len (ip_prefix_version(spref)); ip_prefix_len(dpref) = ip_address_max_len (ip_prefix_version(dpref)); + vni = lisp_get_vni_from_buffer (p0, ip_prefix_version (spref)); + gid_address_vni (&dst) = vni; + gid_address_vni (&src) = vni; + /* if we have remote mapping for destination already in map-chache add forwarding tunnel directly. If not send a map-request */ di = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &dst); @@ -2073,6 +2367,8 @@ lisp_cp_lookup (vlib_main_t * vm, vlib_node_runtime_t * node, sizeof(ip_address_t)); } } + gid_address_free (&dst); + gid_address_free (&src); } vlib_put_next_frame (vm, node, LISP_CP_LOOKUP_NEXT_DROP, n_left_to_next_drop); @@ -2585,6 +2881,7 @@ lisp_cp_init (vlib_main_t *vm) /* default vrf mapped to vni 0 */ 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 */);