MIGSOFTWAR-41070: dhcp4relay drops packets on first VLANs in large batch#112
Open
cshivashgit wants to merge 1 commit into
Open
MIGSOFTWAR-41070: dhcp4relay drops packets on first VLANs in large batch#112cshivashgit wants to merge 1 commit into
cshivashgit wants to merge 1 commit into
Conversation
When a large batch of DHCPV4_RELAY VLANs is configured alongside their
underlying VLAN_INTERFACEs and a Loopback used as source_interface, the
first ~10 VLANs silently drop relayed DHCP packets with
"No IPv4 address configured".
Root cause: prepare_relay_interface_config() resolves the source
interface IP via getifaddrs(). At scale, intfmgrd has not yet programmed
the Loopback IP into the kernel by the time the DHCPV4_RELAY config
arrives, so getifaddrs() misses it, src_intf_sel_addr is left at
0.0.0.0, and from_client() drops every packet for those VLANs. The
authoritative source IP is already known to the dhcp4relay process at
that point (as a *INTERFACE pub/sub event has either landed in the
SubscriberStateTable buffer or already passed through
process_interface_notification with no matching vlan in vlans_copy);
only the kernel state is behind.
Fix: maintain an in-process intf_to_addr_cache map populated as a
side-effect of process_interface_notification, and dispatch
DHCPv4_RELAY_INTERFACE_UPDATE from that cache when a DHCPV4_RELAY batch
registers a vlan whose source_interface IP was cached but never
replayed. No Redis access on the hot path.
Wired in two places:
- In the startup predrain block of handle_swss_notification(), after
process_relay_notification(initial_entries) and before the
DHCPv4_RELAY_SYNC_BARRIER write, drain the *INTERFACE
SubscriberStateTables and feed them through
process_interface_notification. The buffers were seeded by their
construction-time SCAN, so this both populates the cache and
dispatches INTERFACE_UPDATE for vlans registered by the relay
drain immediately above.
- In the runtime select loop, immediately after the DHCPV4_RELAY
branch's process_relay_notification(entries) call, replay matching
cache entries via dispatch_source_intf_from_cache() so a vlan whose
source_interface IP arrived earlier (and was discarded by
process_interface_notification because vlans_copy didn't yet
contain the vlan) still receives a correct src_intf_sel_addr
before any packet reaches prepare_relay_interface_config().
INTERFACE_UPDATE is the same event type produced by
process_interface_notification, so the main thread handler in
dhcp4relay.cpp needs no change. Idempotent: the existing kernel-driven
INTERFACE flow simply rewrites the same src_intf_sel_addr if it later
delivers another event for the same interface.
Signed-off-by: Shivashankar CR <shivashankar.c.r@gmail.com>
Collaborator
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a large batch of DHCPV4_RELAY VLANs is configured alongside their underlying VLAN_INTERFACEs and a Loopback used as source_interface, the first ~10 VLANs silently drop relayed DHCP packets with "No IPv4 address configured".
Root cause: prepare_relay_interface_config() resolves the source interface IP via getifaddrs(). At scale, intfmgrd has not yet programmed the Loopback IP into the kernel by the time the DHCPV4_RELAY config arrives, so getifaddrs() misses it, src_intf_sel_addr is left at 0.0.0.0, and from_client() drops every packet for those VLANs. The authoritative source IP is already known to the dhcp4relay process at that point (as a *INTERFACE pub/sub event has either landed in the SubscriberStateTable buffer or already passed through process_interface_notification with no matching vlan in vlans_copy); only the kernel state is behind.
Fix: maintain an in-process intf_to_addr_cache map populated as a side-effect of process_interface_notification, and dispatch DHCPv4_RELAY_INTERFACE_UPDATE from that cache when a DHCPV4_RELAY batch registers a vlan whose source_interface IP was cached but never replayed. No Redis access on the hot path.
Wired in two places:
In the startup predrain block of handle_swss_notification(), after process_relay_notification(initial_entries) and before the DHCPv4_RELAY_SYNC_BARRIER write, drain the *INTERFACE SubscriberStateTables and feed them through process_interface_notification. The buffers were seeded by their construction-time SCAN, so this both populates the cache and dispatches INTERFACE_UPDATE for vlans registered by the relay drain immediately above.
In the runtime select loop, immediately after the DHCPV4_RELAY branch's process_relay_notification(entries) call, replay matching cache entries via dispatch_source_intf_from_cache() so a vlan whose source_interface IP arrived earlier (and was discarded by process_interface_notification because vlans_copy didn't yet contain the vlan) still receives a correct src_intf_sel_addr before any packet reaches prepare_relay_interface_config().
INTERFACE_UPDATE is the same event type produced by process_interface_notification, so the main thread handler in dhcp4relay.cpp needs no change. Idempotent: the existing kernel-driven INTERFACE flow simply rewrites the same src_intf_sel_addr if it later delivers another event for the same interface.