Here is a question that trips up even experienced engineers: you have an access-list on the router that permits and denies exactly the traffic you want, so why can two servers in the same VLAN still talk to each other freely? The answer is the single most important thing to understand about filtering at Layer 2. A router ACL only ever sees traffic that routes between subnets. Two hosts in the same VLAN share a subnet, so their frames are bridged by the switch and never touch the router. The router ACL is never consulted, and a filter it never sees is a filter that does nothing. A VLAN access-list (VACL) is the tool that fixes this, because it acts on the switch as frames are bridged inside the VLAN. This article is part of the PingLabz VLANs and Layer 2 switching cluster and the wider network infrastructure security guide, and every command here was captured live on a Cisco IOL-XE switch in CML.
Why a router ACL cannot filter inside a VLAN
Trace the path of a packet. When HOST1 (10.20.10.100) sends to HOST2 (10.20.10.101), both are in VLAN 120 on the same 10.20.10.0/24 subnet. HOST1 looks at its own subnet mask, sees that HOST2 is local, and puts the frame straight onto the wire addressed to HOST2's MAC. The switch reads the destination MAC, finds it in the CAM table, and forwards the frame out the right port. At no point does that frame have a reason to go to the default gateway, because the destination is not in another subnet. The router, and therefore any ACL on the router's interface or SVI, is completely bypassed.
Contrast that with HOST1 sending to something in 10.30.0.0/24. Now the destination is off-subnet, so HOST1 forwards the frame to its default gateway, the router routes it, and any inbound or outbound ACL on that path gets its say. This is the whole distinction:
Proving it: intra-VLAN traffic flows freely first
Before any VACL exists, HOST1 can reach HOST2 with no trouble at all - same VLAN, same subnet, a clean bridged path:
HOST1$ ping -c 2 10.20.10.101 (HOST2, same VLAN)
2 packets transmitted, 2 received, 0% packet lossZero loss. If you had put a "deny HOST1 to HOST2" line in a router ACL, this ping would still succeed, because the frames never reach the router to be filtered. To actually stop it, you have to filter on the switch, inside the VLAN. That is a VACL.
How a VACL is built
A VACL (Cisco calls the construct a VLAN access-map) is different in shape from a normal ACL. It is a sequenced list of map entries, and each entry has two parts: a match clause that selects traffic (usually by referencing an ordinary IP or MAC access-list) and an action of forward or drop. You then bind the map to one or more VLANs with a vlan filter statement. Here is the exact config used in the lab to drop HOST1 to HOST2 while forwarding everything else:
ip access-list extended PLZ-H1-H2
permit ip host 10.20.10.100 host 10.20.10.101
vlan access-map PLZ-VACL 10
match ip address PLZ-H1-H2
action drop
vlan access-map PLZ-VACL 20
action forward
vlan filter PLZ-VACL vlan-list 120Read it top to bottom. Sequence 10 matches traffic from 10.20.10.100 to 10.20.10.101 (the permit in the referenced IP ACL means "this is the traffic I am selecting", not "allow it") and the action drops it. Sequence 20 has no match clause, so it catches everything else, and the action forwards it. The order matters exactly like a route-map: the first entry whose match clause hits wins. And crucially, there is no implicit "forward all" at the end of a VACL - the default action for unmatched traffic is drop, which is why sequence 20 with an explicit action forward is not optional. Leave it out and you would blackhole the entire VLAN.
After the VACL: the same ping is dead, the gateway still works
With the map applied to VLAN 120, retry the exact same intra-VLAN ping:
HOST1$ ping -c 3 10.20.10.101 (HOST2, now VACL-filtered)
3 packets transmitted, 0 received, 100% packet lossOne hundred percent loss. HOST1 can no longer reach HOST2 at all. But how do you know it is the VACL doing this and not a broken host, a downed link, or a bad ARP entry? Because the same host, on the same interface, at the same moment, still reaches its gateway without a hitch:
HOST1$ ping -c 2 10.20.10.254 (gateway, still fine)
2 packets transmitted, 2 received, 0% packet lossThat is the clean before-and-after that makes the point undeniable. HOST1 is alive, its NIC works, its path to the network works - traffic to the gateway (matched by sequence 20's forward) sails through. Only the one flow selected by sequence 10 is dropped. This is a filter a router ACL could never have applied, because HOST1-to-HOST2 traffic never leaves the VLAN.
Confirming the state on the switch
Two show commands confirm the map is present and bound. First the access-map itself, which lists each sequence, its match clause, and its action:
SW1#show vlan access-map PLZ-VACL
Vlan access-map "PLZ-VACL" 10
Match clauses:
ip address: PLZ-H1-H2
Action:
drop
Vlan access-map "PLZ-VACL" 20
Action:
forwardThen the filter binding, which tells you which VLANs the map is actually policing:
SW1#show vlan filter
VLAN Map PLZ-VACL is filtering VLANs:
120If a VACL "is not working", these two outputs are the first place to look: a map with the right actions but no vlan filter binding does nothing, and a filter pointed at the wrong VLAN policies traffic you never intended to touch.
Where VACLs earn their keep
Because a VACL is applied to the whole VLAN and is evaluated on the switch fabric, it reaches traffic that no router ACL can. The practical use cases all share that shape:
- Micro-segmenting servers that share a subnet. A pool of app servers and database servers may live in one VLAN for simplicity. A VACL can permit the app tier to reach the database port and drop everything else between them, without renumbering into separate subnets.
- Blocking lateral movement. If one host in a subnet is compromised, the attacker's next move is usually sideways, to the neighbours that share the segment. A VACL that denies host-to-host traffic while permitting host-to-gateway breaks that pivot. It is the same goal as private VLANs, achieved with a policy instead of a port mode.
- Filtering non-routed protocols. A VACL can match on MAC access-lists too, so it can drop or permit frame types that a router ACL, which only sees IP, cannot express.
A VACL is not a replacement for a router ACL - the two operate at different layers and see different traffic. The router ACL guards the doorway between subnets; the VACL polices the room. On a flat VLAN where hosts must share a subnet but must not fully trust each other, the VACL is the only tool that can express that policy.
VACL or private VLAN? Two roads to the same isolation
Once you understand that intra-VLAN traffic needs a Layer 2 control, you will meet two of them: the VACL and the private VLAN. They solve overlapping problems, so it is worth knowing when each fits. A VACL is a policy. You write match clauses that name specific sources, destinations, and protocols, and you can be as surgical as you like - permit app-tier to database on TCP 5432, drop the rest. That precision is its strength and its cost, because someone has to write and maintain the access-lists as the environment changes.
A private VLAN is a port mode. You put ports into an isolated secondary VLAN and the switch enforces host-to-host isolation for you, with no per-flow rules to maintain. It is blunter (all-or-nothing isolation to the promiscuous uplink) but it scales effortlessly to hundreds of ports. Reach for a VACL when you need selective, protocol-aware filtering between known hosts; reach for a private VLAN when you simply need every host in a segment isolated from its neighbours. Many hardened designs use both: private VLANs for the broad isolation, a VACL for the few specific flows that must still be permitted.
How the switch evaluates the map
The access-map is processed in ascending sequence order, and evaluation stops at the first entry whose match clause matches the frame. That is why ordering is a design decision, not an afterthought: put your most specific drop rules at low sequence numbers and your broad action forward catch-all last. If you accidentally place a forward-all entry before a drop entry, the drop never fires because the frame already matched and left the map. Think of it exactly like a route-map or a firewall rule base: specific first, general last, and always an explicit terminal action so nothing falls through to the implicit drop by surprise.
A few operational notes
Keep the referenced IP or MAC access-lists tight and named, so show vlan access-map reads clearly six months from now. Remember that the implicit action for unmatched traffic is drop, so always finish with an explicit action forward entry unless you truly intend the VLAN to be default-deny. And test with the exact before-and-after pattern shown here: ping the target (should fail) and ping the gateway (should succeed) from the same host, so you can prove the VACL is responsible and not some unrelated fault. For the broader picture of how VACLs sit alongside every other Layer 2 control, keep reading the VLANs and Layer 2 switching cluster and the network infrastructure security guide.
Key Takeaways
- A router ACL only filters traffic that routes between subnets. Two hosts in the same VLAN share a subnet, so their frames never reach the router and a router ACL can never filter them.
- A VACL (VLAN access-map) filters traffic as it is bridged inside the VLAN, so it reaches exactly the intra-VLAN flows a router ACL cannot.
- A VACL is a sequenced list of
match+action(forward or drop) entries, referencing IP or MAC access-lists, bound to VLANs withvlan filter. The default action for unmatched traffic is drop, so include an explicitaction forwardcatch-all. - In the lab, HOST1 to HOST2 (same VLAN) went from 0% loss to 100% loss after the VACL, while HOST1 to the gateway stayed at 0% loss, proving the VACL, not a broken host, did the filtering.
- Verify with
show vlan access-mapandshow vlan filter. A map with no filter binding does nothing. - Reach for VACLs to micro-segment servers in a shared subnet, block lateral movement after a compromise, and filter non-routed protocols. See the full VLANs and Layer 2 switching cluster.