Skip to content

[vpp] Permit local traffic ahead of ACL deny rules - #2027

Open
lolyu wants to merge 3 commits into
sonic-net:masterfrom
lolyu:fix_local_addr_drop_by_mux_acl
Open

[vpp] Permit local traffic ahead of ACL deny rules#2027
lolyu wants to merge 3 commits into
sonic-net:masterfrom
lolyu:fix_local_addr_drop_by_mux_acl

Conversation

@lolyu

@lolyu lolyu commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary:
Fixes sonic-net/sonic-buildimage#28884

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation update
  • Test improvement

Approach

What is the motivation for this PR?

the mux drop ACL blackholing ICMP replies at l2-input.
check issue: sonic-net/sonic-buildimage#28884 for more details.

Signed-off-by: Longxiang Lyu lolv@microsoft.com

Work item tracking
  • Microsoft ADO (number only):

How did you do it?

The fix emulates hardware "CoPP before ACL" purely through ACL rule ordering. VPP evaluates the rules of a single ACL in order, first-match-wins, so if permit rules for the switch's own addresses are placed ahead of a deny in the same ACL, traffic to local RIF is allowed through to the BVI and punted at ip4-local, while all other traffic still falls through to the deny unchanged. No extra datapath node and no per-packet lookup are introduced.

  • Learn the switch's own addresses. The switch's local host addresses (loopback, SVI/BVI gateway, L3 router-interface) are exactly the interface addresses it programs into VPP, which VPP turns into local (ip2me) receive routes. The layer now records these addresses as they are added and removed, giving it an up-to-date set of "for-us" destinations for both IPv4 and IPv6.

  • Prepend permits when a table drops traffic. When an ACL table is (re)built and it contains any deny/drop rule, host-scoped permit rules (one per known local address) are inserted ahead of that table's rules. Because the permits live in the same ACL that carries the deny, they are automatically applied to exactly the interfaces the table is bound to, and only traffic destined to the switch's own addresses matches them — everything else is unaffected.

  • Keep the two in sync. The local-address set and the drop ACL are programmed by independent, unordered SAI events, so the solution reconciles them either way: tables that contain a deny are remembered, and a later change to the local-address set re-applies the permits to those tables. Equivalently, if the addresses are already known when the drop table is first built, the permits are emitted immediately. During bulk boot, before any drop ACL exists, addresses simply accumulate with no ACL churn.

How did you verify/test it?

Build and verify on dualtor testbed, the icmp replies are received on mux port:

root@vlab-vpp-04:~# tcpdump -i Ethernet8 -nev
tcpdump: listening on Ethernet8, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:59:27.644064 00:aa:bb:cc:dd:ee > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 69: (tos 0xb8, ttl 64, id 59341, offset 0, flags [none], proto ICMP (1), length 55)
    10.1.0.36 > 192.168.0.3: ICMP echo request, id 8, seq 3285, length 35
12:59:27.657001 00:00:00:00:00:00 > 00:aa:bb:cc:dd:ee, ethertype IPv4 (0x0800), length 69: (tos 0xb8, ttl 64, id 59341, offset 0, flags [none], proto ICMP (1), length 55)
    192.168.0.3 > 10.1.0.36: ICMP echo reply, id 8, seq 3285, length 35

Any platform specific information?

Documentation

@linux-foundation-easycla

linux-foundation-easycla Bot commented Aug 7, 2026

Copy link
Copy Markdown

CLA Missing ID

  • ✅ login: lolyu / name: Longxiang Lyu (54d14c7, dbe8cbd)
  • ❌ The email address for the commit (8315494) is not linked to the GitHub account, preventing the EasyCLA check. Consult this Help Article and GitHub Help to resolve. (To view the commit's email address, add .patch at the end of this PR page's URL.) For further assistance with EasyCLA, please visit our EasyCLA portal and chat with our support bot.

@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

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

@azure-pipelines

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

@lolyu
lolyu force-pushed the fix_local_addr_drop_by_mux_acl branch from 53f2997 to 7c724e1 Compare August 7, 2026 13:33
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

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

make_local_permit left src_prefix unset for IPv6 local addresses. The
xlate defaults an unset source prefix to IPv4, so an IPv6 dst produced a
rule with src=IPv4 / dst=IPv6. VPP rejects mismatched-family ACL rules
with VNET_API_ERROR_INVALID_SRC_ADDRESS (-57), which failed the entire
acl_add_replace. As a result only the very first (IPv4-only) refresh
committed and every later rebuild -- including the ones that would add
the SoC loopback permit -- was rejected, so control traffic to those
addresses kept hitting the mux drop.

Set a same-family wildcard source (0.0.0.0/0 or ::/0) so every rule is
family-consistent and accepted.

Signed-off-by: Longxiang Lyu <lolv@microsoft.com>
@lolyu
lolyu force-pushed the fix_local_addr_drop_by_mux_acl branch 2 times, most recently from 7c724e1 to dbe8cbd Compare August 7, 2026 13:34
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@lolyu lolyu changed the title [vpp] Permit local (for-us) traffic ahead of ACL deny rules [vpp] Permit local traffic ahead of ACL deny rules Aug 7, 2026
@azure-pipelines

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

@lolyu
lolyu requested review from yue-fred-gao and a lite review from Copilot August 7, 2026 13:38

Copilot AI left a comment

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.

Pull request overview

This PR updates the SAI-VPP (libsaivs) datapath so that traffic destined to the switch’s own local IP addresses is permitted ahead of ACL deny rules, preventing control-plane (“for-us”) traffic from being dropped by broad VPP ACL denies (notably the dual-ToR mux drop ACL).

