]> git.proxmox.com Git - mirror_frr.git/blobdiff - isisd/fabricd.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / isisd / fabricd.c
index 537dc9966157f2aec5e897eb84c48093a6f66d5d..e8b729c779cb21286f4b4ba2e4fa0a91f5af8bad 100644 (file)
@@ -65,6 +65,9 @@ struct fabricd {
        uint8_t tier_pending;
        struct thread *tier_calculation_timer;
        struct thread *tier_set_timer;
+
+       int csnp_delay;
+       bool always_send_csnp;
 };
 
 /* Code related to maintaining the neighbor lists */
@@ -78,7 +81,8 @@ struct neighbor_entry {
 static struct neighbor_entry *neighbor_entry_new(const uint8_t *id,
                                                 struct isis_adjacency *adj)
 {
-       struct neighbor_entry *rv = XMALLOC(MTYPE_FABRICD_NEIGHBOR, sizeof(*rv));
+       struct neighbor_entry *rv = XMALLOC(MTYPE_FABRICD_NEIGHBOR,
+                                           sizeof(*rv));
 
        memcpy(rv->id, id, sizeof(rv->id));
        rv->adj = adj;
@@ -128,7 +132,7 @@ static int neighbor_entry_list_cmp(void *a, void *b)
 static struct neighbor_entry *neighbor_entry_lookup_list(struct skiplist *list,
                                                         const uint8_t *id)
 {
-       struct neighbor_entry n = {{0}};
+       struct neighbor_entry n = { {0} };
 
        memcpy(n.id, id, sizeof(n.id));
 
@@ -158,9 +162,15 @@ static struct neighbor_entry *neighbor_entry_lookup_hash(struct hash *hash,
        return rv;
 }
 
-static void neighbor_lists_update(struct fabricd *f)
+static int fabricd_handle_adj_state_change(struct isis_adjacency *arg)
 {
-       neighbor_lists_clear(f);
+       struct fabricd *f = arg->circuit->area->fabricd;
+
+       if (!f)
+               return 0;
+
+       while (!skiplist_empty(f->neighbors))
+               skiplist_delete_first(f->neighbors);
 
        struct listnode *node;
        struct isis_circuit *circuit;
@@ -179,6 +189,14 @@ static void neighbor_lists_update(struct fabricd *f)
                skiplist_insert(f->neighbors, n, n);
        }
 
+       return 0;
+}
+
+static void neighbors_neighbors_update(struct fabricd *f)
+{
+       hash_clean(f->neighbors_neighbors, neighbor_entry_del_void);
+
+       struct listnode *node;
        struct isis_vertex *v;
 
        for (ALL_QUEUE_ELEMENTS_RO(&f->spftree->paths, node, v)) {
@@ -211,6 +229,8 @@ struct fabricd *fabricd_new(struct isis_area *area)
                                              "Fabricd Neighbors");
 
        rv->tier = rv->tier_config = ISIS_TIER_UNDEFINED;
+
+       rv->csnp_delay = FABRICD_DEFAULT_CSNP_DELAY;
        return rv;
 };
 
@@ -458,7 +478,7 @@ void fabricd_run_spf(struct isis_area *area)
                return;
 
        isis_run_hopcount_spf(area, isis->sysid, f->spftree);
-       neighbor_lists_update(f);
+       neighbors_neighbors_update(f);
        fabricd_bump_tier_calculation_timer(f);
 }
 
@@ -506,6 +526,12 @@ int fabricd_write_settings(struct isis_area *area, struct vty *vty)
                written++;
        }
 
+       if (f->csnp_delay != FABRICD_DEFAULT_CSNP_DELAY
+           || f->always_send_csnp) {
+               vty_out(vty, " triggered-csnp-delay %d%s\n", f->csnp_delay,
+                       f->always_send_csnp ? " always" : "");
+       }
+
        return written;
 }
 
