From: Florian Obser Subject: dhcp6leased(8): Find interfaces with changed configuration during reload. To: tech Date: Thu, 18 Sep 2025 18:43:17 +0200 I doubt dhcp6leased(8) always does the right thing though. But at least it detects a config change now. OK? diff --git frontend.c frontend.c index fb6e51b4515..373cfa604b7 100644 --- frontend.c +++ frontend.c @@ -84,6 +84,8 @@ void iface_data_from_imsg(struct iface*, struct imsg_req_dhcp *); ssize_t build_packet(uint8_t, struct iface *, char *); void send_packet(uint8_t, struct iface *); int iface_conf_cmp(struct iface_conf *, struct iface_conf *); +int ia_conf_cmp(struct iface_ia_conf *, struct iface_ia_conf *); +int pd_conf_cmp(struct iface_pd_conf *, struct iface_pd_conf *); LIST_HEAD(, iface) interfaces; struct dhcp6leased_conf *frontend_conf; @@ -1048,7 +1050,7 @@ changed_ifaces(struct dhcp6leased_conf *oconf, struct dhcp6leased_conf *nconf) if (oiface_conf == NULL) { /* new interface added to config */ ret[i++] = if_index; - } else if (iface_conf_cmp(iface_conf, oiface_conf) != 0) { + } else if (!iface_conf_cmp(iface_conf, oiface_conf)) { /* interface conf changed */ ret[i++] = if_index; } @@ -1068,5 +1070,73 @@ changed_ifaces(struct dhcp6leased_conf *oconf, struct dhcp6leased_conf *nconf) int iface_conf_cmp(struct iface_conf *a, struct iface_conf *b) { - return 0; + struct iface_ia_conf *ia_a, *ia_b; + + if (a == NULL && b == NULL) + return 1; + if (a == NULL || b == NULL) + return 0; + + if (a->ia_count != b->ia_count) + return 0; + + ia_a = SIMPLEQ_FIRST(&a->iface_ia_list); + ia_b = SIMPLEQ_FIRST(&b->iface_ia_list); + + for (;;) { + if (!ia_conf_cmp(ia_a, ia_b)) + return 0; + if (ia_a == NULL && ia_b == NULL) + return 1; + ia_a = SIMPLEQ_NEXT(ia_a, entry); + ia_b = SIMPLEQ_NEXT(ia_b, entry); + + } + return 1; +} + +int +ia_conf_cmp(struct iface_ia_conf *a, struct iface_ia_conf *b) +{ + struct iface_pd_conf *pd_a, *pd_b; + + if (a == NULL && b == NULL) + return 1; + if (a == NULL || b == NULL) + return 0; + + if (a->id != b->id) + return 0; + if (a->prefix_len != b->prefix_len) + return 0; + + pd_a = SIMPLEQ_FIRST(&a->iface_pd_list); + pd_b = SIMPLEQ_FIRST(&b->iface_pd_list); + + for (;;) { + if (!pd_conf_cmp(pd_a, pd_b)) + return 0; + + if (pd_a == NULL && pd_b == NULL) + return 1; + + pd_a = SIMPLEQ_NEXT(pd_a, entry); + pd_b = SIMPLEQ_NEXT(pd_b, entry); + + } + return 1; + +} + +int +pd_conf_cmp(struct iface_pd_conf *a, struct iface_pd_conf *b) +{ + if (a == NULL && b == NULL) + return 1; + if (a == NULL || b == NULL) + return 0; + + return (strcmp(a->name, b->name) == 0 && memcmp(&a->prefix_mask, + &b->prefix_mask, sizeof(a->prefix_mask)) == 0 && a->prefix_len == + b->prefix_len); } -- In my defence, I have been left unsupervised.