[bgpd] Trim memory usage of BGP routes

2007-05-03 Paul Jakma <paul.jakma@sun.com>

	* bgp_route.h: (struct info) Move less frequently used
	  fields to a lazily allocated struct info_extra.
	  Export bgp_info_extra_get
	* bgp_route.c: (bgp_info_extra_new) allocate extra
	  (bgp_info_extra_free) Free damp info and the info_extra.
	  (bgp_info_extra_get) Retrieve the info_extra of a struct
	  info, allocating as required.
	  (generally) adjust to use info->extra
	* bgp_damp.c: (generally) use bgp_info_extra_get to access
	  dampinfo
	* bgp_attr.h: Move rarely allocated attributes from struct attr
	  to a struct attr_extra, for a substantial saving in size of
	  struct attr.
	* bgp_attr.c: (bgp_attr_extra_{new,free}), new, self-explanatory.
	  (bgp_attr_extra_get) Get the attr_extra for a given struct
	  attr, allocating it if needs be.
	  (bgp_attr_dup) Shallow copy the struct attr and its attr_extra.
	  (generally) adjust to know about attr->extra.
	* bgp_debug.c: (bgp_dump_attr) ditto
	* bgp_vty.c: (show_bgp_memory) print attr and info extra sizes.
	* bgp_nexthop.c: (generally) adjust to know about attr->extra
	  and info->extra.
	* bgp_{packet,routemap,snmp,zebra}.c: ditto
	* lib/memtypes.c: Add MTYPE_ATTR_EXTRA and MTYPE_BGP_ROUTE_EXTRA
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 50ae74e..4dd5d94 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -196,15 +196,15 @@
 #ifdef HAVE_IPV6
   else if (afi == AFI_IP6)
     {
-      if (attr->mp_nexthop_len == 32)
+      if (attr->extra->mp_nexthop_len == 32)
 	return 1;
-      else if (attr->mp_nexthop_len == 16)
+      else if (attr->extra->mp_nexthop_len == 16)
 	{
-	  if (IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_global))
+	  if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
 	    return 1;
 
 	  rn = bgp_node_match_ipv6 (bgp_connected_table[AFI_IP6],
-				      &attr->mp_nexthop_global);
+				      &attr->extra->mp_nexthop_global);
 	  if (rn)
 	    {
 	      bgp_unlock_node (rn);
@@ -230,21 +230,22 @@
   /* If lookup is not enabled, return valid. */
   if (zlookup->sock < 0)
     {
-      ri->igpmetric = 0;
+      if (ri->extra)
+        ri->extra->igpmetric = 0;
       return 1;
     }
 
   /* Only check IPv6 global address only nexthop. */
   attr = ri->attr;
 
-  if (attr->mp_nexthop_len != 16 
-      || IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_global))
+  if (attr->extra->mp_nexthop_len != 16 
+      || IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
     return 1;
 
   memset (&p, 0, sizeof (struct prefix));
   p.family = AF_INET6;
   p.prefixlen = IPV6_MAX_BITLEN;
-  p.u.prefix6 = attr->mp_nexthop_global;
+  p.u.prefix6 = attr->extra->mp_nexthop_global;
 
   /* IBGP or ebgp-multihop */
   rn = bgp_node_get (bgp_nexthop_cache_table[AFI_IP6], &p);
@@ -256,7 +257,7 @@
     }
   else
     {
-      bnc = zlookup_query_ipv6 (&attr->mp_nexthop_global);
+      bnc = zlookup_query_ipv6 (&attr->extra->mp_nexthop_global);
       if (bnc)
 	{
 	  struct bgp_table *old;
@@ -296,10 +297,10 @@
   if (metricchanged)
     *metricchanged = bnc->metricchanged;
 
-  if (bnc->valid)
-    ri->igpmetric = bnc->metric;
-  else
-    ri->igpmetric = 0;
+  if (bnc->valid && bnc->metric)
+    (bgp_info_extra_get (ri))->igpmetric = bnc->metric;
+  else if (ri->extra)
+    ri->extra->igpmetric = 0;
 
   return bnc->valid;
 }
@@ -318,7 +319,8 @@
   /* If lookup is not enabled, return valid. */
   if (zlookup->sock < 0)
     {
-      ri->igpmetric = 0;
+      if (ri->extra)
+        ri->extra->igpmetric = 0;
       return 1;
     }
 
@@ -384,10 +386,10 @@
   if (metricchanged)
     *metricchanged = bnc->metricchanged;
 
-  if (bnc->valid)
-    ri->igpmetric = bnc->metric;
-  else
-    ri->igpmetric = 0;
+  if (bnc->valid && bnc->metric)
+    (bgp_info_extra_get(ri))->igpmetric = bnc->metric;
+  else if (ri->extra)
+    ri->extra->igpmetric = 0;
 
   return bnc->valid;
 }
@@ -490,7 +492,7 @@
 
               if (CHECK_FLAG (bgp->af_flags[afi][SAFI_UNICAST],
 		  BGP_CONFIG_DAMPENING)
-                  &&  bi->damp_info )
+                  &&  bi->extra && bi->extra->damp_info )
                 if (bgp_damp_scan (bi, afi, SAFI_UNICAST))
 		  bgp_aggregate_increment (bgp, &rn->p, bi,
 					   afi, SAFI_UNICAST);