summaryrefslogtreecommitdiff
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/ChangeLog51
-rw-r--r--bgpd/bgp_advertise.c3
-rw-r--r--bgpd/bgp_attr.c12
-rw-r--r--bgpd/bgp_attr.h45
-rw-r--r--bgpd/bgp_community.c14
-rw-r--r--bgpd/bgp_nexthop.h2
-rw-r--r--bgpd/bgp_route.h58
-rw-r--r--bgpd/bgp_table.c12
-rw-r--r--bgpd/bgp_table.h10
-rw-r--r--bgpd/bgp_vty.c199
-rw-r--r--bgpd/bgpd.c5
11 files changed, 329 insertions, 82 deletions
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index 0c8c9d6e..2a442f27 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -1,3 +1,54 @@
+2006-03-30 Paul Jakma <paul.jakma@sun.com>
+
+ * bgp_community.c: (community_gettoken) Unknown token should
+ return NULL, to give a strong indication to callers that
+ the token no longer can be parsed, otherwise callers looping
+ on this function may have a hard time ending their loop.
+ (community_str2com) While loop around community_gettoken appears
+ to have been coded thinking that break statement would break
+ from the while{}, hence it could never exit for unknown token
+ case. Fix it to do..while, so it can use the NULL result from
+ community_gettoken easily.
+
+2006-03-22 Paul Jakma <paul.jakma@sun.com>
+
+ * bgpd.c: (peer_free) release the per-peer workqueue when
+ freeing the peer.
+
+2006-03-19 Paul Jakma <paul.jakma@sun.com>
+
+ * bgpd/bgp_vty.c: Add includes to get several structs we want
+ to provide usage statistics on.
+ (show_bgp_memory_cmd) Show memory usage stats for various
+ notable fixed size objects. Using mtype_stats_alloc and
+ mtype_memstr recently added to memory.c.
+ (bgp_show_summary) Report some additional stats specific to
+ the given BGP instance and/or AFI/SAFI such as table counts,
+ peers, rsclients and peer-groups.
+ (bgp_vty_init) Install show_bgp_memory_cmd.
+ * bgp_nexthop.h: Include if.h as a dependent header, for struct
+ connected.
+ * bgp_advertise.c: Use a distinct memory type for struct
+ bgp_synchronize.
+
+2006-03-12 Paul Jakma <paul.jakma@sun.com>
+
+ * bgp_attr.h: (struct attr) rearrange fields to avoid
+ wasted padding between them as much as possible.
+ (attr_count,attr_unknown_count) export new functions to
+ return number of counts of cached attributes.
+ * bgp_attr.c: (attr_count,attr_unknown_count) new functions to
+ return number of counts of cached attributes.
+ * bgp_route.h: (struct bgp_info) rearrange fields to avoid
+ wasted padding.
+ * bgp_table.h: (struct bgp_table) Add a count field, of number
+ of nodes in the table.
+ (struct bgp_node) rearrange fields to avoid
+ wasted padding between them, though I don't think there
+ was any in this case.
+ * bgp_table.c: (bgp_node_{delete,get}) Maintain the table node count.
+ (bgp_table_count) new function to access the table count.
+
2006-03-03 Paul Jakma <paul.jakma@sun.com>
* bgp_route.c: (bgp_clear_node_complete) Doh. When clearing
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index 512ff05b..3a49ca85 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -383,7 +383,8 @@ bgp_sync_init (struct peer *peer)
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
- sync = XCALLOC (MTYPE_TMP, sizeof (struct bgp_synchronize));
+ sync = XCALLOC (MTYPE_BGP_SYNCHRONISE,
+ sizeof (struct bgp_synchronize));
FIFO_INIT (&sync->update);
FIFO_INIT (&sync->withdraw);
FIFO_INIT (&sync->withdraw_low);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 3b27517d..27ddab11 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -274,6 +274,18 @@ transit_init ()
struct hash *attrhash;
+unsigned long int
+attr_count (void)
+{
+ return attrhash->count;
+}
+
+unsigned long int
+attr_unknown_count (void)
+{
+ return transit_hash->count;
+}
+
unsigned int
attrhash_key_make (struct attr *attr)
{
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index ad0302d8..a018256f 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -48,30 +48,11 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
/* BGP attribute structure. */
struct attr
{
- /* Reference count of this attribute. */
- unsigned long refcnt;
-
- /* Flag of attribute is set or not. */
- u_int32_t flag;
-
/* Attributes. */
- u_char origin;
- struct in_addr nexthop;
- u_int32_t med;
- u_int32_t local_pref;
- as_t aggregator_as;
- struct in_addr aggregator_addr;
- u_int32_t weight;
- struct in_addr originator_id;
- struct cluster_list *cluster;
-
- u_char mp_nexthop_len;
#ifdef HAVE_IPV6
struct in6_addr mp_nexthop_global;
struct in6_addr mp_nexthop_local;
#endif /* HAVE_IPV6 */
- struct in_addr mp_nexthop_global_in;
- struct in_addr mp_nexthop_local_in;
/* AS Path structure */
struct aspath *aspath;
@@ -81,9 +62,31 @@ struct attr
/* Extended Communities attribute. */
struct ecommunity *ecommunity;
-
+
+ /* Route-Reflector Cluster attribute */
+ struct cluster_list *cluster;
+
/* Unknown transitive attribute. */
struct transit *transit;
+
+ /* Reference count of this attribute. */
+ unsigned long refcnt;
+
+ /* Flag of attribute is set or not. */
+ u_int32_t flag;
+
+ /* Apart from in6_addr, the remaining static attributes */
+ struct in_addr nexthop;
+ u_int32_t med;
+ u_int32_t local_pref;
+ struct in_addr aggregator_addr;
+ struct in_addr originator_id;
+ struct in_addr mp_nexthop_global_in;
+ struct in_addr mp_nexthop_local_in;
+ u_int32_t weight;
+ as_t aggregator_as;
+ u_char origin;
+ u_char mp_nexthop_len;
};
/* Router Reflector related structure. */
@@ -129,6 +132,8 @@ extern void bgp_dump_routes_attr (struct stream *, struct attr *,
extern unsigned int attrhash_key_make (struct attr *);
extern int attrhash_cmp (struct attr *, struct attr *);
extern void attr_show_all (struct vty *);
+extern unsigned long int attr_count (void);
+extern unsigned long int attr_unknown_count (void);
/* Cluster list prototypes. */
extern int cluster_loop_check (struct cluster_list *, struct in_addr);
diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c
index 3033db14..b419a203 100644
--- a/bgpd/bgp_community.c
+++ b/bgpd/bgp_community.c
@@ -520,7 +520,7 @@ community_gettoken (const char *buf, enum community_token *token,
/* Unknown string. */
*token = community_token_unknown;
- return p;
+ return NULL;
}
/* Community value. */
@@ -538,7 +538,7 @@ community_gettoken (const char *buf, enum community_token *token,
if (separator)
{
*token = community_token_unknown;
- return p;
+ return NULL;
}
else
{
@@ -559,14 +559,14 @@ community_gettoken (const char *buf, enum community_token *token,
if (! digit)
{
*token = community_token_unknown;
- return p;
+ return NULL;
}
*val = community_high + community_low;
*token = community_token_val;
return p;
}
*token = community_token_unknown;
- return p;
+ return NULL;
}
/* convert string to community structure */
@@ -578,8 +578,10 @@ community_str2com (const char *str)
u_int32_t val;
enum community_token token;
- while ((str = community_gettoken (str, &token, &val)))
+ do
{
+ str = community_gettoken (str, &token, &val);
+
switch (token)
{
case community_token_val:
@@ -596,7 +598,7 @@ community_str2com (const char *str)
community_free (com);
break;
}
- }
+ } while (str);
if (! com)
return NULL;
diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h
index 150e86cc..a8b92df6 100644
--- a/bgpd/bgp_nexthop.h
+++ b/bgpd/bgp_nexthop.h
@@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_NEXTHOP_H
#define _QUAGGA_BGP_NEXTHOP_H
+#include "if.h"
+
#define BGP_SCAN_INTERVAL_DEFAULT 60
#define BGP_IMPORT_INTERVAL_DEFAULT 15
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 24be30ff..e5f3ae59 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -29,20 +29,27 @@ struct bgp_info
struct bgp_info *next;
struct bgp_info *prev;
+ /* Peer structure. */
+ struct peer *peer;
+
+ /* Attribute structure. */
+ struct attr *attr;
+
+ /* Pointer to dampening structure. */
+ struct bgp_damp_info *damp_info;
+
+ /* Uptime. */
+ time_t uptime;
+
+ /* This route is suppressed with aggregation. */
+ int suppress;
+
+ /* Nexthop reachability check. */
+ u_int32_t igpmetric;
+
/* reference count */
unsigned int lock;
- /* BGP route type. This can be static, RIP, OSPF, BGP etc. */
- u_char type;
-
- /* When above type is BGP. This sub type specify BGP sub type
- information. */
- u_char sub_type;
-#define BGP_ROUTE_NORMAL 0
-#define BGP_ROUTE_STATIC 1
-#define BGP_ROUTE_AGGREGATE 2
-#define BGP_ROUTE_REDISTRIBUTE 3
-
/* BGP information status. */
u_int16_t flags;
#define BGP_INFO_IGP_CHANGED (1 << 0)
@@ -57,26 +64,19 @@ struct bgp_info
#define BGP_INFO_REMOVED (1 << 9)
#define BGP_INFO_COUNTED (1 << 10)
- /* Peer structure. */
- struct peer *peer;
-
- /* Attribute structure. */
- struct attr *attr;
-
- /* This route is suppressed with aggregation. */
- int suppress;
-
- /* Nexthop reachability check. */
- u_int32_t igpmetric;
-
- /* Uptime. */
- time_t uptime;
-
- /* Pointer to dampening structure. */
- struct bgp_damp_info *damp_info;
-
/* MPLS label. */
u_char tag[3];
+
+ /* BGP route type. This can be static, RIP, OSPF, BGP etc. */
+ u_char type;
+
+ /* When above type is BGP. This sub type specify BGP sub type
+ information. */
+ u_char sub_type;
+#define BGP_ROUTE_NORMAL 0
+#define BGP_ROUTE_STATIC 1
+#define BGP_ROUTE_AGGREGATE 2
+#define BGP_ROUTE_REDISTRIBUTE 3
};
/* BGP static route configuration. */
diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c
index a3b489d5..810dab54 100644
--- a/bgpd/bgp_table.c
+++ b/bgpd/bgp_table.c
@@ -350,8 +350,10 @@ bgp_node_get (struct bgp_table *table, struct prefix *p)
match = new;
new = bgp_node_set (table, p);
set_link (match, new);
+ table->count++;
}
}
+ table->count++;
bgp_lock_node (new);
return new;
@@ -389,7 +391,9 @@ bgp_node_delete (struct bgp_node *node)
}
else
node->table->top = child;
-
+
+ node->table->count--;
+
bgp_node_free (node);
/* If parent node is stub then delete it also. */
@@ -492,3 +496,9 @@ bgp_route_next_until (struct bgp_node *node, struct bgp_node *limit)
bgp_unlock_node (start);
return NULL;
}
+
+unsigned long
+bgp_table_count (struct bgp_table *table)
+{
+ return table->count;
+}
diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h
index e13022bb..62421e71 100644
--- a/bgpd/bgp_table.h
+++ b/bgpd/bgp_table.h
@@ -39,6 +39,8 @@ struct bgp_table
void *owner;
struct bgp_node *top;
+
+ unsigned long count;
};
struct bgp_node
@@ -51,18 +53,16 @@ struct bgp_node
#define l_left link[0]
#define l_right link[1]
- unsigned int lock;
-
void *info;
struct bgp_adj_out *adj_out;
struct bgp_adj_in *adj_in;
- void *aggregate;
-
struct bgp_node *prn;
+ unsigned int lock;
+
u_char flags;
#define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
};
@@ -84,5 +84,5 @@ extern struct bgp_node *bgp_node_match_ipv4 (struct bgp_table *,
extern struct bgp_node *bgp_node_match_ipv6 (struct bgp_table *,
struct in6_addr *);
#endif /* HAVE_IPV6 */
-
+extern unsigned long bgp_table_count (struct bgp_table *);
#endif /* _QUAGGA_BGP_TABLE_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 7d3e3402..520ddf95 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -29,15 +29,21 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "thread.h"
#include "log.h"
#include "memory.h"
+#include "hash.h"
#include "bgpd/bgpd.h"
+#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_community.h"
+#include "bgpd/bgp_ecommunity.h"
+#include "bgpd/bgp_damp.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_open.h"
+#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_table.h"
@@ -6464,6 +6470,131 @@ ALIAS (clear_ip_bgp_peer_rsclient,
"BGP IPv6 neighbor to clear\n"
"Soft reconfig for rsclient RIB\n")
+DEFUN (show_bgp_memory,
+ show_bgp_memory_cmd,
+ "show bgp memory",
+ SHOW_STR
+ BGP_STR
+ "Global BGP memory statistics\n")
+{
+ char memstrbuf[MTYPE_MEMSTR_LEN];
+ unsigned long count;
+
+ /* RIB related usage stats */
+ count = mtype_stats_alloc (MTYPE_BGP_NODE);
+ vty_out (vty, "%ld RIB nodes, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct bgp_node)),
+ VTY_NEWLINE);
+
+ count = mtype_stats_alloc (MTYPE_BGP_ROUTE);
+ vty_out (vty, "%ld BGP routes, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct bgp_info)),
+ VTY_NEWLINE);
+
+ if ((count = mtype_stats_alloc (MTYPE_BGP_STATIC)))
+ vty_out (vty, "%ld Static routes, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct bgp_static)),
+ VTY_NEWLINE);
+
+ /* Adj-In/Out */
+ if ((count = mtype_stats_alloc (MTYPE_BGP_ADJ_IN)))
+ vty_out (vty, "%ld Adj-In entries, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct bgp_adj_in)),
+ VTY_NEWLINE);
+ if ((count = mtype_stats_alloc (MTYPE_BGP_ADJ_OUT)))
+ vty_out (vty, "%ld Adj-Out entries, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct bgp_adj_out)),
+ VTY_NEWLINE);
+
+ if ((count = mtype_stats_alloc (MTYPE_BGP_NEXTHOP_CACHE)))
+ vty_out (vty, "%ld Nexthop cache entries, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct bgp_nexthop_cache)),
+ VTY_NEWLINE);
+
+ if ((count = mtype_stats_alloc (MTYPE_BGP_DAMP_INFO)))
+ vty_out (vty, "%ld Dampening entries, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct bgp_damp_info)),
+ VTY_NEWLINE);
+
+ /* Attributes */
+ count = attr_count();
+ vty_out (vty, "%ld BGP attributes, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof(struct attr)),
+ VTY_NEWLINE);
+
+ if ((count = attr_unknown_count()))
+ vty_out (vty, "%ld unknown attributes%s", count, VTY_NEWLINE);
+
+ /* AS_PATH attributes */
+ count = aspath_count ();
+ vty_out (vty, "%ld BGP AS-PATH entries, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct aspath)),
+ VTY_NEWLINE);
+
+ count = mtype_stats_alloc (MTYPE_AS_SEG);
+ vty_out (vty, "%ld BGP AS-PATH segments, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct assegment)),
+ VTY_NEWLINE);
+
+ /* Other attributes */
+ if ((count = community_count ()))
+ vty_out (vty, "%ld BGP community entries, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct community)),
+ VTY_NEWLINE);
+ if ((count = mtype_stats_alloc (MTYPE_ECOMMUNITY)))
+ vty_out (vty, "%ld BGP community entries, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct ecommunity)),
+ VTY_NEWLINE);
+
+ if ((count = mtype_stats_alloc (MTYPE_CLUSTER)))
+ vty_out (vty, "%ld Cluster lists, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct cluster_list)),
+ VTY_NEWLINE);
+
+ /* Peer related usage */
+ count = mtype_stats_alloc (MTYPE_BGP_PEER);
+ vty_out (vty, "%ld peers, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct peer)),
+ VTY_NEWLINE);
+
+ if ((count = mtype_stats_alloc (MTYPE_PEER_GROUP)))
+ vty_out (vty, "%ld peer groups, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct peer_group)),
+ VTY_NEWLINE);
+
+ /* Other */
+ if ((count = mtype_stats_alloc (MTYPE_HASH)))
+ vty_out (vty, "%ld hash tables, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct hash)),
+ VTY_NEWLINE);
+ if ((count = mtype_stats_alloc (MTYPE_HASH_BACKET)))
+ vty_out (vty, "%ld hash buckets, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (struct hash_backet)),
+ VTY_NEWLINE);
+ if ((count = mtype_stats_alloc (MTYPE_BGP_REGEXP)))
+ vty_out (vty, "%ld compiled regexes, using %s of memory%s", count,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ count * sizeof (regex_t)),
+ VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
/* Show BGP peer's summary information. */
static int
@@ -6471,34 +6602,60 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi)
{
struct peer *peer;
struct listnode *node, *nnode;
- int count = 0;
+ unsigned int count = 0;
char timebuf[BGP_UPTIME_LEN];
int len;
/* Header string for each address family. */
static char header[] = "Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd";
-
+
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
if (peer->afc[afi][safi])
{
- if (! count)
- {
- vty_out (vty,
- "BGP router identifier %s, local AS number %d%s",
- inet_ntoa (bgp->router_id), bgp->as, VTY_NEWLINE);
- vty_out (vty,
- "%ld BGP AS-PATH entries%s", aspath_count (),
- VTY_NEWLINE);
- vty_out (vty,
- "%ld BGP community entries%s", community_count (),
- VTY_NEWLINE);
-
- if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
- vty_out (vty, "Dampening enabled.%s", VTY_NEWLINE);
- vty_out (vty, "%s", VTY_NEWLINE);
- vty_out (vty, "%s%s", header, VTY_NEWLINE);
- }
+ if (!count)
+ {
+ unsigned long ents;
+ char memstrbuf[MTYPE_MEMSTR_LEN];
+
+ /* Usage summary and header */
+ vty_out (vty,
+ "BGP router identifier %s, local AS number %d%s",
+ inet_ntoa (bgp->router_id), bgp->as, VTY_NEWLINE);
+
+ ents = bgp_table_count (bgp->rib[afi][safi]);
+ vty_out (vty, "RIB entries %ld, using %s of memory%s", ents,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ ents * sizeof (struct bgp_node)),
+ VTY_NEWLINE);
+
+ /* Peer related usage */
+ ents = listcount (bgp->peer);
+ vty_out (vty, "Peers %ld, using %s of memory%s",
+ ents,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ ents * sizeof (struct peer)),
+ VTY_NEWLINE);
+
+ if ((ents = listcount (bgp->rsclient)))
+ vty_out (vty, "RS-Client peers %ld, using %s of memory%s",
+ ents,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ ents * sizeof (struct peer)),
+ VTY_NEWLINE);
+
+ if ((ents = listcount (bgp->group)))
+ vty_out (vty, "Peer groups %ld, using %s of memory%s", ents,
+ mtype_memstr (memstrbuf, sizeof (memstrbuf),
+ ents * sizeof (struct peer_group)),
+ VTY_NEWLINE);
+
+ if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
+ vty_out (vty, "Dampening enabled.%s", VTY_NEWLINE);
+ vty_out (vty, "%s", VTY_NEWLINE);
+ vty_out (vty, "%s%s", header, VTY_NEWLINE);
+ }
+
count++;
len = vty_out (vty, "%s", peer->host);
@@ -9624,6 +9781,10 @@ bgp_vty_init (void)
install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_metric_rmap_cmd);
#endif /* HAVE_IPV6 */
+ /* "show bgp memory" commands. */
+ install_element (VIEW_NODE, &show_bgp_memory_cmd);
+ install_element (ENABLE_NODE, &show_bgp_memory_cmd);
+
/* Community-list. */
community_list_vty ();
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 9f694f5e..b574a9aa 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -700,7 +700,10 @@ peer_free (struct peer *peer)
if (peer->update_if)
XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
-
+
+ if (peer->clear_node_queue)
+ work_queue_free (peer->clear_node_queue);
+
memset (peer, 0, sizeof (struct peer));
XFREE (MTYPE_BGP_PEER, peer);