From 74c50f3667b98117e29075c56c36ca8c07c93a0b Mon Sep 17 00:00:00 2001 From: Rouven Czerwinski <rouven@czerwinskis.de> Date: Sun, 26 May 2024 16:43:55 +0200 Subject: [PATCH] gluon-radv-filterd: expire routers for redirect For the redirect login implemented for parker, it is beneficial to keep a list of seen routers and mark them as expired instead of removing them from the global routers list. This way we don't enter a new redirect entry for the same router when it shows up again after a mesh link failure. All foreach loops should be adjusted to correctly ignore expired routers. Signed-off-by: Rouven Czerwinski <rouven@czerwinskis.de> --- .../src/gluon-radv-filterd.c | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/package/gluon-radv-filterd/src/gluon-radv-filterd.c b/package/gluon-radv-filterd/src/gluon-radv-filterd.c index 067cfd55..1c0bc5f2 100644 --- a/package/gluon-radv-filterd/src/gluon-radv-filterd.c +++ b/package/gluon-radv-filterd/src/gluon-radv-filterd.c @@ -92,6 +92,7 @@ struct router { struct ether_addr originator; uint16_t tq; bool redirected; + bool expired; struct in6_addr lladdr; struct in6_addr prefix; }; @@ -300,6 +301,9 @@ static struct router *router_find_src(const struct ether_addr *src) { struct router *router; foreach(router, G.routers) { + if (router->expired) + continue; + if (ether_addr_equal(router->src, *src)) return router; } @@ -311,6 +315,9 @@ static struct router *router_find_orig(const struct ether_addr *orig) { struct router *router; foreach(router, G.routers) { + if (router->expired) + continue; + if (ether_addr_equal(router->originator, *orig)) return router; } @@ -321,6 +328,13 @@ static struct router *router_find_orig(const struct ether_addr *orig) { static struct router *router_add(const struct ether_addr *mac) { struct router *router; + foreach(router, G.routers) { + if (ether_addr_equal(router->src, *mac)) { + router->expired = false; + return router; + } + } + router = calloc(1, sizeof(*router)); if (!router) return NULL; @@ -417,7 +431,6 @@ check_failed: } static void expire_routers(void) { - struct router **prev_ptr = &G.routers; struct router *router; struct router *safe; struct timespec now; @@ -425,15 +438,12 @@ static void expire_routers(void) { clock_gettime(CLOCK_MONOTONIC, &now); - foreach_safe(router, safe, G.routers) { + foreach(router, G.routers) { if (timespec_diff(&now, &router->eol, &diff)) { DEBUG_MSG("router " F_MAC " expired", F_MAC_VAR(router->src)); - *prev_ptr = router->next; if (G.best_router == router) G.best_router = NULL; - free(router); - } else { - prev_ptr = &router->next; + router->expired = true; } } } @@ -628,6 +638,9 @@ static void update_tqs(void) { // if all routers have a TQ value, we don't need to check translocal foreach(router, G.routers) { + if (router->expired) + continue; + if (router->tq == 0) break; } @@ -641,6 +654,9 @@ static void update_tqs(void) { } foreach(router, G.routers) { + if (router->expired) + continue; + if (router->tq == 0) { if (ether_addr_equal(router->originator, unspec)) DEBUG_MSG( @@ -666,7 +682,7 @@ static void update_redirect(void) { char addr[INET6_ADDRSTRLEN]; char prefix[INET6_ADDRSTRLEN]; - if (router->redirected) + if (router->redirected || router->expired) continue; router->redirected = true; @@ -784,6 +800,9 @@ static void update_ebtables(void) { } foreach(router, G.routers) { + if (router->expired) + continue; + if (router->tq == G.max_tq) { snprintf(mac, sizeof(mac), F_MAC, F_MAC_VAR(router->src)); break; -- GitLab