summaryrefslogtreecommitdiffstats
path: root/build-data
AgeCommit message (Expand)AuthorFilesLines
2017-01-13vppctl: new bash completion for vppctl commandsPadraig Connolly1-0/+8
2017-01-10Added a sub-case to take into Thunderx platformMarco1-0/+7
2017-01-10Revert "vppctl: bash completion for vppctl commands"Damjan Marion1-8/+0
2017-01-09vppctl: bash completion for vppctl commandsPadraig Connolly1-0/+8
2017-01-03Do not require external vppapigen when not cross-compilingDamjan Marion1-1/+1
2017-01-01Move java,lua api and remaining plugins to src/Damjan Marion6-100/+16
2016-12-28Reorganize source tree to use single autotools instanceDamjan Marion22-332/+23
2016-12-26dpdk: Add support for Mellanox ConnectX-4 devicesDamjan Marion4-0/+12
2016-12-09Add make test code coverage reporting using gcovJuraj Sloboda1-0/+5
2016-12-06Add "vpp-api-install" to plugins_configure_depend in build-data/packages/plug...Andrew Yourtchenko1-1/+2
2016-12-02API: Packaging of JSON files.Ole Troan2-3/+13
2016-11-30Enabling AES-GCM-128 with 16B ICV supportRadu Nicolau1-0/+4
2016-11-30Start spliting vpe.api into logically related piecesDave Barach1-0/+23
2016-11-28dpdk: add ipsec cryptodev supportSergio Gonzalez Monroy4-0/+11
2016-11-12Add clang to 'make verify'Damjan Marion1-0/+5
2016-11-04VPP-498: Prepare vpp RPM packaging for use by downstream distros.Thomas F Herbert1-1/+5
2016-10-29Initial deb packaging of vpp-python-apiEd Warnicke1-0/+4
2016-10-11VPP-474 Revert "FIX sysctl configuration directory"Miroslav Miklus1-1/+1
2016-10-10HONEYCOMB-228 Snat plugin jvpp supportMarek Gradzki1-1/+2
2016-09-27FIX sysctl configuration directoryMiroslav Miklus1-1/+1
2016-08-29VPP-310 Mapping algorithm compute wrong ea-bitsOle Troan1-0/+3
2016-08-25VPP Python language binding - plugin supportOle Troan1-8/+10
2016-08-16Create python package for jvpp generation.Ed Warnicke1-2/+8
2016-08-12VPP: NXP dpaa2 platform porting to dpdk-16.07Sachin1-7/+7
2016-07-21VPP-123: remove japi (the old Java API)Marek Gradzki1-1/+1
2016-07-13Add plugins debian packagingDamjan Marion2-1/+6
2016-07-08Multiple changes in the plugin build infraDamjan Marion1-3/+1
2016-07-06Retire PLATFORM=virlDamjan Marion1-42/+0
2016-07-01Simple ip4 NAT pluginDave Barach1-0/+4
2016-06-28Fix native build on non x86_64 systemsDamjan Marion2-0/+11
2016-06-27Plugins: Clean up the plugin directory so that each plugin has its ownOle Troan5-10/+10
2016-06-22Fix for build failure due to iOAM plugin header file pathShwetha1-0/+5
2016-06-19Improving cross_ldflags arguments for dpaa2 platformSachin1-1/+2
2016-06-18Enhanced RPM build process to make rpm for any given platformSachin1-1/+2
2016-06-17NXP DPAA2 Poll Mode Driver Support in DPDKSachin1-4/+6
2016-06-156rd: Move to pluginOle Troan1-0/+38
2016-06-10NXP dpaa2 platform initial supportSachin Saxena1-0/+63
2016-06-05VPP-94: Add build-data directory for plugins and Makefile targetPierre Pfister1-47/+0
2016-05-27Fix dpdk march/mtune defaultsDamjan Marion1-1/+1
2016-05-20VPP-79: fix cross-compilation build breakDave Barach1-3/+3
2016-05-19Add support for multiple microarchitectures in single binaryDamjan Marion3-4/+15
2016-05-17dpdk/Makefile - Allow dpdk target to be set according to the platformChristophe Fontaine2-3/+21
2016-04-28VPP-8: Set java-8 for JNIMarek Gradzki1-1/+1
2016-04-20Python-API: Inital commit of Python bindings for the VPP API.Ole Troan4-7/+7
2016-04-20Add TAG=vpp_gcov which compiles vpp to produce .gcda filesDave Barach1-0/+5
2016-04-18Add support for AArch32Christophe Fontaine3-4/+49
2016-04-12Add unit test infrastructure for LISP protocolFilip Tehlar1-0/+4
2016-04-11Add configure option to enable building unit testsDamjan Marion2-1/+7
2016-04-01Add options to link with external DPDK treeDamjan Marion6-3/+37
2016-03-25Use rte_mempool private data for storing vlib_buffer_tDamjan Marion2-4/+0
he.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <vlib/punt.h> /** * The last allocated punt reason */ static vlib_punt_reason_t punt_reason_last; /** * Counters per punt-reason */ vlib_combined_counter_main_t punt_counters = { .name = "punt", .stat_segment_name = "/net/punt", }; /** * A punt reason */ typedef struct punt_reason_data_t_ { /** * The reason name */ u8 *pd_name; /** * The allocated reason value */ vlib_punt_reason_t pd_reason; /** * Clients/owners that have registered this reason */ u32 *pd_owners; /** * clients interested/listening to this reason */ u32 pd_users; /** * function to invoke if a client becomes interested in the code. */ punt_interested_listener_t pd_fn; /** * Data to pass to the callback */ void *pd_data; } punt_reason_data_t; /** * data for each punt reason */ static punt_reason_data_t *punt_reason_data; typedef enum punt_format_flags_t_ { PUNT_FORMAT_FLAG_NONE = 0, PUNT_FORMAT_FLAG_DETAIL = (1 << 0), } punt_format_flags_t; /** * A registration, by a client, to direct punted traffic to a given node */ typedef struct punt_reg_t_ { /** * Reason the packets were punted */ vlib_punt_reason_t pr_reason; /** * number of clients that have made this registration */ u16 pr_locks; /** * The edge from the punt dispatch node to the requested node */ u16 pr_edge; /** * node-index to send punted packets to */ u32 pr_node_index; } punt_reg_t; /** * Pool of registrations */ static punt_reg_t *punt_reg_pool; /** * A DB of all the register nodes against punt reason and node index */ static uword *punt_reg_db; /** * A DB used in the DP per-reason to dispatch packets to the requested nodes. * this is a vector of edges per-reason */ u16 **punt_dp_db; /** * A client using the punt serivce and its registrations */ typedef struct punt_client_t_ { /** * The name of the client */ u8 *pc_name; /** * The registrations is has made */ u32 *pc_regs; } punt_client_t; /** * Pool of clients */ static punt_client_t *punt_client_pool; /** * DB of clients key'd by their name */ static uword *punt_client_db; u8 * format_vlib_punt_reason (u8 * s, va_list * args) { vlib_punt_reason_t pr = va_arg (*args, int); return (format (s, "[%d] %v", pr, punt_reason_data[pr].pd_name)); } vlib_punt_hdl_t vlib_punt_client_register (const char *who) { u8 *pc_name; uword *p; u32 pci; pc_name = format (NULL, "%s", who); p = hash_get_mem (punt_client_db, pc_name); if (NULL == p) { punt_client_t *pc; pool_get (punt_client_pool, pc); pci = pc - punt_client_pool; pc->pc_name = pc_name; hash_set_mem (punt_client_db, pc->pc_name, pci); } else { pci = p[0]; vec_free (pc_name); } return (pci); } static int punt_validate_client (vlib_punt_hdl_t client) { return (!pool_is_free_index (punt_client_pool, client)); } static u64 punt_reg_mk_key (vlib_punt_reason_t reason, u32 node_index) { return (((u64) node_index) << 32 | reason); } static u32 punt_reg_find (vlib_punt_reason_t reason, u32 node_index) { uword *p; p = hash_get (punt_reg_db, punt_reg_mk_key (reason, node_index)); if (p) return p[0]; return ~0; } static void punt_reg_add (const punt_reg_t * pr) { hash_set (punt_reg_db, punt_reg_mk_key (pr->pr_reason, pr->pr_node_index), pr - punt_reg_pool); } static void punt_reg_remove (const punt_reg_t * pr) { hash_unset (punt_reg_db, punt_reg_mk_key (pr->pr_reason, pr->pr_node_index)); } /** * reconstruct the DP per-reason DB */ static void punt_reg_mk_dp (vlib_punt_reason_t reason) { u32 pri, *prip, *pris; const punt_reg_t *pr; u16 *edges, *old; u64 key; pris = NULL; edges = NULL; vec_validate (punt_dp_db, reason); old = punt_dp_db[reason]; /* *INDENT-OFF* */ hash_foreach (key, pri, punt_reg_db, ({ vec_add1(pris, pri); })); /* *INDENT-ON* */ /* * A check for an empty vector is done in the DP, so the a zero * length vector here is ok */ vec_foreach (prip, pris) { pr = pool_elt_at_index (punt_reg_pool, *prip); if (pr->pr_reason == reason) vec_add1 (edges, pr->pr_edge); } /* atomic update of the DP */ punt_dp_db[reason] = edges; vec_free (old); } int vlib_punt_register (vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name) { vlib_node_t *punt_to, *punt_from; punt_client_t *pc; vlib_main_t *vm; punt_reg_t *pr; u32 pri; if (reason >= punt_reason_last) return -1; if (!punt_validate_client (client)) return -2; vm = vlib_get_main (); pc = pool_elt_at_index (punt_client_pool, client); punt_to = vlib_get_node_by_name (vm, (u8 *) node_name); punt_from = vlib_get_node_by_name (vm, (u8 *) "punt-dispatch"); /* * find a global matching registration */ pri = punt_reg_find (reason, punt_to->index); if (~0 != pri) { u32 pos; pos = vec_search (pc->pc_regs, pri); if (~0 != pos) { /* duplicate registration for this client */ return -1; } pr = pool_elt_at_index (punt_reg_pool, pri); } else { pool_get (punt_reg_pool, pr); pr->pr_reason = reason; pr->pr_node_index = punt_to->index; pr->pr_edge = vlib_node_add_next (vm, punt_from->index, pr->pr_node_index); pri = pr - punt_reg_pool; if (0 == punt_reason_data[reason].pd_users++ && NULL != punt_reason_data[reason].pd_fn) punt_reason_data[reason].pd_fn (VLIB_ENABLE, punt_reason_data[reason].pd_data); punt_reg_add (pr); } /* * add this reg to the list the client has made */ pr->pr_locks++; vec_add1 (pc->pc_regs, pri); punt_reg_mk_dp (reason); return 0; } int vlib_punt_unregister (vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name) { vlib_node_t *punt_to; punt_client_t *pc; vlib_main_t *vm; punt_reg_t *pr; u32 pri; if (reason >= punt_reason_last) return -1; vm = vlib_get_main (); pc = pool_elt_at_index (punt_client_pool, client); punt_to = vlib_get_node_by_name (vm, (u8 *) node_name); /* * construct a registration and check if it's one this client already has */ pri = punt_reg_find (reason, punt_to->index); if (~0 != pri) { u32 pos; pos = vec_search (pc->pc_regs, pri); if (~0 == pos) { /* not a registration for this client */ return -1; } vec_del1 (pc->pc_regs, pos); pr = pool_elt_at_index (punt_reg_pool, pri); pr->pr_locks--; if (0 == pr->pr_locks) { if (0 == --punt_reason_data[reason].pd_users && NULL != punt_reason_data[reason].pd_fn) punt_reason_data[reason].pd_fn (VLIB_DISABLE, punt_reason_data[reason].pd_data); punt_reg_remove (pr); pool_put (punt_reg_pool, pr); } } /* * rebuild the DP data-base */ punt_reg_mk_dp (reason); return (0); } int vlib_punt_reason_validate (vlib_punt_reason_t reason) { if (reason < punt_reason_last) return (0); return (-1); } int vlib_punt_reason_alloc (vlib_punt_hdl_t client, const char *reason_name, punt_interested_listener_t fn, void *data, vlib_punt_reason_t * reason) { vlib_punt_reason_t new; if (!punt_validate_client (client)) return -2; new = punt_reason_last++; vec_validate (punt_reason_data, new); punt_reason_data[new].pd_name = format (NULL, "%s", reason_name); punt_reason_data[new].pd_reason = new; punt_reason_data[new].pd_fn = fn; punt_reason_data[new].pd_data = data; vec_add1 (punt_reason_data[new].pd_owners, client); vlib_validate_combined_counter (&punt_counters, new); vlib_zero_combined_counter (&punt_counters, new); *reason = new; /* build the DP data-base */ punt_reg_mk_dp (*reason); return (0); } void punt_reason_walk (punt_reason_walk_cb_t cb, void *ctx) { punt_reason_data_t *pd; vec_foreach (pd, punt_reason_data) { cb (pd->pd_reason, pd->pd_name, ctx); } } /* Parse node name -> node index. */ uword unformat_punt_client (unformat_input_t * input, va_list * args) { u32 *result = va_arg (*args, u32 *); return unformat_user (input, unformat_hash_vec_string, punt_client_db, result); } u8 * format_punt_reg (u8 * s, va_list * args) { u32 pri = va_arg (*args, u32); punt_reg_t *pr; pr = pool_elt_at_index (punt_reg_pool, pri); s = format (s, "%U -> %U", format_vlib_punt_reason, pr->pr_reason, format_vlib_node_name, vlib_get_main (), pr->pr_node_index); return (s); } u8 * format_punt_reason_data (u8 * s, va_list * args) { punt_reason_data_t *pd = va_arg (*args, punt_reason_data_t *); punt_client_t *pc; u32 *pci; s = format (s, "[%d] %v from:[", pd->pd_reason, pd->pd_name); vec_foreach (pci, pd->pd_owners) { pc = pool_elt_at_index (punt_client_pool, *pci); s = format (s, "%v ", pc->pc_name); } s = format (s, "]"); return (s); } u8 * format_punt_client (u8 * s, va_list * args) { u32 pci = va_arg (*args, u32); punt_format_flags_t flags = va_arg (*args, punt_format_flags_t); punt_client_t *pc; pc = pool_elt_at_index (punt_client_pool, pci); s = format (s, "%v", pc->pc_name); if (flags & PUNT_FORMAT_FLAG_DETAIL) { punt_reason_data_t *pd; u32 *pri; s = format (s, "\n registrations:"); vec_foreach (pri, pc->pc_regs) { s = format (s, "\n [%U]", format_punt_reg, *pri); } s = format (s, "\n reasons:"); vec_foreach (pd, punt_reason_data) { u32 *tmp; vec_foreach (tmp, pd->pd_owners) { if (*tmp == pci) s = format (s, "\n %U", format_punt_reason_data, pd); } } } return (s); } static clib_error_t * punt_client_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { u32 pci = ~0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "%U", unformat_punt_client, &pci)) ; else break; } if (~0 != pci) { vlib_cli_output (vm, "%U", format_punt_client, pci, PUNT_FORMAT_FLAG_DETAIL); } else { u8 *name; /* *INDENT-OFF* */ hash_foreach(name, pci, punt_client_db, ({ vlib_cli_output (vm, "%U", format_punt_client, pci, PUNT_FORMAT_FLAG_NONE); })); /* *INDENT-ON* */ } return (NULL); } /* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_client_show_command, static) = { .path = "show punt client", .short_help = "show client[s] registered with the punt infra", .function = punt_client_show, }; /* *INDENT-ON* */ static clib_error_t * punt_reason_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { const punt_reason_data_t *pd; vec_foreach (pd, punt_reason_data) { vlib_cli_output (vm, "%U", format_punt_reason_data, pd); } return (NULL); } /* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_reason_show_command, static) = { .path = "show punt reasons", .short_help = "show all punt reasons", .function = punt_reason_show, }; /* *INDENT-ON* */ static clib_error_t * punt_db_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { u32 pri, ii, jj; u64 key; /* *INDENT-OFF* */ hash_foreach (key, pri, punt_reg_db, ({ vlib_cli_output (vm, " %U", format_punt_reg, pri); })); /* *INDENT-ON* */ vlib_cli_output (vm, "\nDerived data-plane data-base:"); vlib_cli_output (vm, " (for each punt-reason the edge[s] from punt-dispatch)"); vec_foreach_index (ii, punt_dp_db) { u8 *s = NULL; vlib_cli_output (vm, " %U", format_vlib_punt_reason, ii); vec_foreach_index (jj, punt_dp_db[ii]) { s = format (s, "%d ", punt_dp_db[ii][jj]); } vlib_cli_output (vm, " [%v]", s); vec_free (s); } return (NULL); } /* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_db_show_command, static) = { .path = "show punt db", .short_help = "show the punt DB", .function = punt_db_show, }; /* *INDENT-ON* */ static clib_error_t * punt_stats_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { vlib_combined_counter_main_t *cm = &punt_counters; vlib_counter_t c; u32 ii; for (ii = 0; ii < vlib_combined_counter_n_counters (cm); ii++) { vlib_get_combined_counter (cm, ii, &c); vlib_cli_output (vm, "%U packets:%lld bytes:%lld", format_vlib_punt_reason, ii, c.packets, c.bytes); } return (NULL); } /* *INDENT-OFF* */ VLIB_CLI_COMMAND (punt_stats_show_command, static) = { .path = "show punt stats", .short_help = "show the punt stats", .function = punt_stats_show, }; /* *INDENT-ON* */ static clib_error_t * punt_init (vlib_main_t * vm) { punt_client_db = hash_create_vec (0, sizeof (u8), sizeof (u32)); return (NULL); } VLIB_INIT_FUNCTION (punt_init); /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */