Skip to content

[EVPN-MH] Add kernel patches for EVPN VXLAN Multihoming support#540

Open
bdfriedman wants to merge 4 commits intosonic-net:masterfrom
bdfriedman:evpn_mh
Open

[EVPN-MH] Add kernel patches for EVPN VXLAN Multihoming support#540
bdfriedman wants to merge 4 commits intosonic-net:masterfrom
bdfriedman:evpn_mh

Conversation

@bdfriedman
Copy link
Copy Markdown

@bdfriedman bdfriedman commented Feb 25, 2026

Why I did it

This PR adds three critical Linux kernel patches required to enable EVPN VXLAN Multihoming in SONiC. These kernel enhancements provide the necessary infrastructure for:

  1. Extended neighbor flags for multi-homing peer synchronization
  2. Protocol field tracking in bridge FDB entries to distinguish control plane vs data plane learned MACs
  3. External validation flag to prevent kernel from invalidating externally managed neighbor entries

These patches are essential for implementing the EVPN-MH feature as described in the EVPN VXLAN Multihoming HLD.

NOTE: The file patches-sonic/0003-neighbor-Add-NTF_EXT_VALIDATED-flag-for-externally-v.patch has been committed upstream to the Linux kernel master branch. See torvalds/linux@03dc03f

Work item tracking
  • Microsoft ADO (number only):

How I did it

Added three kernel patches to patches-sonic directory:

1. NDA_FLAGS_EXT Support with NTF_EXT_MH_PEER_SYNC (0001-vxlan-bridge-Add-NDA_FLAGS_EXT-support-with-NTF_EXT_.patch)

This patch adds extended flags support for VXLAN and bridge FDB entries to enable multi-homing peer synchronization:

  • New field: ext_flags in vxlan_fdb structure
  • New flag: NTF_EXT_MH_PEER_SYNC - Indicates FDB entry is synchronized across EVPN-MH peers
  • New neighbor update flag: NEIGH_UPDATE_F_EXT_MH_PEER_SYNC for propagating sync state
  • Modified functions:
    • vxlan_fdb_alloc() - Initialize ext_flags
    • vxlan_fdb_create() - Pass ext_flags parameter
    • vxlan_fdb_update_existing() - Handle ext_flags updates and notifications
    • vxlan_fdb_update_create() - Create FDB with ext_flags
    • vxlan_fdb_info() - Include NDA_FLAGS_EXT in netlink messages
    • Bridge FDB functions - Propagate ext_flags through bridge layer

Files modified:

  • drivers/net/vxlan/vxlan_core.c (140 lines)
  • drivers/net/vxlan/vxlan_private.h (21 lines)
  • drivers/net/vxlan/vxlan_vnifilter.c (11 lines)
  • include/net/neighbour.h (4 lines)
  • include/uapi/linux/neighbour.h (1 line)
  • net/bridge/br.c (4 lines)
  • net/bridge/br_fdb.c (35 lines)
  • net/bridge/br_private.h (5 lines)
  • net/core/neighbour.c (13 lines)

2. Protocol Field in Bridge FDB (0001-net-bridge-vxlan-Protocol-field-in-bridge-fdb.patch)

This patch introduces an optional "protocol" field for bridge FDB entries to distinguish between control plane and data plane learned MAC addresses:

Purpose: In EVPN Multihoming, MAC addresses can be learned via:

  • Control plane (ZEBRA protocol): Static MACs distributed by FRR/BGP
  • Data plane (HW protocol): Dynamic MACs learned from traffic with aging enabled

This distinction enables:

  • Proper state machine management during MAC transitions
  • Handling traffic hashing between EVPN-MH peers
  • Managing MAC mobility across EVPN peers
  • Synchronization between control and data planes

Implementation:

  • New field: protocol in net_bridge_fdb_entry and vxlan_fdb structures
  • Protocol values: Uses standard routing protocol values (RTPROT_UNSPEC, RTPROT_ZEBRA, RTPROT_KERNEL, etc.)
  • Default: RTPROT_UNSPEC when protocol not specified (backward compatible)
  • NDA_PROTOCOL attribute: Encoded in netlink messages for FDB entries

Usage Example:

# Add MAC with hardware protocol (data plane learned)
bridge fdb add 00:00:00:00:00:88 dev hostbond2 vlan 1000 master dynamic extern_learn proto hw

# Display with protocol field
bridge -d fdb show dev hostbond2
# Output: 00:00:00:00:00:88 vlan 1000 extern_learn master br1000 proto hw

# Transition to zebra (control plane)
bridge fdb replace 00:00:00:00:00:88 dev hostbond2 vlan 1000 master dynamic extern_learn proto zebra

Files modified:

  • drivers/net/vxlan/vxlan_core.c (55 lines)
  • drivers/net/vxlan/vxlan_private.h (5 lines)
  • drivers/net/vxlan/vxlan_vnifilter.c (4 lines)
  • net/bridge/br.c (2 lines)
  • net/bridge/br_fdb.c (55 lines)
  • net/bridge/br_private.h (5 lines)

