]> git.puffer.fish Git - matthieu/frr.git/commitdiff
staticd: track nexthops per-SAFI
authorDavid Lamparter <equinox@opensourcerouting.org>
Mon, 4 Oct 2021 11:05:18 +0000 (13:05 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Sun, 27 Mar 2022 12:57:22 +0000 (14:57 +0200)
This stops intermixing SAFI_UNICAST NHT into SAFI_MULTICAST static
routes.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
staticd/static_nht.c
staticd/static_nht.h
staticd/static_zebra.c

index e1d6ba15d16c645a80bbaa5b00d63e3f83b2c37a..1d87a83c9169240dc6f124e5cf1acb08be6647d3 100644 (file)
@@ -101,18 +101,15 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
        }
 }
 
-void static_nht_update(struct prefix *sp, struct prefix *nhp,
-                      uint32_t nh_num, afi_t afi, vrf_id_t nh_vrf_id)
+void static_nht_update(struct prefix *sp, struct prefix *nhp, uint32_t nh_num,
+                      afi_t afi, safi_t safi, vrf_id_t nh_vrf_id)
 {
 
        struct vrf *vrf;
 
-       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
-               static_nht_update_safi(sp, nhp, nh_num, afi, SAFI_UNICAST,
-                                      vrf, nh_vrf_id);
-               static_nht_update_safi(sp, nhp, nh_num, afi, SAFI_MULTICAST,
-                                      vrf, nh_vrf_id);
-       }
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+               static_nht_update_safi(sp, nhp, nh_num, afi, safi, vrf,
+                                      nh_vrf_id);
 }
 
 static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
@@ -166,16 +163,13 @@ static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
        }
 }
 
-void static_nht_reset_start(struct prefix *nhp, afi_t afi, vrf_id_t nh_vrf_id)
+void static_nht_reset_start(struct prefix *nhp, afi_t afi, safi_t safi,
+                           vrf_id_t nh_vrf_id)
 {
        struct vrf *vrf;
 
-       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
-               static_nht_reset_start_safi(nhp, afi, SAFI_UNICAST,
-                                           vrf, nh_vrf_id);
-               static_nht_reset_start_safi(nhp, afi, SAFI_MULTICAST,
-                                           vrf, nh_vrf_id);
-       }
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+               static_nht_reset_start_safi(nhp, afi, safi, vrf, nh_vrf_id);
 }
 
 static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi,
@@ -212,7 +206,7 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi,
        route_unlock_node(rn);
 }
 
