diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-01-30 15:31:32 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-01-30 15:52:13 +0100 |
commit | b9f0e5ee2455868d6e9fa730c2b7c0082b0e611e (patch) | |
tree | 5b9da87baa350b40e21853fc2c108a8084868d58 /zebra/zebra_rib.c | |
parent | Merge pull request #3414 from pguibert6WIND/iprule_any_flowspec_handling_2 (diff) | |
download | frr-b9f0e5ee2455868d6e9fa730c2b7c0082b0e611e.tar.xz frr-b9f0e5ee2455868d6e9fa730c2b7c0082b0e611e.zip |
zebra: On route update context is sometimes indeterminate in post-processing
When we get into rib_process_result and the operation we are handling
is DPLANE_OP_ROUTE_UPDATE *and* the route entry being looked at
is a route replace, we currently have no way to decode to the old_re
and the re due to how we have stored context. As such they are the
same pointer.
As such the route replace for the same route type is causing the re
to set the installed flag and then immediately unset the installed
flag, leaving us in a state where the kernel has the route but
the rib thinks we are not installed.
Since the true old_re( the one being replaced by the update operation )
is going away( as that it zebra deletes the old one for us already )
this fix is not optimal but will get us moving forward.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r-- | zebra/zebra_rib.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 1eda55dca..3445136d1 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1933,7 +1933,16 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) UNSET_FLAG(re->status, ROUTE_ENTRY_FAILED); SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); } - if (old_re) { + /* + * On an update operation from the same route type + * context retrieval currently has no way to know + * which was the old and which was the new. + * So don't unset our flags that we just set. + * We know redistribution is ok because the + * old_re in this case is used for nothing + * more than knowing whom to contact if necessary. + */ + if (old_re && old_re != re) { UNSET_FLAG(old_re->status, ROUTE_ENTRY_FAILED); UNSET_FLAG(old_re->status, ROUTE_ENTRY_INSTALLED); |