[dhcpmon] Report persistent DHCPv4 relay loss per VLAN - #104
Conversation
|
/azp run |
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR updates DHCPv4 relay-disparity reporting to use per-message-type pending-window state (instead of a single aggregate counter) while also adding counter-state synchronization to safely snapshot/update counters across multiple socket event-loop threads.
Changes:
- Add counter-state locking helpers (
counter_state_{read,write}_lock) and use them to coordinate packet handling vs. health checks / DB snapshotting. - Implement per-message-type DHCPv4 “untransmitted window” tracking and emit a single VLAN-level disparity event per outage episode.
- Limit per-callback packet processing to a fixed maximum to reduce time spent holding the counter-state lock.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sock_mgr.h | Adds shared counter-state lock primitives and new cache-counter snapshot APIs. |
| src/sock_mgr.cpp | Implements counter-state locking and snapshot-based DB counter updates. |
| src/packet_handler.cpp | Acquires counter-state read lock during packet processing and bounds packets per callback. |
| src/health_check.cpp | Switches DHCPv4 disparity reporting to per-message pending-window state with latching. |
| src/dhcp_mon.cpp | Wraps health checks, status printing, and DB sync snapshotting with counter-state write locks; resets DHCPv4 health state at init. |
| src/dhcp_device.h | Exposes API to compute per-message-type untransitted-window ages and to reset DHCPv4 health state. |
| src/dhcp_device.cpp | Implements per-message-type relay flow state tracking and integrates it into positive-health evaluation. |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/sock_mgr.h:142
- sock_mgr_copy_cache_counters() performs a deep copy of the cache counter maps; this must be done while holding counter_state_write_lock, otherwise concurrent packet-handler updates can mutate (and rehash) the unordered_maps during the copy. Please document this requirement in the header to avoid accidental unsafe use by future call sites.
/** Copy cache counters for all sockets */
socket_counters_t sock_mgr_copy_cache_counters();
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
src/health_check.cpp:63
- check_relay_disparity() latches DHCPv4 disparity with one global flag, so it only clears when all message types have no pending windows. This doesn’t match the stated approach of clearing each message type’s latch when its matching TX recovers; consider tracking latches per message type and still emitting only one VLAN-level event.
static void check_relay_disparity()
{
auto windows_by_type = dhcp_device_get_untransmitted_windows(agg_dev_all);
uint32_t report_windows = 0;
bool has_pending = false;
src/sock_mgr.h:141
- sock_mgr_copy_cache_counters() and the snapshot-based sock_mgr_update_db_counters() are now part of the counter-state synchronization story, but their comments don’t state the locking contract. Since these functions iterate/copy mutable cache counter structures, document that callers must hold counter_state_write_lock (or take the lock internally) to avoid races with packet handling.
/** Write a previously locked, immutable cache-counter snapshot */
void sock_mgr_update_db_counters(const socket_counters_t &counters_by_socket);
/** Copy cache counters for all sockets; caller must hold counter_state_write_lock */
socket_counters_t sock_mgr_copy_cache_counters();
|
/azp run |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
70808f7 to
0a65eda
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
0a65eda to
bbba74f
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
| [1] = { | ||
| .check_health = check_agg_health_v6, | ||
| .alert = alert_dhcp_relay_disparity, | ||
| .log = log_agg_error, | ||
| .log = log_v6_agg_error, | ||
| .count = 0, | ||
| }, |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/health_check.cpp:190
- The DHCPv6 aggregate check is still configured to publish the same "dhcp-relay-disparity" event (and log) when it becomes UNHEALTHY. This contradicts the PR dependency notes (#101 disables the invalid DHCPv6 same-type RX/TX disparity signal) and can also create duplicate/false disparity events because DHCPv6 relay transforms message types at the boundary.
If DHCPv6 disparity is intentionally disabled, the v6 aggregate check should not alert/log the disparity event.
.alert = alert_dhcp_relay_disparity,
.log = log_v6_agg_error,
| /** | ||
| * @brief Update and return unmatched DHCPv4 relay RX age in health windows per message type. | ||
| */ | ||
| std::unordered_map<int, uint32_t> dhcp_device_get_untransmitted_windows(const std::string &ifname); |
| /** Reset DHCPv4 relay-flow watermarks */ | ||
| void dhcp_device_reset_health_state(const std::string &ifname); |
Track unmatched receive activity by message type so idle windows and adjacent transmit activity do not create false relay-loss state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 <lukelin0907@gmail.com>
Publish one VLAN-level disparity episode from the independent per-message unmatched receive windows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 39f979be-d826-4d5c-949a-f20abb58bb83 Signed-off-by: Xichen96 <lukelin0907@gmail.com>
bbba74f to
9fdb23c
Compare
| int64_t duration_value = static_cast<int64_t>(report_windows) * window_interval_sec; | ||
| int duration = static_cast<int>(std::min( | ||
| duration_value, static_cast<int64_t>(std::numeric_limits<int>::max()))); |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
|
Closing because this reporting PR depends entirely on #103 persistent unmatched-window state, which is being replaced by stateless one-packet-in-flight tolerance. |
Description of PR
Report DHCPv4 relay disparity from independent per-message pending-window
state instead of one shared aggregate health counter.
Dependencies:
Work item tracking
Type of change
Approach
Simultaneous or staggered message types produce one VLAN-level event because
the existing event contract has no message-type field.
Verification
F2 hardware with a real post-VLAN/no-TX outage produced one disparity log/event.
The pre-VLAN
min_linksloss produced no disparity event.Fresh exact-head Azure PR CI is pending. No local compilation is used.
Back port request
None. This targets master only.