diff options
author | Don Slice <dslice@cumulusnetworks.com> | 2018-03-21 22:23:32 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-04-06 19:22:43 +0200 |
commit | ff9799c31ebff3360706eaaad96c5cd27e3eaef6 (patch) | |
tree | 4883563c97c1ab87e012e20651d2677362ff7ec5 /pbrd/pbr_nht.c | |
parent | lib: dont break display of nexthop-groups themselves (diff) | |
download | frr-ff9799c31ebff3360706eaaad96c5cd27e3eaef6.tar.xz frr-ff9799c31ebff3360706eaaad96c5cd27e3eaef6.zip |
pbrd: add ability to delete routes and rules correctly
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Diffstat (limited to 'pbrd/pbr_nht.c')
-rw-r--r-- | pbrd/pbr_nht.c | 72 |
1 files changed, 46 insertions, 26 deletions
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index c8a58e46f..1ce8c2104 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -47,6 +47,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. @@ -253,6 +257,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)); @@ -271,18 +276,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); } @@ -337,7 +346,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; @@ -345,27 +355,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", @@ -383,20 +398,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); |