3. NTF_EXT_VALIDATED Flag for External Validation (0001-neighbor-Add-NTF_EXT_VALIDATED-flag-for-externally-v.patch)

This patch adds a new "extern_valid" neighbor flag to indicate entries learned and validated externally that should not be invalidated by the kernel:

Background: In EVPN multi-homing:

  • Each host is multi-homed via Ethernet Segment (ES/LAG) to multiple VTEPs
  • Neighbor entries are distributed to ES peers using EVPN MAC/IP advertisement routes
  • When an ES link goes down, EVPN routes are withdrawn, causing intermittent failures

Solution (based on draft-rbickhart-evpn-ip-mac-proxy-adv-03):

  • ES peers install neighbor entries and inject proxy EVPN MAC/IP advertisements
  • When ES link goes down, ES peers start aging timers instead of immediately withdrawing
  • If an ES peer locally learns the entry (becomes "reachable"), it restarts timer and removes proxy indication
  • Prevents intermittent routing failures during ES link transitions

Implementation:

  • New flag: NTF_EXT_VALIDATED (extern_valid) - Entry is externally validated
  • Behavior:
    • Kernel will NOT remove or invalidate the entry
    • Kernel can probe the entry and notify user space when it becomes "reachable"
    • If no confirmation received, kernel returns entry to "stale" state (NOT "failed" state)
    • Control plane (FRR) manages entry lifecycle
  • Initial state: "stale" when installed by control plane
  • State transitions: Kernel notifies control plane when entry becomes "reachable"

Use case: Required for EVPN-MH proxy advertisements where control plane needs full control over neighbor entry validity and removal decisions.

Files modified:

  • Neighbor subsystem for external validation support
  • Netlink attributes for extern_valid flag
  • State machine modifications

How to verify it

  1. Build kernel with these patches applied:

    cd sonic-linux-kernel
    make BLDENV=bookworm
  2. Verify NDA_FLAGS_EXT support:

    # Add FDB entry with extended flags
    bridge fdb add <mac> dev <vxlan-dev> dst <vtep-ip> vni <vni> extern_learn
    
    # Verify in kernel via netlink dump
    bridge -d fdb show | grep <mac>
  3. Verify protocol field support:

    # Add MAC with specific protocol
    bridge fdb add <mac> dev <device> vlan <vid> master dynamic extern_learn proto hw
    
    # Verify protocol shows up
    bridge -d fdb show dev <device> | grep <mac>
    # Expected output includes: proto hw
    
    # Transition protocol
    bridge fdb replace <mac> dev <device> vlan <vid> master dynamic extern_learn proto zebra
    
    # Verify protocol changed
    bridge -d fdb show dev <device> | grep <mac>
    # Expected output includes: proto zebra
  4. Verify extern_valid flag:

    # Add neighbor with extern_valid flag (via FRR/control plane)
    # Entry should remain in "stale" state and not be removed by kernel GC
    
    # Monitor neighbor state transitions
    ip -d neigh show
  5. Integration testing with EVPN-MH:

    • Configure EVPN multi-homing with ES peers
    • Verify MAC/neighbor synchronization across peers
    • Test ES link failure scenarios
    • Verify proxy advertisements and aging behavior
    • Confirm no intermittent routing/ARP failures during transitions
  6. Compatibility testing:

    • Verify existing bridge/VXLAN functionality still works
    • Test backward compatibility (entries without new fields/flags)
    • Confirm no regressions in non-EVPN scenarios

Which release branch to backport (provide reason below if selected)

  • 202305
  • 202311
  • 202405
  • 202411
  • 202505
  • 202511

Tested branch (Please provide the tested image version)

Description for the changelog

Add kernel patches for EVPN VXLAN Multihoming: extended FDB flags (NTF_EXT_MH_PEER_SYNC), protocol field for bridge FDB entries, and extern_valid flag for externally validated neighbor entries

Link to config_db schema for YANG model changes

N/A - This PR only adds kernel patches, no CONFIG_DB schema changes

Depends on

Related upstream work

  • EVPN MAC/IP proxy advertisement draft: draft-rbickhart-evpn-ip-mac-proxy-adv-03
  • Kernel patch for protocol field: Authored by Mrinmoy Ghosh mrghosh@cisco.com

Summary:

  • Total patches: 3
  • Total lines added: +1,558
  • Kernel subsystems modified: VXLAN driver, bridge FDB, neighbor subsystem, netlink attributes
  • Backward compatible: Yes - all new fields/flags are optional with sensible defaults

Critical for EVPN-MH:
✅ Peer synchronization flag (NTF_EXT_MH_PEER_SYNC)
✅ Control/data plane MAC distinction (protocol field)
✅ External neighbor validation (extern_valid flag)
✅ Proxy advertisement support
✅ Prevents intermittent EVPN-MH failures

@bdfriedman bdfriedman requested a review from a team as a code owner February 25, 2026 22:19
@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@lguohan
Copy link
Copy Markdown
Contributor

