From 9175002864d8876f375e0df089d142d239282528 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 16 Aug 2023 18:25:17 +0530 Subject: [PATCH] network: ndisc - Allow to use ICMP6 rate limit from received RA --- man/systemd.network.xml | 8 ++++++++ src/libsystemd-network/ndisc-router.c | 9 +++++++++ src/libsystemd-network/ndisc-router.h | 1 + src/network/networkd-ndisc.c | 16 ++++++++++++++++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 1 + src/network/networkd-network.h | 1 + src/systemd/sd-ndisc.h | 1 + 8 files changed, 38 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index db9a9ac25d..da4282e502 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2652,6 +2652,14 @@ Token=prefixstable:2002:da8:1:: + + UseICMP6RateLimit= + + 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. + + + UseGateway= diff --git a/src/libsystemd-network/ndisc-router.c b/src/libsystemd-network/ndisc-router.c index e25b3c2d9b..86f8ca0364 100644 --- a/src/libsystemd-network/ndisc-router.c +++ b/src/libsystemd-network/ndisc-router.c @@ -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); diff --git a/src/libsystemd-network/ndisc-router.h b/src/libsystemd-network/ndisc-router.h index f5293c96e0..cf702f52c3 100644 --- a/src/libsystemd-network/ndisc-router.h +++ b/src/libsystemd-network/ndisc-router.h @@ -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) { diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index b2b222147d..7570d37662 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -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; } diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index c3f286e8bd..69db429fcd 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index dbe8c59a62..b5eef894be 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 031ba398e7..f3b3271811 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -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; diff --git a/src/systemd/sd-ndisc.h b/src/systemd/sd-ndisc.h index b4faa4428e..be702f68a5 100644 --- a/src/systemd/sd-ndisc.h +++ b/src/systemd/sd-ndisc.h @@ -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); -- 2.25.1