diff options
author | Neale Ranns <nranns@cisco.com> | 2019-11-08 12:42:31 +0000 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2019-11-26 09:15:11 +0000 |
commit | 9db6ada779794779158163f6293b479ae7f6ad5e (patch) | |
tree | 53dd65975958b2d87b1cd312e612b45d7225e531 /src/vnet/mfib/mfib_table.c | |
parent | 0d3d4824a46205e776ff32c82be4cb514f459a5f (diff) |
fib: Table Replace
Type: feature
from the API doc, a table replace is:
"
The use-case is that, for some unspecified reason, the control plane
has a very different set of entries it wants in the table than VPP
currently has. The CP would thus like to 'replace' VPP's current table
only by specifying what the new set of entries shall be, i.e. it is not
going to delete anything that already eixts.
the CP delcartes the start of this procedure with this begin_replace
API Call, and when it has populated all the entries it wants, it calls
the below end_replace API. From this point on it is of coursce free
to add and delete entries as usual.
The underlying mechanism by which VPP implements this replace is
purposefully left unspecified.
"
In the FIB, the algorithm is implemented using mark and sweep.
Algorithm goes:
1) replace_begin: this marks all the entries in that table as 'stale'
2) download all the entries that should be in this table
- this clears the stale flag on those entries
3) signal the table converged: ip_table_replace_end
- this removes all entries that are still stale
this procedure can be used when an agent first connects to VPP,
as an alternative to dump and diff state reconciliation.
Change-Id: I168edec10cf7670866076b129ebfe6149ea8222e
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/mfib/mfib_table.c')
-rw-r--r-- | src/vnet/mfib/mfib_table.c | 99 |
1 files changed, 97 insertions, 2 deletions
diff --git a/src/vnet/mfib/mfib_table.c b/src/vnet/mfib/mfib_table.c index 504333a2474..a6a82774794 100644 --- a/src/vnet/mfib/mfib_table.c +++ b/src/vnet/mfib/mfib_table.c @@ -24,6 +24,8 @@ #include <vnet/mfib/mfib_entry_cover.h> #include <vnet/mfib/mfib_signal.h> +const static char * mfib_table_flags_strings[] = MFIB_TABLE_ATTRIBUTES; + mfib_table_t * mfib_table_get (fib_node_index_t index, fib_protocol_t proto) @@ -643,7 +645,7 @@ typedef struct mfib_table_flush_ctx_t_ mfib_source_t mftf_source; } mfib_table_flush_ctx_t; -static int +static walk_rc_t mfib_table_flush_cb (fib_node_index_t mfib_entry_index, void *arg) { @@ -653,7 +655,7 @@ mfib_table_flush_cb (fib_node_index_t mfib_entry_index, { vec_add1(ctx->mftf_entries, mfib_entry_index); } - return (1); + return (WALK_CONTINUE); } void @@ -679,6 +681,79 @@ mfib_table_flush (u32 mfib_index, vec_free(ctx.mftf_entries); } +static walk_rc_t +mfib_table_mark_cb (fib_node_index_t fib_entry_index, + void *arg) +{ + mfib_table_flush_ctx_t *ctx = arg; + + if (mfib_entry_is_sourced(fib_entry_index, ctx->mftf_source)) + { + mfib_entry_mark(fib_entry_index, ctx->mftf_source); + } + return (WALK_CONTINUE); +} + +void +mfib_table_mark (u32 fib_index, + fib_protocol_t proto, + mfib_source_t source) +{ + mfib_table_flush_ctx_t ctx = { + .mftf_source = source, + }; + mfib_table_t *mfib_table; + + mfib_table = mfib_table_get(fib_index, proto); + + mfib_table->mft_epoch++; + mfib_table->mft_flags |= MFIB_TABLE_FLAG_RESYNC; + + mfib_table_walk(fib_index, proto, + mfib_table_mark_cb, + &ctx); +} + +static walk_rc_t +mfib_table_sweep_cb (fib_node_index_t fib_entry_index, + void *arg) +{ + mfib_table_flush_ctx_t *ctx = arg; + + if (mfib_entry_is_marked(fib_entry_index, ctx->mftf_source)) + { + vec_add1(ctx->mftf_entries, fib_entry_index); + } + return (WALK_CONTINUE); +} + +void +mfib_table_sweep (u32 fib_index, + fib_protocol_t proto, + mfib_source_t source) +{ + mfib_table_flush_ctx_t ctx = { + .mftf_source = source, + }; + fib_node_index_t *fib_entry_index; + mfib_table_t *mfib_table; + + mfib_table = mfib_table_get(fib_index, proto); + + mfib_table->mft_flags &= ~MFIB_TABLE_FLAG_RESYNC; + + mfib_table_walk(fib_index, proto, + mfib_table_sweep_cb, + &ctx); + + vec_foreach(fib_entry_index, ctx.mftf_entries) + { + mfib_table_entry_delete_index(*fib_entry_index, source); + } + + vec_free(ctx.mftf_entries); +} + static void mfib_table_destroy (mfib_table_t *mfib_table) { @@ -770,6 +845,26 @@ mfib_table_walk (u32 fib_index, } u8* +format_mfib_table_flags (u8 *s, va_list *args) +{ + mfib_table_flags_t flags = va_arg(*args, int); + mfib_table_attribute_t attr; + + if (!flags) + { + return format(s, "none"); + } + + FOR_EACH_MFIB_TABLE_ATTRIBUTE(attr) { + if (1 << attr & flags) { + s = format(s, "%s", mfib_table_flags_strings[attr]); + } + } + + return (s); +} + +u8* format_mfib_table_name (u8* s, va_list *ap) { fib_node_index_t fib_index = va_arg(*ap, fib_node_index_t); |