Skip to content

[neighsyncd]: Replay IPv6 link-local neighbors when enabled - #4867

Open
gs1571 wants to merge 1 commit into
sonic-net:masterfrom
gs1571:fix/neighsyncd-link-local-replay
Open

gs1571 wants to merge 1 commit into
sonic-net:masterfrom
gs1571:fix/neighsyncd-link-local-replay

Conversation

@gs1571

@gs1571 gs1571 commented Sep 5, 2026

Copy link
Copy Markdown

What I did

Updated neighsyncd to replay existing IPv6 link-local neighbors when
ipv6_use_link_local_only is enabled on an interface.

The replay uses a separate Netlink socket and passes matching neighbors through
the existing onMsg() processing path. This preserves the current filtering,
warm-restart behavior, and processing of live neighbor notifications.

Why I did it

The issue occurs in the following sequence:

  1. An IPv6 link-local neighbor is learned by the Linux kernel while
    ipv6_use_link_local_only is disabled.
  2. neighsyncd receives the neighbor event but intentionally ignores it because
    the option is disabled.
  3. The option is enabled later, while the neighbor still exists in the kernel.
  4. No new Netlink neighbor event is generated.

As a result, the neighbor remains present in the Linux neighbor table but is
missing from APPL_DB. Objects that depend on this neighbor, such as an
interface-qualified IPv6 next hop, remain unresolved until another neighbor
event is generated by traffic, a state transition, or manual neighbor
recreation.

The primary goal of this PR is to make enabling
ipv6_use_link_local_only reconcile the already existing kernel neighbor state.
The configuration change must take effect without requiring new traffic or
manual neighbor deletion.

How I verified it

Reproduced the scenario with an IPv6 link-local neighbor created before enabling
ipv6_use_link_local_only.

Before the change:

  • the neighbor remained present in the Linux neighbor table;
  • enabling the option did not add it to APPL_DB;
  • the dependent next hop remained unresolved until a new neighbor event occurred.

After the change:

  • enabling the option replayed the existing neighbor without generating new
    neighbor discovery traffic;
  • the neighbor appeared in APPL_DB;
  • the dependent next hop could be resolved;
  • live Netlink notifications continued to be processed through the original
    socket.

Details if related

The implementation subscribes to INTERFACE, PORTCHANNEL_INTERFACE, and
VLAN_INTERFACE configuration updates.

Only IPv6 link-local neighbors on interfaces where the option has just been
enabled are replayed. Address-entry updates are ignored. Pending replay is
cancelled when the option is disabled or the interface is deleted. A failed
kernel snapshot is retried at most once per second.

@gs1571
gs1571 requested a review from prsunny as a code owner September 5, 2026 13:58
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@mssonicbld

Copy link
Copy Markdown
Collaborator

Hi, there are workflow run(s) waiting for approval, you may be first-time contributor. I will notify maintainers to help approve once PR is approved. Thanks!

---Powered by SONiC BuildBot

@anarasimhan-upscale

Copy link
Copy Markdown

@gs1571, can you please add UT for this change?

@gs1571
gs1571 force-pushed the fix/neighsyncd-link-local-replay branch from 364126b to a0019e1 Compare September 12, 2026 06:42
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@gs1571

gs1571 commented Sep 12, 2026

Copy link
Copy Markdown
Author

@anarasimhan-upscale, added a focused DVS regression test for the reported scenario.

The test creates an IPv6 link-local neighbor while
ipv6_use_link_local_only is disabled, verifies that it is absent from
APPL_DB, then enables the option and verifies that the existing kernel
neighbor is replayed without generating another neighbor event.

This is covered in the DVS suite because the behavior depends on Linux
kernel neighbor state and netlink replay.

Comment thread neighsyncd/neighsyncd.cpp Outdated
{
for (const auto &field : kfvFieldsValues(entry))
{
if (fvField(field) == "ipv6_use_link_local_only" && fvValue(field) == "enable")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this treats every SET whose current row still has ipv6_use_link_local_only=enable as an enable event. SubscriberStateTable returns the full row, so an MTU/VRF update on an already-enabled interface schedules another full kernel dump

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anarasimhan-upscale, thank you for pointing this out.

I updated the implementation to track the observed interface state:

  • The initial SubscriberStateTable snapshot initializes the state without scheduling a replay.
  • A replay is scheduled only on a disabled-to-enabled transition.
  • Unrelated full-row SET updates on an already enabled interface no longer trigger another kernel dump.
  • Disable and delete events clear the state, allowing a later re-enable to schedule a new replay.

I also added focused unit tests covering the initial snapshot, repeated full-row updates, pending replay handling, disable/delete and re-enable transitions, and ignored address rows. The DVS regression test still verifies that a link-local neighbor learned before the option is enabled is replayed to APPL_DB without another neighbor event.

Could you please take another look?

@gs1571
gs1571 force-pushed the fix/neighsyncd-link-local-replay branch from a0019e1 to c23f02b Compare September 15, 2026 09:32
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@anarasimhan-upscale anarasimhan-upscale left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@anarasimhan-upscale

Copy link
Copy Markdown

@prsunny can you please help signoff on this PR?

IPv6 link-local neighbors learned while ipv6_use_link_local_only is
disabled are ignored. Enabling the option does not revisit neighbors
already present in the kernel, leaving APPL_DB without their entries
until another neighbor notification arrives.

Subscribe to interface configuration updates and replay matching kernel
neighbors through the existing onMsg path. Initialize the observed
interface state from the SubscriberStateTable snapshot and schedule a
replay only on a disabled-to-enabled transition, so unrelated full-row
updates on an already enabled interface do not trigger another kernel
dump.

Collect the snapshot on a separate Netlink socket so live notifications
remain queued on the original socket. Retry failed snapshots at most once
per second and preserve normal neighbor filtering and warm-restart
handling.

Add focused unit coverage for initial state, repeated full-row updates,
retries, disable and delete transitions, re-enable, and address rows.
Keep the DVS regression test for replaying an existing kernel neighbor
without a new neighbor event.

Signed-off-by: Grigorii Solovev <gs1571@gmail.com>
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants