Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement RFC 8050 MRT Additional Path extension #82

Merged
merged 1 commit into from Feb 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 40 additions & 2 deletions lib/mrt/parsebgp_mrt.c
Expand Up @@ -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;
Expand All @@ -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];

Expand All @@ -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(
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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);
}
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
22 changes: 22 additions & 0 deletions lib/mrt/parsebgp_mrt.h
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

/*
Expand Down