Skip to content

Bug: [vpp] VLAN SVI neighbor host route not installed in VPP data plane (downstream traffic to SVI hosts dropped at glean) #28882

Description

@lolyu

Is it platform specific

generic (VPP platform / docker-syncd-vpp, libsaivs vslib)

Importance or Severity

High

Description of the bug

On the VPP platform, an IP neighbor whose router interface is a VLAN SVI (Vlan<id>, SAI_ROUTER_INTERFACE_TYPE_VLAN, realized in VPP as a BVI bvi<vlan_id>) is never programmed into the VPP data plane. No neighbor adjacency and no /32 (or /128) host route are installed on the BVI.

As a result, routed traffic destined to a host that sits on a VLAN subnet (e.g. uplink → downlink to a server on Vlan1000) has no host route to match. It falls through to the connected /21 glean entry on the BVI, where VPP emits an ARP and drops the triggering packet. Downstream delivery to SVI hosts is silently dropped until (and unless) VPP happens to resolve the host by its own ARP.

Root cause is in SwitchVpp::addRemoveIpNbr() (vslib/vpp/SwitchVppNbr.cpp). It resolves SAI_ROUTER_INTERFACE_ATTR_PORT_ID before it branches on the RIF type:

attr.id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID;
CHECK_STATUS(get(SAI_OBJECT_TYPE_ROUTER_INTERFACE, nbr_entry.rif_id, 1, &attr));
auto port_obj_type = objectTypeQuery(attr.value.oid);
if (port_obj_type != SAI_OBJECT_TYPE_PORT && port_obj_type != SAI_OBJECT_TYPE_LAG)
{
    return SAI_STATUS_SUCCESS;   // <-- VLAN SVI RIF has no PORT_ID => returns here, neighbor never programmed
}

A VLAN SVI RIF has no SAI_ROUTER_INTERFACE_ATTR_PORT_ID (it references a VLAN, not a single port), so the neighbor is dropped before the RIF type is ever considered. Only PORT and SUB_PORT RIFs are handled.

This is the neighbor/host-route counterpart of the RIF-attribute-update bug tracked separately (VLAN RIF updates); both stem from resolving PORT_ID before dispatching on RIF type.

Steps to Reproduce

  1. Deploy a VPP KVM testbed with a VLAN SVI, e.g. Vlan1000 with an IP (dual-ToR t0 exercises this heavily; the server-facing /32s live on the SVI).
  2. Create an IP neighbor on the SVI (learned normally, or via mux/host-route programming). The SAI NEIGHBOR_ENTRY appears in ASIC_DB with a valid DST_MAC.
  3. Inspect the VPP data plane:
    • docker exec syncd vppctl show ip neighbor | grep <host>absent
    • docker exec syncd vppctl show ip fib <host> → only the connected /21 glean, no /32.
  4. Route a packet to that host from an uplink → it is dropped at ip4-glean (no host route/adjacency).

Actual Behavior and Expected Behavior

Actual: A SAI NEIGHBOR_ENTRY on a VLAN SVI RIF is accepted by SONiC (present in ASIC_DB, MAC learned in the VPP L2 FDB) but not realized in VPP L3 — no adjacency, no host route. Downstream packets to the host glean-and-drop.

Expected: Creating the neighbor should install the L3 adjacency and the host route on the BVI (bvi<vlan_id>), so routed traffic to the host forwards immediately — matching ASIC behavior, where a NEIGHBOR_ENTRY installs the host route regardless of whether the switch has itself ARPed the host. addRemoveIpNbr() should dispatch on RIF type first and resolve the BVI for SAI_ROUTER_INTERFACE_TYPE_VLAN (mirroring vpp_create_bvi_interface()), instead of requiring PORT_ID.

Relevant log output

# ASIC_DB has the neighbor with a valid MAC:
redis-cli -n 1 keys '*NEIGHBOR_ENTRY*192.168.0.2*'
  ASIC_STATE:SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:{"ip":"192.168.0.2","rif":"oid:0x6...","switch_id":"oid:0x21..."}
  SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS = 0E:4D:33:65:C0:01

# ... but VPP has no L3 neighbor for it:
docker exec syncd vppctl show ip neighbor | grep 192.168.0.2
  (absent)

# ... and the VPP FIB has only the connected /21 glean (no /32 host route):
docker exec syncd vppctl show ip fib 192.168.0.2
  192.168.0.0/21 fib:0 index:150 locks:2
    ... cfg-flags:glean, bvi1000
  forwarding: unicast-ip4-chain
    [0] [@4]: ipv4-glean: [src:192.168.0.0/21] bvi1000: ... ffffffffffff22ada23408760806

Output of show version, show techsupport

SONiC Software Version: SONiC.master.1182394-fc9ea17bb
Distribution: Debian 13.5
Kernel: 6.12.41+deb13-sonic-amd64
Platform: x86_64-kvm_x86_64-r0
HwSKU: Force10-S6000
ASIC: vpp
ASIC Count: 1

Fix

Dispatch on RIF type before resolving PORT_ID; for SAI_ROUTER_INTERFACE_TYPE_VLAN, resolve the BVI (bvi<vlan_id>) and program the neighbor adjacency + host route there (static, since SONiC owns the SVI neighbor lifecycle).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions