summaryrefslogtreecommitdiffstats
path: root/pbrd
diff options
context:
space:
mode:
authorJafar Al-Gharaibeh <Jafaral@users.noreply.github.com>2019-12-07 00:49:56 +0100
committerGitHub <noreply@github.com>2019-12-07 00:49:56 +0100
commit5bc47da6b55e14f997e232a9b5d6771c7407a0c0 (patch)
treef23bf34e3900212db78e10f47eb14418741dde10 /pbrd
parentMerge pull request #5355 from AnuradhaKaruppiah/pim-state-machine-fixes (diff)
parentpbrd: only remove interface after all seq uninstalled (diff)
downloadfrr-5bc47da6b55e14f997e232a9b5d6771c7407a0c0.tar.xz
frr-5bc47da6b55e14f997e232a9b5d6771c7407a0c0.zip
Merge pull request #5421 from sworleys/PBR-Del-Mark-All-Seq
pbrd: only remove interface after all seq uninstalled
Diffstat (limited to 'pbrd')
-rw-r--r--pbrd/pbr_map.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c
index 7e34066b4..37b6be694 100644
--- a/pbrd/pbr_map.c
+++ b/pbrd/pbr_map.c
@@ -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;