fib: Fix crash when removing a covering prefix

Type: fix

When a covering entry is removed from the table, the covered entries first see it 'updated' and then 'removed'.
the crash occurs because the covered prefixes share (simple pointer copy) the covereds hash table of path extensions. During the cervers deletion this hash table has been removed and the update of the covered crashes when recaluationg forwarding becuase it uses the free'd hash.
Fix is to refetch the shared hash table (which is NULL) when the covered is updated.

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: Icefca9d7b21da975111d0e974d75f663fc0cc00c
diff --git a/src/vnet/mfib/mfib_entry_src_rr.c b/src/vnet/mfib/mfib_entry_src_rr.c
index a6a1e0d..5f697a5 100644
--- a/src/vnet/mfib/mfib_entry_src_rr.c
+++ b/src/vnet/mfib/mfib_entry_src_rr.c
@@ -20,8 +20,8 @@
 #include <vnet/fib/fib_path_list.h>
 
 static void
-mfib_entry_src_rr_deactiviate (mfib_entry_t *mfib_entry,
-                               mfib_entry_src_t *msrc)
+mfib_entry_src_rr_deactivate (mfib_entry_t *mfib_entry,
+                              mfib_entry_src_t *msrc)
 {
     mfib_entry_t *cover;
 
@@ -42,8 +42,8 @@
 }
 
 static void
-mfib_entry_src_rr_activiate (mfib_entry_t *mfib_entry,
-                             mfib_entry_src_t *msrc)
+mfib_entry_src_rr_activate (mfib_entry_t *mfib_entry,
+                            mfib_entry_src_t *msrc)
 {
     mfib_entry_src_t *csrc;
     mfib_entry_t *cover;
@@ -72,8 +72,8 @@
 mfib_entry_src_rr_cover_change (mfib_entry_t *mfib_entry,
                                 mfib_entry_src_t *msrc)
 {
-    mfib_entry_src_rr_deactiviate(mfib_entry, msrc);
-    mfib_entry_src_rr_activiate(mfib_entry, msrc);
+    mfib_entry_src_rr_deactivate(mfib_entry, msrc);
+    mfib_entry_src_rr_activate(mfib_entry, msrc);
 
     return (MFIB_SRC_REEVALUATE);
 }
@@ -87,6 +87,7 @@
      * so there's no need to check for a new one. but we do need to
      * copy down any new flags and input interfaces
      */
+    mfib_entry_src_t *csrc;
     mfib_entry_t *cover;
 
     cover = mfib_entry_get(msrc->mfes_cover);
@@ -95,6 +96,13 @@
     msrc->mfes_itfs = cover->mfe_itfs;
     msrc->mfes_rpf_id = cover->mfe_rpf_id;
 
+    /* The update to the cover could have removed the extensions.
+     * When a cover is removed from the table, the covereds see it first
+     * updated (to have no forwarding) and then changed
+     */
+    csrc = mfib_entry_get_best_src(cover);
+    msrc->mfes_exts = (csrc ? csrc->mfes_exts : NULL);
+
     return (MFIB_SRC_REEVALUATE);
 }
 
@@ -102,8 +110,8 @@
 mfib_entry_src_rr_module_init (void)
 {
     mfib_entry_src_vft mvft = {
-        .mev_activate = mfib_entry_src_rr_activiate,
-        .mev_deactivate = mfib_entry_src_rr_deactiviate,
+        .mev_activate = mfib_entry_src_rr_activate,
+        .mev_deactivate = mfib_entry_src_rr_deactivate,
         .mev_cover_change = mfib_entry_src_rr_cover_change,
         .mev_cover_update = mfib_entry_src_rr_cover_update,
     };