1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-27 10:25:37 +03:00

Merge pull request #32346 from yuwata/sd-radv-handle-header-param-gracefully

sd-radv: handle header param gracefully
This commit is contained in:
Luca Boccassi 2024-04-19 21:14:21 +02:00 committed by GitHub
commit 0c8780babf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 14 additions and 50 deletions

View 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 */

View 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
@ -541,23 +543,13 @@ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) {
int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
assert_return(ra, -EINVAL);
if (ra->state != RADV_STATE_IDLE)
return -EBUSY;
ra->hop_limit = hop_limit;
return 0;
}
int sd_radv_set_retransmit(sd_radv *ra, uint64_t usec) {
assert_return(ra, -EINVAL);
if (ra->state != RADV_STATE_IDLE)
return -EBUSY;
if (usec > RADV_MAX_RETRANSMIT_USEC)
return -EINVAL;
ra->retransmit_usec = usec;
return 0;
}
@ -565,58 +557,35 @@ int sd_radv_set_retransmit(sd_radv *ra, uint64_t usec) {
int sd_radv_set_router_lifetime(sd_radv *ra, uint64_t usec) {
assert_return(ra, -EINVAL);
if (ra->state != RADV_STATE_IDLE)
return -EBUSY;
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;
}
int sd_radv_set_managed_information(sd_radv *ra, int managed) {
int sd_radv_set_managed_information(sd_radv *ra, int b) {
assert_return(ra, -EINVAL);
if (ra->state != RADV_STATE_IDLE)
return -EBUSY;
SET_FLAG(ra->flags, ND_RA_FLAG_MANAGED, managed);
SET_FLAG(ra->flags, ND_RA_FLAG_MANAGED, b);
return 0;
}
int sd_radv_set_other_information(sd_radv *ra, int other) {
int sd_radv_set_other_information(sd_radv *ra, int b) {
assert_return(ra, -EINVAL);
if (ra->state != RADV_STATE_IDLE)
return -EBUSY;
SET_FLAG(ra->flags, ND_RA_FLAG_OTHER, other);
SET_FLAG(ra->flags, ND_RA_FLAG_OTHER, 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;
}

View 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);
@ -208,7 +202,7 @@ TEST(radv) {
ASSERT_RETURN_EXPECTED_SE(sd_radv_set_retransmit(NULL, 10 * USEC_PER_MSEC) < 0);
assert_se(sd_radv_set_retransmit(ra, 10 * USEC_PER_MSEC) >= 0);
assert_se(sd_radv_set_retransmit(ra, 0) >= 0);
assert_se(sd_radv_set_retransmit(ra, usec_add(UINT32_MAX * USEC_PER_MSEC, USEC_PER_MSEC)) < 0);
assert_se(sd_radv_set_retransmit(ra, USEC_INFINITY) >= 0);
ASSERT_RETURN_EXPECTED_SE(sd_radv_set_rdnss(NULL, 0, NULL, 0) < 0);
assert_se(sd_radv_set_rdnss(ra, 0, NULL, 0) >= 0);

View File

@ -59,9 +59,9 @@ 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, 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 managed);
int sd_radv_set_other_information(sd_radv *ra, int other);
int sd_radv_set_preference(sd_radv *ra, unsigned preference);
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, 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);