]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/radv: allow to configure the time between retransmitted Neighbor Solicitatio...
authorSusant Sahani <ssahani@gmail.com>
Wed, 23 Aug 2023 03:37:44 +0000 (09:07 +0530)
committerGitHub <noreply@github.com>
Wed, 23 Aug 2023 03:37:44 +0000 (12:37 +0900)
man/systemd.network.xml
src/libsystemd-network/radv-internal.h
src/libsystemd-network/sd-radv.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h
src/network/networkd-radv.c
src/network/networkd-radv.h
src/systemd/sd-radv.h

index 38a0173cf0916b48abc8ba1a90dbea13225dc042..fcf37a19b82bd45e6fed5ba8ab74895cda1743a5 100644 (file)
@@ -3076,6 +3076,15 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>RetransmitSec=</varname></term>
+
+        <listitem><para>Takes a timespan. Configures the retransmit time, used by clients to retransmit Neighbor
+        Solicitation messages on address resolution and the Neighbor Unreachability Detection algorithm.
+        An integer the default unit of seconds, in the range 0…4294967295 msec. Defaults to 0.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>RouterPreference=</varname></term>
 
index 1a268757ad29eee7248b5d68265435eff1538e38..4bb32f21283d90093598c5803c6bb910cce57f0c 100644 (file)
@@ -87,6 +87,7 @@ struct sd_radv {
         uint8_t hop_limit;
         uint8_t flags;
         uint32_t mtu;
+        uint32_t retransmit_msec;
         usec_t lifetime_usec; /* timespan */
 
         int fd;
index 839c9a9ee6fc92df48eb503c79d3afcb4e2ec96a..5d4dfdef0282b187c51bd8decb2b9d322639a69d 100644 (file)
@@ -179,6 +179,7 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, usec_t lifetime_us
 
         adv.nd_ra_type = ND_ROUTER_ADVERT;
         adv.nd_ra_curhoplimit = ra->hop_limit;
+        adv.nd_ra_retransmit = htobe32(ra->retransmit_msec);
         adv.nd_ra_flags_reserved = ra->flags;
         assert_cc(RADV_MAX_ROUTER_LIFETIME_USEC <= UINT16_MAX * USEC_PER_SEC);
         adv.nd_ra_router_lifetime = htobe16(DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC));
@@ -494,6 +495,17 @@ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
         return 0;
 }
 
+int sd_radv_set_retransmit(sd_radv *ra, uint32_t retransmit_msec) {
+        assert_return(ra, -EINVAL);
+
+        if (ra->state != RADV_STATE_IDLE)
+                return -EBUSY;
+
+        ra->retransmit_msec = retransmit_msec;
+
+        return 0;
+}
+
 int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t lifetime_usec) {
         assert_return(ra, -EINVAL);
 
index 2e062ce3197f15dd2f4eced125df31c1f12c4b29..a364abf2b4765bd9dd6757ce87105539478c0b85 100644 (file)
@@ -368,6 +368,7 @@ DHCPPrefixDelegation.Token,                  config_parse_address_generation_typ
 DHCPPrefixDelegation.RouteMetric,            config_parse_uint32,                                      0,                             offsetof(Network, dhcp_pd_route_metric)
 DHCPPrefixDelegation.NetLabel,               config_parse_string,                                      CONFIG_PARSE_STRING_SAFE,      offsetof(Network, dhcp_pd_netlabel)
 IPv6SendRA.RouterLifetimeSec,                config_parse_router_lifetime,                             0,                             offsetof(Network, router_lifetime_usec)
+IPv6SendRA.RetransmitSec,                    config_parse_router_retransmit,                           0,                             offsetof(Network, router_retransmit_usec)
 IPv6SendRA.Managed,                          config_parse_bool,                                        0,                             offsetof(Network, router_managed)
 IPv6SendRA.OtherInformation,                 config_parse_bool,                                        0,                             offsetof(Network, router_other_information)
 IPv6SendRA.RouterPreference,                 config_parse_router_preference,                           0,                             0
index f3b3271811e6726095f0867c62b37e3fe75018f6..75f1be442aa0a511d2cbb474d1167685c3baca83 100644 (file)
@@ -227,6 +227,7 @@ struct Network {
         RADVPrefixDelegation router_prefix_delegation;
         usec_t router_lifetime_usec;
         uint8_t router_preference;
+        usec_t router_retransmit_usec;
         bool router_managed;
         bool router_other_information;
         bool router_emit_dns;
index 0f67ff09732e12717937fb8fdf5db3233a95c159..e6ef3974f288837993cd8722bd88541880d1f13a 100644 (file)
@@ -486,6 +486,12 @@ static int radv_configure(Link *link) {
                         return r;
         }
 
+        if (link->network->router_retransmit_usec > 0) {
+                r = sd_radv_set_retransmit(link->radv, DIV_ROUND_UP(link->network->router_retransmit_usec, USEC_PER_MSEC));
+                if (r < 0)
+                        return r;
+        }
+
         HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
                 r = radv_set_prefix(link, p);
                 if (r < 0 && r != -EEXIST)
@@ -1305,6 +1311,49 @@ int config_parse_router_lifetime(
         return 0;
 }
 
+int config_parse_router_retransmit(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        usec_t usec, *router_retransmit_usec = ASSERT_PTR(data);
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                *router_retransmit_usec = 0;
+                return 0;
+        }
+
+        r = parse_sec(rvalue, &usec);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
+                return 0;
+        }
+
+        if (usec != USEC_INFINITY &&
+            DIV_ROUND_UP(usec, USEC_PER_MSEC) > UINT32_MAX) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Invalid %s= must be in the range 0...%"PRIu32"Sec, ignoring: %s", lvalue, UINT32_MAX, rvalue);
+                return 0;
+        }
+
+        *router_retransmit_usec = usec;
+        return 0;
+}
+
 int config_parse_router_preference(
                 const char *unit,
                 const char *filename,
index ebebb3942b81d9ec9c83f64008ba69b7c6e612b1..e1c22d054f2691b3d06e21b4dac4ec2480ffe354 100644 (file)
@@ -74,6 +74,7 @@ RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
 
 CONFIG_PARSER_PROTOTYPE(config_parse_router_prefix_delegation);
 CONFIG_PARSER_PROTOTYPE(config_parse_router_lifetime);
+CONFIG_PARSER_PROTOTYPE(config_parse_router_retransmit);
 CONFIG_PARSER_PROTOTYPE(config_parse_router_preference);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix_boolean);
index 5e8d06f18f4bc044d1e86aeb635da3aa07347815..98fda297a72ee7cf85f6a247490d3fa966d9a467 100644 (file)
@@ -53,6 +53,7 @@ int sd_radv_get_ifname(sd_radv *ra, const char **ret);
 int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
 int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
 int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);
+int sd_radv_set_retransmit(sd_radv *ra, uint32_t retransmit_msec);
 int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t lifetime_usec);
 int sd_radv_set_managed_information(sd_radv *ra, int managed);
 int sd_radv_set_other_information(sd_radv *ra, int other);