Revert "router: optimize duplicated PIO comparison"
authorÁlvaro Fernández Rojas <noltari@gmail.com>
Sun, 14 Dec 2025 08:04:33 +0000 (09:04 +0100)
committerÁlvaro Fernández Rojas <noltari@gmail.com>
Sun, 14 Dec 2025 08:25:02 +0000 (09:25 +0100)
This reverts commit d354ebb66cdcccc3373156468eec1c660fb2922c.

As stated by David Härdeman at [1]:
Note that time_t will have an alignment of 4 (unlikely) or 8, meaning
that struct ra_pio will have padding. A straight memcmp() could
therefore generate the wrong result unless both struct ra_pios that are
compared are guaranteed to have been memset to zero.

Avoid the risk of something going wrong here by doing a straight
comparison of the two members of the struct that we want to compare.

[1]: https://github.com/openwrt/odhcpd/pull/348/changes/d02fce006abd4f0761bf3100c9ddd4ce70847edb

Link: https://github.com/openwrt/odhcpd/pull/354
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
src/odhcpd.h
src/router.c

index 86375abaa4b6eb613cf631a6050af73c6e9b70b7..f005909b91975a23f9443a48971173441cc262bc 100644 (file)
@@ -346,13 +346,10 @@ struct dnr_options {
 
 // RA PIO - RFC9096
 struct ra_pio {
-       struct {
-               struct in6_addr prefix;
-               uint8_t length;
-       };
+       struct in6_addr prefix;
+       uint8_t length;
        time_t lifetime;
 };
-#define ra_pio_cmp_len offsetof(struct ra_pio, lifetime)
 
 
 struct interface {
index 8334a1c86b9b20c6737f3ae8fb2a014890b1f890..05c4fcb74948532251d23c90c4b8a201346cefb4 100644 (file)
@@ -539,7 +539,8 @@ static void router_clear_duplicated_ra_pio(struct interface *iface)
                while (j < iface->pio_cnt) {
                        struct ra_pio *pio_b = &iface->pios[j];
 
-                       if (!memcmp(pio_a, pio_b, ra_pio_cmp_len)) {
+                       if (pio_a->length == pio_b->length &&
+                           !memcmp(&pio_a->prefix, &pio_b->prefix, sizeof(struct in6_addr))) {
                                warn("rfc9096: %s: clear duplicated %s/%u",
                                     iface->ifname,
                                     inet_ntop(AF_INET6, &pio_a->prefix, ipv6_str, sizeof(ipv6_str)),