}
}
+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.
}
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;
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[] = {
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;
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,
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);
}
}
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);
}
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);
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)
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;
}
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;
}
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 ?
&& (strcmp(nh_group, pbrms->nhgrp_name) == 0)) {
pbrms->nhs_installed = true;
- pbr_map_check(pbrms);
+ pbr_map_check(pbrms, false);
}
if (pbrms->nhg
== 0)) {
pbrms->nhs_installed = true;
- pbr_map_check(pbrms);
+ pbr_map_check(pbrms, false);
}
}
}
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) {
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);
}
}
}
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;
}
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);
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);
}
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)