0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 18:21:54 +00:00

MRT Table Dump: draft-petrie-grow-mrt-add-paths

Add support for MRT Table Dump draft-petrie-grow-mrt-add-paths
This commit is contained in:
Pavel Tvrdík 2016-01-05 19:48:35 +01:00
parent 696acee0c7
commit 71299a594d
3 changed files with 109 additions and 57 deletions

View File

@ -219,14 +219,14 @@ mrt_rib_table_alloc(struct mrt_rib_table *state)
} }
void void
mrt_rib_table_header(struct mrt_rib_table *state, u32 sequence_number, u8 prefix_length, ip_addr prefix) mrt_rib_table_header(struct mrt_rib_table *state, u32 sequence_number, u8 prefix_length, ip_addr prefix, uint is_addpath)
{ {
mrt_rib_table_reset(state); mrt_rib_table_reset(state);
#ifdef IPV6 #ifdef IPV6
state->subtype = MRT_RIB_IPV6_UNICAST; state->subtype = (is_addpath == MRT_RIB_ADDPATH) ? MRT_RIB_IPV6_UNICAST_ADDPATH : MRT_RIB_IPV6_UNICAST;
#else #else
state->subtype = MRT_RIB_IPV4_UNICAST; state->subtype = (is_addpath == MRT_RIB_ADDPATH) ? MRT_RIB_IPV4_UNICAST_ADDPATH : MRT_RIB_IPV4_UNICAST;
#endif #endif
struct mrt_buffer *msg = &state->msg; struct mrt_buffer *msg = &state->msg;
@ -257,6 +257,16 @@ mrt_rib_table_add_entry(struct mrt_rib_table *state, const struct mrt_rib_entry
mrt_buffer_put_var_autosize(msg, entry->peer_index); mrt_buffer_put_var_autosize(msg, entry->peer_index);
mrt_buffer_put_var_autosize(msg, entry->originated_time); mrt_buffer_put_var_autosize(msg, entry->originated_time);
switch (state->subtype)
{
case MRT_RIB_IPV4_UNICAST_ADDPATH:
case MRT_RIB_IPV6_UNICAST_ADDPATH:
case MRT_RIB_IPV4_MULTICAST_ADDPATH:
case MRT_RIB_IPV6_MULTICAST_ADDPATH:
mrt_buffer_put_var_autosize(msg, entry->path_id);
}
mrt_buffer_put_var_autosize(msg, entry->attributes_length); mrt_buffer_put_var_autosize(msg, entry->attributes_length);
mrt_buffer_put_raw(msg, entry->attributes, entry->attributes_length); mrt_buffer_put_raw(msg, entry->attributes, entry->attributes_length);

View File

@ -37,6 +37,13 @@
#define MRT_RIB_IPV6_UNICAST 4 #define MRT_RIB_IPV6_UNICAST 4
#define MRT_RIB_IPV6_MULTICAST 5 #define MRT_RIB_IPV6_MULTICAST 5
#define MRT_RIB_GENERIC 6 #define MRT_RIB_GENERIC 6
#define MRT_RIB_IPV4_UNICAST_ADDPATH 8 /* Experimental draft-petrie-grow-mrt-add-paths */
#define MRT_RIB_IPV4_MULTICAST_ADDPATH 9 /* Experimental draft-petrie-grow-mrt-add-paths */
#define MRT_RIB_IPV6_UNICAST_ADDPATH 10 /* Experimental draft-petrie-grow-mrt-add-paths */
#define MRT_RIB_IPV6_MULTICAST_ADDPATH 11 /* Experimental draft-petrie-grow-mrt-add-paths */
#define MRT_RIB_GENERIC_ADDPATH 12 /* Experimental draft-petrie-grow-mrt-add-paths */
#define MRT_RIB_NO_ADDPATH 0
#define MRT_RIB_ADDPATH 1
/* MRT BGP4MP Subtypes */ /* MRT BGP4MP Subtypes */
#define MRT_BGP4MP_MESSAGE 1 #define MRT_BGP4MP_MESSAGE 1
@ -72,6 +79,7 @@ struct mrt_rib_entry
{ {
u16 peer_index; u16 peer_index;
u32 originated_time; u32 originated_time;
u32 path_id; /* draft-petrie-grow-mrt-add-paths */
u16 attributes_length; u16 attributes_length;
byte *attributes; /* encoded BGP attributes */ byte *attributes; /* encoded BGP attributes */
}; };
@ -98,7 +106,7 @@ void mrt_peer_index_table_add_peer(struct mrt_peer_index_table *state, u32 peer_
void mrt_peer_index_table_dump(struct mrt_peer_index_table *state, int file_descriptor); void mrt_peer_index_table_dump(struct mrt_peer_index_table *state, int file_descriptor);
void mrt_rib_table_alloc(struct mrt_rib_table *state); void mrt_rib_table_alloc(struct mrt_rib_table *state);
void mrt_rib_table_header(struct mrt_rib_table *state, u32 sequence_number, u8 prefix_length, ip_addr prefix); void mrt_rib_table_header(struct mrt_rib_table *state, u32 sequence_number, u8 prefix_length, ip_addr prefix, uint is_addpath);
void mrt_rib_table_add_entry(struct mrt_rib_table *state, const struct mrt_rib_entry *entry); void mrt_rib_table_add_entry(struct mrt_rib_table *state, const struct mrt_rib_entry *entry);
/* implemented in sysdep */ /* implemented in sysdep */

View File

@ -52,36 +52,26 @@ bgp_mrt_rib_table_dump(struct mrt_table_dump_ctx *state)
mrt_dump_message(fileno(state->rfile->f), MRT_TABLE_DUMP_V2, state->rib_table.subtype, msg, msg_length); mrt_dump_message(fileno(state->rfile->f), MRT_TABLE_DUMP_V2, state->rib_table.subtype, msg, msg_length);
} }
/* static void
* Usage: bgp_mrt_rib_table_entry(struct mrt_table_dump_ctx *state, net *n, uint is_addpath)
* struct mrt_table_dump_ctx ctx;
* bgp_mrt_table_dump_init(rtable, &ctx);
* while (ctx.state != MRT_STATE_COMPLETED)
* bgp_mrt_table_dump_step(&ctx);
*/
void
bgp_mrt_table_dump_step(struct mrt_table_dump_ctx *state)
{ {
if (state->state == MRT_STATE_COMPLETED)
return;
uint max_work_size = 1;
u32 original_rib_sequence_number = state->rib_sequence_number; u32 original_rib_sequence_number = state->rib_sequence_number;
FIB_ITERATE_START(&state->rtable->fib, &state->fit, f) mrt_rib_table_header(&state->rib_table, state->rib_sequence_number++, n->n.pxlen, n->n.prefix, is_addpath);
{
if (!max_work_size--)
{
FIB_ITERATE_PUT(&state->fit, f);
return;
}
net *n = (net *) f;
mrt_rib_table_header(&state->rib_table, state->rib_sequence_number++, n->n.pxlen, n->n.prefix);
rte *e; rte *e;
for (e = n->routes; e; e = e->next) for (e = n->routes; e; e = e->next)
{ {
u32 path_id = 0;
if (is_addpath == MRT_RIB_ADDPATH)
if (e->attrs->src->private_id == 0)
continue;
if (is_addpath == MRT_RIB_NO_ADDPATH)
if (e->attrs->src->private_id != 0)
continue;
struct proto *P = e->attrs->src->proto; struct proto *P = e->attrs->src->proto;
if (!is_route_good_for_table_dump(state, e)) if (!is_route_good_for_table_dump(state, e))
@ -101,22 +91,27 @@ bgp_mrt_table_dump_step(struct mrt_table_dump_ctx *state)
continue; continue;
} }
struct bgp_proto tmp_bgp_proto = { /* Set as4_session=1 to force build AS_PATH as 32bit AS in bgp_encode_attrs() */
.as4_session = 1, /* to force build AS_PATH as 32bit AS in bgp_encode_attrs() */ struct bgp_proto bgp_proto_shallow_copy;
}; memcpy(&bgp_proto_shallow_copy, p, sizeof(bgp_proto_shallow_copy));
bgp_proto_shallow_copy.as4_session = 1;
attributes_length = bgp_encode_attrs(&tmp_bgp_proto, attributes_buffer, e->attrs->eattrs, BGP_ATTR_BUFFER_SIZE); attributes_length = bgp_encode_attrs(&bgp_proto_shallow_copy, attributes_buffer, e->attrs->eattrs, BGP_ATTR_BUFFER_SIZE);
if (attributes_length == -1) if (attributes_length == -1)
{ {
log(L_WARN "%s: MRT Table Dump for %I/%u: Attribute list too long, let it blank", p->p.name, n->n.prefix, n->n.pxlen); log(L_WARN "%s: MRT Table Dump for %I/%u: Attribute list too long, let it blank", p->p.name, n->n.prefix, n->n.pxlen);
attributes_length = 0; attributes_length = 0;
} }
peer_index = p->mrt_peer_index; peer_index = p->mrt_peer_index;
if (is_addpath)
path_id = e->attrs->src->private_id;
} }
struct mrt_rib_entry entry = { struct mrt_rib_entry entry = {
.peer_index = peer_index, .peer_index = peer_index,
.originated_time = (u32) bird_clock_to_unix_timestamp(e->lastmod), .originated_time = (u32) bird_clock_to_unix_timestamp(e->lastmod),
.path_id = path_id,
.attributes_length = attributes_length, .attributes_length = attributes_length,
.attributes = attributes_buffer .attributes = attributes_buffer
}; };
@ -128,6 +123,45 @@ bgp_mrt_table_dump_step(struct mrt_table_dump_ctx *state)
bgp_mrt_rib_table_dump(state); bgp_mrt_rib_table_dump(state);
else else
state->rib_sequence_number = original_rib_sequence_number; state->rib_sequence_number = original_rib_sequence_number;
}
static void
mrt_rib_table_without_addpath(struct mrt_table_dump_ctx *state, net *n)
{
bgp_mrt_rib_table_entry(state, n, MRT_RIB_NO_ADDPATH);
}
static void
mrt_rib_table_with_addpath(struct mrt_table_dump_ctx *state, net *n)
{
bgp_mrt_rib_table_entry(state, n, MRT_RIB_ADDPATH);
}
/*
* Usage:
* struct mrt_table_dump_ctx ctx;
* bgp_mrt_table_dump_init(rtable, &ctx);
* while (ctx.state != MRT_STATE_COMPLETED)
* bgp_mrt_table_dump_step(&ctx);
*/
void
bgp_mrt_table_dump_step(struct mrt_table_dump_ctx *state)
{
if (state->state == MRT_STATE_COMPLETED)
return;
uint max_work_size = 1;
FIB_ITERATE_START(&state->rtable->fib, &state->fit, f)
{
if (!max_work_size--)
{
FIB_ITERATE_PUT(&state->fit, f);
return;
}
mrt_rib_table_without_addpath(state, (net *) f);
mrt_rib_table_with_addpath(state, (net *) f);
} FIB_ITERATE_END(f); } FIB_ITERATE_END(f);
fit_get(&state->rtable->fib, &state->fit); fit_get(&state->rtable->fib, &state->fit);