diff options
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/ChangeLog | 51 | ||||
-rw-r--r-- | bgpd/bgp_advertise.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_attr.c | 12 | ||||
-rw-r--r-- | bgpd/bgp_attr.h | 45 | ||||
-rw-r--r-- | bgpd/bgp_community.c | 14 | ||||
-rw-r--r-- | bgpd/bgp_nexthop.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_route.h | 58 | ||||
-rw-r--r-- | bgpd/bgp_table.c | 12 | ||||
-rw-r--r-- | bgpd/bgp_table.h | 10 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 199 | ||||
-rw-r--r-- | bgpd/bgpd.c | 5 |
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); |