From 4168c4d914c36f76c45cd8c6dde207b9f1c688e2 Mon Sep 17 00:00:00 2001 From: Steven Luong Date: Wed, 5 Jun 2019 10:52:35 -0700 Subject: lacp: create lacp-process on demand Create lacp-process when the very first slave interface is added to the bond. Log an event message when lacp-process starts/stops. Be mindful when lacp-process is signalled to stop. Type: refactor Change-Id: I79e10e0a2a385a21a52ae5b8735f24631fdba293 Signed-off-by: Steven Luong --- src/plugins/lacp/cli.c | 2 ++ src/plugins/lacp/lacp.c | 19 +++++++++-- src/plugins/lacp/node.c | 86 ++++++++++++++++++++++++++++++++++++------------- src/plugins/lacp/node.h | 5 ++- 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/plugins/lacp/cli.c b/src/plugins/lacp/cli.c index d188db6165e..b8ff199c2f4 100644 --- a/src/plugins/lacp/cli.c +++ b/src/plugins/lacp/cli.c @@ -143,11 +143,13 @@ show_lacp (vlib_main_t * vm, u32 * sw_if_indices) static void show_lacp_details (vlib_main_t * vm, u32 * sw_if_indices) { + lacp_main_t *lm = &lacp_main; slave_if_t *sif; lacp_state_struct *state_entry; int i; f64 now; + vlib_cli_output (vm, "Number of interfaces: %d", lm->lacp_int); if (!sw_if_indices) return; diff --git a/src/plugins/lacp/lacp.c b/src/plugins/lacp/lacp.c index 1a588376d9a..4bb50aea32a 100644 --- a/src/plugins/lacp/lacp.c +++ b/src/plugins/lacp/lacp.c @@ -180,6 +180,7 @@ lacp_interface_enable_disable (vlib_main_t * vm, bond_if_t * bif, if (enable) { + lacp_create_periodic_process (); port_number = clib_bitmap_first_clear (bif->port_number_bitmap); bif->port_number_bitmap = clib_bitmap_set (bif->port_number_bitmap, port_number, 1); @@ -195,11 +196,23 @@ lacp_interface_enable_disable (vlib_main_t * vm, bond_if_t * bif, } else { - lm->lacp_int--; + ASSERT (lm->lacp_int >= 1); if (lm->lacp_int == 0) { - vlib_process_signal_event (vm, lm->lacp_process_node_index, - LACP_PROCESS_EVENT_STOP, 0); + /* *INDENT-OFF* */ + ELOG_TYPE_DECLARE (e) = + { + .format = "lacp-int-en-dis: BUG lacp_int == 0", + }; + /* *INDENT-ON* */ + ELOG_DATA (&vlib_global_main.elog_main, e); + } + else + { + lm->lacp_int--; + if (lm->lacp_int == 0) + vlib_process_signal_event (vm, lm->lacp_process_node_index, + LACP_PROCESS_EVENT_STOP, 0); } } } diff --git a/src/plugins/lacp/node.c b/src/plugins/lacp/node.c index d86972666dc..1a5cb4500fb 100644 --- a/src/plugins/lacp/node.c +++ b/src/plugins/lacp/node.c @@ -25,8 +25,6 @@ lacp_state_struct lacp_state_array[] = { {.str = NULL} }; -static vlib_node_registration_t lacp_process_node; - /** \file 2 x LACP graph nodes: an "interior" node to process @@ -136,6 +134,46 @@ VLIB_REGISTER_NODE (lacp_input_node, static) = { }; /* *INDENT-ON* */ +static void +lacp_elog_start_event (void) +{ + lacp_main_t *lm = &lacp_main; + /* *INDENT-OFF* */ + ELOG_TYPE_DECLARE (e) = + { + .format = "Starting LACP process, interface count = %d", + .format_args = "i4", + }; + /* *INDENT-ON* */ + struct + { + u32 count; + } *ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, e); + ed->count = lm->lacp_int; +} + +static void +lacp_elog_stop_event (void) +{ + lacp_main_t *lm = &lacp_main; + /* *INDENT-OFF* */ + ELOG_TYPE_DECLARE (e) = + { + .format = "Stopping LACP process, interface count = %d", + .format_args = "i4", + }; + /* *INDENT-ON* */ + struct + { + u32 count; + } *ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, e); + ed->count = lm->lacp_int; +} + /* * lacp periodic function */ @@ -145,10 +183,6 @@ lacp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) lacp_main_t *lm = &lacp_main; f64 poll_time_remaining; uword event_type, *event_data = 0; - u8 enabled = 0; - - /* So we can send events to the lacp process */ - lm->lacp_process_node_index = lacp_process_node.index; ethernet_register_input_type (vm, ETHERNET_TYPE_SLOW_PROTOCOLS /* LACP */ , lacp_input_node.index); @@ -156,7 +190,7 @@ lacp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) poll_time_remaining = 0.2; while (1) { - if (enabled) + if (lm->lacp_int > 0) poll_time_remaining = vlib_process_wait_for_event_or_clock (vm, poll_time_remaining); else @@ -168,17 +202,21 @@ lacp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) case ~0: /* no events => timeout */ break; case LACP_PROCESS_EVENT_START: - enabled = 1; + poll_time_remaining = 0.2; + lacp_elog_start_event (); break; case LACP_PROCESS_EVENT_STOP: - enabled = 0; - continue; + if (lm->lacp_int == 0) + { + poll_time_remaining = SECS_IN_A_DAY; + lacp_elog_stop_event (); + } + break; default: clib_warning ("BUG: event type 0x%wx", event_type); break; } - if (event_data) - _vec_len (event_data) = 0; + vec_reset_length (event_data); if (vlib_process_suspend_time_is_zero (poll_time_remaining)) { @@ -190,16 +228,20 @@ lacp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) return 0; } -/* - * lacp periodic node declaration - */ -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (lacp_process_node, static) = { - .function = lacp_process, - .type = VLIB_NODE_TYPE_PROCESS, - .name = "lacp-process", -}; -/* *INDENT-ON* */ +void +lacp_create_periodic_process (void) +{ + lacp_main_t *lm = &lacp_main; + + /* Already created the process node? */ + if (lm->lacp_process_node_index > 0) + return; + + /* No, create it now and make a note of the node index */ + lm->lacp_process_node_index = + vlib_process_create (lm->vlib_main, "lacp-process", lacp_process, + 16 /* log2_n_stack_bytes */ ); +} /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/lacp/node.h b/src/plugins/lacp/node.h index ebc6704eb56..88bc5872390 100644 --- a/src/plugins/lacp/node.h +++ b/src/plugins/lacp/node.h @@ -74,6 +74,8 @@ typedef enum LACP_N_ERROR, } lacp_error_t; +#define SECS_IN_A_DAY 86400.0 + /* lacp packet trace capture */ typedef struct { @@ -129,7 +131,7 @@ typedef struct vlib_packet_template_t marker_packet_templates[MARKER_N_PACKET_TEMPLATES]; /* LACP interface count */ - u32 lacp_int; + volatile u32 lacp_int; /* debug is on or off */ u8 debug; @@ -138,6 +140,7 @@ typedef struct extern lacp_state_struct lacp_state_array[]; extern lacp_main_t lacp_main; +void lacp_create_periodic_process (void); clib_error_t *lacp_plugin_api_hookup (vlib_main_t * vm); int lacp_dump_ifs (lacp_interface_details_t ** out_bondids); lacp_error_t lacp_input (vlib_main_t * vm, vlib_buffer_t * b0, u32 bi0); -- cgit 1.2.3-korg