diff options
-rw-r--r-- | bgpd/bgp_main.c | 34 | ||||
-rw-r--r-- | bgpd/bgp_network.c | 1 | ||||
-rw-r--r-- | bgpd/bgp_peer_index.c | 116 | ||||
-rw-r--r-- | bgpd/bgp_peer_index.h | 11 |
4 files changed, 97 insertions, 65 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 91ce0dbf..ac7d959d 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -53,7 +53,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "bgpd/bgp_engine.h" /* bgpd options, we use GNU getopt library. */ -static const struct option longopts[] = +static const struct option longopts[] = { { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, @@ -86,10 +86,10 @@ static void bgp_in_thread_init(void); static qtime_mono_t routing_event_hook(void); static qtime_mono_t bgp_event_hook(void); -static struct quagga_signal_t bgp_signals[] = +static struct quagga_signal_t bgp_signals[] = { - { - .signal = SIGHUP, + { + .signal = SIGHUP, .handler = &sighup, }, { @@ -130,9 +130,9 @@ int vty_port = BGP_VTY_PORT; char *vty_addr = NULL; /* privileges */ -static zebra_capabilities_t _caps_p [] = +static zebra_capabilities_t _caps_p [] = { - ZCAP_BIND, + ZCAP_BIND, ZCAP_NET_RAW, }; @@ -157,7 +157,7 @@ usage (char *progname, int status) if (status != 0) fprintf (stderr, "Try `%s --help' for more information.\n", progname); else - { + { printf ("Usage : %s [OPTION...]\n\n\ Daemon which manages kernel routing table management and \ redistribution between different routing protocols.\n\n\ @@ -182,9 +182,9 @@ Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); exit (status); } - + /* SIGHUP handler. */ -void +void sighup (void) { zlog (NULL, LOG_INFO, "SIGHUP received"); @@ -364,7 +364,7 @@ static void init_second_stage(int pthreads) { qlib_init_second_stage(pthreads); - bgp_peer_index_mutex_init(NULL); + bgp_peer_index_mutex_init(); /* if using pthreads create additional nexus */ if (qpthreads_enabled) @@ -426,14 +426,14 @@ main (int argc, char **argv) bgp_master_init (); /* Command line argument treatment. */ - while (1) + while (1) { opt = getopt_long (argc, argv, "df:i:hp:l:A:P:rnu:g:vCt", longopts, 0); - + if (opt == EOF) break; - switch (opt) + switch (opt) { case 0: break; @@ -459,11 +459,11 @@ main (int argc, char **argv) case 'P': /* Deal with atoi() returning 0 on failure, and bgpd not listening on bgp port... */ - if (strcmp(optarg, "0") == 0) + if (strcmp(optarg, "0") == 0) { vty_port = 0; break; - } + } vty_port = atoi (optarg); if (vty_port <= 0 || vty_port > 0xffff) vty_port = BGP_VTY_PORT; @@ -527,7 +527,7 @@ main (int argc, char **argv) /* Start execution only if not in dry-run mode */ if(dryrun) return(0); - + /* only the calling thread survives in the child after a fork * so ensure we haven't created any threads yet */ @@ -555,7 +555,7 @@ main (int argc, char **argv) zlog_notice("%s", debug_banner); #endif zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION, - vty_port, + vty_port, (bm->address ? bm->address : "<all>"), (int)bm->port); diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 25d82ae3..5fa8cda2 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -971,6 +971,7 @@ bgp_md5_set_listeners(union sockunion* su, const char* password) ret = bgp_md5_set_socket(qps_file_fd(&listener->qf), su, password) ; if (ret != 0) return ret ; + listener = listener->next ; } ; return 0 ; diff --git a/bgpd/bgp_peer_index.c b/bgpd/bgp_peer_index.c index 556262ec..87b761df 100644 --- a/bgpd/bgp_peer_index.c +++ b/bgpd/bgp_peer_index.c @@ -51,7 +51,7 @@ static struct symbol_table bgp_peer_index ; /* lookup by 'name' */ static struct vector bgp_peer_id_index ; /* lookup by peer-id */ -static qpt_mutex_t bgp_peer_index_mutex ; +static qpt_mutex bgp_peer_index_mutex = NULL ; CONFIRM(bgp_peer_id_null == 0) ; @@ -67,12 +67,12 @@ struct bgp_peer_id_table_chunk inline static void BGP_PEER_INDEX_LOCK(void) { - qpt_mutex_lock(&bgp_peer_index_mutex) ; + qpt_mutex_lock(bgp_peer_index_mutex) ; } ; inline static void BGP_PEER_INDEX_UNLOCK(void) { - qpt_mutex_unlock(&bgp_peer_index_mutex) ; + qpt_mutex_unlock(bgp_peer_index_mutex) ; } ; static bgp_peer_id_t bgp_peer_id_count = 0 ; @@ -82,9 +82,6 @@ static bgp_peer_id_table_chunk bgp_peer_id_table = NULL ; static bgp_peer_index_entry bgp_peer_id_free_head = NULL ; static bgp_peer_index_entry bgp_peer_id_free_tail = NULL ; -/* Overloads the peer field to be next in list of free peers. */ -#define bgp_peer_id_free_next(e) ((e)->peer) - /* Forward references */ static void bgp_peer_id_table_free_entry(bgp_peer_index_entry entry) ; static void bgp_peer_id_table_make_ids(void) ; @@ -100,10 +97,10 @@ bgp_peer_index_init(void* parent) symbol_table_init_new( &bgp_peer_index, parent, - 10, /* start ready for a few sessions */ - 200, /* allow to be quite dense */ - sockunion_symbol_hash, /* "name" is an IP Address */ - NULL) ; /* no value change call-back */ + 10, /* start ready for a few sessions */ + 200, /* allow to be quite dense */ + sockunion_symbol_hash, /* "name" is an IP Address */ + NULL) ; /* no value change call-back */ vector_init_new(&bgp_peer_id_index, bgp_peer_id_unit) ; @@ -113,6 +110,9 @@ bgp_peer_index_init(void* parent) bgp_peer_id_free_tail = NULL ; bgp_peer_id_count = 0 ; + + /* OK up to creation of qpthreads ! */ + bgp_peer_index_mutex = NULL ; } ; /*------------------------------------------------------------------------------ @@ -121,9 +121,55 @@ bgp_peer_index_init(void* parent) * This must be done as soon as any qpthreads are enabled. */ extern void -bgp_peer_index_mutex_init(void* parent) +bgp_peer_index_mutex_init(void) +{ + bgp_peer_index_mutex = qpt_mutex_init_new(NULL, qpt_mutex_recursive) ; +} ; + +/*------------------------------------------------------------------------------ + * Reset the peer index -- freeing all memory. + * + * The index can be used again without initialisation, and without further + * initialisation of the mutex. + * + * NB: all peers MUST have been deregistered already. + */ +extern void +bgp_peer_index_reset(void) { - qpt_mutex_init(&bgp_peer_index_mutex, qpt_mutex_recursive) ; + bgp_peer_index_entry entry ; + bgp_peer_id_table_chunk chunk ; + + /* Ream out the peer id vector -- checking that all entries are empty */ + while ((entry = vector_ream_keep(&bgp_peer_id_index)) != NULL) + passert(entry->peer == NULL) ; + + /* Discard body of symbol table -- must be empty ! */ + symbol_table_reset_keep(&bgp_peer_index) ; + + /* Discard the empty chunks of entries */ + while (bgp_peer_id_table != NULL) + { + chunk = bgp_peer_id_table ; + bgp_peer_id_table = chunk->next ; + XFREE(MTYPE_BGP_PEER_ID_TABLE, chunk) ; + } ; + + /* Set utterly empty */ + bgp_peer_id_table = NULL ; + bgp_peer_id_free_head = NULL ; + bgp_peer_id_free_tail = NULL ; + + bgp_peer_id_count = 0 ; +} ; + +/*------------------------------------------------------------------------------ + * Free the bgp_peer_index_mutex -- for shut down. + */ +extern void +bgp_peer_index_mutex_free(void) +{ + qpt_mutex_destroy_free(bgp_peer_index_mutex) ; } ; /*------------------------------------------------------------------------------ @@ -148,7 +194,7 @@ bgp_peer_index_register(bgp_peer peer, union sockunion* su) bgp_peer_id_table_make_ids() ; entry = bgp_peer_id_free_head ; - bgp_peer_id_free_head = (void*)bgp_peer_id_free_next(entry) ; + bgp_peer_id_free_head = (void*)entry->accept ; assert(vector_get_item(&bgp_peer_id_index, entry->id) == entry) ; @@ -267,36 +313,14 @@ bgp_session_index_seek(union sockunion* su, int* p_found) return accept ; } ; -/*------------------------------------------------------------------------------ - * Set peer's session pointer. - * - * For use by the Routeing Engine. Locks the bgp_peer_index mutex so that the - * BGP Engine is not fooled when it looks up the session. - * - * Returns the old session pointer value. - * - * NB: it is a FATAL error to change the pointer if the current session is - * "active". - */ -bgp_session -bgp_peer_new_session(bgp_peer peer, bgp_session new_session) -{ - bgp_session old_session ; - - BGP_PEER_INDEX_LOCK() ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ - - old_session = peer->session ; - peer->session = new_session ; - - passert(!bgp_session_is_active(old_session)) ; - - BGP_PEER_INDEX_UNLOCK() ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/ - - return old_session ; -} - /*============================================================================== * Extending the bgp_peer_id_table and adding free entries to it. + * + * NB: when entry is free, the peer field is NULL. + * when entry is in use, the peer field is not NULL ! + * + * when entry is free, the accept field is overloaded as pointer to next + * free entry. */ /*------------------------------------------------------------------------------ @@ -311,10 +335,12 @@ bgp_peer_id_table_free_entry(bgp_peer_index_entry entry) if (bgp_peer_id_free_head == NULL) bgp_peer_id_free_head = entry ; else - bgp_peer_id_free_next(bgp_peer_id_free_tail) = (void*)entry ; + bgp_peer_id_free_tail->accept = (void*)entry ; - bgp_peer_id_free_tail = entry ; - bgp_peer_id_free_next(entry) = NULL ; + bgp_peer_id_free_tail = entry ; + entry->accept = NULL ; /* used as 'next' for free list */ + + entry->peer = NULL ; /* only when free ! */ } ; /*------------------------------------------------------------------------------ @@ -337,6 +363,8 @@ bgp_peer_id_table_make_ids(void) /* Special case to avoid id == 0 being used. Is not set in vector. */ if (bgp_peer_id_count == 0) { + confirm(bgp_peer_id_null == 0) ; + entry->id = 0 ; /* should never be used */ entry->peer = NULL ; /* invalid in use */ entry->accept = (void*)entry ; /* invalid if not active ! */ diff --git a/bgpd/bgp_peer_index.h b/bgpd/bgp_peer_index.h index 355b3654..a77eab59 100644 --- a/bgpd/bgp_peer_index.h +++ b/bgpd/bgp_peer_index.h @@ -68,7 +68,13 @@ extern void bgp_peer_index_init(void* parent) ; extern void -bgp_peer_index_mutex_init(void* parent) ; +bgp_peer_index_mutex_init(void) ; + +extern void +bgp_peer_index_reset(void) ; + +extern void +bgp_peer_index_mutex_free(void) ; extern void bgp_peer_index_register(bgp_peer peer, union sockunion* su) ; @@ -85,8 +91,5 @@ bgp_peer_index_seek_entry(union sockunion* su) ; extern bgp_session bgp_session_index_seek(union sockunion* su, int* p_found) ; -extern bgp_session -bgp_peer_new_session(bgp_peer peer, bgp_session new_session); - #endif /* _QUAGGA_BGP_PEER_INDEX_H */ |