lguohan commented Mar 11, 2026

@bdfriedman , are these PR upstreamed to linux kernel already? or in the process of upstream?

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • Bug in br.c (patch 2): br_switchdev_event passes fdb_info->locked (bool) as the protocol parameter and RTPROT_UNSPEC as ext_flags — argument order is wrong after the signature change
  • Bug in br_fdb_add (patch 2): protocol is initialized to RTPROT_UNSPEC but never parsed from tb[NDA_PROTOCOL] — the add path silently ignores the user-supplied protocol, unlike the delete path which parses it correctly
  • Patch 1 (NDA_FLAGS_EXT) and Patch 3 (NTF_EXT_VALIDATED) look structurally sound
  • Patches are not upstream-accepted — these appear to be custom SONiC patches carrying significant kernel neighbor/FDB subsystem changes

}

- err = __br_fdb_delete(br, p, addr, vid);
+ err = __br_fdb_delete(br, p, addr, vid, protocol);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Wrong argument order. After adding protocol to br_fdb_external_learn_add's signature (as the 5th positional param after vid), this call site passes fdb_info->locked as protocol and appends RTPROT_UNSPEC at the end as ext_flags.

Current: (br, p, addr, vid, fdb_info->locked, false, 0, RTPROT_UNSPEC)
Expected: (br, p, addr, vid, RTPROT_UNSPEC, fdb_info->locked, false, 0)

When fdb_info->locked is true, the entry will get protocol=1 instead of RTPROT_UNSPEC, and locked will silently be forced to false.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open. In the new patch 0002, br_switchdev_event calls br_fdb_external_learn_add(br, p, fdb_info->addr, fdb_info->vid, fdb_info->locked, false, 0, RTPROT_UNSPEC) but the updated signature is (br, p, addr, vid, protocol, locked, swdev_notify, ext_flags). So fdb_info->locked (bool) is still being passed as protocol (u8).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in dd2f4ef. br_switchdev_event passes fdb_info->locked as protocol and RTPROT_UNSPEC as ext_flags. Should be: br_fdb_external_learn_add(br, p, fdb_info->addr, fdb_info->vid, RTPROT_UNSPEC, fdb_info->locked, false, 0).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in iteration 2. This bug remains in the current diff.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 41a91c8. br_switchdev_event now correctly passes RTPROT_UNSPEC as protocol before fdb_info->locked. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 0ae2cb5. br_switchdev_event now passes RTPROT_UNSPEC as protocol before fdb_info->locked. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified fixed in 0ae2cb5. The argument order is now correct.

