From 2a437850fda131061b5433ff02328c5e02eca32b Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 31 Aug 2020 21:42:44 -0300 Subject: [PATCH 1/4] tools: make frr-reload handle fpm commands Instruct `frr-reload.py` to not use `fpm` commands as configuration node. Signed-off-by: Rafael Zalamena --- tools/frr-reload.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 0de6c1c2e3..3b29bbd263 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -531,6 +531,7 @@ end "dump ", "enable ", "frr ", + "fpm ", "hostname ", "ip ", "ipv6 ", From a3adec468eb955d87b82f3d122e9f58eb5d4a23f Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Fri, 23 Oct 2020 15:45:08 -0300 Subject: [PATCH 2/4] zebra,fpm: fix configuration display Use `pI4` and `pI6` to format addresses and fix a bug when displaying IPv6 addresses. Signed-off-by: Rafael Zalamena --- zebra/dplane_fpm_nl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index bd9966c801..20b178b649 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -377,7 +377,6 @@ static int fpm_write_config(struct vty *vty) struct sockaddr_in *sin; struct sockaddr_in6 *sin6; int written = 0; - char addrstr[INET6_ADDRSTRLEN]; if (gfnc->disabled) return written; @@ -386,8 +385,7 @@ static int fpm_write_config(struct vty *vty) case AF_INET: written = 1; sin = (struct sockaddr_in *)&gfnc->addr; - inet_ntop(AF_INET, &sin->sin_addr, addrstr, sizeof(addrstr)); - vty_out(vty, "fpm address %s", addrstr); + vty_out(vty, "fpm address %pI4", &sin->sin_addr); if (sin->sin_port != htons(SOUTHBOUND_DEFAULT_PORT)) vty_out(vty, " port %d", ntohs(sin->sin_port)); @@ -396,8 +394,7 @@ static int fpm_write_config(struct vty *vty) case AF_INET6: written = 1; sin6 = (struct sockaddr_in6 *)&gfnc->addr; - inet_ntop(AF_INET, &sin6->sin6_addr, addrstr, sizeof(addrstr)); - vty_out(vty, "fpm address %s", addrstr); + vty_out(vty, "fpm address %pI6", &sin6->sin6_addr); if (sin6->sin6_port != htons(SOUTHBOUND_DEFAULT_PORT)) vty_out(vty, " port %d", ntohs(sin6->sin6_port)); From 1f9193c1f04776a6784b1fb52520a5f0c70d71b4 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Wed, 2 Sep 2020 13:45:31 -0300 Subject: [PATCH 3/4] fpm: simplify reset logic Instead of checking for next group reset, always do it and skip sending if next hop group support is disabled. Also remove unused `*_complete` variables. Signed-off-by: Rafael Zalamena --- zebra/dplane_fpm_nl.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 20b178b649..cbaf5744d1 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -75,9 +75,6 @@ struct fpm_nl_ctx { int socket; bool disabled; bool connecting; - bool nhg_complete; - bool rib_complete; - bool rmac_complete; bool use_nhg; struct sockaddr_storage addr; @@ -905,12 +902,8 @@ static int fpm_lsp_send(struct thread *t) WALK_FINISH(fnc, FNE_LSP_FINISHED); /* Now move onto routes */ - if (fnc->use_nhg) - thread_add_timer(zrouter.master, fpm_nhg_reset, fnc, 0, - &fnc->t_nhgreset); - else - thread_add_timer(zrouter.master, fpm_rib_reset, fnc, 0, - &fnc->t_ribreset); + thread_add_timer(zrouter.master, fpm_nhg_reset, fnc, 0, + &fnc->t_nhgreset); } else { /* Didn't finish - reschedule LSP walk */ thread_add_timer(zrouter.master, fpm_lsp_send, fnc, 0, @@ -963,7 +956,8 @@ static int fpm_nhg_send(struct thread *t) fna.complete = true; /* Send next hops. */ - hash_walk(zrouter.nhgs_id, fpm_nhg_send_cb, &fna); + if (fnc->use_nhg) + hash_walk(zrouter.nhgs_id, fpm_nhg_send_cb, &fna); /* `free()` allocated memory. */ dplane_ctx_fini(&fna.ctx); @@ -1121,7 +1115,6 @@ static int fpm_nhg_reset(struct thread *t) { struct fpm_nl_ctx *fnc = THREAD_ARG(t); - fnc->nhg_complete = false; hash_iterate(zrouter.nhgs_id, fpm_nhg_reset_cb, NULL); /* Schedule next step: send next hop groups. */ @@ -1164,8 +1157,6 @@ static int fpm_rib_reset(struct thread *t) struct route_table *rt; rib_tables_iter_t rt_iter; - fnc->rib_complete = false; - rt_iter.state = RIB_TABLES_ITER_S_INIT; while ((rt = rib_tables_iter_next(&rt_iter))) { for (rn = route_top(rt); rn; rn = srcdest_route_next(rn)) { @@ -1205,7 +1196,6 @@ static int fpm_rmac_reset(struct thread *t) { struct fpm_nl_ctx *fnc = THREAD_ARG(t); - fnc->rmac_complete = false; hash_iterate(zrouter.l3vni_table, fpm_unset_l3vni_table, NULL); /* Schedule next event: send RMAC entries. */ @@ -1300,20 +1290,14 @@ static int fpm_process_event(struct thread *t) if (IS_ZEBRA_DEBUG_FPM) zlog_debug("%s: next hop groups walk finished", __func__); - - fnc->nhg_complete = true; break; case FNE_RIB_FINISHED: if (IS_ZEBRA_DEBUG_FPM) zlog_debug("%s: RIB walk finished", __func__); - - fnc->rib_complete = true; break; case FNE_RMAC_FINISHED: if (IS_ZEBRA_DEBUG_FPM) zlog_debug("%s: RMAC walk finished", __func__); - - fnc->rmac_complete = true; break; case FNE_LSP_FINISHED: if (IS_ZEBRA_DEBUG_FPM) From f584de526dd4c0cef8f01d401de450d7497509ed Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Fri, 6 Nov 2020 12:27:54 -0300 Subject: [PATCH 4/4] fpm: reset/walk data structures on connection Don't attempt to walk data structures while not connected so we can save some CPU usage when FPM server is offline. Signed-off-by: Rafael Zalamena --- zebra/dplane_fpm_nl.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index cbaf5744d1..1c82e2a814 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -536,6 +536,13 @@ static int fpm_write(struct thread *t) fnc->connecting = false; + /* + * Starting with LSPs walk all FPM objects, marking them + * as unsent and then replaying them. + */ + thread_add_timer(zrouter.master, fpm_lsp_reset, fnc, 0, + &fnc->t_lspreset); + /* Permit receiving messages now. */ thread_add_read(fnc->fthread->master, fpm_read, fnc, fnc->socket, &fnc->t_read); @@ -658,9 +665,12 @@ static int fpm_connect(struct thread *t) /* * Starting with LSPs walk all FPM objects, marking them * as unsent and then replaying them. + * + * If we are not connected, then delay the objects reset/send. */ - thread_add_timer(zrouter.master, fpm_lsp_reset, fnc, 0, - &fnc->t_lspreset); + if (!fnc->connecting) + thread_add_timer(zrouter.master, fpm_lsp_reset, fnc, 0, + &fnc->t_lspreset); return 0; }