]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Create a new NHE if the mpls labels change
authorStephen Worley <sworley@cumulusnetworks.com>
Tue, 14 May 2019 23:35:13 +0000 (16:35 -0700)
committerStephen Worley <sworley@cumulusnetworks.com>
Fri, 25 Oct 2019 15:13:40 +0000 (11:13 -0400)
We should create a new NHE if the mpls labels change
since we hash on them. This adds the functonality to do that
and decrement the refcnt on the old one.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
zebra/zebra_mpls.c

index 6e0c0b8d88defd5a310be05186c7d99a6427dd38..cbbb02be35d2a11af26101e05910274a26edd547 100644 (file)
@@ -2590,11 +2590,13 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
        struct route_node *rn;
        struct route_entry *re;
        struct nexthop *nexthop;
+       struct nexthop_group new_grp = {};
+       struct nhg_hash_entry *nhe = NULL;
        bool found;
+       afi_t afi = family2afi(prefix->family);
 
        /* Lookup table.  */
-       table = zebra_vrf_table(family2afi(prefix->family), SAFI_UNICAST,
-                               zvrf_id(zvrf));
+       table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf));
        if (!table)
                return -1;
 
@@ -2610,8 +2612,15 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
        if (re == NULL)
                return -1;
 
+       /*
+        * Copy over current nexthops into a temporary group.
+        * We can't just change the values here since we are hashing
+        * on labels. We need to create a whole new group
+        */
+       nexthop_group_copy(&new_grp, re->ng);
+
        found = false;
-       for (nexthop = re->ng->nexthop; nexthop; nexthop = nexthop->next) {
+       for (nexthop = new_grp.nexthop; nexthop; nexthop = nexthop->next) {
                switch (nexthop->type) {
                case NEXTHOP_TYPE_IPV4:
                case NEXTHOP_TYPE_IPV4_IFINDEX:
@@ -2625,7 +2634,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
                                continue;
                        if (!mpls_ftn_update_nexthop(add, nexthop, type,
                                                     out_label))
-                               return 0;
+                               break;
                        found = true;
                        break;
                case NEXTHOP_TYPE_IPV6:
@@ -2640,7 +2649,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
                                continue;
                        if (!mpls_ftn_update_nexthop(add, nexthop, type,
                                                     out_label))
-                               return 0;
+                               break;
                        found = true;
                        break;
                default:
@@ -2648,14 +2657,19 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
                }
        }
 
-       if (!found)
-               return -1;
+       if (found) {
+               nhe = zebra_nhg_rib_find(0, &new_grp, re->vrf_id, afi);
 
-       SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
-       SET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED);
-       rib_queue_add(rn);
+               zebra_nhg_re_update_ref(re, nhe);
 
-       return 0;
+               SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
+               SET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED);
+               rib_queue_add(rn);
+       }
+
+       nexthops_free(new_grp.nexthop);
+
+       return (found ? 0 : -1);
 }
 
 int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
@@ -2889,7 +2903,12 @@ static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
        for (rn = route_top(table); rn; rn = route_next(rn)) {
                update = 0;
                RNODE_FOREACH_RE (rn, re) {
-                       for (nexthop = re->ng->nexthop; nexthop;
+                       struct nexthop_group new_grp = {};
+                       struct nhg_hash_entry *nhe = NULL;
+
+                       nexthop_group_copy(&new_grp, re->ng);
+
+                       for (nexthop = new_grp.nexthop; nexthop;
                             nexthop = nexthop->next) {
                                if (nexthop->nh_label_type != lsp_type)
                                        continue;
@@ -2900,6 +2919,15 @@ static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
                                         ROUTE_ENTRY_LABELS_CHANGED);
                                update = 1;
                        }
+
+                       if (CHECK_FLAG(re->status,
+                                      ROUTE_ENTRY_LABELS_CHANGED)) {
+                               nhe = zebra_nhg_rib_find(0, &new_grp,
+                                                        re->vrf_id, afi);
+                               zebra_nhg_re_update_ref(re, nhe);
+                       }
+
+                       nexthops_free(new_grp.nexthop);
                }
 
                if (update)