- bool swdev_notify, u32 ext_flags)
+ const unsigned char *addr, u16 vid, u8 protocol,
+ bool locked, bool swdev_notify, u32 ext_flags)
{
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: protocol is never parsed from netlink in the add path. The variable is initialized to RTPROT_UNSPEC but there's no if (tb[NDA_PROTOCOL]) protocol = nla_get_u8(tb[NDA_PROTOCOL]); anywhere in br_fdb_add. Compare with br_fdb_delete which correctly parses it. This means bridge fdb add ... proto hw will silently ignore the protocol — it will always store RTPROT_UNSPEC.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open. br_fdb_add initializes u8 protocol = RTPROT_UNSPEC but never parses tb[NDA_PROTOCOL]. The parsing only exists in br_fdb_delete and vxlan_fdb_parse, not in the bridge add path.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed. br_fdb_add declares u8 protocol = RTPROT_UNSPEC but never parses tb[NDA_PROTOCOL]. The parsing block (if (tb[NDA_PROTOCOL]) protocol = nla_get_u8(...)) exists in br_fdb_delete but is missing from br_fdb_add.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in iteration 2. This bug remains in the current diff.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 41a91c8. br_fdb_add now parses tb[NDA_PROTOCOL] via nla_get_u8. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in 0ae2cb5. br_fdb_add declares u8 protocol = RTPROT_UNSPEC but never parses tb[NDA_PROTOCOL]. The parsing exists in br_fdb_delete but is still missing from br_fdb_add.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 27a7faf. br_fdb_add now correctly parses tb[NDA_PROTOCOL] via nla_get_u8. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified fixed in 27a7faf. br_fdb_add now parses NDA_PROTOCOL.

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • Patch ordering concern: Patch 2 (protocol field) modifies br_fdb_external_learn_add signature from patch 1 but gets argument order wrong in br.c (already noted by prior reviewer).
  • Missing NDA_PROTOCOL parse in br_fdb_add: protocol is initialized to RTPROT_UNSPEC but never read from tb[NDA_PROTOCOL], so bridge fdb add silently ignores user-specified protocol (already noted).
  • Internal callers can silently overwrite protocol: vxlan_snoop and vxlan_fdb_external_learn_add pass RTPROT_UNSPEC — if the entry already has a real protocol set, it gets silently cleared on update.
  • Patches are well-structured overall: Clean kernel patch backports with proper commit messages and sign-offs. The NTF_EXT_VALIDATED and NTF_EXT_MH_PEER_SYNC patches look correct.

int err;

if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
@@ -1281,7 +1296,7 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Protocol overwrite on internal update. When vxlan_fdb_update_existing is called by internal callers like vxlan_snoop or vxlan_fdb_external_learn_add with RTPROT_UNSPEC, this block will overwrite any previously-set protocol value back to 0. Consider guarding with if (protocol != RTPROT_UNSPEC && f->protocol != protocol) to avoid unintentional protocol clearing by internal callers that don't carry protocol context.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open. vxlan_fdb_update_existing unconditionally sets f->protocol = protocol when they differ. Internal callers like vxlan_snoop pass RTPROT_UNSPEC, which will overwrite a previously-set protocol value.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed. vxlan_fdb_update_existing unconditionally overwrites f->protocol when values differ. Internal callers like vxlan_snoop pass RTPROT_UNSPEC, which will clear a previously-set protocol value (e.g. RTPROT_ZEBRARTPROT_UNSPEC).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in iteration 2. This bug remains in the current diff.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in 41a91c8. vxlan_fdb_update_existing unconditionally overwrites f->protocol when values differ. Internal callers like vxlan_snoop pass RTPROT_UNSPEC, which will clear a previously-set protocol (e.g. RTPROT_ZEBRARTPROT_UNSPEC). Needs a guard: if (protocol != RTPROT_UNSPEC && ...).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 0ae2cb5. Guard now uses if (protocol != RTPROT_UNSPEC && f->protocol != protocol). ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 0ae2cb5. vxlan_fdb_update_existing now guards with if (protocol != RTPROT_UNSPEC && f->protocol != protocol), preventing internal callers from clobbering a previously-set protocol. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified fixed. vxlan_fdb_update_existing now guards with if (protocol != RTPROT_UNSPEC && f->protocol != protocol).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed. vxlan_fdb_update_existing now guards with if (protocol != RTPROT_UNSPEC && f->protocol != protocol), preventing snoop from clearing control-plane protocol. ✅

if (!fdb || READ_ONCE(fdb->dst) != p)
return -ENOENT;

+ /* If the delete comes from a different protocol type,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Non-extern_learn path doesn't propagate protocol. When __br_fdb_add takes the fdb_add_entry path (non-extern_learn), the protocol parameter is unused — fdb_add_entry never receives or sets it. This means bridge fdb add ... proto hw without extern_learn will silently store RTPROT_UNSPEC. Either fdb_add_entry should also accept and set protocol, or the kernel should reject protocol with non-extern_learn entries.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open. __br_fdb_add passes protocol to br_fdb_external_learn_add but the fdb_add_entry path (non-extern_learn) still does not receive or set the protocol field.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed. fdb_add_entry does not accept or set the protocol field. bridge fdb add without extern_learn will always store RTPROT_UNSPEC regardless of what protocol is specified.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in iteration 2. This bug remains in the current diff.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in 41a91c8. fdb_add_entry (non-extern_learn path) still does not receive or set the protocol field. bridge fdb add without extern_learn will always store RTPROT_UNSPEC.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in 0ae2cb5. fdb_add_entry does not accept or set the protocol field. The non-extern_learn path will always store RTPROT_UNSPEC.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 27a7faf. fdb_add_entry now accepts a protocol parameter and sets fdb->protocol accordingly. Both the add-path parsing and propagation are addressed. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified fixed in 27a7faf. fdb_add_entry now propagates the protocol field.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed. fdb_add_entry now accepts and sets the protocol field. ✅

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • VXLAN FDB protocol field not emitted in netlink dumps: vxlan_fdb_info() is not updated to include NDA_PROTOCOL in the protocol patch, so VXLAN FDB dumps won't show the protocol even though it's stored internally. Bridge side (fdb_fill_info) does this correctly.
  • Existing review comments correctly identify: wrong argument order in br_switchdev_event call, missing NDA_PROTOCOL parsing in br_fdb_add, protocol not propagated through fdb_add_entry path, and protocol overwrite risk from internal VXLAN callers.
  • NTF_EXT_VALIDATED patch is well-designed — proper state validation, GC exemption, stale-instead-of-failed fallback, and carrier-down protection.
  • NTF_EXT_MH_PEER_SYNC / ext_flags plumbing through VXLAN and bridge layers looks correct.
  • All three patches use 0001- prefix — consider renaming to 0001-/0002-/0003- for clarity in the series.

6 files changed, 85 insertions(+), 41 deletions(-)

diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index de1b3fa96..c34b9f75c 100644
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing: vxlan_fdb_info() does not emit NDA_PROTOCOL. The protocol field is stored in vxlan_fdb and parsed/updated correctly, but vxlan_fdb_info() (the function that builds netlink messages for VXLAN FDB dumps) is never updated to include nla_put_u8(skb, NDA_PROTOCOL, fdb->protocol). This means bridge fdb show for VXLAN devices won't display the protocol, even though it's correctly tracked internally.

Compare with the bridge side where fdb_fill_info() correctly adds NDA_PROTOCOL. The same needs to happen in vxlan_fdb_info() — likely right after the existing NDA_VNI put.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in the latest push — vxlan_fdb_info() now emits NDA_PROTOCOL. Thanks!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Confirmed fixed. vxlan_fdb_info() now emits NDA_PROTOCOL via nla_put_u8. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Confirmed still fixed in 0ae2cb5. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified fixed. vxlan_fdb_info now emits NDA_PROTOCOL.

@tahmed-dev
Copy link
Copy Markdown

Patch 3 (NTF_EXT_VALIDATED) is upstreamed and merged — great. Patches 1 and 2 appear to be Cisco-specific and not yet submitted upstream. Are there plans to upstream these? Carrying out-of-tree kernel patches long-term creates maintenance burden on every kernel version bump. If there are upstream submissions in progress, linking them here would help reviewers assess the risk.

@tahmed-dev
Copy link
Copy Markdown

The series file applies NDA_FLAGS_EXT first, then Protocol, then NTF_EXT_VALIDATED. But NTF_EXT_VALIDATED is already in mainline (merged by Kicinski). When SONiC bumps to a kernel that includes it natively, the patch will fail to apply. Should this be gated with a version check, or is the plan to drop it from the series once the kernel is rebased past that commit?

@tahmed-dev
Copy link
Copy Markdown

The bugs flagged by banidoru (wrong argument order in br_fdb_external_learn_add, protocol never parsed from netlink in the add path, protocol overwrite on internal update, non-extern_learn path missing propagation, NDA_PROTOCOL not emitted in vxlan_fdb_info) look like they'd break the protocol field feature on real hardware. Are fixes in progress?

@saiarcot895
Copy link
Copy Markdown
Contributor

saiarcot895 commented Apr 20, 2026

Agree with what Tamer has said about upstreaming patches. There is already a fullcone NAT patch in this repo that hasn't been upstreamed, requires significant maintenance work to update, and is currently not getting applied on the Trixie kernel because no one has updated it. I do not want another instance of that.

Additionally, if a patch has been upstreamed, please use the git patch from upstream, adjust for any patch conflicts, and (preferably) add the commit ID in the patch description.

@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

Re-review (iteration 2):

  • Fixed: vxlan_fdb_info() now emits NDA_PROTOCOL — resolved
  • Still open (bug): br_switchdev_event passes fdb_info->locked as protocol — wrong argument order after patch 0002 changes the signature
  • Still open (bug): br_fdb_add never parses tb[NDA_PROTOCOL] — protocol is always RTPROT_UNSPEC in the bridge add path
  • Still open: vxlan_fdb_update_existing unconditionally overwrites protocol from internal callers passing RTPROT_UNSPEC
  • Still open: non-extern_learn path in __br_fdb_add ignores the protocol parameter

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

Re-review (iteration 2) — 4 of 5 previous issues remain unaddressed:

  • br_switchdev_event wrong arg order: fdb_info->locked passed as protocol param — will interpret bool as protocol type
  • br_fdb_add missing NDA_PROTOCOL parse: protocol always RTPROT_UNSPEC on add path
  • vxlan_fdb_update_existing unconditional overwrite: internal callers (snoop) clear previously-set protocol to RTPROT_UNSPEC
  • fdb_add_entry ignores protocol: non-extern_learn bridge FDB adds never store protocol

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • Patch 0002 bug: br_switchdev_event passes fdb_info->locked as protocol — wrong argument order after signature change
  • Patch 0002 bug: br_fdb_add never parses tb[NDA_PROTOCOL]bridge fdb add ... proto hw silently ignored
  • Patch 0002 design: vxlan_fdb_update_existing unconditionally overwrites protocol — internal callers (e.g. vxlan_snoop) will clear previously-set protocol values
  • Patch 0002 design: fdb_add_entry (non-extern_learn path) ignores protocol param — silent data loss
  • Patch 0002 fix confirmed: vxlan_fdb_info now emits NDA_PROTOCOL
  • Patches 0001, 0003: No new issues found; well-structured kernel patches with proper state machine handling

@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • Fixed: br_switchdev_event arg order — RTPROT_UNSPEC now correctly passed as protocol
  • Fixed: br_fdb_add now parses tb[NDA_PROTOCOL] from netlink
  • Still open: vxlan_fdb_update_existing unconditionally overwrites f->protocol — internal callers like vxlan_snoop will clear a previously-set protocol value
  • Still open: fdb_add_entry (non-extern_learn path) ignores protocol — bridge fdb add without extern_learn always stores RTPROT_UNSPEC

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

Iteration 3 re-review:

  • br_switchdev_event argument order fixed — RTPROT_UNSPEC now correctly passed as protocol
  • br_fdb_add now parses tb[NDA_PROTOCOL]
  • vxlan_fdb_info() emits NDA_PROTOCOL (confirmed in prior iteration)
  • vxlan_fdb_update_existing still unconditionally overwrites f->protocol — internal callers passing RTPROT_UNSPEC will clear a previously-set protocol
  • fdb_add_entry (non-extern_learn path) still ignores the protocol parameter

int err;

if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_REACHABLE))) {
@@ -1281,7 +1296,7 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in iteration 3. vxlan_fdb_update_existing does if (f->protocol != protocol) { f->protocol = protocol; } but internal callers like vxlan_snoop pass RTPROT_UNSPEC. This will silently clear a protocol value set by the control plane (e.g. RTPROT_ZEBRARTPROT_UNSPEC).

Suggested fix: if (protocol != RTPROT_UNSPEC && f->protocol != protocol)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 0ae2cb5. vxlan_fdb_update_existing now correctly guards with if (protocol != RTPROT_UNSPEC && f->protocol != protocol). ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Confirmed fixed in 0ae2cb5. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified fixed in 0ae2cb5.

if (!fdb || READ_ONCE(fdb->dst) != p)
return -ENOENT;

+ /* If the delete comes from a different protocol type,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in iteration 3. fdb_add_entry does not accept or set the protocol field. bridge fdb add without extern_learn will always store RTPROT_UNSPEC regardless of what protocol the user specifies.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in 0ae2cb5. The commit message claims "fdb_add_entry: propagate protocol for non-extern_learn path" but __br_fdb_add still calls fdb_add_entry(br, p, addr, ndm, nlh_flags, vid, nfea_tb) without passing protocol. The fdb_add_entry function signature is unchanged.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still unaddressed in 0ae2cb5. br_fdb_add never parses tb[NDA_PROTOCOL] so protocol is always RTPROT_UNSPEC — even __br_fdb_add receives it but it is always 0. Both the add-path parsing and fdb_add_entry propagation are missing.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Confirmed still unaddressed in 0ae2cb5. br_fdb_add declares u8 protocol = RTPROT_UNSPEC at line 1218 but there is no if (tb[NDA_PROTOCOL]) protocol = nla_get_u8(...) anywhere before it's used. The non-extern_learn path (fdb_add_entry) also never receives protocol. Both the add-path parse and fdb_add_entry propagation are missing.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in 27a7faf. br_fdb_add now parses tb[NDA_PROTOCOL] and passes it through __br_fdb_addfdb_add_entry. Both paths (extern_learn and non-extern_learn) now propagate protocol correctly. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified fixed in 27a7faf.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed. The update path now correctly guards with if (protocol != RTPROT_UNSPEC && fdb->protocol != protocol). ✅

@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 4, 2026

CLA Missing ID CLA Not Signed

One or more co-authors of this pull request were not found. You must specify co-authors in commit message trailer via:

Co-authored-by: name <email>

Supported Co-authored-by: formats include:

  1. Anything <id+login@users.noreply.github.com> - it will locate your GitHub user by id part.
  2. Anything <login@users.noreply.github.com> - it will locate your GitHub user by login part.
  3. Anything <public-email> - it will locate your GitHub user by public-email part. Note that this email must be made public on Github.
  4. Anything <other-email> - it will locate your GitHub user by other-email part but only if that email was used before for any other CLA as a main commit author.
  5. login <any-valid-email> - it will locate your GitHub user by login part, note that login part must be at least 3 characters long.

Alternatively, if the co-author should not be included, remove the Co-authored-by: line from the commit message.

Please update your commit message(s) by doing git commit --amend and then git push [--force] and then request re-running CLA check via commenting on this pull request:

/easycla

@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

Add three Linux kernel patches required for EVPN VXLAN Multihoming in SONiC:

1. NDA_FLAGS_EXT with NTF_EXT_MH_PEER_SYNC - Extended FDB flags for
   multi-homing peer synchronization across EVPN-MH peers.

2. Protocol field in bridge FDB - Distinguishes control plane (zebra)
   vs data plane (hw) learned MACs for proper EVPN-MH state management.

3. NTF_EXT_VALIDATED for externally validated neighbors - Prevents kernel
   from invalidating neighbor entries managed by the control plane during
   ES link transitions.

These patches are essential for the EVPN-MH feature described in:
https://github.com/sonic-net/SONiC/blob/master/doc/vxlan/EVPN/EVPN_VxLAN_Multihoming.md

Co-authored-by: Barry Friedman (friedman) <friedman@cisco.com>
Co-authored-by: Mrinmoy Ghosh <mrghosh@cisco.com>
Signed-off-by: Tamer Ahmed <tamerahmed@microsoft.com>
@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

Iteration 4 Re-review (0ae2cb5)

Fixes confirmed:

  • vxlan_fdb_update_existing: now guards with if (protocol != RTPROT_UNSPEC && ...) — prevents internal callers from clearing protocol
  • vxlan_fdb_info(): emits NDA_PROTOCOL
  • br_fdb_add: now parses tb[NDA_PROTOCOL]
  • br_switchdev_event: correct argument order with RTPROT_UNSPEC as protocol

Remaining issue:

  • fdb_add_entry (non-extern_learn path) still does not receive or set protocol. __br_fdb_add passes protocol to br_fdb_external_learn_add but the else branch calls fdb_add_entry(br, p, addr, ndm, nlh_flags, vid, nfea_tb) unchanged. Commit message claims this is fixed but the code does not reflect it.

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • APPROVE partial: vxlan_fdb_update_existing protocol guard and br_switchdev_event arg order both fixed ✅
  • Bug: br_fdb_add never parses tb[NDA_PROTOCOL] — protocol is always RTPROT_UNSPEC on the add path
  • Bug: fdb_add_entry (non-extern_learn) still does not receive or set protocol — bridge fdb add without extern_learn ignores the proto field
  • These two issues mean protocol only works for extern_learn entries added via bridge; regular bridge FDB adds silently lose it
  • VXLAN side looks correct and complete

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • br_fdb_add declares u8 protocol = RTPROT_UNSPEC but never parses tb[NDA_PROTOCOL] — protocol is dead code in the add path
  • fdb_add_entry (non-extern_learn branch) still doesn't receive or set protocol — entries created via this path always have RTPROT_UNSPEC
  • VXLAN protocol guard (RTPROT_UNSPEC check in vxlan_fdb_update_existing) looks correct now
  • Commit message claims "br_fdb_add: parse NDA_PROTOCOL from netlink add path" but the code doesn't do this
  • Patch 3 (NTF_EXT_VALIDATED) looks solid

Comment on lines +241 to +248
- err = vxlan_fdb_update(vxlan, addr, &ip, ndm->ndm_state, flags,
- port, src_vni, vni, ifindex,
- ndm->ndm_flags | NTF_VXLAN_ADDED_BY_USER,
- nhid, true, extack);
+ err = vxlan_fdb_update(vxlan, addr, &ip, ndm->ndm_state, flags, port,
+ src_vni, vni, ifindex,
+ ndm->ndm_flags | NTF_VXLAN_ADDED_BY_USER, nhid,
+ true, extack, ext_flags);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a reason the formatting was changed for just adding one argument at the end of the function call? This applies to all instances of this (function declarations and calls).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor style nit — reformatting the entire call when adding one argument is common in kernel patches to stay within 80-col limits. No functional concern here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Acknowledged. Style preference; not a blocker.

/* Extended flags under NDA_FLAGS_EXT: */
#define NTF_EXT_MANAGED (1 << 0)
#define NTF_EXT_LOCKED (1 << 1)
+#define NTF_EXT_MH_PEER_SYNC (1 << 2)
Copy link
Copy Markdown
Contributor

@saiarcot895 saiarcot895 May 7, 2026

Choose a reason for hiding this comment

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

As of the 6.16 kernel, this bit is used for NTF_EXT_EXT_VALIDATED. Can this be changed to 1 << 3, in case SONiC uses some application in the near future that actually uses this bit for something?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Confirmed: NTF_EXT_MH_PEER_SYNC is already defined as (1 << 3), which avoids the conflict with NTF_EXT_EXT_VALIDATED (1 << 2) in 6.16+. ✅

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified. NTF_EXT_MH_PEER_SYNC is defined as (1 << 3), avoiding the conflict.

Signed-off-by: Tamer Ahmed <tamerahmed@microsoft.com>
@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • All previously reported bugs (br_fdb_add NDA_PROTOCOL parsing, fdb_add_entry propagation, vxlan protocol overwrite guard, switchdev arg order, vxlan_fdb_info NDA_PROTOCOL emit) are now fixed. ✅
  • NTF_EXT_MH_PEER_SYNC correctly uses 1 << 3 avoiding conflict with upstream NTF_EXT_EXT_VALIDATED.
  • Remaining bug: br_fdb_external_learn_add update path still lacks RTPROT_UNSPEC guard — switchdev caller will clobber existing protocol values.
  • Could not resolve threads due to repo permissions (replies posted acknowledging fixes).

test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &fdb->flags))
atomic_dec(&br->fdb_n_learned);

