]> git.proxmox.com Git - mirror_frr.git/blobdiff - pbrd/pbr_map.c
Merge pull request #6147 from opensourcerouting/ldpd-broken-lsps
[mirror_frr.git] / pbrd / pbr_map.c
index 7e34066b47b32861a428030df57e3e74a4dbc483..7928b8e2e739e26978d74d4e8b03914aee911ead 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.
@@ -114,7 +145,7 @@ static bool pbr_map_interface_is_valid(const struct pbr_map_interface *pmi)
 }
 
 static void pbr_map_pbrms_update_common(struct pbr_map_sequence *pbrms,
-                                       bool install)
+                                       bool install, bool changed)
 {
        struct pbr_map *pbrm;
        struct listnode *node;
@@ -130,19 +161,19 @@ static void pbr_map_pbrms_update_common(struct pbr_map_sequence *pbrms,
                        if (install && !pbr_map_interface_is_valid(pmi))
                                continue;
 
-                       pbr_send_pbr_map(pbrms, pmi, install);
+                       pbr_send_pbr_map(pbrms, pmi, install, changed);
                }
        }
 }
 
-static void pbr_map_pbrms_install(struct pbr_map_sequence *pbrms)
+static void pbr_map_pbrms_install(struct pbr_map_sequence *pbrms, bool changed)
 {
-       pbr_map_pbrms_update_common(pbrms, true);
+       pbr_map_pbrms_update_common(pbrms, true, changed);
 }
 
 static void pbr_map_pbrms_uninstall(struct pbr_map_sequence *pbrms)
 {
-       pbr_map_pbrms_update_common(pbrms, false);
+       pbr_map_pbrms_update_common(pbrms, false, false);
 }
 
 static const char *const pbr_map_reason_str[] = {
@@ -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 && !pbr_map_interface_is_installed(pbrm, pmi)) {
                listnode_delete(pbrm->incoming, pmi);
                pmi->pbrm = NULL;
 
@@ -261,7 +292,7 @@ void pbr_map_policy_interface_update(const struct interface *ifp, bool state_up)
        for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms))
                for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi))
                        if (pmi->ifp == ifp && pbr_map_interface_is_valid(pmi))
-                               pbr_send_pbr_map(pbrms, pmi, state_up);
+                               pbr_send_pbr_map(pbrms, pmi, state_up, false);
 }
 
 static void pbrms_vrf_update(struct pbr_map_sequence *pbrms,
@@ -275,7 +306,7 @@ static void pbrms_vrf_update(struct pbr_map_sequence *pbrms,
                DEBUGD(&pbr_dbg_map, "\tSeq %u uses vrf %s (%u), updating map",
                       pbrms->seqno, vrf_name, pbr_vrf_id(pbr_vrf));
 
-               pbr_map_check(pbrms);
+               pbr_map_check(pbrms, false);
        }
 }
 
@@ -296,8 +327,7 @@ void pbr_map_vrf_update(const struct pbr_vrf *pbr_vrf)
               enabled ? "enabled" : "disabled");
 
        RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) {
-               DEBUGD(&pbr_dbg_map, "%s: Looking at %s", __PRETTY_FUNCTION__,
-                      pbrm->name);
+               DEBUGD(&pbr_dbg_map, "%s: Looking at %s", __func__, pbrm->name);
                for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms))
                        pbrms_vrf_update(pbrms, pbr_vrf);
        }
@@ -330,7 +360,7 @@ extern void pbr_map_delete(struct pbr_map_sequence *pbrms)
        pbrm = pbrms->parent;
 
        for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi))
-               pbr_send_pbr_map(pbrms, pmi, false);
+               pbr_send_pbr_map(pbrms, pmi, false, false);
 
        if (pbrms->nhg)
                pbr_nht_delete_individual_nexthop(pbrms);
@@ -354,7 +384,7 @@ static void pbr_map_delete_common(struct pbr_map_sequence *pbrms)
        pbrm->valid = false;
        pbrms->nhs_installed = false;
        pbrms->reason |= PBR_MAP_INVALID_NO_NEXTHOPS;
-       pbrms->nhgrp_name = NULL;
+       XFREE(MTYPE_TMP, pbrms->nhgrp_name);
 }
 
 void pbr_map_delete_nexthops(struct pbr_map_sequence *pbrms)
@@ -386,8 +416,7 @@ struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique, ifindex_t ifindex,
                        for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, snode,
                                                  pbrms)) {
                                DEBUGD(&pbr_dbg_map, "%s: Comparing %u to %u",
-                                      __PRETTY_FUNCTION__, pbrms->unique,
-                                      unique);
+                                      __func__, pbrms->unique, unique);
                                if (pbrms->unique == unique)
                                        return pbrms;
                        }
@@ -564,8 +593,8 @@ bool pbr_map_check_valid(const char *name)
        pbrm = pbrm_find(name);
        if (!pbrm) {
                DEBUGD(&pbr_dbg_map,
-                      "%s: Specified PBR-MAP(%s) does not exist?",
-                      __PRETTY_FUNCTION__, name);
+                      "%s: Specified PBR-MAP(%s) does not exist?", __func__,
+                      name);
                return false;
        }
 
