]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: ndisc - Allow to use ICMP6 rate limit from received RA
authorSusant Sahani <ssahani@gmail.com>
Wed, 16 Aug 2023 12:55:17 +0000 (18:25 +0530)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 21 Aug 2023 09:14:42 +0000 (11:14 +0200)
man/systemd.network.xml
src/libsystemd-network/ndisc-router.c
src/libsystemd-network/ndisc-router.h
src/network/networkd-ndisc.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/systemd/sd-ndisc.h

index db9a9ac25d437b9c39174427df4a639318f2badd..da4282e5020c8697d90b73a922e54c63cc5785a3 100644 (file)
@@ -2652,6 +2652,14 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>UseICMP6RateLimit=</varname></term>
+        <listitem>
+          <para>Takes a boolean. When true, the ICMP6 rate limit received in the Router Advertisement will be set to ICMP6
+          rate limit based on the advertisement. Defaults to true.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>UseGateway=</varname></term>
         <listitem>
index e25b3c2d9b9b794150351910a3ccc205c5e32344..86f8ca0364d9bfb28693f7214e88596caf769acb 100644 (file)
@@ -95,6 +95,7 @@ int ndisc_router_parse(sd_ndisc *nd, sd_ndisc_router *rt) {
         rt->hop_limit = a->nd_ra_curhoplimit;
         rt->flags = a->nd_ra_flags_reserved; /* the first 8 bits */
         rt->lifetime = be16toh(a->nd_ra_router_lifetime);
+        rt->icmp6_ratelimit_msec = be32toh(a->nd_ra_retransmit);
 
         rt->preference = (rt->flags >> 3) & 3;
         if (!IN_SET(rt->preference, SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_HIGH))
@@ -221,6 +222,14 @@ int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret) {
         return 0;
 }
 
+int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint32_t *ret) {
+        assert_return(rt, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        *ret = rt->icmp6_ratelimit_msec;
+        return 0;
+}
+
 int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret_flags) {
         assert_return(rt, -EINVAL);
         assert_return(ret_flags, -EINVAL);
index f5293c96e01df8d4c0eebc7e05a4079b3610cf33..cf702f52c394aa949934750dc0c02d82c34b8e67 100644 (file)
@@ -27,6 +27,7 @@ struct sd_ndisc_router {
 
         uint8_t hop_limit;
         uint32_t mtu;
+        uint32_t icmp6_ratelimit_msec;
 };
 
 static inline void* NDISC_ROUTER_RAW(const sd_ndisc_router *rt) {
index b2b222147d154e36fc80005fc90584228042cfd0..7570d37662f67c2e1f31bb9fda79bdbdc0b1ce0e 100644 (file)
@@ -23,6 +23,7 @@
 #include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
+#include "sysctl-util.h"
 
 #define NDISC_DNSSL_MAX 64U
 #define NDISC_RDNSS_MAX 64U
@@ -272,6 +273,7 @@ static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) {
 
 static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
         usec_t lifetime_usec, timestamp_usec;
+        uint32_t icmp6_ratelimit = 0;
         struct in6_addr gateway;
         uint16_t lifetime_sec;
         unsigned preference;
@@ -352,6 +354,20 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
                         return log_link_warning_errno(link, r, "Could not request gateway: %m");
         }
 
+        r = sd_ndisc_router_get_icmp6_ratelimit(rt, &icmp6_ratelimit);
+        if (r < 0)
+                log_link_debug(link, "Failed to get default router preference from RA: %m");
+
+        if (icmp6_ratelimit > 0 && link->network->ipv6_accept_ra_use_icmp6_ratelimit) {
+                char buf[DECIMAL_STR_MAX(unsigned)];
+
+                xsprintf(buf, "%u", icmp6_ratelimit);
+
+                r = sysctl_write("net/ipv6/icmp/ratelimit", buf);
+                if (r < 0)
+                        log_link_warning_errno(link, r, "Could not configure icmp6 rate limit: %m");
+        }
+
         return 0;
 }
 
index c3f286e8bd358a52beacb24ad9e381010b31518f..69db429fcdd0c6b4147383e31138e0407c983868 100644 (file)
@@ -286,6 +286,7 @@ IPv6AcceptRA.UseDNS,                         config_parse_bool,
 IPv6AcceptRA.UseDomains,                     config_parse_ipv6_accept_ra_use_domains,                  0,                             offsetof(Network, ipv6_accept_ra_use_domains)
 IPv6AcceptRA.UseMTU,                         config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_mtu)
 IPv6AcceptRA.UseHopLimit,                    config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_hop_limit)
+IPv6AcceptRA.UseICMP6RateLimit,              config_parse_bool,                                        0,                             offsetof(Network, ipv6_accept_ra_use_icmp6_ratelimit)
 IPv6AcceptRA.DHCPv6Client,                   config_parse_ipv6_accept_ra_start_dhcp6_client,           0,                             offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
 IPv6AcceptRA.RouteTable,                     config_parse_dhcp_or_ra_route_table,                      AF_INET6,                      0
 IPv6AcceptRA.RouteMetric,                    config_parse_ipv6_accept_ra_route_metric,                 0,                             0
index dbe8c59a625e55159b87ef6f20523e6134c1946d..b5eef894be9d6d81d3db16a7a677ade547667b20 100644 (file)
@@ -487,6 +487,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .ipv6_accept_ra_use_onlink_prefix = true,
                 .ipv6_accept_ra_use_mtu = true,
                 .ipv6_accept_ra_use_hop_limit = true,
+                .ipv6_accept_ra_use_icmp6_ratelimit = true,
                 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
                 .ipv6_accept_ra_route_metric_high = IPV6RA_ROUTE_METRIC_HIGH,
                 .ipv6_accept_ra_route_metric_medium = IPV6RA_ROUTE_METRIC_MEDIUM,
index 031ba398e7ec2274d5a12c163bd2d2ead0d0b03f..f3b3271811e6726095f0867c62b37e3fe75018f6 100644 (file)
@@ -320,6 +320,7 @@ struct Network {
         bool ipv6_accept_ra_use_onlink_prefix;
         bool ipv6_accept_ra_use_mtu;
         bool ipv6_accept_ra_use_hop_limit;
+        bool ipv6_accept_ra_use_icmp6_ratelimit;
         bool ipv6_accept_ra_quickack;
         bool ipv6_accept_ra_use_captive_portal;
         bool active_slave;
index b4faa4428e5d6f35a91a94d3efbf5967ddd61d6a..be702f68a52c3c947540f3380193b4a41fe38faa 100644 (file)
@@ -90,6 +90,7 @@ int sd_ndisc_router_get_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t
 int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size_t *size);
 
 int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret);
+int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint32_t *ret);
 int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret_flags);
 int sd_ndisc_router_get_preference(sd_ndisc_router *rt, unsigned *ret);
 int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint16_t *ret_lifetime);