+ if (fdb->protocol != protocol) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Missing RTPROT_UNSPEC guard in br_fdb_external_learn_add update path.

The existing-entry update block does:

if (fdb->protocol != protocol) {
    modified = true;
    fdb->protocol = protocol;
}

But br_switchdev_event calls this with RTPROT_UNSPEC. If the entry already has RTPROT_ZEBRA (set by control plane), switchdev will clobber it to RTPROT_UNSPEC.

This is the same class of bug that was correctly fixed in vxlan_fdb_update_existing. Apply the same guard:

if (protocol != RTPROT_UNSPEC && fdb->protocol != protocol) {
    modified = true;
    fdb->protocol = protocol;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open in 27a7faf. br_fdb_external_learn_add update path does if (fdb->protocol != protocol) { modified = true; fdb->protocol = protocol; } without guarding against RTPROT_UNSPEC. Since br_switchdev_event passes RTPROT_UNSPEC, this will clobber a control-plane-set protocol (e.g. RTPROT_ZEBRARTPROT_UNSPEC). Apply the same guard as the VXLAN side: if (protocol != RTPROT_UNSPEC && fdb->protocol != protocol).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open. The update path at line 534 does if (fdb->protocol != protocol) without guarding against RTPROT_UNSPEC. When br_switchdev_event calls this with RTPROT_UNSPEC, it will overwrite a previously-set protocol (e.g. RTPROT_ZEBRA) with RTPROT_UNSPEC. Needs the same protocol != RTPROT_UNSPEC && guard used in vxlan_fdb_update_existing.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed. br_fdb_external_learn_add update path now guards with if (protocol != RTPROT_UNSPEC && ...). ✅

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

Re-review of iteration 5 (27a7faf):

  • ✅ All previously reported bugs now fixed: argument order in br_switchdev_event, br_fdb_add NDA_PROTOCOL parsing, fdb_add_entry protocol propagation, vxlan_fdb_update_existing RTPROT_UNSPEC guard
  • ⚠️ One open issue remains: br_fdb_external_learn_add update path still unconditionally overwrites fdb->protocol — needs the same protocol != RTPROT_UNSPEC guard applied in the VXLAN side
  • Protocol-aware delete in both bridge and VXLAN (fdb_delete_by_addr_and_port, vxlan_fdb_delete) is a nice addition
  • New NTF_EXT_VALIDATED patch (0003) looks correct — proper integration with neigh GC skip and state machine

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • All previously raised issues are fixed except one: br_fdb_external_learn_add update path still lacks RTPROT_UNSPEC guard — will overwrite control-plane protocol when called from br_switchdev_event
  • Patch 1 (NDA_FLAGS_EXT / NTF_EXT_MH_PEER_SYNC): Correct and clean
  • Patch 2 (protocol field): Solid implementation; netlink parse, propagation, and delete-path filtering all look good now
  • Patch 3 (NTF_EXT_VALIDATED): Well-designed upstream patch, no concerns
  • One remaining bug to fix before merge (the RTPROT_UNSPEC guard noted above)

tahmed-dev added 2 commits May 8, 2026 13:22
Signed-off-by: Tamer Ahmed <tamerahmed@microsoft.com>
Signed-off-by: Tamer Ahmed <tamerahmed@microsoft.com>
@mssonicbld
Copy link
Copy Markdown

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

All previously reported bugs are now fixed. Remaining minor items:

  • Unused variable in patch 0002: vxlan_fdb_external_learn_add declares u32 ext_flags which is never used (leftover from refactoring)
  • Whitespace inconsistency in vxlan_private.h: ext_flags and protocol fields use spaces for alignment while surrounding fields use tabs
  • Patch 0003 is a clean upstream cherry-pick (NTF_EXT_VALIDATED) — no issues
  • Protocol-aware delete semantics look correct and well-guarded
  • Series comment about dropping 0003 when kernel >= 6.12 is helpful

goto out;
}
@@ -1301,7 +1316,7 @@ out:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Unused variable. ext_flags is declared here but never referenced in this function. This will cause a compiler warning (-Wunused-variable). Remove it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still present — ext_flags is declared but never used in vxlan_fdb_delete. It's only passed to vxlan_fdb_parse which writes it, but it's never read after that. Minor compiler warning risk, but not a blocker.

