summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_peer_index.c
diff options
context:
space:
mode:
authorChris Hall <GMCH@hestia.halldom.com>2010-01-19 18:27:23 +0000
committerChris Hall <GMCH@hestia.halldom.com>2010-01-19 18:27:23 +0000
commit5b8978176cbefe7c38f3ed72fd863e2e313d86d8 (patch)
tree47a1fe4db6f831466b862fa29a38aa6078faddaa /bgpd/bgp_peer_index.c
parent92acc391ac183ba796102dff905a46fa3bc49762 (diff)
downloadquagga-5b8978176cbefe7c38f3ed72fd863e2e313d86d8.tar.bz2
quagga-5b8978176cbefe7c38f3ed72fd863e2e313d86d8.tar.xz
Small fix to bgp_network & add reset to peer index
Correctly stepping along list of listeners in bgp_md5_set_listeners. Added reset function for peer index and remove spurious argument for bgp_peer_index_mutex_init.
Diffstat (limited to 'bgpd/bgp_peer_index.c')
-rw-r--r--bgpd/bgp_peer_index.c116
1 files changed, 72 insertions, 44 deletions
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 ! */