]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-bgp.c
gre: add support for MikroTik Ethernet-over-IP hack.
[tcpdump] / print-bgp.c
index eca5d3da9463d8925d4fdc64ae311ec6fbce64b6..694346d733205956ce83733dc7c396eba0c0a3c3 100644 (file)
@@ -174,6 +174,7 @@ static const struct tok bgp_route_refresh_subtype_values[] = {
 #define BGPTYPE_ENTROPY_LABEL           28    /* RFC6790 */
 #define BGPTYPE_LARGE_COMMUNITY         32    /* draft-ietf-idr-large-community-05 */
 #define BGPTYPE_BGPSEC_PATH             33    /* RFC8205 */
+#define BGPTYPE_OTC                     35    /* RFC9234 */
 #define BGPTYPE_ATTR_SET               128    /* RFC6368 */
 
 #define BGP_MP_NLRI_MINSIZE              3    /* End of RIB Marker detection */
@@ -203,6 +204,7 @@ static const struct tok bgp_attr_values[] = {
     { BGPTYPE_ENTROPY_LABEL,    "Entropy Label"},
     { BGPTYPE_LARGE_COMMUNITY,  "Large Community"},
     { BGPTYPE_BGPSEC_PATH,      "BGPsec Path"},
+    { BGPTYPE_OTC,              "Only to Customer (OTC)"},
     { BGPTYPE_ATTR_SET,         "Attribute Set"},
     { 255,                      "Reserved for development"},
     { 0, NULL}
@@ -249,6 +251,7 @@ static const struct tok bgp_opt_values[] = {
 #define BGP_CAPCODE_EXT_MSG             6 /* RFC8654 */
 #define BGP_CAPCODE_BGPSEC              7 /* RFC8205 */
 #define BGP_CAPCODE_ML                  8 /* RFC8277 */
+#define BGP_CAPCODE_ROLE                9 /* RFC9234 */
 #define BGP_CAPCODE_RESTART            64 /* RFC4724  */
 #define BGP_CAPCODE_AS_NEW             65 /* RFC6793 */
 #define BGP_CAPCODE_DYN_CAP            67 /* draft-ietf-idr-dynamic-cap */
@@ -275,6 +278,7 @@ static const struct tok bgp_capcode_values[] = {
     { BGP_CAPCODE_ENH_RR,       "Enhanced Route Refresh"},
     { BGP_CAPCODE_LLGR,         "Long-lived Graceful Restart"},
     { BGP_CAPCODE_RR_CISCO,     "Route Refresh (Cisco)"},
+    { BGP_CAPCODE_ROLE,         "Role Capability"},
     { 0, NULL}
 };
 
@@ -405,6 +409,21 @@ static const struct tok bgp_aigp_values[] = {
     { 0, NULL}
 };
 
+#define BGP_ROLE_PROVIDER 0
+#define BGP_ROLE_RS 1
+#define BGP_ROLE_RS_CLIENT 2
+#define BGP_ROLE_CUSTOMER 3
+#define BGP_ROLE_PEER 4
+
+static const struct tok bgp_role_values[] = {
+    { BGP_ROLE_PROVIDER, "Provider"},
+    { BGP_ROLE_RS, "RS"},
+    { BGP_ROLE_RS_CLIENT, "RS-Client"},
+    { BGP_ROLE_CUSTOMER, "Customer"},
+    { BGP_ROLE_PEER, "Peer"},
+    { 0, NULL}
+};
+
 /* Subsequent address family identifier, RFC2283 section 7 */
 #define SAFNUM_RES                      0
 #define SAFNUM_UNICAST                  1
@@ -469,6 +488,7 @@ static const struct tok bgp_graceful_restart_comm_flag_values[] = {
 #define BGP_EXT_COM_RO_1        0x0103  /* Route Origin,Format IP address:AN(2bytes) */
 #define BGP_EXT_COM_RO_2        0x0203  /* Route Origin,Format AN(4bytes):local(2bytes) */
 #define BGP_EXT_COM_LINKBAND    0x4004  /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */
+#define BGP_EXT_COM_OVS         0x4300  /* BGP Prefix Origin Validation State Extended Community */
                                         /* rfc2547 bgp-mpls-vpns */
 #define BGP_EXT_COM_VPN_ORIGIN  0x0005  /* OSPF Domain ID / VPN of Origin  - draft-rosen-vpns-ospf-bgp-mpls */
 #define BGP_EXT_COM_VPN_ORIGIN2 0x0105  /* duplicate - keep for backwards compatibility */
@@ -506,6 +526,14 @@ static const struct tok bgp_extd_comm_flag_values[] = {
     { 0, NULL},
 };
 
+/* rfc8097 */
+static const struct tok bgp_prefix_origin_validation_state[] = {
+  { 0, "valid" },
+  { 1, "not found" },
+  { 2, "invalid" },
+  { 0, NULL },
+};
+
 static const struct tok bgp_extd_comm_subtype_values[] = {
     { BGP_EXT_COM_RT_0,        "target"},
     { BGP_EXT_COM_RT_1,        "target"},
@@ -514,6 +542,7 @@ static const struct tok bgp_extd_comm_subtype_values[] = {
     { BGP_EXT_COM_RO_1,        "origin"},
     { BGP_EXT_COM_RO_2,        "origin"},
     { BGP_EXT_COM_LINKBAND,    "link-BW"},
+    { BGP_EXT_COM_OVS,         "origin-validation-state"},
     { BGP_EXT_COM_VPN_ORIGIN,  "ospf-domain"},
     { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"},
     { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"},
@@ -906,6 +935,23 @@ bgp_extended_community_print(netdissect_options *ndo,
                      bw.f*8/1000000);
             break;
 
+    case BGP_EXT_COM_OVS:
+        /* The Reserved field MUST be set to 0 and ignored upon the
+         * receipt of this community.
+         */
+        {
+            uint64_t reserved = GET_BE_U_5(pptr + 2);
+
+            if (reserved)
+                ND_PRINT("[the reserved field 0x%" PRIx64 " MUST be 0] ",
+                         reserved);
+            ND_PRINT("ovs: %s",
+                     tok2str(bgp_prefix_origin_validation_state,
+                             "unknown origin validation state",
+                             GET_U_1(pptr + 7)));
+        }
+        break;
+
     case BGP_EXT_COM_VPN_ORIGIN:
     case BGP_EXT_COM_VPN_ORIGIN2:
     case BGP_EXT_COM_VPN_ORIGIN3:
@@ -1730,23 +1776,23 @@ bgp_mp_af_print(netdissect_options *ndo,
                   safi);
 
         switch(af<<8 | safi) {
-        case (AFNUM_INET<<8 | SAFNUM_UNICAST):
-        case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
-        case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
-        case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
-        case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
-        case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
-        case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
-        case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
-        case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
-        case (AFNUM_INET<<8 | SAFNUM_MDT):
-        case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
-        case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
-        case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
-        case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
-        case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
-        case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
-        case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
+        case (AFNUM_IP<<8 | SAFNUM_UNICAST):
+        case (AFNUM_IP<<8 | SAFNUM_MULTICAST):
+        case (AFNUM_IP<<8 | SAFNUM_UNIMULTICAST):
+        case (AFNUM_IP<<8 | SAFNUM_LABUNICAST):
+        case (AFNUM_IP<<8 | SAFNUM_RT_ROUTING_INFO):
+        case (AFNUM_IP<<8 | SAFNUM_VPNUNICAST):
+        case (AFNUM_IP<<8 | SAFNUM_VPNMULTICAST):
+        case (AFNUM_IP<<8 | SAFNUM_VPNUNIMULTICAST):
+        case (AFNUM_IP<<8 | SAFNUM_MULTICAST_VPN):
+        case (AFNUM_IP<<8 | SAFNUM_MDT):
+        case (AFNUM_IP6<<8 | SAFNUM_UNICAST):
+        case (AFNUM_IP6<<8 | SAFNUM_MULTICAST):
+        case (AFNUM_IP6<<8 | SAFNUM_UNIMULTICAST):
+        case (AFNUM_IP6<<8 | SAFNUM_LABUNICAST):
+        case (AFNUM_IP6<<8 | SAFNUM_VPNUNICAST):
+        case (AFNUM_IP6<<8 | SAFNUM_VPNMULTICAST):
+        case (AFNUM_IP6<<8 | SAFNUM_VPNUNIMULTICAST):
         case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
         case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
         case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
@@ -1780,9 +1826,9 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
        u_int path_id = 0;
 
        switch (af<<8 | safi) {
-            case (AFNUM_INET<<8 | SAFNUM_UNICAST):
-            case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
-            case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
+            case (AFNUM_IP<<8 | SAFNUM_UNICAST):
+            case (AFNUM_IP<<8 | SAFNUM_MULTICAST):
+            case (AFNUM_IP<<8 | SAFNUM_UNIMULTICAST):
                 if (add_path4) {
                     path_id = GET_BE_U_4(tptr);
                     tptr += 4;
@@ -1799,7 +1845,7 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
                    advance += 4;
                 }
                 break;
-            case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
+            case (AFNUM_IP<<8 | SAFNUM_LABUNICAST):
                 advance = decode_labeled_prefix4(ndo, tptr, len, buf, buflen);
                 if (advance == -1)
                     ND_PRINT("\n\t    (illegal prefix length)");
@@ -1810,20 +1856,20 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
                 else
                     ND_PRINT("\n\t      %s", buf);
                 break;
-            case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
-            case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
-            case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
+            case (AFNUM_IP<<8 | SAFNUM_VPNUNICAST):
+            case (AFNUM_IP<<8 | SAFNUM_VPNMULTICAST):
+            case (AFNUM_IP<<8 | SAFNUM_VPNUNIMULTICAST):
                 advance = decode_labeled_vpn_prefix4(ndo, tptr, buf, buflen);
                 if (advance == -1)
                     ND_PRINT("\n\t    (illegal prefix length)");
                 else
                     ND_PRINT("\n\t      %s", buf);
                 break;
-            case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
+            case (AFNUM_IP<<8 | SAFNUM_RT_ROUTING_INFO):
                 advance = decode_rt_routing_info(ndo, tptr);
                 break;
-            case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
-            case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
+            case (AFNUM_IP<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
+            case (AFNUM_IP6<<8 | SAFNUM_MULTICAST_VPN):
                 advance = decode_multicast_vpn(ndo, tptr, buf, buflen);
                 if (advance == -1)
                     ND_PRINT("\n\t    (illegal prefix length)");
@@ -1833,7 +1879,7 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
                     ND_PRINT("\n\t      %s", buf);
                 break;
 
-            case (AFNUM_INET<<8 | SAFNUM_MDT):
+            case (AFNUM_IP<<8 | SAFNUM_MDT):
                 advance = decode_mdt_vpn_nlri(ndo, tptr, buf, buflen);
                 if (advance == -1)
                     ND_PRINT("\n\t    (illegal prefix length)");
@@ -1842,9 +1888,9 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
                 else
                     ND_PRINT("\n\t      %s", buf);
                 break;
-            case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
-            case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
-            case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
+            case (AFNUM_IP6<<8 | SAFNUM_UNICAST):
+            case (AFNUM_IP6<<8 | SAFNUM_MULTICAST):
+            case (AFNUM_IP6<<8 | SAFNUM_UNIMULTICAST):
                 if (add_path6) {
                     path_id = GET_BE_U_4(tptr);
                     tptr += 4;
@@ -1861,7 +1907,7 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
                    advance += 4;
                 }
                 break;
-            case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
+            case (AFNUM_IP6<<8 | SAFNUM_LABUNICAST):
                 advance = decode_labeled_prefix6(ndo, tptr, len, buf, buflen);
                 if (advance == -1)
                     ND_PRINT("\n\t    (illegal prefix length)");
@@ -1872,9 +1918,9 @@ bgp_nlri_print(netdissect_options *ndo, uint16_t af, uint8_t safi,
                 else
                     ND_PRINT("\n\t      %s", buf);
                 break;
-            case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
-            case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
-            case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
+            case (AFNUM_IP6<<8 | SAFNUM_VPNUNICAST):
+            case (AFNUM_IP6<<8 | SAFNUM_VPNMULTICAST):
+            case (AFNUM_IP6<<8 | SAFNUM_VPNUNIMULTICAST):
                 advance = decode_labeled_vpn_prefix6(ndo, tptr, buf, buflen);
                 if (advance == -1)
                     ND_PRINT("\n\t    (illegal prefix length)");
@@ -2139,13 +2185,13 @@ bgp_attr_print(netdissect_options *ndo,
                     ND_PRINT(", " );
                 }
                 switch(af<<8 | safi) {
-                case (AFNUM_INET<<8 | SAFNUM_UNICAST):
-                case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
-                case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
-                case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
-                case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
-                case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
-                case (AFNUM_INET<<8 | SAFNUM_MDT):
+                case (AFNUM_IP<<8 | SAFNUM_UNICAST):
+                case (AFNUM_IP<<8 | SAFNUM_MULTICAST):
+                case (AFNUM_IP<<8 | SAFNUM_UNIMULTICAST):
+                case (AFNUM_IP<<8 | SAFNUM_LABUNICAST):
+                case (AFNUM_IP<<8 | SAFNUM_RT_ROUTING_INFO):
+                case (AFNUM_IP<<8 | SAFNUM_MULTICAST_VPN):
+                case (AFNUM_IP<<8 | SAFNUM_MDT):
                     if (tnhlen < sizeof(nd_ipv4)) {
                         ND_PRINT("invalid len");
                         tptr += tnhlen;
@@ -2158,9 +2204,9 @@ bgp_attr_print(netdissect_options *ndo,
                         tlen -= sizeof(nd_ipv4);
                     }
                     break;
-                case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
-                case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
-                case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
+                case (AFNUM_IP<<8 | SAFNUM_VPNUNICAST):
+                case (AFNUM_IP<<8 | SAFNUM_VPNMULTICAST):
+                case (AFNUM_IP<<8 | SAFNUM_VPNUNIMULTICAST):
                     if (tnhlen < sizeof(nd_ipv4)+BGP_VPN_RD_LEN) {
                         ND_PRINT("invalid len");
                         tptr += tnhlen;
@@ -2175,10 +2221,10 @@ bgp_attr_print(netdissect_options *ndo,
                         tnhlen -= (sizeof(nd_ipv4)+BGP_VPN_RD_LEN);
                     }
                     break;
-                case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
-                case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
-                case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
-                case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
+                case (AFNUM_IP6<<8 | SAFNUM_UNICAST):
+                case (AFNUM_IP6<<8 | SAFNUM_MULTICAST):
+                case (AFNUM_IP6<<8 | SAFNUM_UNIMULTICAST):
+                case (AFNUM_IP6<<8 | SAFNUM_LABUNICAST):
                     if (tnhlen < sizeof(nd_ipv6)) {
                         ND_PRINT("invalid len");
                         tptr += tnhlen;
@@ -2191,9 +2237,9 @@ bgp_attr_print(netdissect_options *ndo,
                         tnhlen -= sizeof(nd_ipv6);
                     }
                     break;
-                case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
-                case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
-                case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
+                case (AFNUM_IP6<<8 | SAFNUM_VPNUNICAST):
+                case (AFNUM_IP6<<8 | SAFNUM_VPNMULTICAST):
+                case (AFNUM_IP6<<8 | SAFNUM_VPNUNIMULTICAST):
                     if (tnhlen < sizeof(nd_ipv6)+BGP_VPN_RD_LEN) {
                         ND_PRINT("invalid len");
                         tptr += tnhlen;
@@ -2284,8 +2330,8 @@ bgp_attr_print(netdissect_options *ndo,
             ND_PRINT("\n\t    %u SNPA", snpa);
             for (/*nothing*/; snpa != 0; snpa--) {
                 uint8_t snpalen;
-               if (tlen < 1)
-                   goto trunc;
+               if (tlen < 1)
+                   goto trunc;
                 snpalen = GET_U_1(tptr);
                 ND_PRINT("\n\t      %u bytes", snpalen);
                 tptr++;
@@ -2627,6 +2673,15 @@ bgp_attr_print(netdissect_options *ndo,
         }
         break;
     }
+    case BGPTYPE_OTC:
+    {
+        if (len < 4) {
+            ND_PRINT("invalid len");
+            break;
+        }
+        ND_PRINT("\n\t    OTC %u", GET_BE_U_4(pptr));
+        break;
+    }
     default:
         ND_TCHECK_LEN(pptr, len);
         ND_PRINT("\n\t    no Attribute %u decoder", atype); /* we have no decoder for the attribute */
@@ -2739,6 +2794,15 @@ bgp_capabilities_print(netdissect_options *ndo,
                 cap_offset += 4;
             }
             break;
+        case BGP_CAPCODE_ROLE:
+            if (cap_len < 1) {
+                ND_PRINT(" (too short, < 1)");
+                return;
+            }
+            ND_PRINT("\n\t\tRole name %s (%u)",
+                     tok2str(bgp_role_values, "Unassigned",
+                             GET_U_1(opt + i + 2)), GET_U_1(opt + i + 2));
+            break;
         case BGP_CAPCODE_RR:
         case BGP_CAPCODE_LLGR:
         case BGP_CAPCODE_RR_CISCO:
@@ -3142,8 +3206,7 @@ bgp_notification_print_code(netdissect_options *ndo,
             /* garbage, hexdump it all */
             if (shutdown_comm_length > length - 1) {
                 ND_PRINT(", invalid Shutdown Communication length");
-            }
-            else if (shutdown_comm_length == 0) {
+            } else if (shutdown_comm_length == 0) {
                 ND_PRINT(", empty Shutdown Communication");
                 remainder_offset += 1;
             }