summaryrefslogtreecommitdiffstats
path: root/pbrd/pbr_nht.c
diff options
context:
space:
mode:
authorDon Slice <dslice@cumulusnetworks.com>2018-03-21 22:23:32 +0100
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-04-06 19:22:43 +0200
commitff9799c31ebff3360706eaaad96c5cd27e3eaef6 (patch)
tree4883563c97c1ab87e012e20651d2677362ff7ec5 /pbrd/pbr_nht.c
parentlib: dont break display of nexthop-groups themselves (diff)
downloadfrr-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.c72
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);