diff options
Diffstat (limited to 'pbrd/pbr_map.c')
| -rw-r--r-- | pbrd/pbr_map.c | 301 |
1 files changed, 118 insertions, 183 deletions
diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c index 3b058675d7..8e4d52cbcf 100644 --- a/pbrd/pbr_map.c +++ b/pbrd/pbr_map.c @@ -32,7 +32,6 @@ #include "pbr_nht.h" #include "pbr_map.h" -#include "pbr_event.h" #include "pbr_zebra.h" #include "pbr_memory.h" #include "pbr_debug.h" @@ -84,9 +83,20 @@ static int pbr_map_interface_compare(const struct pbr_map_interface *pmi1, return strcmp(pmi1->ifp->name, pmi2->ifp->name); } -static void pbr_map_interface_list_delete(const struct pbr_map_interface *pmi) +static void pbr_map_interface_list_delete(struct pbr_map_interface *pmi) { - pbr_map_policy_delete(pmi->ifp->name); + struct pbr_map_interface *pmi_int; + struct listnode *node, *nnode; + struct pbr_map *pbrm; + + RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) { + for (ALL_LIST_ELEMENTS(pbrm->incoming, node, nnode, pmi_int)) { + if (pmi == pmi_int) { + pbr_map_policy_delete(pbrm, pmi); + return; + } + } + } } static const char *pbr_map_reason_str[] = { @@ -117,26 +127,20 @@ void pbr_map_interface_delete(struct pbr_map *pbrm, struct interface *ifp_del) struct listnode *node; struct pbr_map_interface *pmi; - struct pbr_event *pbre; for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, node, pmi)) { if (ifp_del == pmi->ifp) break; } - if (pmi) { - pmi->delete = true; - - pbre = pbr_event_new(PBR_POLICY_DELETED, pmi->ifp->name); - pbr_event_enqueue(pbre); - } + if (pmi) + pbr_map_policy_delete(pbrm, pmi); } void pbr_map_add_interface(struct pbr_map *pbrm, struct interface *ifp_add) { struct listnode *node; struct pbr_map_interface *pmi; - struct pbr_event *pbre; for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, node, pmi)) { if (ifp_add == pmi->ifp) @@ -148,8 +152,9 @@ void pbr_map_add_interface(struct pbr_map *pbrm, struct interface *ifp_add) pmi->pbrm = pbrm; listnode_add_sort(pbrm->incoming, pmi); - pbre = pbr_event_new(PBR_POLICY_CHANGED, pbrm->name); - pbr_event_enqueue(pbre); + pbr_map_check_valid(pbrm->name); + if (pbrm->valid && !pbrm->installed) + pbr_map_install(pbrm); } void pbr_map_write_interfaces(struct vty *vty, struct interface *ifp) @@ -169,35 +174,21 @@ struct pbr_map *pbrm_find(const char *name) return RB_FIND(pbr_map_entry_head, &pbr_maps, &pbrm); } -extern void pbr_map_delete(const char *name, uint32_t seqno) +extern void pbr_map_delete(struct pbr_map_sequence *pbrms) { struct pbr_map *pbrm; - struct pbr_map_sequence *pbrms; - struct listnode *node, *nnode; - bool uninstall = false; - - pbrm = pbrm_find(name); - - for (ALL_LIST_ELEMENTS(pbrm->seqnumbers, node, nnode, pbrms)) { - if (pbrms->reason & PBR_MAP_DEL_SEQUENCE_NUMBER) { - uninstall = true; - break; - } - } + struct listnode *inode; + struct pbr_map_interface *pmi; - if (uninstall) - pbr_send_pbr_map(pbrm, 0); + pbrm = pbrms->parent; - for (ALL_LIST_ELEMENTS(pbrm->seqnumbers, node, nnode, pbrms)) { - if (!(pbrms->reason & PBR_MAP_DEL_SEQUENCE_NUMBER)) - continue; + for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi)) + pbr_send_pbr_map(pbrms, pmi, false); - if (pbrms->nhg) - pbr_nht_delete_individual_nexthop(pbrms->parent->name, - pbrms->seqno); + if (pbrms->nhg) + pbr_nht_delete_individual_nexthop(pbrms); - listnode_delete(pbrm->seqnumbers, pbrms); - } + listnode_delete(pbrm->seqnumbers, pbrms); if (pbrm->seqnumbers->count == 0) { RB_REMOVE(pbr_map_entry_head, &pbr_maps, pbrm); @@ -205,6 +196,24 @@ extern void pbr_map_delete(const char *name, uint32_t seqno) } } +void pbr_map_delete_nexthop_group(struct pbr_map_sequence *pbrms) +{ + struct pbr_map *pbrm = pbrms->parent; + struct listnode *node; + struct pbr_map_interface *pmi; + + if (pbrm->valid && pbrms->nhs_installed && pbrm->incoming->count) { + for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, node, pmi)) + pbr_send_pbr_map(pbrms, pmi, false); + } + + pbrm->valid = false; + pbrms->nhs_installed = false; + pbrms->installed = false; + pbrms->reason |= PBR_MAP_INVALID_NO_NEXTHOPS; + pbrms->nhgrp_name = NULL; +} + struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique, ifindex_t ifindex) { @@ -232,12 +241,28 @@ struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique, return NULL; } +static void pbr_map_add_interfaces(struct pbr_map *pbrm) +{ + struct interface *ifp; + struct pbr_interface *pbr_ifp; + struct vrf *vrf; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + FOR_ALL_INTERFACES (vrf, ifp) { + if (ifp->info) { + pbr_ifp = ifp->info; + if (strcmp(pbrm->name, pbr_ifp->mapname) == 0) + pbr_map_add_interface(pbrm, ifp); + } + } + } +} + struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno) { struct pbr_map *pbrm; struct pbr_map_sequence *pbrms; struct listnode *node; - struct pbr_event *pbre; pbrm = pbrm_find(name); if (!pbrm) { @@ -258,9 +283,8 @@ struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno) RB_INSERT(pbr_map_entry_head, &pbr_maps, pbrm); - pbre = pbr_event_new(PBR_MAP_ADD, name); - } else - pbre = NULL; + pbr_map_add_interfaces(pbrm); + } for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) { if (pbrms->seqno == seqno) @@ -284,9 +308,6 @@ struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno) pbrm->installed = false; } - if (pbre) - pbr_event_enqueue(pbre); - return pbrms; } @@ -375,7 +396,6 @@ bool pbr_map_check_valid(const char *name) void pbr_map_schedule_policy_from_nhg(const char *nh_group) { struct pbr_map_sequence *pbrms; - struct pbr_event *pbre; struct pbr_map *pbrm; struct listnode *node; @@ -390,11 +410,7 @@ void pbr_map_schedule_policy_from_nhg(const char *nh_group) && (strcmp(nh_group, pbrms->nhgrp_name) == 0)) { pbrms->nhs_installed = true; - pbre = pbr_event_new(PBR_MAP_MODIFY, - pbrm->name); - pbre->seqno = pbrms->seqno; - - pbr_event_enqueue(pbre); + pbr_map_check(pbrms); } if (pbrms->nhg @@ -402,11 +418,7 @@ void pbr_map_schedule_policy_from_nhg(const char *nh_group) == 0)) { pbrms->nhs_installed = true; - pbre = pbr_event_new(PBR_MAP_MODIFY, - pbrm->name); - pbre->seqno = pbrms->seqno; - - pbr_event_enqueue(pbre); + pbr_map_check(pbrms); } } } @@ -416,49 +428,41 @@ void pbr_map_policy_install(const char *name) { struct pbr_map_sequence *pbrms; struct pbr_map *pbrm; - struct listnode *node; - bool install; + struct listnode *node, *inode; + struct pbr_map_interface *pmi; DEBUGD(&pbr_dbg_map, "%s: for %s", __PRETTY_FUNCTION__, name); pbrm = pbrm_find(name); if (!pbrm) return; - install = true; 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); - if (!pbrm->valid || !pbrms->nhs_installed) - install = false; - } - if (install && pbrm->incoming->count) { - DEBUGD(&pbr_dbg_map, "\tInstalling"); - pbr_send_pbr_map(pbrm, true); + if (pbrm->valid && pbrms->nhs_installed && pbrm->incoming->count) { + DEBUGD(&pbr_dbg_map, "\tInstalling %s %u", + pbrm->name, pbrms->seqno); + for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi)) + pbr_send_pbr_map(pbrms, pmi, true); + } } } -void pbr_map_policy_delete(const char *ifname) +void pbr_map_policy_delete(struct pbr_map *pbrm, struct pbr_map_interface *pmi) { - struct listnode *node, *nnode; - struct pbr_map_interface *pmi; - struct pbr_map *pbrm; + struct listnode *node; + struct pbr_map_sequence *pbrms; - RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) { - for (ALL_LIST_ELEMENTS(pbrm->incoming, node, nnode, pmi)) { - DEBUGD(&pbr_dbg_map, "Comparing %s to %s %d", - pmi->ifp->name, ifname, pmi->delete); - if (strcmp(ifname, pmi->ifp->name) != 0) - continue; - pbr_send_pbr_map(pbrm, false); - listnode_delete(pbrm->incoming, pmi); - pmi->pbrm = NULL; - XFREE(MTYPE_PBR_MAP_INTERFACE, pmi); - } - } + for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) + pbr_send_pbr_map(pbrms, pmi, false); + + listnode_delete(pbrm->incoming, pmi); + pmi->pbrm = NULL; + XFREE(MTYPE_PBR_MAP_INTERFACE, pmi); } /* @@ -490,133 +494,64 @@ void pbr_map_check_nh_group_change(const char *nh_group) pbr_map_check_valid_internal(pbrm); - if (original != pbrm->valid) { - struct pbr_event *pbre; - - pbre = pbr_event_new(PBR_MAP_INSTALL, - pbrm->name); - pbr_event_enqueue(pbre); - } + if (original != pbrm->valid) + pbr_map_install(pbrm); break; } } } } -void pbr_map_check(const char *name, uint32_t seqno) +void pbr_map_check(struct pbr_map_sequence *pbrms) { - struct pbr_map_sequence *pbrms; - struct listnode *node; struct pbr_map *pbrm; + struct listnode *inode; + struct pbr_map_interface *pmi; + bool install; - DEBUGD(&pbr_dbg_map, "%s: for %s(%u)", __PRETTY_FUNCTION__, name, - seqno); - if (pbr_map_check_valid(name)) - DEBUGD(&pbr_dbg_map, "We are totally valid %s\n", name); - - pbrm = pbrm_find(name); - if (!pbrm) - return; + pbrm = pbrms->parent; + DEBUGD(&pbr_dbg_map, "%s: for %s(%u)", __PRETTY_FUNCTION__, + pbrm->name, pbrms->seqno); + if (pbr_map_check_valid(pbrm->name)) + DEBUGD(&pbr_dbg_map, "We are totally valid %s\n", + pbrm->name); - for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) { - if (seqno != pbrms->seqno) - continue; + DEBUGD(&pbr_dbg_map, "%s: Installing %s(%u) reason: %" PRIu64, + __PRETTY_FUNCTION__, pbrm->name, pbrms->seqno, pbrms->reason); + if (pbrms->reason == PBR_MAP_VALID_SEQUENCE_NUMBER) { + install = true; DEBUGD(&pbr_dbg_map, "%s: Installing %s(%u) reason: %" PRIu64, - __PRETTY_FUNCTION__, name, seqno, pbrms->reason); - - if (pbrms->reason == PBR_MAP_VALID_SEQUENCE_NUMBER) { - struct pbr_event *pbre; - - DEBUGD(&pbr_dbg_map, - "%s: Installing %s(%u) reason: %" PRIu64, - __PRETTY_FUNCTION__, name, seqno, pbrms->reason); - DEBUGD(&pbr_dbg_map, - "\tSending PBR_MAP_POLICY_INSTALL event"); - - pbre = pbr_event_new(PBR_MAP_POLICY_INSTALL, - pbrm->name); - pbre->event = PBR_MAP_POLICY_INSTALL; - strcpy(pbre->name, pbrm->name); - - pbr_event_enqueue(pbre); - - break; - } else { - DEBUGD(&pbr_dbg_map, - "%s: Removing %s(%u) reason: %" PRIu64, - __PRETTY_FUNCTION__, name, seqno, pbrms->reason); - pbr_send_pbr_map(pbrm, false); - break; - } - } -} - -void pbr_map_install(const char *name) -{ - struct pbr_map *pbrm; - - pbrm = pbrm_find(name); - if (!pbrm) { + __PRETTY_FUNCTION__, pbrm->name, pbrms->seqno, + pbrms->reason); DEBUGD(&pbr_dbg_map, - "%s: Specified PBR-MAP(%s) does not exist?", - __PRETTY_FUNCTION__, name); - return; - } - - if (!pbrm->incoming->count) - return; - - pbr_send_pbr_map(pbrm, true); - pbrm->installed = true; -} - -void pbr_map_add_interfaces(const char *name) -{ - struct pbr_map *pbrm; - struct interface *ifp; - struct pbr_interface *pbr_ifp; - struct vrf *vrf; - - pbrm = pbrm_find(name); - if (!pbrm) { + "\tSending PBR_MAP_POLICY_INSTALL event"); + } else { + install = false; DEBUGD(&pbr_dbg_map, - "%s: Specified PBR-MAP(%s) does not exist?", - __PRETTY_FUNCTION__, name); - return; + "%s: Removing %s(%u) reason: %" PRIu64, + __PRETTY_FUNCTION__, pbrm->name, + pbrms->seqno, pbrms->reason); } - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - FOR_ALL_INTERFACES (vrf, ifp) { - if (ifp->info) { - pbr_ifp = ifp->info; - if (strcmp(name, pbr_ifp->mapname) == 0) - pbr_map_add_interface(pbrm, ifp); - } - } - } + for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi)) + pbr_send_pbr_map(pbrms, pmi, install); } -void pbr_map_check_policy_change(const char *name) +void pbr_map_install(struct pbr_map *pbrm) { - struct pbr_map *pbrm; + struct listnode *node, *inode; + struct pbr_map_sequence *pbrms; + struct pbr_map_interface *pmi; - pbrm = pbrm_find(name); - if (!pbrm) { - DEBUGD(&pbr_dbg_map, - "%s: Specified PBR-MAP(%s) does not exist?", - __PRETTY_FUNCTION__, name); + if (!pbrm->incoming->count) return; - } - - pbr_map_check_valid(name); - if (pbrm->valid && !pbrm->installed) { - struct pbr_event *pbre; - pbre = pbr_event_new(PBR_MAP_INSTALL, name); + for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) + for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi)) + pbr_send_pbr_map(pbrms, pmi, true); - pbr_event_enqueue(pbre); - } + pbrm->installed = true; } void pbr_map_init(void) |
