diff options
author | Dave Barach <dave@barachs.net> | 2019-05-14 18:01:44 -0400 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2019-05-16 16:11:23 +0000 |
commit | f8d50682cd1245f6f5ce4c846ca6f1bdc11255a6 (patch) | |
tree | 8ecc60e4715db88bdbc8ea6bd0170fbae6f645eb /src | |
parent | c1f93067ed4b9954bbba82e2c9c104b22e2f7f33 (diff) |
init / exit function ordering
The vlib init function subsystem now supports a mix of procedural and
formally-specified ordering constraints. We should eliminate procedural
knowledge wherever possible.
The following schemes are *roughly* equivalent:
static clib_error_t *init_runs_first (vlib_main_t *vm)
{
clib_error_t *error;
... do some stuff...
if ((error = vlib_call_init_function (init_runs_next)))
return error;
...
}
VLIB_INIT_FUNCTION (init_runs_first);
and
static clib_error_t *init_runs_first (vlib_main_t *vm)
{
... do some stuff...
}
VLIB_INIT_FUNCTION (init_runs_first) =
{
.runs_before = VLIB_INITS("init_runs_next"),
};
The first form will [most likely] call "init_runs_next" on the
spot. The second form means that "init_runs_first" runs before
"init_runs_next," possibly much earlier in the sequence.
Please DO NOT construct sets of init functions where A before B
actually means A *right before* B. It's not necessary - simply combine
A and B - and it leads to hugely annoying debugging exercises when
trying to switch from ad-hoc procedural ordering constraints to formal
ordering constraints.
Change-Id: I5e4353503bf43b4acb11a45fb33c79a5ade8426c
Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src')
62 files changed, 959 insertions, 476 deletions
diff --git a/src/examples/vlib/main_stub.c b/src/examples/vlib/main_stub.c index c5c19aaa01a..3735055d789 100644 --- a/src/examples/vlib/main_stub.c +++ b/src/examples/vlib/main_stub.c @@ -25,18 +25,17 @@ main (int argc, char *argv[]) static clib_error_t * main_stub_init (vlib_main_t * vm) { - clib_error_t *error; - - if ((error = unix_physmem_init (vm))) - return error; - - if ((error = vlib_call_init_function (vm, unix_cli_init))) - return error; + clib_error_t *error = 0; return error; } -VLIB_INIT_FUNCTION (main_stub_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (main_stub_init) = +{ + .runs_after = VLIB_INITS("unix_physmem_init", "unix_cli_init"), +}; +/* *INDENT-ON* */ #if 0 /* Node test code. */ diff --git a/src/plugins/abf/abf_itf_attach.c b/src/plugins/abf/abf_itf_attach.c index 151fb988edf..9569306ec2a 100644 --- a/src/plugins/abf/abf_itf_attach.c +++ b/src/plugins/abf/abf_itf_attach.c @@ -764,7 +764,12 @@ abf_itf_bond_init (vlib_main_t * vm) return (NULL); } -VLIB_INIT_FUNCTION (abf_itf_bond_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (abf_itf_bond_init) = +{ + .runs_after = VLIB_INITS("acl_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/avf/device.c b/src/plugins/avf/device.c index 7d01149a1a0..74b6ab4e4b0 100644 --- a/src/plugins/avf/device.c +++ b/src/plugins/avf/device.c @@ -1433,12 +1433,8 @@ clib_error_t * avf_init (vlib_main_t * vm) { avf_main_t *am = &avf_main; - clib_error_t *error; vlib_thread_main_t *tm = vlib_get_thread_main (); - if ((error = vlib_call_init_function (vm, pci_bus_init))) - return error; - vec_validate_aligned (am->per_thread_data, tm->n_vlib_mains - 1, CLIB_CACHE_LINE_BYTES); @@ -1448,7 +1444,12 @@ avf_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (avf_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (avf_init) = +{ + .runs_after = VLIB_INITS ("pci_bus_init"), +}; +/* *INDENT-OFF* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/cdp/cdp_input.c b/src/plugins/cdp/cdp_input.c index 946aaf7f845..dbe179ad095 100644 --- a/src/plugins/cdp/cdp_input.c +++ b/src/plugins/cdp/cdp_input.c @@ -408,15 +408,11 @@ cdp_input (vlib_main_t * vm, vlib_buffer_t * b0, u32 bi0) static clib_error_t * cdp_input_init (vlib_main_t * vm) { - clib_error_t *error; cdp_main_t *cm = &cdp_main; void vnet_cdp_node_reference (void); vnet_cdp_node_reference (); - if ((error = vlib_call_init_function (vm, cdp_periodic_init))) - return error; - cm->vlib_main = vm; cm->vnet_main = vnet_get_main (); cm->neighbor_by_sw_if_index = hash_create (0, sizeof (uword)); @@ -424,7 +420,12 @@ cdp_input_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (cdp_input_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (cdp_input_init) = +{ + .runs_after = VLIB_INITS("cdp_periodic_init"), +}; +/* *INDENT-ON* */ static u8 * diff --git a/src/plugins/crypto_ia32/main.c b/src/plugins/crypto_ia32/main.c index 45bf34e7814..a02fc38f99e 100644 --- a/src/plugins/crypto_ia32/main.c +++ b/src/plugins/crypto_ia32/main.c @@ -97,10 +97,7 @@ crypto_ia32_init (vlib_main_t * vm) { crypto_ia32_main_t *cm = &crypto_ia32_main; vlib_thread_main_t *tm = vlib_get_thread_main (); - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, vnet_crypto_init))) - return error; + clib_error_t *error = 0; vec_validate_aligned (cm->per_thread_data, tm->n_vlib_mains - 1, CLIB_CACHE_LINE_BYTES); @@ -124,7 +121,12 @@ error: return error; } -VLIB_INIT_FUNCTION (crypto_ia32_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (crypto_ia32_init) = +{ + .runs_after = VLIB_INITS ("vnet_crypto_init"), +}; +/* *INDENT-ON* */ #include <vpp/app/version.h> diff --git a/src/plugins/crypto_ipsecmb/ipsecmb.c b/src/plugins/crypto_ipsecmb/ipsecmb.c index 7495452eb29..fccc697cba3 100644 --- a/src/plugins/crypto_ipsecmb/ipsecmb.c +++ b/src/plugins/crypto_ipsecmb/ipsecmb.c @@ -475,9 +475,6 @@ crypto_ipsecmb_init (vlib_main_t * vm) u32 eidx; u8 *name; - if ((error = vlib_call_init_function (vm, vnet_crypto_init))) - return error; - if (!clib_cpu_supports_aes ()) return 0; @@ -547,7 +544,12 @@ crypto_ipsecmb_init (vlib_main_t * vm) return (NULL); } -VLIB_INIT_FUNCTION (crypto_ipsecmb_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (crypto_ipsecmb_init) = +{ + .runs_after = VLIB_INITS ("vnet_crypto_init"), +}; +/* *INDENT-ON* */ /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = diff --git a/src/plugins/crypto_openssl/main.c b/src/plugins/crypto_openssl/main.c index f6e153798c4..2132c5bb15a 100644 --- a/src/plugins/crypto_openssl/main.c +++ b/src/plugins/crypto_openssl/main.c @@ -232,13 +232,9 @@ crypto_openssl_init (vlib_main_t * vm) vlib_thread_main_t *tm = vlib_get_thread_main (); openssl_per_thread_data_t *ptd; u8 *seed_data = 0; - clib_error_t *error; time_t t; pid_t pid; - if ((error = vlib_call_init_function (vm, vnet_crypto_init))) - return error; - u32 eidx = vnet_crypto_register_engine (vm, "openssl", 50, "OpenSSL"); #define _(m, a, b) \ @@ -284,7 +280,13 @@ crypto_openssl_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (crypto_openssl_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (crypto_openssl_init) = +{ + .runs_after = VLIB_INITS ("vnet_crypto_init"), +}; +/* *INDENT-ON* */ + /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { diff --git a/src/plugins/dpdk/api/dpdk_api.c b/src/plugins/dpdk/api/dpdk_api.c index 97c4bc75721..5ff8d5f2f41 100755 --- a/src/plugins/dpdk/api/dpdk_api.c +++ b/src/plugins/dpdk/api/dpdk_api.c @@ -297,10 +297,6 @@ dpdk_api_init (vlib_main_t * vm) dpdk_main_t *dm = &dpdk_main; clib_error_t *error = 0; - /* init CLI */ - if ((error = vlib_call_init_function (vm, dpdk_init))) - return error; - u8 *name; name = format (0, "dpdk_%08x%c", api_version, 0); @@ -320,8 +316,11 @@ dpdk_api_init (vlib_main_t * vm) return error; } -VLIB_INIT_FUNCTION (dpdk_api_init); - +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (dpdk_api_init) = +{ + .runs_after = VLIB_INITS ("dpdk_init"), +/* *INDENT-OFF* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/dpdk/device/cli.c b/src/plugins/dpdk/device/cli.c index 765b298f8a9..04cf37f5304 100644 --- a/src/plugins/dpdk/device/cli.c +++ b/src/plugins/dpdk/device/cli.c @@ -1737,6 +1737,12 @@ VLIB_CLI_COMMAND (show_vpe_version_command, static) = { }; /* *INDENT-ON* */ +/* Dummy function to get us linked in. */ +void +dpdk_cli_reference (void) +{ +} + clib_error_t * dpdk_cli_init (vlib_main_t * vm) { diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index bd9b35901d5..f79465cf8b4 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -512,6 +512,7 @@ clib_error_t *unformat_hqos (unformat_input_t * input, struct rte_pci_device *dpdk_get_pci_device (const struct rte_eth_dev_info *info); +void dpdk_cli_reference (void); #if CLI_DEBUG int dpdk_buffer_validate_trajectory_all (u32 * uninitialized); diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index c83b2b57c4c..22ea659094b 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -1734,6 +1734,8 @@ dpdk_init (vlib_main_t * vm) STATIC_ASSERT (RTE_CACHE_LINE_SIZE == 1 << CLIB_LOG2_CACHE_LINE_BYTES, "DPDK RTE CACHE LINE SIZE does not match with 1<<CLIB_LOG2_CACHE_LINE_BYTES"); + dpdk_cli_reference (); + dm->vlib_main = vm; dm->vnet_main = vnet_get_main (); dm->conf = &dpdk_config_main; @@ -1751,10 +1753,6 @@ dpdk_init (vlib_main_t * vm) dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL; dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL; - /* init CLI */ - if ((error = vlib_call_init_function (vm, dpdk_cli_init))) - return error; - dm->log_default = vlib_log_register_class ("dpdk", 0); return error; @@ -1762,7 +1760,6 @@ dpdk_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (dpdk_init); - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/dpdk/main.c b/src/plugins/dpdk/main.c index d22b671e008..a1ea9e32c93 100644 --- a/src/plugins/dpdk/main.c +++ b/src/plugins/dpdk/main.c @@ -85,16 +85,18 @@ static clib_error_t * dpdk_main_init (vlib_main_t * vm) dm->vlib_main = vm; dm->vnet_main = vnet_get_main (); - if ((error = vlib_call_init_function (vm, dpdk_init))) - return error; - /* register custom delay function */ rte_delay_us_callback_register (rte_delay_us_override_cb); return error; } -VLIB_INIT_FUNCTION (dpdk_main_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (dpdk_main_init) = +{ + .runs_after = VLIB_INITS("dpdk_init"), +}; +/* *INDENT-ON* */ clib_error_t * diff --git a/src/plugins/gbp/gbp_vxlan.c b/src/plugins/gbp/gbp_vxlan.c index 49dae7e9f4c..de635d0aa14 100644 --- a/src/plugins/gbp/gbp_vxlan.c +++ b/src/plugins/gbp/gbp_vxlan.c @@ -678,25 +678,24 @@ static clib_error_t * gbp_vxlan_init (vlib_main_t * vm) { vxlan_gbp_main_t *vxm = &vxlan_gbp_main; - clib_error_t *error; gt_logger = vlib_log_register_class ("gbp", "tun"); - if ((error = vlib_call_init_function (vm, punt_init))) - return error; - if ((error = vlib_call_init_function (vm, vxlan_gbp_init))) - return error; - punt_hdl = vlib_punt_client_register ("gbp-vxlan"); vlib_punt_register (punt_hdl, vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP4], "gbp-vxlan4"); - return (error); + return (0); } -VLIB_INIT_FUNCTION (gbp_vxlan_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (gbp_vxlan_init) = +{ + .runs_after = VLIB_INITS("punt_init", "vxlan_gbp_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/igmp/igmp.c b/src/plugins/igmp/igmp.c index 7f828619331..4e2fce1b916 100644 --- a/src/plugins/igmp/igmp.c +++ b/src/plugins/igmp/igmp.c @@ -479,24 +479,24 @@ igmp_enable_disable (u32 sw_if_index, u8 enable, igmp_mode_t mode) static clib_error_t * igmp_init (vlib_main_t * vm) { - clib_error_t *error; igmp_main_t *im = &igmp_main; - if ((error = vlib_call_init_function (vm, ip4_lookup_init))) - return error; - im->igmp_api_client_by_client_index = hash_create (0, sizeof (u32)); im->logger = vlib_log_register_class ("igmp", 0); IGMP_DBG ("initialized"); - return (error); + return (0); } -VLIB_INIT_FUNCTION (igmp_init); /* *INDENT-OFF* */ -VLIB_PLUGIN_REGISTER () = { +VLIB_INIT_FUNCTION (igmp_init) = +{ + .runs_after = VLIB_INITS("ip4_lookup_init"), +}; +VLIB_PLUGIN_REGISTER () = +{ .version = VPP_BUILD_VER, .description = "Internet Group Management Protocol (IGMP)", }; diff --git a/src/plugins/igmp/igmp_input.c b/src/plugins/igmp/igmp_input.c index 83e11ec6cc5..d5f714bc033 100644 --- a/src/plugins/igmp/igmp_input.c +++ b/src/plugins/igmp/igmp_input.c @@ -445,19 +445,19 @@ VLIB_REGISTER_NODE (igmp_parse_report_node) = static clib_error_t * igmp_input_init (vlib_main_t * vm) { - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, igmp_init))) - return error; - ip4_register_protocol (IP_PROTOCOL_IGMP, igmp_input_node.index); IGMP_DBG ("input-initialized"); - return (error); + return (0); } -VLIB_INIT_FUNCTION (igmp_input_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (igmp_input_init) = +{ + .runs_after = VLIB_INITS("igmp_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/igmp/igmp_ssm_range.c b/src/plugins/igmp/igmp_ssm_range.c index 3d12712d3db..c74d312b508 100644 --- a/src/plugins/igmp/igmp_ssm_range.c +++ b/src/plugins/igmp/igmp_ssm_range.c @@ -138,20 +138,19 @@ VLIB_CLI_COMMAND (igmp_show_timers_command, static) = { static clib_error_t * igmp_ssm_range_init (vlib_main_t * vm) { - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, igmp_init))) - return error; - igmp_ssm_range_populate (); IGMP_DBG ("ssm-range-initialized"); - return (error); + return (0); } -VLIB_INIT_FUNCTION (igmp_ssm_range_init); - +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (igmp_ssm_range_init) = +{ + .runs_after = VLIB_INITS("igmp_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index 2340137bb9c..e7b2f92941d 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -3295,13 +3295,9 @@ clib_error_t * ikev2_init (vlib_main_t * vm) { ikev2_main_t *km = &ikev2_main; - clib_error_t *error; vlib_thread_main_t *tm = vlib_get_thread_main (); int thread_id; - if ((error = vlib_call_init_function (vm, ipsec_init))) - return error; - clib_memset (km, 0, sizeof (ikev2_main_t)); km->vnet_main = vnet_get_main (); km->vlib_main = vm; @@ -3319,16 +3315,20 @@ ikev2_init (vlib_main_t * vm) km->sa_by_ispi = hash_create (0, sizeof (uword)); - - if ((error = vlib_call_init_function (vm, ikev2_cli_init))) - return error; - udp_register_dst_port (vm, 500, ikev2_node.index, 1); + ikev2_cli_reference (); + return 0; } -VLIB_INIT_FUNCTION (ikev2_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ikev2_init) = +{ + .runs_after = VLIB_INITS("ipsec_init"), +}; +/* *INDENT-ON* */ + static u8 ikev2_mngr_process_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * csa) diff --git a/src/plugins/ikev2/ikev2.h b/src/plugins/ikev2/ikev2.h index 55731bff975..2feecf73fdb 100644 --- a/src/plugins/ikev2/ikev2.h +++ b/src/plugins/ikev2/ikev2.h @@ -422,6 +422,7 @@ uword unformat_ikev2_transform_dh_type (unformat_input_t * input, va_list * args); uword unformat_ikev2_transform_esn_type (unformat_input_t * input, va_list * args); +void ikev2_cli_reference (void); #endif /* __included_ikev2_h__ */ diff --git a/src/plugins/ikev2/ikev2_cli.c b/src/plugins/ikev2/ikev2_cli.c index 8801793be0b..0933667c4bd 100644 --- a/src/plugins/ikev2/ikev2_cli.c +++ b/src/plugins/ikev2/ikev2_cli.c @@ -584,15 +584,11 @@ VLIB_CLI_COMMAND (ikev2_initiate_command, static) = { }; /* *INDENT-ON* */ - -clib_error_t * -ikev2_cli_init (vlib_main_t * vm) +void +ikev2_cli_reference (void) { - return 0; } -VLIB_INIT_FUNCTION (ikev2_cli_init); - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/ioam/analyse/ioam_summary_export.c b/src/plugins/ioam/analyse/ioam_summary_export.c index c16e8398bd3..4851491012b 100644 --- a/src/plugins/ioam/analyse/ioam_summary_export.c +++ b/src/plugins/ioam/analyse/ioam_summary_export.c @@ -427,15 +427,15 @@ ioam_flow_create (u8 del) clib_error_t * ioam_flow_report_init (vlib_main_t * vm) { - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, flow_report_init))) - return error; - return 0; } -VLIB_INIT_FUNCTION (ioam_flow_report_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ioam_flow_report_init) = +{ + .runs_after = VLIB_INITS("flow_report_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/ioam/encap/ip6_ioam_e2e.c b/src/plugins/ioam/encap/ip6_ioam_e2e.c index cdaf740d251..58714083fe4 100644 --- a/src/plugins/ioam/encap/ip6_ioam_e2e.c +++ b/src/plugins/ioam/encap/ip6_ioam_e2e.c @@ -44,7 +44,7 @@ static u8 * ioam_e2e_trace_handler (u8 * s, return s; } -int +int ioam_e2e_config_handler (void *data, u8 disable) { int *analyse = data; @@ -171,13 +171,6 @@ VLIB_CLI_COMMAND (ioam_show_e2e_cmd, static) = { static clib_error_t * ioam_e2e_init (vlib_main_t * vm) { - clib_error_t * error; - - if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init))) - { - return(error); - } - /* * As of now we have only PPC under E2E header. */ @@ -213,4 +206,9 @@ ioam_e2e_init (vlib_main_t * vm) * Init function for the E2E lib. * ip6_hop_by_hop_ioam_e2e_init gets called during init. */ -VLIB_INIT_FUNCTION (ioam_e2e_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ioam_e2e_init) = +{ + .runs_after = VLIB_INITS("ip6_hop_by_hop_ioam_init"), +}; +/* *INDENT-ON* */ diff --git a/src/plugins/ioam/encap/ip6_ioam_pot.c b/src/plugins/ioam/encap/ip6_ioam_pot.c index 8dd06c144e3..71c0cc92709 100644 --- a/src/plugins/ioam/encap/ip6_ioam_pot.c +++ b/src/plugins/ioam/encap/ip6_ioam_pot.c @@ -29,7 +29,7 @@ _(PROCESSED, "Pkts with ip6 hop-by-hop pot options") \ _(PROFILE_MISS, "Pkts with ip6 hop-by-hop pot options but no profile set") \ _(PASSED, "Pkts with POT in Policy") \ - _(FAILED, "Pkts with POT out of Policy") + _(FAILED, "Pkts with POT out of Policy") static char * ip6_hop_by_hop_ioam_pot_stats_strings[] = { #define _(sym,string) string, @@ -47,7 +47,7 @@ typedef enum { typedef struct { /* stats */ u64 counters[ARRAY_LEN(ip6_hop_by_hop_ioam_pot_stats_strings)]; - + /* convenience */ vlib_main_t * vlib_main; vnet_main_t * vnet_main; @@ -55,7 +55,7 @@ typedef struct { ip6_hop_by_hop_ioam_pot_main_t ip6_hop_by_hop_ioam_pot_main; -always_inline void +always_inline void ip6_ioam_stats_increment_counter (u32 counter_index, u64 increment) { ip6_hop_by_hop_ioam_pot_main_t *hm = &ip6_hop_by_hop_ioam_pot_main; @@ -69,13 +69,13 @@ static u8 * format_ioam_pot (u8 * s, va_list * args) ioam_pot_option_t * pot0 = va_arg (*args, ioam_pot_option_t *); u64 random, cumulative; random = cumulative = 0; - if (pot0) - { + if (pot0) + { random = clib_net_to_host_u64 (pot0->random); cumulative = clib_net_to_host_u64 (pot0->cumulative); } - s = format (s, "random = 0x%Lx, Cumulative = 0x%Lx, Index = 0x%x", + s = format (s, "random = 0x%Lx, Cumulative = 0x%Lx, Index = 0x%x", random, cumulative, pot0 ? pot0->reserved_profile_id : ~0); return s; } @@ -117,22 +117,22 @@ ip6_hbh_ioam_proof_of_transit_handler (vlib_buffer_t *b, pot0->reserved_profile_id = pot_profile_index & PROFILE_ID_MASK; pot_profile_incr_usage_stats(pot_profile); - } - else + } + else { /* Non encap node */ - if (PREDICT_FALSE(pot0->reserved_profile_id != - pot_profile_index || pot_profile == 0)) + if (PREDICT_FALSE(pot0->reserved_profile_id != + pot_profile_index || pot_profile == 0)) { /* New profile announced by encap node. */ new_profile = - pot_profile_find(pot0->reserved_profile_id); + pot_profile_find(pot0->reserved_profile_id); if (PREDICT_FALSE(new_profile == 0 || - new_profile->valid == 0)) + new_profile->valid == 0)) { ip6_ioam_stats_increment_counter (IP6_IOAM_POT_PROFILE_MISS, 1); return(-1); - } - else + } + else { pot_profile_index = pot0->reserved_profile_id; pot_profile = new_profile; @@ -143,7 +143,7 @@ ip6_hbh_ioam_proof_of_transit_handler (vlib_buffer_t *b, pot_profile_incr_usage_stats(pot_profile); } - if (pot0->random == 0) + if (pot0->random == 0) { pot0->random = clib_host_to_net_u64(pot_generate_random(pot_profile)); pot0->cumulative = 0; @@ -196,7 +196,7 @@ int ip6_hop_by_hop_ioam_pot_rewrite_handler (u8 *rewrite_string, u8 *rewrite_siz pot_option = (ioam_pot_option_t *)rewrite_string; pot_option->hdr.type = HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT | HBH_OPTION_TYPE_DATA_CHANGE_ENROUTE; - pot_option->hdr.length = sizeof (ioam_pot_option_t) - + pot_option->hdr.length = sizeof (ioam_pot_option_t) - sizeof (ip6_hop_by_hop_option_t); return(0); } @@ -235,15 +235,11 @@ static clib_error_t * ip6_hop_by_hop_ioam_pot_init (vlib_main_t * vm) { ip6_hop_by_hop_ioam_pot_main_t * hm = &ip6_hop_by_hop_ioam_pot_main; - clib_error_t * error; - - if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init))) - return(error); hm->vlib_main = vm; hm->vnet_main = vnet_get_main(); clib_memset(hm->counters, 0, sizeof(hm->counters)); - + if (ip6_hbh_register_option(HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT, ip6_hbh_ioam_proof_of_transit_handler, ip6_hbh_ioam_proof_of_transit_trace_handler) < 0) return (clib_error_create("registration of HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT failed")); @@ -260,6 +256,9 @@ ip6_hop_by_hop_ioam_pot_init (vlib_main_t * vm) return (0); } -VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_pot_init); - - +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_pot_init) = +{ + .runs_after = VLIB_INITS("ip6_hop_by_hop_ioam_init"), +}; +/* *INDENT-OFF* */ diff --git a/src/plugins/ioam/encap/ip6_ioam_trace.c b/src/plugins/ioam/encap/ip6_ioam_trace.c index ddd9ae99dd5..53fb63ea6fd 100644 --- a/src/plugins/ioam/encap/ip6_ioam_trace.c +++ b/src/plugins/ioam/encap/ip6_ioam_trace.c @@ -417,16 +417,6 @@ static clib_error_t * ip6_hop_by_hop_ioam_trace_init (vlib_main_t * vm) { ip6_hop_by_hop_ioam_trace_main_t *hm = &ip6_hop_by_hop_ioam_trace_main; - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, ip_main_init))) - return (error); - - if ((error = vlib_call_init_function (vm, ip6_lookup_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_ioam_init))) - return (error); hm->vlib_main = vm; hm->vnet_main = vnet_get_main (); @@ -452,6 +442,14 @@ ip6_hop_by_hop_ioam_trace_init (vlib_main_t * vm) return (0); } +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_trace_init) = +{ + .runs_after = VLIB_INITS ("ip_main_init", "ip6_lookup_init", + "ip6_hop_by_hop_ioam_init"), +}; +/* *INDENT-ON* */ + int ip6_trace_profile_cleanup (void) { @@ -490,9 +488,6 @@ ip6_trace_profile_setup (void) return (0); } - -VLIB_INIT_FUNCTION (ip6_hop_by_hop_ioam_trace_init); - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_ioam_trace.c b/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_ioam_trace.c index e2c130c00df..c51d251bee3 100644 --- a/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_ioam_trace.c +++ b/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_ioam_trace.c @@ -436,16 +436,6 @@ static clib_error_t * vxlan_gpe_ioam_trace_init (vlib_main_t * vm) { vxlan_gpe_ioam_trace_main_t *hm = &vxlan_gpe_ioam_trace_main; - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, ip_main_init))) - return (error); - - if ((error = vlib_call_init_function (vm, ip6_lookup_init))) - return error; - - if ((error = vlib_call_init_function (vm, vxlan_gpe_init))) - return (error); hm->vlib_main = vm; hm->vnet_main = vnet_get_main (); @@ -470,7 +460,14 @@ vxlan_gpe_ioam_trace_init (vlib_main_t * vm) return (0); } -VLIB_INIT_FUNCTION (vxlan_gpe_ioam_trace_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (vxlan_gpe_ioam_trace_init) = +{ + .runs_after = VLIB_INITS("ip_main_init", "ip6_lookup_init", + "vxlan_gpe_init"), +}; +/* *INDENT-ON* */ + int vxlan_gpe_trace_profile_cleanup (void) diff --git a/src/plugins/ioam/udp-ping/udp_ping_export.c b/src/plugins/ioam/udp-ping/udp_ping_export.c index 7a7cad4934a..d25eb1041dd 100644 --- a/src/plugins/ioam/udp-ping/udp_ping_export.c +++ b/src/plugins/ioam/udp-ping/udp_ping_export.c @@ -290,15 +290,16 @@ VLIB_CLI_COMMAND (set_udp_ping_export_command, static) = { clib_error_t * udp_ping_flow_report_init (vlib_main_t * vm) { - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, flow_report_init))) - return error; - return 0; } -VLIB_INIT_FUNCTION (udp_ping_flow_report_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (udp_ping_flow_report_init) = +{ + .runs_after = VLIB_INITS ("flow_report_init"), +}; +/* *INDENT-ON* */ + /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/ioam/udp-ping/udp_ping_node.c b/src/plugins/ioam/udp-ping/udp_ping_node.c index 59e4511eb7d..e5916dbd0e1 100644 --- a/src/plugins/ioam/udp-ping/udp_ping_node.c +++ b/src/plugins/ioam/udp-ping/udp_ping_node.c @@ -819,21 +819,21 @@ VLIB_REGISTER_NODE (udp_ping_local, static) = static clib_error_t * udp_ping_init (vlib_main_t * vm) { - clib_error_t *error = 0; - udp_ping_main.vlib_main = vm; udp_ping_main.vnet_main = vnet_get_main (); udp_ping_main.timer_interval = 1e9; - if ((error = vlib_call_init_function (vm, ip_main_init))) - return (error); - ip6_register_protocol (IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS, udp_ping_local.index); return 0; } -VLIB_INIT_FUNCTION (udp_ping_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (udp_ping_init) = +{ + .runs_after = VLIB_INITS("ip_main_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/ixge/ixge.c b/src/plugins/ixge/ixge.c index 8faa9a91ca2..c27042df8b2 100644 --- a/src/plugins/ixge/ixge.c +++ b/src/plugins/ixge/ixge.c @@ -2788,7 +2788,6 @@ clib_error_t * ixge_init (vlib_main_t * vm) { ixge_main_t *xm = &ixge_main; - clib_error_t *error; xm->vlib_main = vm; clib_memset (&xm->tx_descriptor_template, 0, @@ -2807,13 +2806,15 @@ ixge_init (vlib_main_t * vm) | IXGE_TX_DESCRIPTOR_STATUS0_REPORT_STATUS); xm->tx_descriptor_template_mask.status1 &= ~(IXGE_TX_DESCRIPTOR_STATUS1_DONE); - - error = vlib_call_init_function (vm, pci_bus_init); - - return error; + return 0; } -VLIB_INIT_FUNCTION (ixge_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ixge_init) = +{ + .runs_before = VLIB_INITS("pci_bus_init"), +}; +/* *INDENT-ON* */ static void diff --git a/src/plugins/lacp/input.c b/src/plugins/lacp/input.c index 8212b119784..ef7cca9c442 100644 --- a/src/plugins/lacp/input.c +++ b/src/plugins/lacp/input.c @@ -233,15 +233,15 @@ lacp_input (vlib_main_t * vm, vlib_buffer_t * b0, u32 bi0) static clib_error_t * lacp_init (vlib_main_t * vm) { - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, lacp_periodic_init))) - return error; - return 0; } -VLIB_INIT_FUNCTION (lacp_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (lacp_init) = +{ + .runs_after = VLIB_INITS("lacp_periodic_init"), +}; +/* *INDENT-ON* */ /* * packet trace format function, very similar to diff --git a/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_trace.c b/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_trace.c index bd56a6ab7b1..c40e89b52be 100644 --- a/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_trace.c +++ b/src/plugins/nsh/nsh-md2-ioam/nsh_md2_ioam_trace.c @@ -354,13 +354,6 @@ nsh_md2_ioam_trace_init (vlib_main_t * vm) { nsh_md2_ioam_trace_main_t *hm = &nsh_md2_ioam_trace_main; nsh_md2_ioam_main_t *gm = &nsh_md2_ioam_main; - clib_error_t *error; - - if ((error = vlib_call_init_function (vm, nsh_init))) - return (error); - - if ((error = vlib_call_init_function (vm, nsh_md2_ioam_init))) - return (error); hm->vlib_main = vm; hm->vnet_main = vnet_get_main (); @@ -384,7 +377,12 @@ nsh_md2_ioam_trace_init (vlib_main_t * vm) return (0); } -VLIB_INIT_FUNCTION (nsh_md2_ioam_trace_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (nsh_md2_ioam_trace_init) = +{ + .runs_after = VLIB_INITS ("nsh_init", "nsh_md2_ioam_init"), +}; +/* *INDENT-ON* */ int nsh_md2_ioam_trace_profile_cleanup (void) diff --git a/src/plugins/tlsmbedtls/tls_mbedtls.c b/src/plugins/tlsmbedtls/tls_mbedtls.c index e356088d619..73112323f0e 100644 --- a/src/plugins/tlsmbedtls/tls_mbedtls.c +++ b/src/plugins/tlsmbedtls/tls_mbedtls.c @@ -635,14 +635,10 @@ tls_mbedtls_init (vlib_main_t * vm) { vlib_thread_main_t *vtm = vlib_get_thread_main (); mbedtls_main_t *mm = &mbedtls_main; - clib_error_t *error; u32 num_threads; num_threads = 1 /* main thread */ + vtm->n_threads; - if ((error = vlib_call_init_function (vm, tls_init))) - return error; - if (tls_init_ca_chain ()) { clib_warning ("failed to initialize TLS CA chain"); @@ -667,7 +663,12 @@ tls_mbedtls_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (tls_mbedtls_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (tls_mbedtls_init) = +{ + .runs_after = VLIB_INITS("tls_init"), +}; +/* *INDENT-ON* */ /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c index f6de0e003e8..4d4c4c37170 100644 --- a/src/plugins/tlsopenssl/tls_openssl.c +++ b/src/plugins/tlsopenssl/tls_openssl.c @@ -835,14 +835,10 @@ tls_openssl_init (vlib_main_t * vm) { vlib_thread_main_t *vtm = vlib_get_thread_main (); openssl_main_t *om = &openssl_main; - clib_error_t *error; u32 num_threads; num_threads = 1 /* main thread */ + vtm->n_threads; - if ((error = vlib_call_init_function (vm, tls_init))) - return error; - SSL_library_init (); SSL_load_error_strings (); @@ -864,6 +860,12 @@ tls_openssl_init (vlib_main_t * vm) return 0; } +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (tls_openssl_init) = +{ + .runs_after = VLIB_INITS("tls_init"), +}; +/* *INDENT-ON* */ #ifdef HAVE_OPENSSL_ASYNC static clib_error_t * @@ -938,9 +940,6 @@ VLIB_CLI_COMMAND (tls_openssl_set_command, static) = /* *INDENT-ON* */ #endif - -VLIB_INIT_FUNCTION (tls_openssl_init); - /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, diff --git a/src/vlib/init.c b/src/vlib/init.c index 8d4784513ab..8010e9e97cd 100644 --- a/src/vlib/init.c +++ b/src/vlib/init.c @@ -38,16 +38,309 @@ */ #include <vlib/vlib.h> +#include <vppinfra/ptclosure.h> + +/** + * @file + * @brief Init function ordering and execution implementation + * Topological sort for all classes of init functions, and + * a relatively simple API routine to invoke them. + */ + +/*? %%clicmd:group_label Init functions %% ?*/ + +static int +comma_split (u8 * s, u8 ** a, u8 ** b) +{ + *a = s; + + while (*s && *s != ',') + s++; + + if (*s == ',') + *s = 0; + else + return 1; + + *b = (u8 *) (s + 1); + return 0; +} + +/** + * @brief Topological sorter for init function chains. + * @param head [in/out] address of the listhead to be sorted + * @returns 0 on success, otherwise a clib_error_t *. + */ + +static clib_error_t *init_exit_function_sort + (_vlib_init_function_list_elt_t ** head) +{ + uword *index_by_name; + uword *reg_by_index; + u8 **init_f_names = 0; + u8 *init_f_name; + char **these_constraints; + char *this_constraint_c; + u8 **constraints = 0; + u8 *constraint_tuple; + u8 *this_constraint; + char *prev_name; + u8 **orig, **closure; + uword *p; + int i, j, k; + u8 *a_name, *b_name; + int a_index, b_index; + int n_init_fns; + u32 *result = 0; + _vlib_init_function_list_elt_t *this_reg = 0; + hash_pair_t *hp; + u8 **keys_to_delete = 0; + + /* + * two hash tables: name to index in init_f_names, and + * init function registration pointer by index + */ + index_by_name = hash_create_string (0, sizeof (uword)); + reg_by_index = hash_create (0, sizeof (uword)); + + this_reg = *head; + + /* pass 1, collect init fcn names, construct a before b pairs */ + while (this_reg) + { + init_f_name = format (0, "%s%c", this_reg->name, 0); + hash_set (reg_by_index, vec_len (init_f_names), (uword) this_reg); + + hash_set_mem (index_by_name, init_f_name, vec_len (init_f_names)); + + vec_add1 (init_f_names, init_f_name); + + these_constraints = this_reg->runs_before; + while (these_constraints && these_constraints[0]) + { + this_constraint_c = these_constraints[0]; + + constraint_tuple = format (0, "%s,%s%c", init_f_name, + this_constraint_c, 0); + vec_add1 (constraints, constraint_tuple); + these_constraints++; + } + + these_constraints = this_reg->runs_after; + while (these_constraints && these_constraints[0]) + { + this_constraint_c = these_constraints[0]; + + constraint_tuple = format (0, "%s,%s%c", + this_constraint_c, init_f_name, 0); + vec_add1 (constraints, constraint_tuple); + these_constraints++; + } + + this_reg = this_reg->next_init_function; + } + + /* + * pass 2: collect "a then b then c then d" constraints. + * all init fcns must be known at this point. + */ + this_reg = *head; + while (this_reg) + { + these_constraints = this_reg->init_order; + + prev_name = 0; + /* Across the list of constraints */ + while (these_constraints && these_constraints[0]) + { + this_constraint_c = these_constraints[0]; + p = hash_get_mem (index_by_name, this_constraint_c); + if (p == 0) + { + clib_warning + ("order constraint fcn '%s' not found", this_constraint_c); + these_constraints++; + continue; + } + + if (prev_name == 0) + { + prev_name = this_constraint_c; + these_constraints++; + continue; + } + + constraint_tuple = format (0, "%s,%s%c", prev_name, + this_constraint_c, 0); + vec_add1 (constraints, constraint_tuple); + prev_name = this_constraint_c; + these_constraints++; + } + this_reg = this_reg->next_init_function; + } + + n_init_fns = vec_len (init_f_names); + orig = clib_ptclosure_alloc (n_init_fns); + + for (i = 0; i < vec_len (constraints); i++) + { + this_constraint = constraints[i]; + + if (comma_split (this_constraint, &a_name, &b_name)) + return clib_error_return (0, "comma_split failed!"); + + p = hash_get_mem (index_by_name, a_name); + /* + * Note: the next two errors mean that something is + * b0rked. As in: if you code "A runs before on B," and you type + * B incorrectly, you lose. Nonexistent init functions are tolerated. + */ + if (p == 0) + { + clib_warning ("init function '%s' not found (before '%s')", + a_name, b_name); + continue; + } + a_index = p[0]; + + p = hash_get_mem (index_by_name, b_name); + if (p == 0) + { + clib_warning ("init function '%s' not found (after '%s')", + b_name, a_name); + continue; + } + b_index = p[0]; + + /* add a before b to the original set of constraints */ + orig[a_index][b_index] = 1; + vec_free (this_constraint); + } + + /* Compute the positive transitive closure of the original constraints */ + closure = clib_ptclosure (orig); + + /* Compute a partial order across feature nodes, if one exists. */ +again: + for (i = 0; i < n_init_fns; i++) + { + for (j = 0; j < n_init_fns; j++) + { + if (closure[i][j]) + goto item_constrained; + } + /* Item i can be output */ + vec_add1 (result, i); + { + for (k = 0; k < n_init_fns; k++) + closure[k][i] = 0; + /* + * Add a "Magic" a before a constraint. + * This means we'll never output it again + */ + closure[i][i] = 1; + goto again; + } + item_constrained: + ; + } + + /* see if we got a partial order... */ + if (vec_len (result) != n_init_fns) + return clib_error_return + (0, "Failed to find a suitable init function order!"); + + /* + * We win. + * Bind the index variables, and output the feature node name vector + * using the partial order we just computed. Result is in stack + * order, because the entry with the fewest constraints (e.g. none) + * is output first, etc. + * Reset the listhead, and add items in result (aka reverse) order. + */ + *head = 0; + for (i = 0; i < n_init_fns; i++) + { + p = hash_get (reg_by_index, result[i]); + ASSERT (p != 0); + this_reg = (_vlib_init_function_list_elt_t *) p[0]; + + this_reg->next_init_function = *head; + *head = this_reg; + } + + /* Finally, clean up all the fine data we allocated */ + /* *INDENT-OFF* */ + hash_foreach_pair (hp, index_by_name, + ({ + vec_add1 (keys_to_delete, (u8 *)hp->key); + })); + /* *INDENT-ON* */ + hash_free (index_by_name); + for (i = 0; i < vec_len (keys_to_delete); i++) + vec_free (keys_to_delete[i]); + vec_free (keys_to_delete); + hash_free (reg_by_index); + vec_free (result); + clib_ptclosure_free (orig); + clib_ptclosure_free (closure); + return 0; +} + +/** + * @brief call a set of init / exit / main-loop enter functions + * @param vm vlib_main_t + * @param head address of the listhead to sort and then invoke + * @returns 0 on success, clib_error_t * on error + * + * The "init_functions_called" hash supports a subtle mix of procedural + * and formally-specified ordering constraints. The following schemes + * are *roughly* equivalent: + * + * static clib_error_t *init_runs_first (vlib_main_t *vm) + * { + * clib_error_t *error; + * + * ... do some stuff... + * + * if ((error = vlib_call_init_function (init_runs_next))) + * return error; + * ... + * } + * VLIB_INIT_FUNCTION (init_runs_first); + * + * and + * + * static clib_error_t *init_runs_first (vlib_main_t *vm) + * { + * ... do some stuff... + * } + * VLIB_INIT_FUNCTION (init_runs_first) = + * { + * .runs_before = VLIB_INITS("init_runs_next"), + * }; + * + * The first form will [most likely] call "init_runs_next" on the + * spot. The second form means that "init_runs_first" runs before + * "init_runs_next," possibly much earlier in the sequence. + * + * Please DO NOT construct sets of init functions where A before B + * actually means A *right before* B. It's not necessary - simply combine + * A and B - and it leads to hugely annoying debugging exercises. + */ clib_error_t * vlib_call_init_exit_functions (vlib_main_t * vm, - _vlib_init_function_list_elt_t * head, + _vlib_init_function_list_elt_t ** headp, int call_once) { clib_error_t *error = 0; _vlib_init_function_list_elt_t *i; - i = head; + if ((error = init_exit_function_sort (headp))) + return (error); + + i = *headp; while (i) { if (call_once && !hash_get (vm->init_functions_called, i->f)) @@ -73,21 +366,21 @@ vlib_call_all_init_functions (vlib_main_t * vm) #undef _ return vlib_call_init_exit_functions - (vm, vm->init_function_registrations, 1 /* call_once */ ); + (vm, &vm->init_function_registrations, 1 /* call_once */ ); } clib_error_t * vlib_call_all_main_loop_enter_functions (vlib_main_t * vm) { return vlib_call_init_exit_functions - (vm, vm->main_loop_enter_function_registrations, 1 /* call_once */ ); + (vm, &vm->main_loop_enter_function_registrations, 1 /* call_once */ ); } clib_error_t * vlib_call_all_main_loop_exit_functions (vlib_main_t * vm) { return vlib_call_init_exit_functions - (vm, vm->main_loop_exit_function_registrations, 1 /* call_once */ ); + (vm, &vm->main_loop_exit_function_registrations, 1 /* call_once */ ); } clib_error_t * @@ -159,6 +452,204 @@ done: return error; } +void +vlib_init_dump (void) +{ + vlib_main_t *vm = vlib_get_main (); + int i = 0; + + _vlib_init_function_list_elt_t *head, *this; + head = vm->init_function_registrations; + + this = head; + while (this) + { + fformat (stdout, "[%d]: %s\n", i++, this->name); + this = this->next_init_function; + } +} + +static clib_error_t * +show_init_function_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + int which = 1; + int verbose = 0; + int i, n_init_fns; + _vlib_init_function_list_elt_t *head, *this; + uword *index_by_name; + uword *reg_by_index; + u8 **init_f_names = 0; + u8 *init_f_name; + uword *p; + _vlib_init_function_list_elt_t *this_reg = 0; + hash_pair_t *hp; + u8 **keys_to_delete = 0; + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (input, "init")) + which = 1; + else if (unformat (input, "enter")) + which = 2; + else if (unformat (input, "exit")) + which = 3; + else if (unformat (input, "verbose %d", &verbose)) + ; + else if (unformat (input, "verbose")) + verbose = 1; + else + break; + } + + switch (which) + { + case 1: + head = vm->init_function_registrations; + break; + case 2: + head = vm->main_loop_enter_function_registrations; + break; + case 3: + head = vm->main_loop_exit_function_registrations; + break; + default: + return clib_error_return (0, "BUG"); + } + + if (verbose == 0) + { + this = head; + i = 0; + while (this) + { + vlib_cli_output (vm, "[%d]: %s", i++, this->name); + this = this->next_init_function; + } + return 0; + } + + index_by_name = hash_create_string (0, sizeof (uword)); + reg_by_index = hash_create (0, sizeof (uword)); + + this_reg = head; + n_init_fns = 0; + /* collect init fcn names */ + while (this_reg) + { + init_f_name = format (0, "%s%c", this_reg->name, 0); + hash_set (reg_by_index, vec_len (init_f_names), (uword) this_reg); + + hash_set_mem (index_by_name, init_f_name, vec_len (init_f_names)); + vec_add1 (init_f_names, init_f_name); + n_init_fns++; + this_reg = this_reg->next_init_function; + } + + for (i = 0; i < n_init_fns; i++) + { + p = hash_get (reg_by_index, i); + ASSERT (p != 0); + this_reg = (_vlib_init_function_list_elt_t *) p[0]; + vlib_cli_output (vm, "[%d] %s", i, this_reg->name); + { + char **runs_before, **runs_after, **init_order; + runs_before = this_reg->runs_before; + while (runs_before && runs_before[0]) + { + _vlib_init_function_list_elt_t *successor; + uword successor_index; + p = hash_get_mem (index_by_name, runs_before[0]); + if (p == 0) + { + clib_warning ("couldn't find successor '%s'", runs_before[0]); + runs_before++; + continue; + } + successor_index = p[0]; + p = hash_get (reg_by_index, p[0]); + ASSERT (p != 0); + successor = (_vlib_init_function_list_elt_t *) p[0]; + vlib_cli_output (vm, " before '%s' [%lld]", + successor->name, successor_index); + runs_before++; + } + runs_after = this_reg->runs_after; + while (runs_after && runs_after[0]) + { + _vlib_init_function_list_elt_t *predecessor; + uword predecessor_index; + p = hash_get_mem (index_by_name, runs_after[0]); + if (p == 0) + { + clib_warning ("couldn't find predecessor '%s'", + runs_after[0]); + runs_after++; + continue; + } + predecessor_index = p[0]; + p = hash_get (reg_by_index, p[0]); + ASSERT (p != 0); + predecessor = (_vlib_init_function_list_elt_t *) p[0]; + vlib_cli_output (vm, " after '%s' [%lld]", + predecessor->name, predecessor_index); + runs_after++; + } + init_order = this_reg->init_order; + while (init_order && init_order[0]) + { + _vlib_init_function_list_elt_t *inorder; + uword inorder_index; + p = hash_get_mem (index_by_name, init_order[0]); + if (p == 0) + { + clib_warning ("couldn't find order element'%s'", + init_order[0]); + init_order++; + continue; + } + inorder_index = p[0]; + p = hash_get (reg_by_index, p[0]); + ASSERT (p != 0); + inorder = (_vlib_init_function_list_elt_t *) p[0]; + vlib_cli_output (vm, " in order '%s' [%lld]", + inorder->name, inorder_index); + init_order++; + } + } + } + /* *INDENT-OFF* */ + hash_foreach_pair (hp, index_by_name, + ({ + vec_add1 (keys_to_delete, (u8 *)hp->key); + })); + /* *INDENT-ON* */ + hash_free (index_by_name); + for (i = 0; i < vec_len (keys_to_delete); i++) + vec_free (keys_to_delete[i]); + vec_free (keys_to_delete); + hash_free (reg_by_index); + + return 0; +} + +/*? + * Show init function order + * + * @cliexpar + * @cliexstart{show init-function [init | enter | exit] [verbose [nn]]} + * @cliexend + ?*/ +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (show_init_function, static) = { + .path = "show init-function", + .short_help = "show init-function [init | enter | exit][verbose [nn]]", + .function = show_init_function_command_fn, +}; +/* *INDENT-ON* */ + + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vlib/init.h b/src/vlib/init.h index a9367697a85..6d2711489d8 100644 --- a/src/vlib/init.h +++ b/src/vlib/init.h @@ -54,6 +54,10 @@ typedef struct _vlib_init_function_list_elt { struct _vlib_init_function_list_elt *next_init_function; vlib_init_function_t *f; + char *name; + char **runs_before; + char **runs_after; + char **init_order; } _vlib_init_function_list_elt_t; /* Configuration functions: called with configuration input just before @@ -116,48 +120,54 @@ typedef struct vlib_config_function_runtime_t be called from other modules to resolve init function depend. */ #ifndef CLIB_MARCH_VARIANT -#define VLIB_DECLARE_INIT_FUNCTION(x, tag) \ -vlib_init_function_t * _VLIB_INIT_FUNCTION_SYMBOL (x, tag) = x; \ -static void __vlib_add_##tag##_function_##x (void) \ - __attribute__((__constructor__)) ; \ -static void __vlib_add_##tag##_function_##x (void) \ -{ \ - vlib_main_t * vm = vlib_get_main(); \ - static _vlib_init_function_list_elt_t _vlib_init_function; \ - _vlib_init_function.next_init_function \ - = vm->tag##_function_registrations; \ - vm->tag##_function_registrations = &_vlib_init_function; \ - _vlib_init_function.f = &x; \ -} \ -static void __vlib_rm_##tag##_function_##x (void) \ - __attribute__((__destructor__)) ; \ -static void __vlib_rm_##tag##_function_##x (void) \ -{ \ - vlib_main_t * vm = vlib_get_main(); \ - _vlib_init_function_list_elt_t *next; \ - if (vm->tag##_function_registrations->f == &x) \ - { \ - vm->tag##_function_registrations = \ - vm->tag##_function_registrations->next_init_function; \ - return; \ - } \ - next = vm->tag##_function_registrations; \ - while (next->next_init_function) \ - { \ - if (next->next_init_function->f == &x) \ - { \ - next->next_init_function = \ - next->next_init_function->next_init_function; \ - return; \ - } \ - next = next->next_init_function; \ - } \ -} +#define VLIB_DECLARE_INIT_FUNCTION(x, tag) \ +vlib_init_function_t * _VLIB_INIT_FUNCTION_SYMBOL (x, tag) = x; \ +static void __vlib_add_##tag##_function_##x (void) \ + __attribute__((__constructor__)) ; \ +static _vlib_init_function_list_elt_t _vlib_init_function_##tag_##x; \ +static void __vlib_add_##tag##_function_##x (void) \ +{ \ + vlib_main_t * vm = vlib_get_main(); \ + _vlib_init_function_##tag_##x.next_init_function \ + = vm->tag##_function_registrations; \ + vm->tag##_function_registrations = &_vlib_init_function_##tag_##x; \ + _vlib_init_function_##tag_##x.f = &x; \ + _vlib_init_function_##tag_##x.name = #x; \ +} \ +static void __vlib_rm_##tag##_function_##x (void) \ + __attribute__((__destructor__)) ; \ +static void __vlib_rm_##tag##_function_##x (void) \ +{ \ + vlib_main_t * vm = vlib_get_main(); \ + _vlib_init_function_list_elt_t *this, *prev; \ + this = vm->tag##_function_registrations; \ + if (this == 0) \ + return; \ + if (this->f == &x) \ + { \ + vm->tag##_function_registrations = this->next_init_function; \ + return; \ + } \ + prev = this; \ + this = this->next_init_function; \ + while (this) \ + { \ + if (this->f == &x) \ + { \ + prev->next_init_function = \ + this->next_init_function; \ + return; \ + } \ + prev = this; \ + this = this->next_init_function; \ + } \ +} \ +static _vlib_init_function_list_elt_t _vlib_init_function_##tag_##x #else /* create unused pointer to silence compiler warnings and get whole function optimized out */ #define VLIB_DECLARE_INIT_FUNCTION(x, tag) \ -static __clib_unused void * __clib_unused_##tag##_##x = x; +static __clib_unused void * __clib_unused_##tag##_##x = x #endif #define VLIB_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,init) @@ -316,8 +326,8 @@ clib_error_t *vlib_call_all_main_loop_enter_functions (struct vlib_main_t *vm); clib_error_t *vlib_call_all_main_loop_exit_functions (struct vlib_main_t *vm); clib_error_t *vlib_call_init_exit_functions (struct vlib_main_t *vm, - _vlib_init_function_list_elt_t * - head, int call_once); + _vlib_init_function_list_elt_t ** + headp, int call_once); #define foreach_vlib_module_reference \ _ (node_cli) \ @@ -327,6 +337,7 @@ clib_error_t *vlib_call_init_exit_functions (struct vlib_main_t *vm, #define _(x) void vlib_##x##_reference (void); foreach_vlib_module_reference #undef _ +#define VLIB_INITS(...) (char*[]) { __VA_ARGS__, 0} #endif /* included_vlib_init_h */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vlib/linux/pci.c b/src/vlib/linux/pci.c index 8b614c751a1..20d44cd6d6e 100644 --- a/src/vlib/linux/pci.c +++ b/src/vlib/linux/pci.c @@ -1449,13 +1449,9 @@ linux_pci_init (vlib_main_t * vm) { vlib_pci_main_t *pm = &pci_main; vlib_pci_addr_t *addr = 0, *addrs; - clib_error_t *error; pm->vlib_main = vm; - if ((error = vlib_call_init_function (vm, unix_input_init))) - return error; - ASSERT (sizeof (vlib_pci_addr_t) == sizeof (u32)); addrs = vlib_pci_get_all_dev_addrs (); @@ -1471,10 +1467,15 @@ linux_pci_init (vlib_main_t * vm) } /* *INDENT-ON* */ - return error; + return 0; } -VLIB_INIT_FUNCTION (linux_pci_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (linux_pci_init) = +{ + .runs_after = VLIB_INITS("unix_input_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vlib/linux/vmbus.c b/src/vlib/linux/vmbus.c index d0efbd748ef..2fc438b4778 100644 --- a/src/vlib/linux/vmbus.c +++ b/src/vlib/linux/vmbus.c @@ -407,10 +407,15 @@ linux_vmbus_init (vlib_main_t * vm) pm->vlib_main = vm; - return vlib_call_init_function (vm, unix_input_init); + return 0; } -VLIB_INIT_FUNCTION (linux_vmbus_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (linux_vmbus_init) = +{ + .runs_before = VLIB_INITS("unix_input_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vlib/threads.c b/src/vlib/threads.c index cb1eb5fdba4..6a23bfd8a2f 100644 --- a/src/vlib/threads.c +++ b/src/vlib/threads.c @@ -1736,7 +1736,7 @@ vlib_worker_thread_fn (void *arg) vlib_worker_thread_barrier_check (); e = vlib_call_init_exit_functions - (vm, vm->worker_init_function_registrations, 1 /* call_once */ ); + (vm, &vm->worker_init_function_registrations, 1 /* call_once */ ); if (e) clib_error_report (e); diff --git a/src/vlib/unix/input.c b/src/vlib/unix/input.c index 1c1cb1aa79c..43bb206eb29 100644 --- a/src/vlib/unix/input.c +++ b/src/vlib/unix/input.c @@ -411,10 +411,15 @@ VLIB_INIT_FUNCTION (linux_epoll_input_init); static clib_error_t * unix_input_init (vlib_main_t * vm) { - return vlib_call_init_function (vm, linux_epoll_input_init); + return 0; } -VLIB_INIT_FUNCTION (unix_input_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (unix_input_init) = +{ + .runs_before = VLIB_INITS ("linux_epoll_input_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vlib/unix/main.c b/src/vlib/unix/main.c index 8c9bc1b2ce2..3ec4c342cf1 100755 --- a/src/vlib/unix/main.c +++ b/src/vlib/unix/main.c @@ -67,10 +67,15 @@ unix_main_init (vlib_main_t * vm) { unix_main_t *um = &unix_main; um->vlib_main = vm; - return vlib_call_init_function (vm, unix_input_init); + return 0; } -VLIB_INIT_FUNCTION (unix_main_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (unix_main_init) = +{ + .runs_before = VLIB_INITS ("unix_input_init"), +}; +/* *INDENT-ON* */ static int unsetup_signal_handlers (int sig) diff --git a/src/vlib/vmbus/vmbus.c b/src/vlib/vmbus/vmbus.c index ea395ece6a8..eadf5f176d6 100644 --- a/src/vlib/vmbus/vmbus.c +++ b/src/vlib/vmbus/vmbus.c @@ -30,11 +30,10 @@ vlib_vmbus_addr_t * __attribute__ ((weak)) vlib_vmbus_get_all_dev_addrs () return NULL; } - clib_error_t * vmbus_bus_init (vlib_main_t * vm) { - return vlib_call_init_function (vm, vmbus_bus_init); + return 0; } VLIB_INIT_FUNCTION (vmbus_bus_init); diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c index 9fc26b986f5..10425dd971c 100644 --- a/src/vlibmemory/memory_api.c +++ b/src/vlibmemory/memory_api.c @@ -954,8 +954,10 @@ vlibmemory_init (vlib_main_t * vm) { api_main_t *am = &api_main; svm_map_region_args_t _a, *a = &_a; - clib_error_t *error; u8 *remove_path1, *remove_path2; + void vlibsocket_reference (void); + + vlibsocket_reference (); /* * By popular request / to avoid support fires, remove any old api segment @@ -993,9 +995,7 @@ vlibmemory_init (vlib_main_t * vm) svm_region_init_args (a); - error = vlib_call_init_function (vm, vlibsocket_init); - - return error; + return 0; } void diff --git a/src/vlibmemory/socket_api.c b/src/vlibmemory/socket_api.c index f0c7f1feeb1..31c1ff9880e 100644 --- a/src/vlibmemory/socket_api.c +++ b/src/vlibmemory/socket_api.c @@ -805,14 +805,11 @@ socksvr_config (vlib_main_t * vm, unformat_input_t * input) VLIB_CONFIG_FUNCTION (socksvr_config, "socksvr"); -clib_error_t * -vlibsocket_init (vlib_main_t * vm) +void +vlibsocket_reference () { - return 0; } -VLIB_INIT_FUNCTION (vlibsocket_init); - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vlibmemory/vlib_api.c b/src/vlibmemory/vlib_api.c index 7763a88becf..73dd5bda33c 100644 --- a/src/vlibmemory/vlib_api.c +++ b/src/vlibmemory/vlib_api.c @@ -306,7 +306,7 @@ vl_api_clnt_process (vlib_main_t * vm, vlib_node_runtime_t * node, q = shm->vl_input_queue; e = vlib_call_init_exit_functions - (vm, vm->api_init_function_registrations, 1 /* call_once */ ); + (vm, &vm->api_init_function_registrations, 1 /* call_once */ ); if (e) clib_error_report (e); diff --git a/src/vnet/adj/adj_bfd.c b/src/vnet/adj/adj_bfd.c index b7ff64dcccf..2d787d41ab6 100644 --- a/src/vnet/adj/adj_bfd.c +++ b/src/vnet/adj/adj_bfd.c @@ -280,16 +280,16 @@ const static adj_delegate_vft_t adj_delegate_vft = { static clib_error_t * adj_bfd_main_init (vlib_main_t * vm) { - clib_error_t * error = NULL; - - if ((error = vlib_call_init_function (vm, bfd_main_init))) - return (error); - bfd_register_listener(adj_bfd_notify); adj_delegate_register_type (ADJ_DELEGATE_BFD, &adj_delegate_vft); - return (error); + return (0); } -VLIB_INIT_FUNCTION (adj_bfd_main_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (adj_bfd_main_init)= +{ + .runs_after = VLIB_INITS("bfd_main_init"), +}; +/* *INDENT-ON* */ diff --git a/src/vnet/classify/in_out_acl.c b/src/vnet/classify/in_out_acl.c index 553c353b7ae..7f5a926212c 100644 --- a/src/vnet/classify/in_out_acl.c +++ b/src/vnet/classify/in_out_acl.c @@ -251,10 +251,6 @@ clib_error_t * in_out_acl_init (vlib_main_t * vm) { in_out_acl_main_t *am = &in_out_acl_main; - clib_error_t *error = 0; - - if ((error = vlib_call_init_function (vm, ip_in_out_acl_init))) - return error; am->vlib_main = vm; am->vnet_main = vnet_get_main (); @@ -262,8 +258,12 @@ in_out_acl_init (vlib_main_t * vm) return 0; } - -VLIB_INIT_FUNCTION (in_out_acl_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (in_out_acl_init) = +{ + .runs_after = VLIB_INITS("ip_in_out_acl_init"), +}; +/* *INDENT-ON* */ uword unformat_acl_type (unformat_input_t * input, va_list * args) diff --git a/src/vnet/cop/cop.c b/src/vnet/cop/cop.c index 700bd7348ed..edd09856092 100644 --- a/src/vnet/cop/cop.c +++ b/src/vnet/cop/cop.c @@ -29,7 +29,7 @@ cop_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) clib_memset (data, 0, sizeof(*data)); - /* + /* * Ignore local interface, pg interfaces. $$$ need a #define for the * first "real" interface. The answer is 5 at the moment. */ @@ -41,7 +41,7 @@ cop_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) { ccm = &cm->cop_config_mains[address_family]; - /* + /* * Once-only code to initialize the per-address-family * cop feature subgraphs. * Since the (single) start-node, cop-input, must be able @@ -60,8 +60,8 @@ cop_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) [IP4_RX_COP_WHITELIST] = "ip4-cop-whitelist", [IP4_RX_COP_INPUT] = "ip4-input", }; - - vnet_config_init (vm, &ccm->config_main, + + vnet_config_init (vm, &ccm->config_main, start_nodes, ARRAY_LEN(start_nodes), feature_nodes, ARRAY_LEN(feature_nodes)); } @@ -73,7 +73,7 @@ cop_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) [IP6_RX_COP_WHITELIST] = "ip6-cop-whitelist", [IP6_RX_COP_INPUT] = "ip6-input", }; - vnet_config_init (vm, &ccm->config_main, + vnet_config_init (vm, &ccm->config_main, start_nodes, ARRAY_LEN(start_nodes), feature_nodes, ARRAY_LEN(feature_nodes)); } @@ -86,7 +86,7 @@ cop_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) [DEFAULT_RX_COP_WHITELIST] = "default-cop-whitelist", [DEFAULT_RX_COP_INPUT] = "ethernet-input", }; - vnet_config_init (vm, &ccm->config_main, + vnet_config_init (vm, &ccm->config_main, start_nodes, ARRAY_LEN(start_nodes), feature_nodes, ARRAY_LEN(feature_nodes)); } @@ -109,15 +109,15 @@ cop_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) default_next = IP6_RX_COP_INPUT; else default_next = DEFAULT_RX_COP_INPUT; - + if (is_add) ci = vnet_config_add_feature (vm, &ccm->config_main, - ci, + ci, default_next, data, sizeof(*data)); else ci = vnet_config_del_feature (vm, &ccm->config_main, - ci, + ci, default_next, data, sizeof(*data)); @@ -132,13 +132,6 @@ static clib_error_t * cop_init (vlib_main_t *vm) { cop_main_t * cm = &cop_main; - clib_error_t * error; - - if ((error = vlib_call_init_function (vm, ip4_whitelist_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip6_whitelist_init))) - return error; cm->vlib_main = vm; cm->vnet_main = vnet_get_main(); @@ -146,7 +139,12 @@ cop_init (vlib_main_t *vm) return 0; } -VLIB_INIT_FUNCTION (cop_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (cop_init) = +{ + .runs_after = VLIB_INITS ("ip4_whitelist_init", "ip6_whitelist_init"), +}; +/* *INDENT-ON* */ int cop_interface_enable_disable (u32 sw_if_index, int enable_disable) { @@ -159,11 +157,11 @@ int cop_interface_enable_disable (u32 sw_if_index, int enable_disable) sw = vnet_get_sw_interface (cm->vnet_main, sw_if_index); if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE) return VNET_API_ERROR_INVALID_SW_IF_INDEX; - - /* + + /* * Redirect pkts from the driver to the cop node. * Returns VNET_API_ERROR_UNIMPLEMENTED if the h/w driver - * doesn't implement the API. + * doesn't implement the API. * * Node_index = ~0 => shut off redirection */ @@ -180,7 +178,7 @@ cop_enable_disable_command_fn (vlib_main_t * vm, cop_main_t * cm = &cop_main; u32 sw_if_index = ~0; int enable_disable = 1; - + int rv; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -195,7 +193,7 @@ cop_enable_disable_command_fn (vlib_main_t * vm, if (sw_if_index == ~0) return clib_error_return (0, "Please specify an interface..."); - + rv = cop_interface_enable_disable (sw_if_index, enable_disable); switch(rv) { @@ -203,7 +201,7 @@ cop_enable_disable_command_fn (vlib_main_t * vm, break; case VNET_API_ERROR_INVALID_SW_IF_INDEX: - return clib_error_return + return clib_error_return (0, "Invalid interface, only works on physical ports"); break; @@ -220,7 +218,7 @@ cop_enable_disable_command_fn (vlib_main_t * vm, VLIB_CLI_COMMAND (cop_interface_command, static) = { .path = "cop interface", - .short_help = + .short_help = "cop interface <interface-name> [disable]", .function = cop_enable_disable_command_fn, }; @@ -246,10 +244,10 @@ int cop_whitelist_enable_disable (cop_whitelist_enable_disable_args_t *a) */ for (address_family = VNET_COP_IP4; address_family < VNET_N_COPS; - address_family++) + address_family++) { ccm = &cm->cop_config_mains[address_family]; - + switch(address_family) { case VNET_COP_IP4: @@ -267,7 +265,7 @@ int cop_whitelist_enable_disable (cop_whitelist_enable_disable_args_t *a) continue; } break; - + case VNET_COP_IP6: is_add = (a->ip6 != 0); next_to_add_del = IP6_RX_COP_WHITELIST; @@ -287,7 +285,7 @@ int cop_whitelist_enable_disable (cop_whitelist_enable_disable_args_t *a) is_add = (a->default_cop != 0); next_to_add_del = DEFAULT_RX_COP_WHITELIST; break; - + default: clib_warning ("BUG"); } @@ -343,7 +341,7 @@ cop_whitelist_enable_disable_command_fn (vlib_main_t * vm, if (sw_if_index == ~0) return clib_error_return (0, "Please specify an interface..."); - + a->sw_if_index = sw_if_index; a->ip4 = ip4; a->ip6 = ip6; @@ -357,12 +355,12 @@ cop_whitelist_enable_disable_command_fn (vlib_main_t * vm, break; case VNET_API_ERROR_INVALID_SW_IF_INDEX: - return clib_error_return + return clib_error_return (0, "Invalid interface, only works on physical ports"); break; case VNET_API_ERROR_NO_SUCH_FIB: - return clib_error_return + return clib_error_return (0, "Invalid fib"); break; @@ -380,8 +378,7 @@ cop_whitelist_enable_disable_command_fn (vlib_main_t * vm, VLIB_CLI_COMMAND (cop_whitelist_command, static) = { .path = "cop whitelist", - .short_help = + .short_help = "cop whitelist <interface-name> [ip4][ip6][default][fib-id <NN>][disable]", .function = cop_whitelist_enable_disable_command_fn, }; - diff --git a/src/vnet/devices/virtio/vhost_user.c b/src/vnet/devices/virtio/vhost_user.c index 1d52b42b73b..72b71f98763 100644 --- a/src/vnet/devices/virtio/vhost_user.c +++ b/src/vnet/devices/virtio/vhost_user.c @@ -953,14 +953,9 @@ vhost_user_socksvr_accept_ready (clib_file_t * uf) static clib_error_t * vhost_user_init (vlib_main_t * vm) { - clib_error_t *error; vhost_user_main_t *vum = &vhost_user_main; vlib_thread_main_t *tm = vlib_get_thread_main (); - error = vlib_call_init_function (vm, ip4_init); - if (error) - return error; - vum->log_default = vlib_log_register_class ("vhost-user", 0); vum->coalesce_frames = 32; @@ -983,7 +978,12 @@ vhost_user_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (vhost_user_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (vhost_user_init) = +{ + .runs_after = VLIB_INITS("ip4_init"), +}; +/* *INDENT-ON* */ static uword vhost_user_send_interrupt_process (vlib_main_t * vm, diff --git a/src/vnet/dpo/dpo.c b/src/vnet/dpo/dpo.c index df78456bf60..13ae37a74a8 100644 --- a/src/vnet/dpo/dpo.c +++ b/src/vnet/dpo/dpo.c @@ -16,7 +16,7 @@ * @brief * A Data-Path Object is an object that represents actions that are * applied to packets are they are switched through VPP. - * + * * The DPO is a base class that is specialised by other objects to provide * concrete actions * @@ -267,10 +267,10 @@ dpo_copy (dpo_id_t *dst, * the destination is written in a single u64 write - hence atomically w.r.t * any packets inflight. */ - *((u64*)dst) = *(u64*)src; + *((u64*)dst) = *(u64*)src; dpo_lock(dst); - dpo_unlock(&tmp); + dpo_unlock(&tmp); } int @@ -592,7 +592,12 @@ dpo_module_init (vlib_main_t * vm) return (NULL); } -VLIB_INIT_FUNCTION(dpo_module_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION(dpo_module_init) = +{ + .runs_before = VLIB_INITS ("ip_main_init"), +}; +/* *INDENT-ON* */ static clib_error_t * dpo_memory_show (vlib_main_t * vm, diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c index 12c3fa47eac..f294893d846 100644 --- a/src/vnet/ethernet/arp.c +++ b/src/vnet/ethernet/arp.c @@ -1761,12 +1761,8 @@ ethernet_arp_init (vlib_main_t * vm) { ethernet_arp_main_t *am = ðernet_arp_main; ip4_main_t *im = &ip4_main; - clib_error_t *error; pg_node_t *pn; - if ((error = vlib_call_init_function (vm, ethernet_init))) - return error; - ethernet_register_input_type (vm, ETHERNET_TYPE_ARP, arp_input_node.index); pn = pg_get_node (arp_input_node.index); @@ -1809,8 +1805,12 @@ ethernet_arp_init (vlib_main_t * vm) return 0; } - -VLIB_INIT_FUNCTION (ethernet_arp_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ethernet_arp_init) = +{ + .runs_after = VLIB_INITS("ethernet_init"), +}; +/* *INDENT-ON* */ static void arp_entry_free (ethernet_arp_interface_t * eai, ethernet_arp_ip4_entry_t * e) diff --git a/src/vnet/ethernet/ethernet.h b/src/vnet/ethernet/ethernet.h index 94322a715f9..344705b0cc3 100644 --- a/src/vnet/ethernet/ethernet.h +++ b/src/vnet/ethernet/ethernet.h @@ -544,6 +544,7 @@ u8 *ethernet_build_rewrite (vnet_main_t * vnm, vnet_link_t link_type, const void *dst_address); const u8 *ethernet_ip4_mcast_dst_addr (void); const u8 *ethernet_ip6_mcast_dst_addr (void); +void ethernet_input_init (vlib_main_t * vm, ethernet_main_t * em); extern vlib_node_registration_t ethernet_input_node; diff --git a/src/vnet/ethernet/init.c b/src/vnet/ethernet/init.c index 5d10c60fd5f..9fd95f1b75a 100644 --- a/src/vnet/ethernet/init.c +++ b/src/vnet/ethernet/init.c @@ -83,14 +83,6 @@ static clib_error_t * ethernet_init (vlib_main_t * vm) { ethernet_main_t *em = ðernet_main; - clib_error_t *error; - - /* - * Set up the L2 path now, or we'll wipe out the L2 ARP - * registration set up by ethernet_arp_init. - */ - if ((error = vlib_call_init_function (vm, l2_init))) - return error; em->vlib_main = vm; @@ -101,17 +93,28 @@ ethernet_init (vlib_main_t * vm) #include "types.def" #undef ethernet_type - if ((error = vlib_call_init_function (vm, llc_init))) - return error; - if ((error = vlib_call_init_function (vm, ethernet_input_init))) - return error; - if ((error = vlib_call_init_function (vm, vnet_feature_init))) - return error; - + /* + * ethernet_input_init is effectively part of this function. + * Simply ensuring that it happens after we set up the hash tables + * is not sufficient. + */ + ethernet_input_init (vm, em); return 0; } -VLIB_INIT_FUNCTION (ethernet_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ethernet_init) = +{ + /* + * Set up the L2 path before ethernet_init, or we'll wipe out the L2 ARP + * registration set up by ethernet_arp_init. + */ + .init_order = VLIB_INITS("l2_init", + "ethernet_init", + "llc_init", + "vnet_feature_init"), +}; +/* *INDENT-ON* */ ethernet_main_t * ethernet_get_main (vlib_main_t * vm) diff --git a/src/vnet/ethernet/node.c b/src/vnet/ethernet/node.c index 87c447f44d3..286ec3c0e78 100755 --- a/src/vnet/ethernet/node.c +++ b/src/vnet/ethernet/node.c @@ -2025,11 +2025,9 @@ next_by_ethertype_register (next_by_ethertype_t * l3_next, return 0; } - -static clib_error_t * -ethernet_input_init (vlib_main_t * vm) +void +ethernet_input_init (vlib_main_t * vm, ethernet_main_t * em) { - ethernet_main_t *em = ðernet_main; __attribute__ ((unused)) vlan_table_t *invalid_vlan_table; __attribute__ ((unused)) qinq_table_t *invalid_qinq_table; @@ -2048,12 +2046,8 @@ ethernet_input_init (vlib_main_t * vm) pool_get (em->vlan_pool, invalid_vlan_table); // first id = 0 // The first qinq pool will always be reserved for an invalid table pool_get (em->qinq_pool, invalid_qinq_table); // first id = 0 - - return 0; } -VLIB_INIT_FUNCTION (ethernet_input_init); - void ethernet_register_input_type (vlib_main_t * vm, ethernet_type_t type, u32 node_index) diff --git a/src/vnet/fib/fib.c b/src/vnet/fib/fib.c index 413f93e893c..28e18dded23 100644 --- a/src/vnet/fib/fib.c +++ b/src/vnet/fib/fib.c @@ -22,13 +22,6 @@ static clib_error_t * fib_module_init (vlib_main_t * vm) { - clib_error_t * error; - - if ((error = vlib_call_init_function (vm, dpo_module_init))) - return (error); - if ((error = vlib_call_init_function (vm, adj_module_init))) - return (error); - fib_entry_module_init(); fib_entry_src_module_init(); fib_path_module_init(); @@ -38,4 +31,9 @@ fib_module_init (vlib_main_t * vm) return (NULL); } -VLIB_INIT_FUNCTION (fib_module_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (fib_module_init) = +{ + .runs_after = VLIB_INITS("dpo_module_init", "adj_module_init"), +}; +/* *INDENT-ON* */ diff --git a/src/vnet/fib/fib_bfd.c b/src/vnet/fib/fib_bfd.c index ae7ceec1a6b..f785ba2e68f 100644 --- a/src/vnet/fib/fib_bfd.c +++ b/src/vnet/fib/fib_bfd.c @@ -183,14 +183,14 @@ fib_bfd_notify (bfd_listen_event_e event, static clib_error_t * fib_bfd_main_init (vlib_main_t * vm) { - clib_error_t * error = NULL; - - if ((error = vlib_call_init_function (vm, bfd_main_init))) - return (error); - bfd_register_listener(fib_bfd_notify); - return (error); + return (NULL); } -VLIB_INIT_FUNCTION (fib_bfd_main_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (fib_bfd_main_init) = +{ + .runs_after = VLIB_INITS("bfd_main_init"), +}; +/* *INDENT-ON* */ diff --git a/src/vnet/ip/ip_init.c b/src/vnet/ip/ip_init.c index 638cbd167db..b3ab90d6dc3 100644 --- a/src/vnet/ip/ip_init.c +++ b/src/vnet/ip/ip_init.c @@ -101,50 +101,28 @@ do { \ } } - if ((error = vlib_call_init_function (vm, vnet_main_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip4_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip6_init))) - return error; - - if ((error = vlib_call_init_function (vm, icmp4_init))) - return error; - - if ((error = vlib_call_init_function (vm, icmp6_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_init))) - return error; - - if ((error = vlib_call_init_function (vm, udp_local_init))) - return error; - - if ((error = vlib_call_init_function (vm, udp_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip_classify_init))) - return error; - - if ((error = vlib_call_init_function (vm, in_out_acl_init))) - return error; - - if ((error = vlib_call_init_function (vm, policer_classify_init))) - return error; - - if ((error = vlib_call_init_function (vm, flow_classify_init))) - return error; - - if ((error = vlib_call_init_function (vm, dns_init))) - return error; - return error; } -VLIB_INIT_FUNCTION (ip_main_init); - +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (ip_main_init) = +{ + .init_order = + VLIB_INITS ("vnet_main_init", + "ip4_init", + "ip6_init", + "icmp4_init", + "icmp6_init", + "ip6_hop_by_hop_init", + "udp_local_init", + "udp_init", + "ip_classify_init", + "in_out_acl_init", + "policer_classify_init", + "flow_classify_init", + "dns_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vnet/ipfix-export/flow_report.c b/src/vnet/ipfix-export/flow_report.c index 103392ad81e..d904479c9c9 100644 --- a/src/vnet/ipfix-export/flow_report.c +++ b/src/vnet/ipfix-export/flow_report.c @@ -607,7 +607,7 @@ flow_report_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (flow_report_init) +VLIB_INIT_FUNCTION (flow_report_init); /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/lisp-gpe/lisp_gpe_adjacency.c b/src/vnet/lisp-gpe/lisp_gpe_adjacency.c index 7361e8eb0d6..1b53e4dd9fe 100644 --- a/src/vnet/lisp-gpe/lisp_gpe_adjacency.c +++ b/src/vnet/lisp-gpe/lisp_gpe_adjacency.c @@ -592,7 +592,7 @@ lisp_gpe_adj_module_init (vlib_main_t * vm) return (NULL); } -VLIB_INIT_FUNCTION (lisp_gpe_adj_module_init) +VLIB_INIT_FUNCTION (lisp_gpe_adj_module_init); /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/misc.c b/src/vnet/misc.c index ff85e3dedfe..ab0f823cb65 100644 --- a/src/vnet/misc.c +++ b/src/vnet/misc.c @@ -74,31 +74,9 @@ clib_error_t * vnet_main_init (vlib_main_t * vm) { vnet_main_t *vnm = vnet_get_main (); - clib_error_t *error; u32 hw_if_index; vnet_hw_interface_t *hw; - if ((error = vlib_call_init_function (vm, vnet_interface_init))) - return error; - - if ((error = vlib_call_init_function (vm, fib_module_init))) - return error; - - if ((error = vlib_call_init_function (vm, mfib_module_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip_main_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip4_lookup_init))) - return error; - - if ((error = vlib_call_init_function (vm, ip6_lookup_init))) - return error; - - if ((error = vlib_call_init_function (vm, mpls_init))) - return error; - vnm->vlib_main = vm; hw_if_index = vnet_register_interface @@ -117,7 +95,20 @@ vnet_main_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (vnet_main_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (vnet_main_init)= +{ + .init_order = VLIB_INITS("vnet_interface_init", + "ethernet_init", + "fib_module_init", + "mfib_module_init", + "ip_main_init", + "ip4_lookup_init", + "ip6_lookup_init", + "mpls_init", + "vnet_main_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vnet/mpls/mpls_input.c b/src/vnet/mpls/mpls_input.c index 1dd5e326a3c..37fa1aead12 100644 --- a/src/vnet/mpls/mpls_input.c +++ b/src/vnet/mpls/mpls_input.c @@ -50,8 +50,8 @@ format_mpls_input_trace (u8 * s, va_list * args) #define _(a,b) if (t->next_index == MPLS_INPUT_NEXT_##a) next_name = b; foreach_mpls_input_next; #undef _ - - s = format (s, "MPLS: next %s[%d] label %d ttl %d exp %d", + + s = format (s, "MPLS: next %s[%d] label %d ttl %d exp %d", next_name, t->next_index, vnet_mpls_uc_get_label(label), vnet_mpls_uc_get_ttl(label), @@ -209,9 +209,9 @@ mpls_input_inline (vlib_main_t * vm, vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1); } - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) + if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { - mpls_input_trace_t *tr = vlib_add_trace (vm, node, + mpls_input_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->next_index = next0; tr->label_net_byte_order = *(u32*)h0; @@ -278,16 +278,15 @@ mpls_setup_nodes (vlib_main_t * vm) static clib_error_t * mpls_input_init (vlib_main_t * vm) { - clib_error_t * error; - - error = vlib_call_init_function (vm, mpls_init); - if (error) - clib_error_report (error); - mpls_setup_nodes (vm); return 0; } -VLIB_INIT_FUNCTION (mpls_input_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (mpls_input_init) = +{ + .runs_after = VLIB_INITS("mpls_init"), +}; +/* *INDENT-ON* */ #endif /* CLIB_MARCH_VARIANT */ diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c index d5166d9142e..81bdb8bd0e4 100644 --- a/src/vnet/udp/udp.c +++ b/src/vnet/udp/udp.c @@ -395,17 +395,9 @@ udp_init (vlib_main_t * vm) ip_main_t *im = &ip_main; vlib_thread_main_t *tm = vlib_get_thread_main (); u32 num_threads; - clib_error_t *error = 0; ip_protocol_info_t *pi; int i; - if ((error = vlib_call_init_function (vm, ip_main_init))) - return error; - if ((error = vlib_call_init_function (vm, ip4_lookup_init))) - return error; - if ((error = vlib_call_init_function (vm, ip6_lookup_init))) - return error; - /* * Registrations */ @@ -443,10 +435,17 @@ udp_init (vlib_main_t * vm) clib_spinlock_init (&um->peekers_readers_locks[i]); clib_spinlock_init (&um->peekers_write_locks[i]); } - return error; + return 0; } -VLIB_INIT_FUNCTION (udp_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (udp_init) = +{ + .runs_after = VLIB_INITS("ip_main_init", "ip4_lookup_init", + "ip6_lookup_init"), +}; +/* *INDENT-ON* */ + static clib_error_t * show_udp_punt_fn (vlib_main_t * vm, unformat_input_t * input, diff --git a/src/vnet/unix/tuntap.c b/src/vnet/unix/tuntap.c index 103b6496a34..9d6f8992414 100644 --- a/src/vnet/unix/tuntap.c +++ b/src/vnet/unix/tuntap.c @@ -1011,7 +1011,6 @@ VNET_DEVICE_CLASS (tuntap_dev_class,static) = { static clib_error_t * tuntap_init (vlib_main_t * vm) { - clib_error_t *error; ip4_main_t *im4 = &ip4_main; ip6_main_t *im6 = &ip6_main; ip4_add_del_interface_address_callback_t cb4; @@ -1019,10 +1018,6 @@ tuntap_init (vlib_main_t * vm) tuntap_main_t *tm = &tuntap_main; vlib_thread_main_t *m = vlib_get_thread_main (); - error = vlib_call_init_function (vm, ip4_init); - if (error) - return error; - mhash_init (&tm->subif_mhash, sizeof (u32), sizeof (subif_address_t)); cb4.function = tuntap_ip4_add_del_interface_address; @@ -1038,7 +1033,12 @@ tuntap_init (vlib_main_t * vm) return 0; } -VLIB_INIT_FUNCTION (tuntap_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (tuntap_init) = +{ + .runs_after = VLIB_INITS("ip4_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vnet/vxlan-gbp/vxlan_gbp.c b/src/vnet/vxlan-gbp/vxlan_gbp.c index e39c26fc5d1..001de73b840 100644 --- a/src/vnet/vxlan-gbp/vxlan_gbp.c +++ b/src/vnet/vxlan-gbp/vxlan_gbp.c @@ -1144,14 +1144,10 @@ clib_error_t * vxlan_gbp_init (vlib_main_t * vm) { vxlan_gbp_main_t *vxm = &vxlan_gbp_main; - clib_error_t *error; vxm->vnet_main = vnet_get_main (); vxm->vlib_main = vm; - if ((error = vlib_call_init_function (vm, punt_init))) - return (error); - /* initialize the ip6 hash */ clib_bihash_init_16_8 (&vxm->vxlan4_gbp_tunnel_by_key, "vxlan4-gbp", VXLAN_GBP_HASH_NUM_BUCKETS, @@ -1175,10 +1171,15 @@ vxlan_gbp_init (vlib_main_t * vm) "VXLAN-GBP-no-such-v6-tunnel", &vxm->punt_no_such_tunnel[FIB_PROTOCOL_IP6]); - return (error); + return (0); } -VLIB_INIT_FUNCTION (vxlan_gbp_init); +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (vxlan_gbp_init) = +{ + .runs_after = VLIB_INITS("punt_init"), +}; +/* *INDENT-ON* */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/vpp/stats/stat_segment.c b/src/vpp/stats/stat_segment.c index 300cfe785e1..bb2ffad8f6d 100644 --- a/src/vpp/stats/stat_segment.c +++ b/src/vpp/stats/stat_segment.c @@ -680,11 +680,6 @@ static clib_error_t * statseg_init (vlib_main_t * vm) { stat_segment_main_t *sm = &stat_segment_main; - clib_error_t *error; - - /* dependent on unix_input_init */ - if ((error = vlib_call_init_function (vm, unix_input_init))) - return error; if (sm->socket_name) stats_segment_socket_init (); @@ -692,6 +687,14 @@ statseg_init (vlib_main_t * vm) return 0; } +/* *INDENT-OFF* */ +VLIB_INIT_FUNCTION (statseg_init) = +{ + .runs_after = VLIB_INITS("unix_input_init"), +}; +/* *INDENT-ON* */ + + clib_error_t * stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn, u32 caller_index) @@ -832,7 +835,6 @@ statseg_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add) return 0; } -VLIB_INIT_FUNCTION (statseg_init); VLIB_EARLY_CONFIG_FUNCTION (statseg_config, "statseg"); VNET_SW_INTERFACE_ADD_DEL_FUNCTION (statseg_sw_interface_add_del); |