Changes:

  • Track switch-owned local interface IP addresses as they are added/removed in VPP (trackLocalIp).
  • When programming an ACL table that contains any deny rule, prepend per-local-IP “permit dst /32|/128” rules to the same VPP ACL (injectLocalPermits) and keep these permits refreshed when local IPs change.
  • Offset VPP rule index bookkeeping to keep ACL counters aligned after permit injection.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
vslib/vpp/SwitchVppRif.cpp Calls trackLocalIp() on successful interface IP add/del so local IPs are tracked from all relevant programming paths.
vslib/vpp/SwitchVppAcl.cpp Adds local-IP tracking and ACL permit injection ahead of deny rules during ACL table (re)configuration.
vslib/vpp/SwitchVpp.h Adds state (m_local_ips, m_local_deny_tables) and declares the new helper methods.

Comment thread vslib/vpp/SwitchVppAcl.cpp Outdated
lolyu pushed a commit to lolyu/sonic-sairedis that referenced this pull request Aug 7, 2026
Local permits are prepended only to the regular ACL rule list, but the
base-index fixup shifted vpp_rule_base_index for every ACE, including
tunnel-termination ACEs whose indices are relative to the separate
tunterm ACL. That table does not gain the leading permit rules, so
shifting its ACEs corrupts the ACL counter-to-rule mapping for tunterm
entries. Only adjust regular (non-tunterm) ACEs.

Addresses review feedback on sonic-net#2027.
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

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

lolyu pushed a commit to lolyu/sonic-sairedis that referenced this pull request Aug 7, 2026
Local permits are prepended only to the regular ACL rule list, but the
base-index fixup shifted vpp_rule_base_index for every ACE, including
tunnel-termination ACEs whose indices are relative to the separate
tunterm ACL. That table does not gain the leading permit rules, so
shifting its ACEs corrupts the ACL counter-to-rule mapping for tunterm
entries. Only adjust regular (non-tunterm) ACEs.

Addresses review feedback on sonic-net#2027.

Signed-off-by: Longxiang Lyu <lolv@microsoft.com>
@lolyu
lolyu force-pushed the fix_local_addr_drop_by_mux_acl branch from 47ac022 to 2ba150f Compare August 7, 2026 13:52
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

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

Signed-off-by: Longxiang Lyu <lolv@microsoft.com>
@lolyu
lolyu force-pushed the fix_local_addr_drop_by_mux_acl branch from 2ba150f to 54d14c7 Compare August 7, 2026 13:53
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

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

@lolyu
lolyu requested a review from yxieca August 7, 2026 13:53

@yue-fred-gao yue-fred-gao left a comment

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.

vpp only supports about 80 rules. This can easily take half of that. Is there anyway to limit this feature only to where it is actually needed?
Have you run t1-lag sanity?

…addrs

Address review feedback on rule-count budget: the previous logic injected
a permit for every local interface address into any table containing a
deny, which scales with fabric size and can consume a large share of the
practical VPP per-interface ACL budget.

Narrow the feature to exactly where it is needed:

- Trigger only on the dual-ToR mux drop, identified as a DROP ACE scoped
  by SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS (the pattern VPP cannot represent
  and thus renders as a port-wide deny). Ordinary security/data ACLs and
  platforms with no mux drop (e.g. t1-lag) get nothing injected.

- Track only mux-reachable local addresses -- the VLAN SVI (BVI) gateway
  and loopbacks reached through it. Routed port/portchannel (uplink)
  addresses never traverse a mux port, so they are skipped, bounding the
  permit count independent of uplink/fabric count.

Addresses review feedback on sonic-net#2027.
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run

@azure-pipelines

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

@lolyu

lolyu commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — both good points. Pushed a follow-up (Scope local-permit injection to the mux drop ACL and reachable addrs) that narrows the feature substantially.

Rule-count / "limit it to where it's needed": the previous logic injected a permit for every local interface address into any table with a deny, which scales with fabric size. It's now scoped two ways:

  1. Trigger only on the mux drop — a table gets permits only if it contains a DROP ACE scoped by SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS (the exact pattern VPP can't represent and renders as a port-wide deny). Ordinary security/data ACLs (denies without IN_PORTS) get nothing, and a platform with no mux drop gets nothing.
  2. Track only mux-reachable addresses — the VLAN SVI (BVI) gateway and the loopbacks reached through it. Routed port/portchannel (uplink) RIF addresses never traverse a mux port, so they're excluded. This removes the fabric-proportional term, so the permit count is bounded regardless of uplink count.

Measured on a live dual-ToR DUT, the mux ACL went from 18 permits + 1 deny (19) to 10 permits + 1 deny (11) — the 8 uplink /31 (v4+v6) permits are gone — and only the mux table (0x700000002) receives permits; the other ACL tables are untouched. The ICMP heartbeat to the SoC loopback still matches its permit and is punted (verified via VPP trace), and no acl_add_replace failures.

t1-lag sanity: I have not run a full t1-lag testbed yet (only dual-ToR DUTs are up in my environment). By construction, on t1-lag there is no IN_PORTS-scoped mux drop ACL, so injectLocalPermits returns 0 and nothing is added — the feature is inert. I confirmed the trigger scoping empirically on the dual-ToR box (non-mux ACL tables receive 0 injected permits). I'll run a full t1-lag sanity pass to confirm no regression before merge.

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.

Bug: [vpp][dualtor] Mux drop ACL drops control-plane/for-us traffic — IN_PORTS ignored and L2 ACL runs before ip4-local punt (mux stuck unhealthy)

4 participants