diff options
author | Luca Boccassi <bluca@debian.org> | 2024-04-18 23:24:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-18 23:24:42 +0200 |
commit | 7f4f75593d86fc2f7918638fd785c3809e8b0de3 (patch) | |
tree | 74b8222c7727dbc229d1e5f26efee0422b32e883 | |
parent | Merge pull request #31790 from poettering/pcrlock-policy-fix (diff) | |
parent | sd-radv: drop unnecessary argument (diff) | |
download | systemd-7f4f75593d86fc2f7918638fd785c3809e8b0de3.tar.xz systemd-7f4f75593d86fc2f7918638fd785c3809e8b0de3.zip |
Merge pull request #32292 from yuwata/sd-radv-send-on-stop
sd-radv: set only basic information in RA message on stop
-rw-r--r-- | src/libsystemd-network/sd-radv.c | 41 | ||||
-rw-r--r-- | src/libsystemd-network/test-ndisc-ra.c | 7 |
2 files changed, 38 insertions, 10 deletions
diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c index 79210f9e2ca..6a71ce14ff4 100644 --- a/src/libsystemd-network/sd-radv.c +++ b/src/libsystemd-network/sd-radv.c @@ -129,9 +129,32 @@ static bool router_lifetime_is_valid(usec_t lifetime_usec) { lifetime_usec <= RADV_MAX_ROUTER_LIFETIME_USEC); } -static int radv_send_router(sd_radv *ra, const struct in6_addr *dst, usec_t lifetime_usec) { +static int radv_send_router_on_stop(sd_radv *ra) { + static const struct nd_router_advert adv = { + .nd_ra_type = ND_ROUTER_ADVERT, + }; + + _cleanup_set_free_ Set *options = NULL; + usec_t time_now; + int r; + + assert(ra); + + r = sd_event_now(ra->event, CLOCK_BOOTTIME, &time_now); + if (r < 0) + return r; + + if (!ether_addr_is_null(&ra->mac_addr)) { + r = ndisc_option_set_link_layer_address(&options, SD_NDISC_OPTION_SOURCE_LL_ADDRESS, &ra->mac_addr); + if (r < 0) + return r; + } + + return ndisc_send(ra->fd, &IN6_ADDR_ALL_NODES_MULTICAST, &adv.nd_ra_hdr, options, time_now); +} + +static int radv_send_router(sd_radv *ra, const struct in6_addr *dst) { assert(ra); - assert(router_lifetime_is_valid(lifetime_usec)); struct sockaddr_in6 dst_addr = { .sin6_family = AF_INET6, @@ -139,7 +162,7 @@ static int radv_send_router(sd_radv *ra, const struct in6_addr *dst, usec_t life }; struct nd_router_advert adv = { .nd_ra_type = ND_ROUTER_ADVERT, - .nd_ra_router_lifetime = usec_to_be16_sec(lifetime_usec), + .nd_ra_router_lifetime = usec_to_be16_sec(ra->lifetime_usec), .nd_ra_retransmit = usec_to_be32_msec(ra->retransmit_usec), }; struct { @@ -261,7 +284,7 @@ static int radv_process_packet(sd_radv *ra, ICMP6Packet *packet) { if (r < 0 && r != -ENODATA) /* null address is allowed */ return log_radv_errno(ra, r, "Failed to get sender address of RS, ignoring: %m"); - r = radv_send_router(ra, &src, ra->lifetime_usec); + r = radv_send_router(ra, &src); if (r < 0) return log_radv_errno(ra, r, "Unable to send solicited Router Advertisement to %s, ignoring: %m", IN6_ADDR_TO_STRING(&src)); @@ -299,7 +322,7 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) { if (r < 0) goto fail; - r = radv_send_router(ra, NULL, ra->lifetime_usec); + r = radv_send_router(ra, NULL); if (r < 0) log_radv_errno(ra, r, "Unable to send Router Advertisement, ignoring: %m"); @@ -362,7 +385,7 @@ int sd_radv_stop(sd_radv *ra) { /* RFC 4861, Section 6.2.5: * the router SHOULD transmit one or more (but not more than MAX_FINAL_RTR_ADVERTISEMENTS) final * multicast Router Advertisements on the interface with a Router Lifetime field of zero. */ - r = radv_send_router(ra, NULL, 0); + r = radv_send_router_on_stop(ra); if (r < 0) log_radv_errno(ra, r, "Unable to send last Router Advertisement with router lifetime set to zero, ignoring: %m"); @@ -679,7 +702,7 @@ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { return 0; /* If RAs have already been sent, send an RA immediately to announce the newly-added prefix */ - r = radv_send_router(ra, NULL, ra->lifetime_usec); + r = radv_send_router(ra, NULL); if (r < 0) log_radv_errno(ra, r, "Unable to send Router Advertisement for added prefix %s, ignoring: %m", addr_p); else @@ -775,7 +798,7 @@ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p) { return 0; /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */ - r = radv_send_router(ra, NULL, ra->lifetime_usec); + r = radv_send_router(ra, NULL); if (r < 0) log_radv_errno(ra, r, "Unable to send Router Advertisement for added route prefix %s, ignoring: %m", strna(addr_p)); @@ -847,7 +870,7 @@ int sd_radv_add_pref64_prefix(sd_radv *ra, sd_radv_pref64_prefix *p) { return 0; /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */ - r = radv_send_router(ra, NULL, ra->lifetime_usec); + r = radv_send_router(ra, NULL); if (r < 0) log_radv_errno(ra, r, "Unable to send Router Advertisement for added PREF64 prefix %s, ignoring: %m", strna(addr_p)); diff --git a/src/libsystemd-network/test-ndisc-ra.c b/src/libsystemd-network/test-ndisc-ra.c index c5f10cc7955..76f4d7ba3f2 100644 --- a/src/libsystemd-network/test-ndisc-ra.c +++ b/src/libsystemd-network/test-ndisc-ra.c @@ -294,8 +294,13 @@ static void verify_message(const uint8_t *buf, size_t len) { /* verify only up to known options, rest is not yet implemented */ for (size_t i = 0, m = MIN(len, sizeof(advertisement)); i < m; i++) { if (test_stopped) + /* on stop, many header fields are zero */ switch (i) { - case 6 ... 7: /* router lifetime must be zero on stop. */ + case 4: /* hop limit */ + case 5: /* flags */ + case 6 ... 7: /* router lifetime */ + case 8 ... 11: /* reachable time */ + case 12 ... 15: /* retrans timer */ assert_se(buf[i] == 0); continue; } |