bgpd: Add support for BGP Large Communities

As described by Michael Lambert <lambert@psc.edu>  to the list:

  Traditional communities are four-octet entities to support two-octet ASNs
  and are usually represented as <asn>:<data>.  Large communities are an
  enhancement to support four-octet ASNs and are 12 octets long, represented
  as <asn>:<data-1>:<data-2>.

  This issue has been tracked in quagga bugzilla ticket #875, which documents
  some of the usage and indicates that some testing has been done.

TODO: Documentation - update doc/bgpd.texi.

* bgp_attr.{c,h}: Add BGP_ATTR_LARGE_COMMUNITIES codepoint. Add
  (struct lcommunity *) to (struct bgp_attr_extra).
* bgp_clist.{c,h}: Large community codepoints and routines.
* bgp_route.c: Display support.
* bgp_routemap.c: 'match lcommunity', 'set large-community' and
  'set large-comm-list'
* bgp_vty.c: Peer configuration, add 'large' to 'neighbor send-community ..'.
  Add "show ip bgp large-community", ""ip large-community-list ...".

Authors: Keyur Patel <keyur@arrcus.com>
         Job Snijders <job@instituut.net>
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 6189411..6aeecb1 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -627,6 +627,7 @@
     {
       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
+      SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY);
     }
 
   /* Clear neighbor default_originate_rmap */
@@ -863,6 +864,7 @@
 	  {
 	    SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
 	    SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
+	    SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_LARGE_COMMUNITY);
 	  }
 	peer->orf_plist[afi][safi] = NULL;
       }
@@ -2505,6 +2507,7 @@
     { PEER_FLAG_NEXTHOP_SELF,             1, peer_change_reset_out },
     { PEER_FLAG_SEND_COMMUNITY,           1, peer_change_reset_out },
     { PEER_FLAG_SEND_EXT_COMMUNITY,       1, peer_change_reset_out },
+    { PEER_FLAG_SEND_LARGE_COMMUNITY,     1, peer_change_reset_out },
     { PEER_FLAG_SOFT_RECONFIG,            0, peer_change_reset_in },
     { PEER_FLAG_REFLECTOR_CLIENT,         1, peer_change_reset },
     { PEER_FLAG_RSERVER_CLIENT,           1, peer_change_reset },
@@ -5111,23 +5114,31 @@
       if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
 	{
 	  if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
-	      && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
-	    vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE);
+	      && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)
+	      && peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
+	    vty_out (vty, " neighbor %s send-community all%s", addr, VTY_NEWLINE);
 	  else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))	
 	    vty_out (vty, " neighbor %s send-community extended%s",
 		     addr, VTY_NEWLINE);
+	  else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
+	    vty_out (vty, " neighbor %s send-community large%s",
+		     addr, VTY_NEWLINE);
 	  else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
 	    vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
 	}
       else
 	{
 	  if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
-	      && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
-	    vty_out (vty, " no neighbor %s send-community both%s",
+	      && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)
+	      && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
+	    vty_out (vty, " no neighbor %s send-community all%s",
 		     addr, VTY_NEWLINE);
 	  else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
 	    vty_out (vty, " no neighbor %s send-community extended%s",
 		     addr, VTY_NEWLINE);
+	  else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))
+	    vty_out (vty, " no neighbor %s send-community large%s",
+		     addr, VTY_NEWLINE);
 	  else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
 	    vty_out (vty, " no neighbor %s send-community%s",
 		     addr, VTY_NEWLINE);