bgpd: encap: extend extcommunity handling

Add code to print ENCAP communities.

Signed-off-by: Lou Berger <lberger@labn.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index c76f01e..5d69b42 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -643,15 +643,34 @@
 
       /* High-order octet of type. */
       encode = *pnt++;
-      if (encode != ECOMMUNITY_ENCODE_AS && encode != ECOMMUNITY_ENCODE_IP
-		      && encode != ECOMMUNITY_ENCODE_AS4)
-	{
-	  len = sprintf (str_buf + str_pnt, "?");
-	  str_pnt += len;
-	  first = 0;
-	  continue;
-	}
-      
+
+      switch (encode)
+        {
+        case ECOMMUNITY_ENCODE_AS:
+        case ECOMMUNITY_ENCODE_IP:
+        case ECOMMUNITY_ENCODE_AS4:
+          break;
+
+        case ECOMMUNITY_ENCODE_OPAQUE:
+          if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP)
+            {
+              uint16_t tunneltype;
+              memcpy (&tunneltype, pnt + 5, 2);
+              tunneltype = ntohs(tunneltype);
+              len = sprintf (str_buf + str_pnt, "ET:%d", tunneltype);
+              str_pnt += len;
+              first = 0;
+              continue;
+            }
+            /* fall through */
+
+        default:
+          len = sprintf (str_buf + str_pnt, "?");
+          str_pnt += len;
+          first = 0;
+          continue;
+        }
+
       /* Low-order octet of type. */
       type = *pnt++;
       if (type !=  ECOMMUNITY_ROUTE_TARGET && type != ECOMMUNITY_SITE_ORIGIN)
diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h
index 92affcc..993fd5a 100644
--- a/bgpd/bgp_ecommunity.h
+++ b/bgpd/bgp_ecommunity.h
@@ -25,11 +25,15 @@
 #define ECOMMUNITY_ENCODE_AS                0x00
 #define ECOMMUNITY_ENCODE_IP                0x01
 #define ECOMMUNITY_ENCODE_AS4               0x02
+#define ECOMMUNITY_ENCODE_OPAQUE            0x03
 
-/* Low-order octet of the Extended Communityes type field.  */
+/* Low-order octet of the Extended Communities type field.  */
 #define ECOMMUNITY_ROUTE_TARGET             0x02
 #define ECOMMUNITY_SITE_ORIGIN              0x03
 
+/* Low-order octet of the Extended Communities type field for OPAQUE types */
+#define ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP     0x0c
+
 /* Extended communities attribute string format.  */
 #define ECOMMUNITY_FORMAT_ROUTE_MAP            0
 #define ECOMMUNITY_FORMAT_COMMUNITY_LIST       1