]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-radv: set router preference gracefully 32346/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 15 Apr 2024 03:04:23 +0000 (12:04 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 19 Apr 2024 02:44:59 +0000 (11:44 +0900)
Rather than refusing to set non-zero preference, when lifetime is zero,
let's handle that gracefully on send.

src/libsystemd-network/radv-internal.h
src/libsystemd-network/sd-radv.c
src/libsystemd-network/test-ndisc-ra.c
src/systemd/sd-radv.h

index d2ec912d496cc7d6db025bb82c32a33ff55688eb..cf3fe9e226eabb531fb5af78167aaaab2dd63201 100644 (file)
@@ -106,6 +106,7 @@ struct sd_radv {
         struct ether_addr mac_addr;
         uint8_t hop_limit;
         uint8_t flags;
+        uint8_t preference;
         uint32_t mtu;
         usec_t retransmit_usec;
         usec_t lifetime_usec; /* timespan */
index 0709a55c138ab1ddec8c02d60f71961e35023435..e6c375f311e86336758e555fd01503ce2bb9c9bf 100644 (file)
@@ -201,7 +201,9 @@ static int radv_send_router(sd_radv *ra, const struct in6_addr *dst) {
         /* The nd_ra_curhoplimit and nd_ra_flags_reserved fields cannot specified with nd_ra_router_lifetime
          * simultaneously in the structured initializer in the above. */
         adv.nd_ra_curhoplimit = ra->hop_limit;
-        adv.nd_ra_flags_reserved = ra->flags;
+        /* RFC 4191, Section 2.2,
+         * "...If the Router Lifetime is zero, the preference value MUST be set to (00) by the sender..." */
+        adv.nd_ra_flags_reserved = ra->flags | (ra->lifetime_usec > 0 ? (ra->preference << 3) : 0);
         iov[msg.msg_iovlen++] = IOVEC_MAKE(&adv, sizeof(adv));
 
         /* MAC address is optional, either because the link does not use L2 addresses or load sharing is
@@ -554,12 +556,6 @@ int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t usec) {
         if (!router_lifetime_is_valid(usec))
                 return -EINVAL;
 
-        /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
-         * to (00) by the sender..." */
-        if (usec == 0 &&
-            (ra->flags & (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM << 3))
-                return -EINVAL;
-
         ra->lifetime_usec = usec;
         return 0;
 }
@@ -578,20 +574,14 @@ int sd_radv_set_other_information(sd_radv *ra, int b) {
         return 0;
 }
 
-int sd_radv_set_preference(sd_radv *ra, unsigned preference) {
+int sd_radv_set_preference(sd_radv *ra, uint8_t preference) {
         assert_return(ra, -EINVAL);
         assert_return(IN_SET(preference,
                              SD_NDISC_PREFERENCE_LOW,
                              SD_NDISC_PREFERENCE_MEDIUM,
                              SD_NDISC_PREFERENCE_HIGH), -EINVAL);
 
-        /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
-         * to (00) by the sender..." */
-        if (ra->lifetime_usec == 0 && preference != SD_NDISC_PREFERENCE_MEDIUM)
-                return -EINVAL;
-
-        ra->flags = (ra->flags & ~(0x3 << 3)) | (preference << 3);
-
+        ra->preference = preference;
         return 0;
 }
 
index c63d9dfdabfa031519a7c12c80518cd2b58b35d0..78635ee657670f22b58cc783ced763f6f14ffe40 100644 (file)
@@ -191,12 +191,6 @@ TEST(radv) {
         assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
         ASSERT_RETURN_EXPECTED_SE(sd_radv_set_preference(ra, ~0) < 0);
 
-        assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
-        assert_se(sd_radv_set_router_lifetime(ra, 300 * USEC_PER_SEC) >= 0);
-        assert_se(sd_radv_set_router_lifetime(ra, 0) < 0);
-        assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
-        assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
-
         ASSERT_RETURN_EXPECTED_SE(sd_radv_set_managed_information(NULL, true) < 0);
         assert_se(sd_radv_set_managed_information(ra, true) >= 0);
         assert_se(sd_radv_set_managed_information(ra, false) >= 0);
index 2538f2ab6fae8011c55a31ea6ced4da60f6e8eca..55b123973e90553592b29fa206b72e99df7ab5b9 100644 (file)
@@ -60,7 +60,7 @@ int sd_radv_set_retransmit(sd_radv *ra, uint64_t usec);
 int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t usec);
 int sd_radv_set_managed_information(sd_radv *ra, int b);
 int sd_radv_set_other_information(sd_radv *ra, int b);
-int sd_radv_set_preference(sd_radv *ra, unsigned preference);
+int sd_radv_set_preference(sd_radv *ra, uint8_t preference);
 int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p);
 int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p);
 int sd_radv_add_pref64_prefix(sd_radv *ra, sd_radv_pref64_prefix *p);