-void static_nht_mark_state(struct prefix *sp, vrf_id_t vrf_id,
+void static_nht_mark_state(struct prefix *sp, safi_t safi, vrf_id_t vrf_id,
                           enum static_install_states state)
 {
        struct vrf *vrf;
@@ -226,6 +220,5 @@ void static_nht_mark_state(struct prefix *sp, vrf_id_t vrf_id,
        if (!vrf || !vrf->info)
                return;
 
-       static_nht_mark_state_safi(sp, afi, SAFI_UNICAST, vrf, state);
-       static_nht_mark_state_safi(sp, afi, SAFI_MULTICAST, vrf, state);
+       static_nht_mark_state_safi(sp, afi, safi, vrf, state);
 }
index 08dba2ebb53f8d04422196ea6225a83ec82f6524..c29acc32ef421d14cdfc19027ac515354ef0cf5d 100644 (file)
@@ -37,19 +37,21 @@ extern "C" {
  * vrf_id -> The vrf the nexthop is in.
  */
 extern void static_nht_update(struct prefix *sp, struct prefix *nhp,
-                             uint32_t nh_num, afi_t afi, vrf_id_t vrf_id);
+                             uint32_t nh_num, afi_t afi, safi_t safi,
+                             vrf_id_t vrf_id);
 
 /*
  * For the given tracked nexthop, nhp, mark all routes that use
  * this route as in starting state again.
  */
-extern void static_nht_reset_start(struct prefix *nhp, afi_t afi,
+extern void static_nht_reset_start(struct prefix *nhp, afi_t afi, safi_t safi,
                                   vrf_id_t nh_vrf_id);
 
 /*
  * For the given prefix, sp, mark it as in a particular state
  */
-extern void static_nht_mark_state(struct prefix *sp, vrf_id_t vrf_id,
+extern void static_nht_mark_state(struct prefix *sp, safi_t safi,
+                                 vrf_id_t vrf_id,
                                  enum static_install_states state);
 
 /*
index 882c770189715f2f91635a82d4c0a917966101f0..af153b4bc353e9559a3fd17f5fb9e248efb5cf9d 100644 (file)
@@ -51,6 +51,7 @@ struct static_nht_data {
        struct static_nht_hash_item itm;
 
        struct prefix nh;
+       safi_t safi;
 
        vrf_id_t nh_vrf_id;
 
@@ -63,6 +64,8 @@ static int static_nht_data_cmp(const struct static_nht_data *nhtd1,
 {
        if (nhtd1->nh_vrf_id != nhtd2->nh_vrf_id)
                return numcmp(nhtd1->nh_vrf_id, nhtd2->nh_vrf_id);
+       if (nhtd1->safi != nhtd2->safi)
+               return numcmp(nhtd1->safi, nhtd2->safi);
 
        return prefix_cmp(&nhtd1->nh, &nhtd2->nh);
 }
@@ -72,7 +75,7 @@ static unsigned int static_nht_data_hash(const struct static_nht_data *nhtd)
        unsigned int key = 0;
 
        key = prefix_hash_key(&nhtd->nh);
-       return jhash_1word(nhtd->nh_vrf_id, key);
+       return jhash_2words(nhtd->nh_vrf_id, nhtd->safi, key);
 }
 
 DECLARE_HASH(static_nht_hash, struct static_nht_data, itm, static_nht_data_cmp,
@@ -139,31 +142,32 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS)
        struct prefix p;
        enum zapi_route_notify_owner note;
        uint32_t table_id;
+       safi_t safi;
 
-       if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note,
-                                     NULL, NULL))
+       if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note, NULL,
+                                     &safi))
                return -1;
 
        switch (note) {
        case ZAPI_ROUTE_FAIL_INSTALL:
-               static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
+               static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED);
                zlog_warn("%s: Route %pFX failed to install for table: %u",
                          __func__, &p, table_id);
                break;
        case ZAPI_ROUTE_BETTER_ADMIN_WON:
-               static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
+               static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED);
                zlog_warn(
                        "%s: Route %pFX over-ridden by better route for table: %u",
                        __func__, &p, table_id);
                break;
        case ZAPI_ROUTE_INSTALLED:
-               static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED);
+               static_nht_mark_state(&p, safi, vrf_id, STATIC_INSTALLED);
                break;
        case ZAPI_ROUTE_REMOVED:
-               static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
+               static_nht_mark_state(&p, safi, vrf_id, STATIC_NOT_INSTALLED);
                break;
        case ZAPI_ROUTE_REMOVE_FAIL:
-               static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED);
+               static_nht_mark_state(&p, safi, vrf_id, STATIC_INSTALLED);
                zlog_warn("%s: Route %pFX failure to remove for table: %u",
                          __func__, &p, table_id);
                break;
@@ -215,15 +219,17 @@ static int static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
        memset(&lookup, 0, sizeof(lookup));
        lookup.nh = matched;
        lookup.nh_vrf_id = vrf_id;
+       lookup.safi = nhr.safi;
 
        nhtd = static_nht_hash_find(static_nht_hash, &lookup);
 
        if (nhtd) {
                nhtd->nh_num = nhr.nexthop_num;
 
-               static_nht_reset_start(&matched, afi, nhtd->nh_vrf_id);
+               static_nht_reset_start(&matched, afi, nhr.safi,
+                                      nhtd->nh_vrf_id);
                static_nht_update(NULL, &matched, nhr.nexthop_num, afi,
-                                 nhtd->nh_vrf_id);
+                                 nhr.safi, nhtd->nh_vrf_id);
        } else
                zlog_err("No nhtd?");
 
@@ -247,6 +253,7 @@ static_nht_hash_getref(const struct static_nht_data *ref)
 
                prefix_copy(&nhtd->nh, &ref->nh);
                nhtd->nh_vrf_id = ref->nh_vrf_id;
+               nhtd->safi = ref->safi;
 
                static_nht_hash_add(static_nht_hash, nhtd);
        }
@@ -277,6 +284,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
 {
        struct static_path *pn = nh->pn;
        struct route_node *rn = pn->rn;
+       struct static_route_info *si = static_route_info_from_rnode(rn);
        struct static_nht_data lookup;
        uint32_t cmd;
        struct prefix p;
@@ -315,6 +323,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
        memset(&lookup, 0, sizeof(lookup));
        lookup.nh = p;
        lookup.nh_vrf_id = nh->nh_vrf_id;
+       lookup.safi = si->safi;
 
        nh->nh_registered = reg;
 
@@ -329,7 +338,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
                               &p, rn, nhtd->nh_num);
                        if (nhtd->nh_num)
                                static_nht_update(&rn->p, &nhtd->nh,
-                                                 nhtd->nh_num, afi,
+                                                 nhtd->nh_num, afi, si->safi,
                                                  nh->nh_vrf_id);
                        return;
                }
@@ -346,7 +355,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
        DEBUGD(&static_dbg_route, "%s nexthop(%pFX) for %pRN",
               reg ? "Registering" : "Unregistering", &p, rn);
 
-       if (zclient_send_rnh(zclient, cmd, &p, SAFI_UNICAST, false, false,
+       if (zclient_send_rnh(zclient, cmd, &p, si->safi, false, false,
                             nh->nh_vrf_id) == ZCLIENT_SEND_FAILURE)
                zlog_warn("%s: Failure to send nexthop to zebra", __func__);
 }
@@ -358,6 +367,7 @@ int static_zebra_nh_update(struct static_nexthop *nh)
 {
        struct static_path *pn = nh->pn;
        struct route_node *rn = pn->rn;
+       struct static_route_info *si = static_route_info_from_rnode(rn);
        struct static_nht_data *nhtd, lookup = {};
        struct prefix p = {};
        afi_t afi = AFI_IP;
@@ -387,12 +397,13 @@ int static_zebra_nh_update(struct static_nexthop *nh)
 
        lookup.nh = p;
        lookup.nh_vrf_id = nh->nh_vrf_id;
+       lookup.safi = si->safi;
 
        nhtd = static_nht_hash_find(static_nht_hash, &lookup);
        if (nhtd && nhtd->nh_num) {
                nh->state = STATIC_START;
                static_nht_update(&rn->p, &nhtd->nh, nhtd->nh_num, afi,
-                                 nh->nh_vrf_id);
+                                 si->safi, nh->nh_vrf_id);
                return 1;
        }
        return 0;