]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/ndisc: do not store too many captive portals provided through RA
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 10 Jul 2023 04:28:59 +0000 (13:28 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 24 Aug 2023 10:59:34 +0000 (19:59 +0900)
Prompted by https://github.com/systemd/systemd/pull/28285#issuecomment-1627585140.

src/network/networkd-ndisc.c

index c6ca7f95e2d3664f5956908423c1c9d4432d6fe2..de03abad224e6e2a5d3b4588701d02e2482042c0 100644 (file)
@@ -27,6 +27,9 @@
 
 #define NDISC_DNSSL_MAX 64U
 #define NDISC_RDNSS_MAX 64U
+/* Not defined RFC, but let's set an upper limit to make not consume much memory.
+ * This should be safe as typically there should be at most 1 portal per network. */
+#define NDISC_CAPTIVE_PORTAL_MAX 64U
 
 bool link_ipv6_accept_ra_enabled(Link *link) {
         assert(link);
@@ -914,6 +917,19 @@ static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt)
                 return 0;
         }
 
+        if (set_size(link->ndisc_captive_portals) >= NDISC_CAPTIVE_PORTAL_MAX) {
+                NDiscCaptivePortal *c, *target = NULL;
+
+                /* Find the portal who has the minimal lifetime and drop it to store new one. */
+                SET_FOREACH(c, link->ndisc_captive_portals)
+                        if (!target || c->lifetime_usec < target->lifetime_usec)
+                                target = c;
+
+                assert(target);
+                assert(set_remove(link->ndisc_captive_portals, target) == target);
+                ndisc_captive_portal_free(target);
+        }
+
         new_entry = new(NDiscCaptivePortal, 1);
         if (!new_entry)
                 return log_oom();