+ __be32 *vni, u32 *ifindex, u32 *nhid, u8 *protocol,
struct netlink_ext_ack *extack, u32 *ext_flags)
{
struct net *net = dev_net(vxlan->dev);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor: inconsistent indentation. The surrounding struct members use tab+spaces for alignment (\t\t ), but ext_flags and protocol use just spaces. Match the existing style for consistency:

	u32\t\t  ext_flags;
	u8\t\t  protocol;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Minor style nit, not a blocker.

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • All prior blocking issues (protocol guard in update paths, missing propagation in fdb_add_entry, vxlan_fdb_update_existing) confirmed fixed
  • Protocol field correctly guarded with RTPROT_UNSPEC check to avoid clobbering on unspecified updates
  • Delete path properly scoped by protocol to prevent cross-protocol removal
  • Remaining cosmetic nits (struct indentation) are non-blocking
  • LGTM — patches are well-structured and backward compatible

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

  • All previously reported bugs (argument ordering, protocol parsing, RTPROT_UNSPEC guard, fdb_add_entry propagation, vxlan_fdb_info emission) are fixed
  • br_fdb_external_learn_add update path now correctly guards against RTPROT_UNSPEC overwrite
  • Protocol-aware delete semantics are sound — only deletes matching protocol entries
  • Minor: ext_flags in vxlan_fdb_delete is written by vxlan_fdb_parse but never read — harmless but could suppress with (void)ext_flags or __always_unused
  • LGTM — no remaining correctness issues

Copy link
Copy Markdown

@banidoru banidoru left a comment

Choose a reason for hiding this comment

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

All reviewers approved. LGTM.

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.

6 participants