From: E. Scott Daniels Date: Fri, 9 Apr 2021 12:40:20 +0000 (-0400) Subject: Ensure RT incremental update not applied early X-Git-Tag: 4.7.3~1 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=c8e651e15839411c85e105d16fd2ffc14c1cc1dd;p=ric-plt%2Flib%2Frmr.git Ensure RT incremental update not applied early This change ensures that a full table has been provided by the route generator (route manager) prior to RMR accepting any incremental updates. The change also captures the initial value of the RMR_SEED environment variable such that it cannot be changed once it has been used. Issue-ID: RIC-329 Signed-off-by: E. Scott Daniels Change-Id: I168cb42905e41641590130de724965e8dbca67e6 --- diff --git a/CHANGES_CORE.txt b/CHANGES_CORE.txt index 51c254c..cfa9ea3 100644 --- a/CHANGES_CORE.txt +++ b/CHANGES_CORE.txt @@ -5,6 +5,13 @@ # API and build change and fix summaries. Doc corrections # and/or changes are not mentioned here; see the commit messages. +2021 April 9; version 4.7.2 + Ensure that route table update received from route generator is not + applied before a full route table is received. + +2021 April 2; version 4.7.1 + Correct issues found during static code analysis. + 2021 March 31; version 4.7.0 The route table collector thread will capture the current "offering" from the Route Manager (table generator) if the RMR_SEED_RT environment diff --git a/CMakeLists.txt b/CMakeLists.txt index a8220b4..a0d1b7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ cmake_minimum_required( VERSION 3.5 ) set( major_version "4" ) # should be automatically populated from git tag later, but until CI process sets a tag we use this set( minor_version "7" ) -set( patch_level "1" ) +set( patch_level "2" ) set( install_root "${CMAKE_INSTALL_PREFIX}" ) set( install_inc "include/rmr" ) diff --git a/docs/rel-notes.rst b/docs/rel-notes.rst index 7f29300..dadc465 100644 --- a/docs/rel-notes.rst +++ b/docs/rel-notes.rst @@ -22,6 +22,21 @@ the need to leap frog versions ceased, and beginning with version 4.0.0, the RMR versions should no longer skip. +2021 April 9; version 4.7.2 +--------------------------- + +Ensure that route table update received from route generator +is not applied before a full route table is received. + + + +2021 April 2; version 4.7.1 +--------------------------- + +Correct issues found during static code analysis. + + + 2021 March 31; version 4.7.0 ---------------------------- diff --git a/src/rmr/common/include/rmr_agnostic.h b/src/rmr/common/include/rmr_agnostic.h index 7e6fdda..0858fde 100644 --- a/src/rmr/common/include/rmr_agnostic.h +++ b/src/rmr/common/include/rmr_agnostic.h @@ -83,11 +83,11 @@ typedef struct uta_ctx uta_ctx_t; // internal flags, must be > than UFLAG_MASK //#define IFL_.... + // context flags #define CFL_MTC_ENABLED 0x01 // multi-threaded call is enabled #define CFL_NO_RTACK 0x02 // no route table ack needed when end received - - // context flags -#define CTXFL_WARN 0x01 // ok to warn on stderr for some things that shouldn't happen +#define CFL_WARN 0x04 // ok to warn on stderr for some things that shouldn't happen +#define CFL_FULLRT 0x08 // set when we have received an initial full route table (prevent updates before one arrives) // msg buffer flags #define MFL_ZEROCOPY 0x01 // the message is an allocated zero copy message and can be sent. diff --git a/src/rmr/common/src/rt_generic_static.c b/src/rmr/common/src/rt_generic_static.c index 2e4b711..dcedb49 100644 --- a/src/rmr/common/src/rt_generic_static.c +++ b/src/rmr/common/src/rt_generic_static.c @@ -852,7 +852,7 @@ static void cycle_snarfed_rt( uta_ctx_t* ctx ) { return; } - if( (snarf_fname = getenv( ENV_STASH_RT )) == NULL ) { // specific place to stash the rt not given + if( (snarf_fname = getenv( ENV_STASH_RT )) == NULL ) { // specific place to stash the rt not given if( (seed_fname = getenv( ENV_SEED_RT )) != NULL ) { // no seed, we leave in the default file memset( wfname, 0, sizeof( wfname ) ); snprintf( wfname, sizeof( wfname ) - 1, "%s.stash", seed_fname ); @@ -861,6 +861,7 @@ static void cycle_snarfed_rt( uta_ctx_t* ctx ) { } if( snarf_fname == NULL ) { + rmr_vlog( RMR_VL_DEBUG, "cycle_snarf: no file to save in" ); return; } @@ -1018,6 +1019,7 @@ static void parse_rt_rec( uta_ctx_t* ctx, uta_ctx_t* pctx, char* buf, int vleve send_rt_ack( pctx, mbuf, ctx->table_id, RMR_OK, NULL ); ctx->rtable_ready = 1; // route based sends can now happen + ctx->flags |= CFL_FULLRT; // indicate we have seen a complete route table } else { if( DEBUG > 1 ) rmr_vlog_force( RMR_VL_DEBUG, "end of route table noticed, but one was not started!\n" ); ctx->new_rtable = NULL; @@ -1079,6 +1081,11 @@ static void parse_rt_rec( uta_ctx_t* ctx, uta_ctx_t* pctx, char* buf, int vleve break; case 'u': // update current table, not a total replacement + if( ! ctx->flags & CFL_FULLRT ) { // we cannot update until we have a full table from route generator + rmr_vlog( RMR_VL_WARN, "route table update ignored: full table not previously recevied" ); + break; + } + tokens[1] = clip( tokens[1] ); if( strcmp( tokens[1], "end" ) == 0 ) { // wrap up the table we were building if( ctx->new_rtable == NULL ) { // update table not in progress @@ -1158,8 +1165,13 @@ static void read_static_rt( uta_ctx_t* ctx, int vlevel ) { char* eor; // end of the record int rcount = 0; // record count for debug - if( (fname = getenv( ENV_SEED_RT )) == NULL ) { - return; + if( (fname = ctx->seed_rt_fname) == NULL ) { + if( (fname = getenv( ENV_SEED_RT )) == NULL ) { + return; + } + + ctx->seed_rt_fname = strdup( fname ); + fname = ctx->seed_rt_fname; } if( (fbuf = ensure_nlterm( uta_fib( fname ) ) ) == NULL ) { // read file into a single buffer (nil terminated string) diff --git a/src/rmr/common/src/rtc_static.c b/src/rmr/common/src/rtc_static.c index 96f8330..10bc2a7 100644 --- a/src/rmr/common/src/rtc_static.c +++ b/src/rmr/common/src/rtc_static.c @@ -310,6 +310,7 @@ static void* rtc( void* vctx ) { ctx->flags |= CFL_NO_RTACK; // don't ack when reading from a file read_static_rt( ctx, vlevel ); // seed the route table if one provided ctx->flags &= ~CFL_NO_RTACK; + ctx->flags &= ~CFL_FULLRT; // even though rmr-ready goes true, the seed doesn't count as a full RT from route generator my_port = getenv( ENV_CTL_PORT ); // default port to listen on (likely 4561) diff --git a/src/rmr/si/include/rmr_si_private.h b/src/rmr/si/include/rmr_si_private.h index ee71409..414c649 100644 --- a/src/rmr/si/include/rmr_si_private.h +++ b/src/rmr/si/include/rmr_si_private.h @@ -122,7 +122,7 @@ struct uta_ctx { int shutdown; // thread notification if we need to tell them to stop int max_mlen; // max message length payload+header int max_plen; // max payload length - int flags; // CTXFL_ constants + int flags; // CFL_ constants int nrtele; // number of elements in the routing table int send_retries; // number of retries send_msg() should attempt if eagain/timeout indicated by nng int trace_data_len; // number of bytes to allocate in header for trace data @@ -132,6 +132,7 @@ struct uta_ctx { int rtable_ready; // set to true when rt is received or loaded int snarf_rt_fd; // the file des where we save the last rt from RM int dcount; // drop counter when app is slow + char* seed_rt_fname; // the static/seed route table; name captured at start route_table_t* rtable; // the active route table route_table_t* old_rtable; // the previously used rt, sits here to allow for draining route_table_t* new_rtable; // route table under construction diff --git a/src/rmr/si/src/rmr_si.c b/src/rmr/si/src/rmr_si.c index b8bb2a0..8f88cf8 100644 --- a/src/rmr/si/src/rmr_si.c +++ b/src/rmr/si/src/rmr_si.c @@ -733,7 +733,7 @@ static void* init( char* uproto_port, int def_msg_size, int flags ) { if( (tok = getenv( ENV_WARNINGS )) != NULL ) { if( *tok == '1' ) { - ctx->flags |= CTXFL_WARN; // turn on some warnings (not all, just ones that shouldn't impact performance) + ctx->flags |= CFL_WARN; // turn on some warnings (not all, just ones that shouldn't impact performance) } } @@ -884,6 +884,10 @@ extern void rmr_close( void* vctx ) { return; } + if( ctx->seed_rt_fname != NULL ) { + free( ctx->seed_rt_fname ); + } + ctx->shutdown = 1; SItp_stats( ctx->si_ctx ); // dump some interesting stats diff --git a/test/rt_static_test.c b/test/rt_static_test.c index 7a51bca..3bdd312 100644 --- a/test/rt_static_test.c +++ b/test/rt_static_test.c @@ -1,3 +1,4 @@ + // : vi ts=4 sw=4 noet : /* ================================================================================== @@ -500,6 +501,10 @@ static int rt_test( ) { errors += fail_if_nil( ctx->rtable, "edge case route table didn't generate a pointer into the context" ); unsetenv( "RMR_SEED_RT" ); // remove for next read try + if( ctx && ctx->seed_rt_fname != NULL ) { + free( ctx->seed_rt_fname ); + ctx->seed_rt_fname = NULL; + } read_static_rt( ctx, 0 ); // drive for not there coverage } @@ -571,6 +576,10 @@ static int rt_test( ) { ctx->rtable = NULL; ctx->my_name = strdup( "my_host_name" ); // set up to load a rtable ctx->my_ip = strdup( "192.168.1.30" ); + if( ctx && ctx->seed_rt_fname != NULL ) { + free( ctx->seed_rt_fname ); + ctx->seed_rt_fname = NULL; + } gen_rt( ctx ); // generate a route table with meid entries and hang off ctx mbuf = rmr_alloc_msg( ctx, 2048 ); // buffer to play with diff --git a/test/test_ctx_support.c b/test/test_ctx_support.c index d15239a..cd3f14e 100644 --- a/test/test_ctx_support.c +++ b/test/test_ctx_support.c @@ -45,6 +45,7 @@ static inline uta_ctx_t *mk_dummy_ctx() { } memset( ctx, 0, sizeof( *ctx ) ); + ctx->snarf_rt_fd = -1; return ctx; } @@ -70,6 +71,7 @@ static inline uta_ctx_t *mk_dummy_ctx() { ctx->si_ctx = malloc( 1024 ); ctx->my_name = strdup( "hostname1" ); ctx->my_ip = strdup( "123.45.67.89" ); + ctx->snarf_rt_fd = -1; ctx->rtgate = (pthread_mutex_t *) malloc( sizeof( *ctx->rtgate ) ); if( ctx->rtgate != NULL ) { diff --git a/test/test_gen_rt.c b/test/test_gen_rt.c index 79b413f..5748ca1 100644 --- a/test/test_gen_rt.c +++ b/test/test_gen_rt.c @@ -45,6 +45,7 @@ static void gen_rt( uta_ctx_t* ctx ) { int fd; char* rt_stuff; // strings for the route table +ctx->flags |= 0x08; fd = open( "utesting.rt", O_WRONLY | O_CREAT, 0600 ); if( fd < 0 ) { fprintf( stderr, " unable to open file for testing route table gen\n" );