@@ -526,7 +552,8 @@ static void move_to_queue(struct isis_lsp *lsp, struct neighbor_entry *n,
        if (n->adj)
                isis_tx_queue_add(n->adj->circuit->tx_queue, lsp, type);
 
-       uint8_t *neighbor_id = XMALLOC(MTYPE_FABRICD_FLOODING_INFO, sizeof(n->id));
+       uint8_t *neighbor_id = XMALLOC(MTYPE_FABRICD_FLOODING_INFO,
+                                      sizeof(n->id));
 
        memcpy(neighbor_id, n->id, sizeof(n->id));
        listnode_add(lsp->flooding_neighbors[type], neighbor_id);
@@ -599,7 +626,8 @@ static void fabricd_lsp_reset_flooding_info(struct isis_lsp *lsp,
                }
 
                lsp->flooding_neighbors[type] = list_new();
-               lsp->flooding_neighbors[type]->del = fabricd_free_lsp_flooding_info;
+               lsp->flooding_neighbors[type]->del =
+                       fabricd_free_lsp_flooding_info;
        }
 
        if (circuit) {
@@ -620,33 +648,17 @@ void fabricd_lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
        void *cursor = NULL;
        struct neighbor_entry *n;
 
-       /* Mark all elements in NL as present and move T0s into DNR */
-       while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor)) {
+       /* Mark all elements in NL as present */
+       while (!skiplist_next(f->neighbors, NULL, (void **)&n, &cursor))
                n->present = true;
 
-               struct isis_lsp *node_lsp = lsp_for_neighbor(f, n);
-               if (!node_lsp
-                   || !node_lsp->tlvs
-                   || !node_lsp->tlvs->spine_leaf
-                   || !node_lsp->tlvs->spine_leaf->has_tier
-                   || node_lsp->tlvs->spine_leaf->tier != 0) {
-                       continue;
-               }
-
-               if (isis->debugs & DEBUG_FLOODING) {
-                       zlog_debug("Moving %s to DNR because it's T0",
-                                  rawlspid_print(node_lsp->hdr.lsp_id));
-               }
-
-               move_to_queue(lsp, n, TX_LSP_CIRCUIT_SCOPED, circuit);
-       }
-
        /* Mark all elements in NN as present */
        hash_iterate(f->neighbors_neighbors, mark_neighbor_as_present, NULL);
 
-       struct isis_vertex *originator = isis_find_vertex(&f->spftree->paths,
-                                                         lsp->hdr.lsp_id,
-                                                         VTYPE_NONPSEUDO_TE_IS);
+       struct isis_vertex *originator =
+               isis_find_vertex(&f->spftree->paths,
+                                lsp->hdr.lsp_id,
+                                VTYPE_NONPSEUDO_TE_IS);
 
        /* Remove all IS from NL and NN in the shortest path
         * to the IS that originated the LSP */
@@ -707,13 +719,16 @@ void fabricd_lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit)
        }
 }
 
-void fabricd_trigger_csnp(struct isis_area *area)
+void fabricd_trigger_csnp(struct isis_area *area, bool circuit_scoped)
 {
        struct fabricd *f = area->fabricd;
 
        if (!f)
                return;
 
+       if (!circuit_scoped && !f->always_send_csnp)
+               return;
+
        struct listnode *node;
        struct isis_circuit *circuit;
 
@@ -723,7 +738,7 @@ void fabricd_trigger_csnp(struct isis_area *area)
 
                thread_cancel(circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
                thread_add_timer_msec(master, send_l2_csnp, circuit,
-                                     isis_jitter(500, CSNP_JITTER),
+                                     isis_jitter(f->csnp_delay, CSNP_JITTER),
                                      &circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
        }
 }
@@ -773,3 +788,21 @@ void fabricd_update_lsp_no_flood(struct isis_lsp *lsp,
        fabricd_lsp_reset_flooding_info(lsp, circuit);
        lsp->flooding_circuit_scoped = true;
 }
+
+void fabricd_configure_triggered_csnp(struct isis_area *area, int delay,
+                                     bool always_send_csnp)
+{
+       struct fabricd *f = area->fabricd;
+
+       if (!f)
+               return;
+
+       f->csnp_delay = delay;
+       f->always_send_csnp = always_send_csnp;
+}
+
+void fabricd_init(void)
+{
+       hook_register(isis_adj_state_change_hook,
+                     fabricd_handle_adj_state_change);
+}