diff --git a/lib/mrt/parsebgp_mrt.c b/lib/mrt/parsebgp_mrt.c index df1a15e..5b32a47 100644 --- a/lib/mrt/parsebgp_mrt.c +++ b/lib/mrt/parsebgp_mrt.c @@ -274,21 +274,25 @@ static parsebgp_error_t parse_table_dump_v2_rib_entries( opts->bgp.mp_reach_no_afi_safi_reserved = 1; switch (subtype) { case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH: opts->bgp.afi = PARSEBGP_BGP_AFI_IPV4; opts->bgp.safi = PARSEBGP_BGP_SAFI_UNICAST; break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH: opts->bgp.afi = PARSEBGP_BGP_AFI_IPV4; opts->bgp.safi = PARSEBGP_BGP_SAFI_MULTICAST; break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH: opts->bgp.afi = PARSEBGP_BGP_AFI_IPV6; opts->bgp.safi = PARSEBGP_BGP_SAFI_UNICAST; break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH: opts->bgp.afi = PARSEBGP_BGP_AFI_IPV6; opts->bgp.safi = PARSEBGP_BGP_SAFI_MULTICAST; break; @@ -299,6 +303,12 @@ static parsebgp_error_t parse_table_dump_v2_rib_entries( PARSEBGP_RETURN_INVALID_MSG_ERR; } + uint8_t has_addl_path_id = + (subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH || + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH || + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH || + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH); + for (i = 0; i < entry_count; i++) { entry = &entries[i]; @@ -308,6 +318,13 @@ static parsebgp_error_t parse_table_dump_v2_rib_entries( // Originated Time PARSEBGP_DESERIALIZE_UINT32(buf, len, nread, entry->originated_time); + // Path Identifier (RFC 8050) + if ((entry->has_addl_path_id = has_addl_path_id)) { + PARSEBGP_DESERIALIZE_UINT32(buf, len, nread, entry->addl_path_id); + } else { + entry->addl_path_id = 0; + } + // Path Attributes slen = len - nread; if ((err = parsebgp_bgp_update_path_attrs_decode( @@ -371,7 +388,9 @@ parse_table_dump_v2_afi_safi_rib(parsebgp_opts_t *opts, // Prefix slen = len - nread; max_pfx = (subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST || - subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST) ? + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH || + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST || + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH) ? 32 : 128; err = parsebgp_decode_prefix(msg->prefix_len, msg->prefix, buf, &slen, max_pfx); @@ -433,7 +452,9 @@ dump_table_dump_v2_afi_safi_rib( PARSEBGP_DUMP_STRUCT_HDR(parsebgp_mrt_table_dump_v2_afi_safi_rib_t, depth); int afi = (subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST || - subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST) + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH || + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST || + subtype == PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH) ? PARSEBGP_BGP_AFI_IPV4 : PARSEBGP_BGP_AFI_IPV6; @@ -451,6 +472,8 @@ dump_table_dump_v2_afi_safi_rib( PARSEBGP_DUMP_INT(depth, "Peer Index", entry->peer_index); PARSEBGP_DUMP_INT(depth, "Originated Time", entry->originated_time); + if (entry->has_addl_path_id) + PARSEBGP_DUMP_INT(depth, "Path Identifier", entry->addl_path_id); parsebgp_bgp_update_path_attrs_dump(&entry->path_attrs, depth + 1); } @@ -469,14 +492,19 @@ static parsebgp_error_t parse_table_dump_v2( break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH: return parse_table_dump_v2_afi_safi_rib(opts, subtype, &msg->afi_safi_rib, buf, lenp, remain); break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC_ADDPATH: // these probably aren't too hard to support, but bgpdump doesn't support // them, so it likely means we don't have any actual use for it. PARSEBGP_SKIP_NOT_IMPLEMENTED(opts, buf, nread, remain, @@ -521,13 +549,18 @@ static void clear_table_dump_v2(parsebgp_mrt_table_dump_v2_subtype_t subtype, break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH: clear_table_dump_v2_afi_safi_rib(subtype, &msg->afi_safi_rib); break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC_ADDPATH: default: break; } @@ -545,13 +578,18 @@ static void dump_table_dump_v2(parsebgp_mrt_table_dump_v2_subtype_t subtype, break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH: case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH: dump_table_dump_v2_afi_safi_rib(subtype, &msg->afi_safi_rib, depth + 1); break; case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC: + case PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC_ADDPATH: default: break; } diff --git a/lib/mrt/parsebgp_mrt.h b/lib/mrt/parsebgp_mrt.h index 49cb3fd..5a55f83 100644 --- a/lib/mrt/parsebgp_mrt.h +++ b/lib/mrt/parsebgp_mrt.h @@ -145,9 +145,16 @@ typedef struct parsebgp_mrt_table_dump_v2_rib_entry { recently parsed peer index table) */ uint16_t peer_index; + /** Has additional path identifier? */ + uint8_t has_addl_path_id; + /** Time prefix was heard (in seconds since the unix epoch) */ uint32_t originated_time; + /** Path Identifier differentiates between additional paths for the same + prefix (RFC 7911, 8050) */ + uint32_t addl_path_id; + /** Path Attributes */ parsebgp_bgp_update_path_attrs_t path_attrs; @@ -201,6 +208,21 @@ typedef enum parsebgp_mrt_table_dump_v2_subtype { /** Generic RIB */ PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC = 6, + /** IPv4 Unicast RIB with Additional Path Identifier */ + PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH = 8, + + /** IPv4 Multicast RIB with Additional Path Identifier */ + PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH = 9, + + /** IPv6 Unicast RIB with Additional Path Identifier */ + PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH = 10, + + /** IPv6 Multicast RIB with Additional Path Identifier */ + PARSEBGP_MRT_TABLE_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH = 11, + + /** Generic RIB with Additional Path Identifier */ + PARSEBGP_MRT_TABLE_DUMP_V2_RIB_GENERIC_ADDPATH = 12, + } parsebgp_mrt_table_dump_v2_subtype_t; /*