]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pbrd: add ability to delete routes and rules correctly
authorDon Slice <dslice@cumulusnetworks.com>
Wed, 21 Mar 2018 21:23:32 +0000 (21:23 +0000)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 6 Apr 2018 17:22:43 +0000 (13:22 -0400)
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
pbrd/pbr_map.c
pbrd/pbr_nht.c

index f3ecc5882a7edef7a777ec127d99270daee0dd05..ea79320a712501a12bbd9adc61d3667b383366f6 100644 (file)
@@ -476,10 +476,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;
@@ -495,9 +495,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);
                        }
                }
        }
index c8a58e46f5af03fb83285a56fe0bb2222ba31098..1ce8c2104d249a9221d579f0f524ac9210b5e432 100644 (file)
@@ -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);