ospfd, vtysh: Add support for Route tags

[Forward ported by Cumulus]

Credit
------
A huge amount of credit for this patch goes to Piotr Chytla for
their 'route tags support' patch that was submitted to quagga-dev
in June 2007.

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.

Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com>
Signed-off-by: Piotr Chytla <pch@packetconsulting.pl>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index d9b0837..ce268cd 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -370,6 +370,12 @@
       if (distance)
         SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
 
+      /* Check if path type is ASE and use only 16bit tags */
+      if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL) ||
+          (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)) &&
+           (or->u.ext.tag > 0) && (or->u.ext.tag < UINT16_MAX))
+        SET_FLAG (message, ZAPI_MESSAGE_TAG);
+
       /* Make packet. */
       s = zclient->obuf;
       stream_reset (s);
@@ -437,6 +443,9 @@
             stream_putl (s, or->cost);
         }
 
+      if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
+         stream_putw (s, (u_short)or->u.ext.tag);
+
       stream_putw_at (s, 0, stream_get_endp (s));
 
       zclient_send_message(zclient);
@@ -911,8 +920,12 @@
        *     || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
        * return 0;
        */
-        
-      ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
+
+      /* Protocol tag overwrites all other tag value send by zebra */
+      if (ospf->dtag[api.type] > 0)
+       api.tag = ospf->dtag[api.type];
+
+      ei = ospf_external_info_add (api.type, p, ifindex, nexthop, api.tag);
 
       if (ospf->router_id.s_addr == 0)
         /* Set flags to generate AS-external-LSA originate event