]> git.proxmox.com Git - mirror_frr.git/commitdiff
pbrd: only remove interface after all seq uninstalled
authorStephen Worley <sworley@cumulusnetworks.com>
Sat, 23 Nov 2019 18:29:38 +0000 (13:29 -0500)
committerStephen Worley <sworley@cumulusnetworks.com>
Mon, 2 Dec 2019 22:22:29 +0000 (17:22 -0500)
Only remove the interface from the pbr_map after we get
a callback from zapi that every sequence using that interface
has been removed.

Before, if we created a map with multiple sequences and put that on an interface,
then removed it from that interface, it would fail to mark the sequences after
the first one as uninstalled.

This was because we failed to lookup the other ones after we removed
the interface from the pbr_map.

This patch adds a conditional to only delete the interface from the pbr
map if all its sequneces using that interface have been uninstalled.

This patch extends the work done in 38e9ccde2f8edd6946d48c80967027d05e64d73f

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
pbrd/pbr_map.c

index 7e34066b47b32861a428030df57e3e74a4dbc483..37b6be694931738dbc069b874725572f9bf860e5 100644 (file)
@@ -100,6 +100,37 @@ static void pbr_map_interface_list_delete(struct pbr_map_interface *pmi)
        }
 }
 
+static bool pbrms_is_installed(const struct pbr_map_sequence *pbrms,
+                              const struct pbr_map_interface *pmi)
+{
+       uint64_t is_installed = (uint64_t)1 << pmi->install_bit;
+
+       is_installed &= pbrms->installed;
+
+       if (is_installed)
+               return true;
+
+       return false;
+}
+
+/* If any sequence is installed on the interface, assume installed */
+static bool
+pbr_map_interface_is_installed(const struct pbr_map *pbrm,
+                              const struct pbr_map_interface *check_pmi)
+{
+
+       struct pbr_map_sequence *pbrms;
+       struct pbr_map_interface *pmi;
+       struct listnode *node, *inode;
+
+       for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms))
+               for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi))
+                       if (pmi == check_pmi && pbrms_is_installed(pbrms, pmi))
+                               return true;
+
+       return false;
+}
+
 static bool pbr_map_interface_is_valid(const struct pbr_map_interface *pmi)
 {
        /* Don't install rules without a real ifindex on the incoming interface.
@@ -171,7 +202,7 @@ void pbr_map_reason_string(unsigned int reason, char *buf, int size)
 void pbr_map_final_interface_deletion(struct pbr_map *pbrm,
                                      struct pbr_map_interface *pmi)
 {
-       if (pmi->delete == true) {
+       if (pmi->delete == true && !pbr_map_interface_is_installed(pbrm, pmi)) {
                listnode_delete(pbrm->incoming, pmi);
                pmi->pbrm = NULL;