bgpd, vtysh: Add support for route tags

[Forward ported by Cumulus]

Documentation
-------------
All ipv4 and ipv6 static route commands now have a "tag" option
which allows the user to set a tag between 1 and 65535.

quagga(config)# ip route 1.1.1.1/32 10.1.1.1 tag ?
  <1-65535>  Tag value
quagga(config)# ip route 1.1.1.1/32 10.1.1.1 tag 40
quagga(config)#

quagga# show ip route 1.1.1.1/32
Routing entry for 1.1.1.1/32
  Known via "static", distance 1, metric 0, tag 40, best
  * 10.1.1.1, via swp1

quagga#

The route-map parser supports matching on tags and setting tags
!
route-map MATCH_TAG_18 permit 10
 match tag 18
!

!
route-map SET_TAG_22 permit 10
 set tag 22
!

BGP and OSPF support:
- matching on tags when redistribing routes from the RIB into BGP/OSPF.
- setting tags when redistribing routes from the RIB into BGP/OSPF.

BGP also supports setting a tag via a table-map, when installing BGP
routes into the RIB.

Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Signed-off-by: Piotr Chytla <pch@packetconsulting.pl>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>

Edits by: Paul Jakma <paul.jakma@hpe.com - conflicts on re-ordering with the
rmap-event and table-map patches, those will now need to update the tags stuff.
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 93902de..bab9961 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -5605,7 +5605,7 @@
 void
 bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
 		      const struct in6_addr *nexthop6,
-		      u_int32_t metric, u_char type)
+		      u_int32_t metric, u_char type, u_short tag)
 {
   struct bgp *bgp;
   struct listnode *node, *nnode;
@@ -5632,6 +5632,7 @@
 
   attr.med = metric;
   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
+  attr.extra->tag = tag;
 
   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
     {
@@ -6292,7 +6293,7 @@
 		   VTY_NEWLINE);
 	}
 
-      /* Line 3 display Origin, Med, Locpref, Weight, valid, Int/Ext/Local, Atomic, best */
+      /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
       vty_out (vty, "      Origin %s", bgp_origin_long_str[attr->origin]);
 	  
       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
@@ -6305,6 +6306,9 @@
 
       if (attr->extra && attr->extra->weight != 0)
 	vty_out (vty, ", weight %u", attr->extra->weight);
+
+      if (attr->extra && attr->extra->tag != 0)
+        vty_out (vty, ", tag %d", attr->extra->tag);
 	
       if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
 	vty_out (vty, ", invalid");