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_zebra.c b/bgpd/bgp_zebra.c
index 5283d74..6c57a6f 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -296,8 +296,8 @@
 		     api.metric,
 		     api.tag);
 	}
-      bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
-			   api.metric, api.type);
+      bgp_redistribute_add ((struct prefix *)&p, &nexthop, NULL,
+			    api.metric, api.type, api.tag);
     }
   else
     {
@@ -388,7 +388,7 @@
 		     api.tag);
 	}
       bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
-			    api.metric, api.type);
+			    api.metric, api.type, api.tag);
     }
   else
     {
@@ -705,6 +705,9 @@
   flags = 0;
   peer = info->peer;
 
+  if ((info->attr->extra) && (info->attr->extra->tag != 0))
+    tag = info->attr->extra->tag;
+
   if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
     {
       SET_FLAG (flags, ZEBRA_FLAG_IBGP);
@@ -758,10 +761,10 @@
       api.metric = info->attr->med;
 
       if (tag)
-	{
-	  SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
-	  api.tag = tag;
-	}
+        {
+          SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
+          api.tag = tag;
+        }
 
       distance = bgp_distance_apply (p, info, bgp);
 
@@ -1005,13 +1008,20 @@
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = info->attr->med;
 
+      if ((info->attr->extra) && (info->attr->extra->tag != 0))
+        {
+          SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
+          api.tag = info->attr->extra->tag;
+        }
+
       if (BGP_DEBUG(zebra, ZEBRA))
 	{
 	  char buf[2][INET_ADDRSTRLEN];
-	  zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u",
+	  zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u tag %d",
 		     inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])),
 		     p->prefixlen,
-		     api.metric);
+		     api.metric,
+		     api.tag);
 	}
 
       zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, 
@@ -1033,13 +1043,20 @@
       SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
       api.metric = info->attr->med;
 
+      if ((info->attr->extra) && (info->attr->extra->tag != 0))
+        {
+          SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
+          api.tag = info->attr->extra->tag;
+        }
+
       if (BGP_DEBUG(zebra, ZEBRA))
 	{
 	  char buf[2][INET6_ADDRSTRLEN];
-	  zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u",
+	  zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u tag %d",
 		     inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])),
 		     p->prefixlen,
-		     api.metric);
+		     api.metric,
+		     api.tag);
 	}
 
       zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient,