bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'

* Extended communities has some kind of resource allocation problem which
  causes a double-free if the 'set extcommunity ...' command is used.
  Try fix by properly interning extcommunities.

  Also, more generally, make unintern functions take a double pointer
  so they can NULL out callers references - a usefully defensive programming
  pattern for functions which make refs invalid.

  Sadly, this patch doesn't fix the problem entirely - crashes still
  occur on session clear.

* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
  args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
  to the attr, and unintern any old one.
  (route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
  for the route-map set.
  (route_set_ecommunity_*_free) unintern to match, instead of free
  (route_set_ecommunity_soo) Do as _rt does and don't just leak
  any pre-existing community, add to it (is additive right though?)
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index 87eb7ac..666218f 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -140,13 +140,13 @@
     baa->refcnt--;
 
   if (baa->refcnt && baa->attr)
-    bgp_attr_unintern (baa->attr);
+    bgp_attr_unintern (&baa->attr);
   else
     {
       if (baa->attr)
 	{
 	  hash_release (hash, baa);
-	  bgp_attr_unintern (baa->attr);
+	  bgp_attr_unintern (&baa->attr);
 	}
       baa_free (baa);
     }
@@ -319,7 +319,7 @@
 		    struct peer *peer, afi_t afi, safi_t safi)
 {
   if (adj->attr)
-    bgp_attr_unintern (adj->attr);
+    bgp_attr_unintern (&adj->attr);
 
   if (adj->adv)
     bgp_advertise_clean (peer, adj, afi, safi);
@@ -339,7 +339,7 @@
 	{
 	  if (adj->attr != attr)
 	    {
-	      bgp_attr_unintern (adj->attr);
+	      bgp_attr_unintern (&adj->attr);
 	      adj->attr = bgp_attr_intern (attr);
 	    }
 	  return;
@@ -355,7 +355,7 @@
 void
 bgp_adj_in_remove (struct bgp_node *rn, struct bgp_adj_in *bai)
 {
-  bgp_attr_unintern (bai->attr);
+  bgp_attr_unintern (&bai->attr);
   BGP_ADJ_IN_DEL (rn, bai);
   peer_unlock (bai->peer); /* adj_in peer reference */
   XFREE (MTYPE_BGP_ADJ_IN, bai);