@@ -580,8 +609,7 @@ void pbr_map_schedule_policy_from_nhg(const char *nh_group)
        struct listnode *node;
 
        RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) {
-               DEBUGD(&pbr_dbg_map, "%s: Looking at %s", __PRETTY_FUNCTION__,
-                      pbrm->name);
+               DEBUGD(&pbr_dbg_map, "%s: Looking at %s", __func__, pbrm->name);
                for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) {
                        DEBUGD(&pbr_dbg_map, "\tNH Grp name: %s",
                               pbrms->nhgrp_name ?
@@ -591,7 +619,7 @@ void pbr_map_schedule_policy_from_nhg(const char *nh_group)
                            && (strcmp(nh_group, pbrms->nhgrp_name) == 0)) {
                                pbrms->nhs_installed = true;
 
-                               pbr_map_check(pbrms);
+                               pbr_map_check(pbrms, false);
                        }
 
                        if (pbrms->nhg
@@ -599,7 +627,7 @@ void pbr_map_schedule_policy_from_nhg(const char *nh_group)
                                == 0)) {
                                pbrms->nhs_installed = true;
 
-                               pbr_map_check(pbrms);
+                               pbr_map_check(pbrms, false);
                        }
                }
        }
@@ -612,16 +640,15 @@ void pbr_map_policy_install(const char *name)
        struct listnode *node, *inode;
        struct pbr_map_interface *pmi;
 
-       DEBUGD(&pbr_dbg_map, "%s: for %s", __PRETTY_FUNCTION__, name);
+       DEBUGD(&pbr_dbg_map, "%s: for %s", __func__, name);
        pbrm = pbrm_find(name);
        if (!pbrm)
                return;
 
        for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) {
                DEBUGD(&pbr_dbg_map,
-                      "%s: Looking at what to install %s(%u) %d %d",
-                      __PRETTY_FUNCTION__, name, pbrms->seqno, pbrm->valid,
-                      pbrms->nhs_installed);
+                      "%s: Looking at what to install %s(%u) %d %d", __func__,
+                      name, pbrms->seqno, pbrm->valid, pbrms->nhs_installed);
 
                if (pbrm->valid && pbrms->nhs_installed
                    && pbrm->incoming->count) {
@@ -629,7 +656,8 @@ void pbr_map_policy_install(const char *name)
                               pbrms->seqno);
                        for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi))
                                if (pbr_map_interface_is_valid(pmi))
-                                       pbr_send_pbr_map(pbrms, pmi, true);
+                                       pbr_send_pbr_map(pbrms, pmi, true,
+                                                        false);
                }
        }
 }
@@ -641,7 +669,7 @@ void pbr_map_policy_delete(struct pbr_map *pbrm, struct pbr_map_interface *pmi)
 
 
        for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms))
-               pbr_send_pbr_map(pbrms, pmi, false);
+               pbr_send_pbr_map(pbrms, pmi, false, false);
 
        pmi->delete = true;
 }
@@ -683,20 +711,20 @@ void pbr_map_check_nh_group_change(const char *nh_group)
                                                     pbrm->incoming, inode,
                                                     pmi))
                                                pbr_send_pbr_map(pbrms, pmi,
-                                                                false);
+                                                                false, false);
                        }
                }
        }
 }
 
-void pbr_map_check(struct pbr_map_sequence *pbrms)
+void pbr_map_check(struct pbr_map_sequence *pbrms, bool changed)
 {
        struct pbr_map *pbrm;
        bool install;
 
        pbrm = pbrms->parent;
-       DEBUGD(&pbr_dbg_map, "%s: for %s(%u)", __PRETTY_FUNCTION__,
-              pbrm->name, pbrms->seqno);
+       DEBUGD(&pbr_dbg_map, "%s: for %s(%u)", __func__, pbrm->name,
+              pbrms->seqno);
        if (pbr_map_check_valid(pbrm->name))
                DEBUGD(&pbr_dbg_map, "We are totally valid %s",
                       pbrm->name);
@@ -704,20 +732,17 @@ void pbr_map_check(struct pbr_map_sequence *pbrms)
        if (pbrms->reason == PBR_MAP_VALID_SEQUENCE_NUMBER) {
                install = true;
                DEBUGD(&pbr_dbg_map, "%s: Installing %s(%u) reason: %" PRIu64,
-                      __PRETTY_FUNCTION__, pbrm->name, pbrms->seqno,
-                      pbrms->reason);
+                      __func__, pbrm->name, pbrms->seqno, pbrms->reason);
                DEBUGD(&pbr_dbg_map,
                       "\tSending PBR_MAP_POLICY_INSTALL event");
        } else {
                install = false;
-               DEBUGD(&pbr_dbg_map,
-                      "%s: Removing %s(%u) reason: %" PRIu64,
-                      __PRETTY_FUNCTION__, pbrm->name,
-                      pbrms->seqno, pbrms->reason);
+               DEBUGD(&pbr_dbg_map, "%s: Removing %s(%u) reason: %" PRIu64,
+                      __func__, pbrm->name, pbrms->seqno, pbrms->reason);
        }
 
        if (install)
-               pbr_map_pbrms_install(pbrms);
+               pbr_map_pbrms_install(pbrms, changed);
        else
                pbr_map_pbrms_uninstall(pbrms);
 }
@@ -731,7 +756,7 @@ void pbr_map_install(struct pbr_map *pbrm)
                return;
 
        for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms))
-               pbr_map_pbrms_install(pbrms);
+               pbr_map_pbrms_install(pbrms, false);
 }
 
 void pbr_map_init(void)