From 52a7c7a8bd439e481d6dc323bb193b2f0ba67259 Mon Sep 17 00:00:00 2001 From: Don Slice Date: Wed, 21 Mar 2018 21:23:32 +0000 Subject: [PATCH] pbrd: add ability to delete routes and rules correctly Signed-off-by: Don Slice --- pbrd/pbr_map.c | 14 +++++++--- pbrd/pbr_nht.c | 72 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c index dee06fc0124b..de6b5c73aec7 100644 --- a/pbrd/pbr_map.c +++ b/pbrd/pbr_map.c @@ -477,10 +477,10 @@ void pbr_map_check_nh_group_change(const char *nh_group) { struct pbr_map_sequence *pbrms; struct pbr_map *pbrm; - struct listnode *node; + struct listnode *node, *inode; + struct pbr_map_interface *pmi; bool found_name; - zlog_warn("*** %s for %s ***", __func__, nh_group); RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) { for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) { found_name = false; @@ -496,9 +496,15 @@ void pbr_map_check_nh_group_change(const char *nh_group) pbr_map_check_valid_internal(pbrm); - if (original != pbrm->valid) + if (pbrm->valid && (original != pbrm->valid)) pbr_map_install(pbrm); - break; + + if (pbrm->valid == false) + for (ALL_LIST_ELEMENTS_RO( + pbrm->incoming, inode, + pmi)) + pbr_send_pbr_map(pbrms, pmi, + false); } } } diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index fb79e94b29c4..38c56ff6bbdb 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -49,6 +49,10 @@ static bool nhg_tableid[65535]; static void pbr_nht_install_nexthop_group(struct pbr_nexthop_group_cache *pnhgc, struct nexthop_group nhg); +static void +pbr_nht_uninstall_nexthop_group(struct pbr_nexthop_group_cache *pnhgc, + struct nexthop_group nhg, + enum nexthop_types_t nh_afi); /* * Nexthop refcount. @@ -255,6 +259,7 @@ void pbr_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc, struct pbr_nexthop_group_cache *pnhgc; struct pbr_nexthop_cache pnhc_find = {}; struct pbr_nexthop_cache *pnhc; + enum nexthop_types_t nh_afi = nhop->type; /* find pnhgc by name */ strlcpy(pnhgc_find.name, nhgc->name, sizeof(pnhgc_find.name)); @@ -273,18 +278,22 @@ void pbr_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc, __PRETTY_FUNCTION__, debugstr, nhgc->name); } - pbr_nht_install_nexthop_group(pnhgc, nhgc->nhg); + if (pnhgc->nhh->count) + pbr_nht_install_nexthop_group(pnhgc, nhgc->nhg); + else + pbr_nht_uninstall_nexthop_group(pnhgc, nhgc->nhg, nh_afi); + pbr_map_check_nh_group_change(nhgc->name); } void pbr_nhgroup_delete_cb(const char *name) { - /* delete group from all pbrms's */ - pbr_nht_delete_group(name); - DEBUGD(&pbr_dbg_nht, "%s: Removed nexthop-group %s", __PRETTY_FUNCTION__, name); + /* delete group from all pbrms's */ + pbr_nht_delete_group(name); + pbr_map_check_nh_group_change(name); } @@ -339,7 +348,8 @@ void pbr_nht_route_removed_for_table(uint32_t table_id) * - AFI of last nexthop in the group * - AFI_MAX on error */ -static afi_t pbr_nht_which_afi(struct nexthop_group nhg) +static afi_t pbr_nht_which_afi(struct nexthop_group nhg, + enum nexthop_types_t nh_afi) { struct nexthop *nexthop; afi_t install_afi = AFI_MAX; @@ -347,27 +357,32 @@ static afi_t pbr_nht_which_afi(struct nexthop_group nhg) v6 = v4 = bh = false; - for (ALL_NEXTHOPS(nhg, nexthop)) { - switch (nexthop->type) { - case NEXTHOP_TYPE_IFINDEX: - break; - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - v6 = true; - install_afi = AFI_IP; - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - v4 = true; - install_afi = AFI_IP6; - break; - case NEXTHOP_TYPE_BLACKHOLE: - bh = true; - install_afi = AFI_MAX; + if (!nh_afi) { + for (ALL_NEXTHOPS(nhg, nexthop)) { + nh_afi = nexthop->type; break; } } + switch (nh_afi) { + case NEXTHOP_TYPE_IFINDEX: + break; + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + v6 = true; + install_afi = AFI_IP; + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + v4 = true; + install_afi = AFI_IP6; + break; + case NEXTHOP_TYPE_BLACKHOLE: + bh = true; + install_afi = AFI_MAX; + break; + } + if (!bh && v6 && v4) DEBUGD(&pbr_dbg_nht, "%s: Saw both V6 and V4 nexthops...using %s", @@ -385,20 +400,23 @@ static void pbr_nht_install_nexthop_group(struct pbr_nexthop_group_cache *pnhgc, struct nexthop_group nhg) { afi_t install_afi; + enum nexthop_types_t nh_afi = 0; - install_afi = pbr_nht_which_afi(nhg); + install_afi = pbr_nht_which_afi(nhg, nh_afi); pnhgc->installed = false; + route_add(pnhgc, nhg, install_afi); } static void pbr_nht_uninstall_nexthop_group(struct pbr_nexthop_group_cache *pnhgc, - struct nexthop_group nhg) + struct nexthop_group nhg, + enum nexthop_types_t nh_afi) { afi_t install_afi; - install_afi = pbr_nht_which_afi(nhg); + install_afi = pbr_nht_which_afi(nhg, nh_afi); pnhgc->installed = false; pnhgc->valid = false; @@ -477,6 +495,7 @@ void pbr_nht_delete_individual_nexthop(struct pbr_map_sequence *pbrms) struct listnode *node; struct pbr_map_interface *pmi; struct nexthop *nh; + enum nexthop_types_t nh_afi = 0; if (pbrm->valid && pbrms->nhs_installed && pbrm->incoming->count) { for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, node, pmi)) @@ -493,12 +512,13 @@ void pbr_nht_delete_individual_nexthop(struct pbr_map_sequence *pbrms) pnhgc = hash_lookup(pbr_nhg_hash, &find); nh = pbrms->nhg->nexthop; + nh_afi = nh->type; lup.nexthop = nh; pnhc = hash_lookup(pnhgc->nhh, &lup); pnhc->parent = NULL; hash_release(pnhgc->nhh, pnhc); pbr_nh_delete(&pnhc); - pbr_nht_uninstall_nexthop_group(pnhgc, *pbrms->nhg); + pbr_nht_uninstall_nexthop_group(pnhgc, *pbrms->nhg, nh_afi); hash_release(pbr_nhg_hash, pnhgc);