IP Access List Matcher: which ACL line permits or denies an address

Paste an access list and an address or prefix, and get the verdict with the exact entry that produced it — including the implicit rules your platform applies but never prints.

  • The line, not just the answerpermit or deny, and the exact entry that decided it, with every earlier line and why it did not match.
  • Five platforms, their real behaviourIOS and IOS-XE, NX-OS, IOS-XR, Arista EOS and Junos, including the implicit rules each one applies but never shows in the configuration.
  • Prefixes split, exactlyask about 10.0.0.0/16 and get the parts back one by one when different lines own different halves of it.
  • It says when it cannot be surea line testing a protocol or port you did not give is reported as conditional rather than assumed away.
  • Prefix lists tooge, le and eq windows, and Junos route filters with their longest-match rule, with the reason an entry missed.
  • Nothing leaves your browserthe whole matcher runs client-side. No upload, no account, works offline.

Access list matcher

Paste the list, give an address or a prefix, and see which entry decides it — with every line above it and the reason it did not match. Standard and extended, numbered and named, IPv4 and IPv6, from five platforms. A line that tests a protocol or a port you have not given is reported as conditional, never quietly assumed away.

Packet
An address or a prefix. Everything else is optional and only makes the answer more certain.
Tested as the
10.20.5.5 -> permit (seq 40: 40 permit ip 10.20.0.0 0.0.255.255 any)
Verdict
DC-EDGE-IN · 5 entries including the implicit rules
permit
10.20.5.5 is permitted as the source by seq 40.
40 permit ip 10.20.0.0 0.0.255.255 any
Read the conditional lines below before acting on this.
Lines that could take precedence
These match the address, but test something you did not give. For a packet where they all hold, the first of them decides instead.
  • seq 20permit20 permit tcp 10.20.0.0 0.0.255.255 host 10.0.0.10 eq 22
    applies when protocol tcp, and destination port eq 22, and destination host 10.0.0.10
Every line, in order
What the router does with this packet at each entry, including the rules it never prints.
LineEntryOutcome
seq 2020 permit tcp 10.20.0.0 0.0.255.255 host 10.0.0.10 eq 22
protocol tcp · source 10.20.0.0 0.0.255.255 · destination host 10.0.0.10 · eq 22
conditional
matches on address, but only for packets where protocol tcp and destination port eq 22 and destination host 10.0.0.10
seq 3030 deny ip 10.20.99.0 0.0.0.255 any
source 10.20.99.0 0.0.0.255
no match
no address in 10.20.5.5 is inside 10.20.99.0 0.0.0.255
seq 4040 permit ip 10.20.0.0 0.0.255.255 any
source 10.20.0.0 0.0.255.255
decides
permits the whole of 10.20.5.5
seq 5050 deny ip any any log
matches everything
not reached
every address in the query was already decided by an earlier line
implicitdeny ip any any
matches everything
not reached
every address in the query was already decided by an earlier line
How this platform treats this list
  • Traffic matching no entry hits the implicit deny at the end of the list.

Access list matcher: the verdict, and the line that produced it

Reading an access list by eye is a reliable way to be wrong. The entries are evaluated top to bottom and stop at the first match, wildcard masks read backwards from the subnet masks beside them, and the rule that actually catches your traffic is often one the configuration does not contain at all. This tool takes the list and an address and answers the real question: permitted or denied, and by which line — with every entry above it and the reason each one did not match.

Five platforms, and where they genuinely differ

Cisco IOS and IOS-XE, NX-OS, IOS-XR, Arista EOS and Juniper Junos all express the same idea in different syntax, and a matcher that only handled the syntax would still give wrong answers. The differences that change the result are modelled per platform: which protocol keyword means "everything" (ip on IOS and NX-OS, ipv4 on IOS-XR, inet on Junos), whether an object group's members carry subnet masks or wildcard masks, and above all the implicit rules each platform appends to a list without ever printing them. Both Cisco spellings are read, from show running-config and from show access-lists — hit counters, wildcard bits and all.

The implicit rules your configuration does not contain

Every IPv4 list ends with an unwritten deny ip any any. IPv6 lists carry more: on IOS and IOS-XE they end with permit icmp any any nd-na, permit icmp any any nd-ns and then the deny, which is what keeps Neighbor Discovery alive. NX-OS adds router-advertisement and router-solicitation to that set. Anything you configure sits ahead of all of it, which is why an explicit deny ipv6 any any as your last line silently stops address resolution working. Those rules are part of the walk here and appear in the trace, marked as implicit, so the answer accounts for them instead of stopping where the text does.

Ask about a prefix, get an honest answer

A single address has one answer. A prefix usually does not. Ask about 10.1.0.0/16 against a list that denies 10.1.1.0/24 on one line and permits the rest two lines later, and the truthful reply is two verdicts with the exact address ranges attached to each. That decomposition is computed by set arithmetic over the address space rather than by sampling, so every address in the prefix is accounted for exactly once and attributed to the line that really decides it — including under non-contiguous wildcard masks like 0.0.0.254, which match only every other host and which no CIDR prefix can express.

It tells you when it cannot be sure

An address is not a packet. permit tcp 10.0.0.0/8 any eq 22 says nothing definite about 10.1.1.1 unless you also know the protocol and the port, and a matcher that quietly assumes the rest of the packet matches is how you end up confidently wrong. Lines like that are reported as conditional: they are listed as entries that would take precedence for a packet whose unspecified fields line up, the walk continues past them to the first line that is definitely decided, and you can narrow the question with a protocol, ports or the other end of the packet to settle them one by one. The same applies to an object group the configuration references but never defines — it is reported, not guessed at.

Prefix lists and routing policy

The second tab answers the routing question. A prefix list entry tests two things independently — is the candidate inside the entry's network, comparing only the entry's own prefix length of leading bits, and is the candidate's own prefix length inside the ge/le window — and nearly every "why isn't my route matching" is the second one. With neither keyword the window is exactly the entry's length, which is why permit 10.0.0.0/8 does not match 10.1.0.0/16. Both tests are shown for every entry, with eq supported where the platform supports it.

Junos, on its own terms

Junos is not Cisco syntax with different words, and the differences bite. A term with no from clause matches every packet. A then holding only non-terminating actions — count, log, policer — still terminates, with an implicit accept, so a term that "just counts" accepts the traffic. then next term continues instead of deciding. Address lists are order-independent and resolved by longest prefix match, where except marks a prefix as non-matching. And in routing policy, route filters inside one term are longest-match: only the longest configured prefix containing the route is evaluated, and if its match type then fails, the whole term fails and the shorter filters never get a say. All of that is implemented here, in both brace and set configuration form.

Nothing you paste leaves your browser

The whole matcher is TypeScript running on your machine — the same engine, tested the same way, as the subnet calculator, the MAC address lookup and the data unit converter. Access lists name your internal ranges, your jump hosts and your management networks, so there is no upload, no account, no server-side logging, and the page keeps working offline once loaded.

Access list questions, answered

How do I find out which ACL line is matching my traffic?

An access list is evaluated top to bottom and stops at the first entry that matches, so the line you want is the first one whose every condition the packet satisfies. On a live device you can approximate this by adding log to entries and reading the hit counters in show access-lists, but that only tells you afterwards, and only for traffic that actually arrived.

This tool answers it directly: paste the list and the address, and it walks the entries in order, reports the first definite match, and shows every line above it with the reason it did not match. Entries the platform applies but never prints, such as the implicit deny, are included in the walk.

What is the implicit deny at the end of an access list?

Every IPv4 access list on Cisco IOS, IOS-XE, NX-OS, IOS-XR and Arista EOS ends with an invisible deny ip any any (spelled deny ipv4 any any on IOS-XR). It does not appear in the running configuration and it keeps no counters, but it is what a packet hits when no entry matched. A list containing only permits therefore denies everything else.

Junos does the same thing under a different name: every firewall filter ends in an implicit discard, applied to any packet no term matched.

Why does an IPv6 ACL break neighbour discovery?

IPv6 access lists carry more implicit rules than IPv4 ones. On Cisco IOS and IOS-XE an IPv6 list ends with three: permit icmp any any nd-na, permit icmp any any nd-ns, then deny ipv6 any any. Those two permits are what keeps Neighbor Discovery — IPv6's replacement for ARP — working. NX-OS adds router-advertisement and router-solicitation to the same set, and Arista EOS installs rules so ICMPv6 bypasses the default drop entirely.

The trap is that anything you configure sits ahead of all of them. Writing an explicit deny ipv6 any any as your last line puts it before the implicit ND permits, so neighbour discovery is dropped and the segment stops resolving addresses. If you want an explicit final deny, add the two ND permits immediately above it.

What is the difference between a wildcard mask and a subnet mask?

They are inverses. In a subnet mask a 1 bit means "this bit is part of the network"; in a wildcard mask a 0 bit means "compare this bit" and a 1 bit means "ignore it". So the /24 written 255.255.255.0 as a mask is 0.0.0.255 as a wildcard, and 10.1.1.0 0.0.0.255 in an access list is the same set of addresses as 10.1.1.0/24.

The distinction matters in one place people trip over: inside a Cisco IOS object-group network, members are written with a subnet mask (10.2.0.0 255.255.0.0), not a wildcard, while an NX-OS object-group ip address uses wildcards. This tool reads each one the way its own platform does.

Wildcard masks are also more expressive than prefixes: the compared bits do not have to be contiguous. 10.0.0.0 0.0.0.254 matches only the even addresses in 10.0.0.0/24, which no CIDR prefix can express.

Why doesn't my prefix list match my route?

Almost always because of the prefix length, not the address. A prefix list entry asks two separate questions: is the candidate inside the entry's network, comparing only the entry's own prefix length of leading bits, and is the candidate's own prefix length inside the entry's accepted window.

With no ge or le, that window is exactly the entry's length. So ip prefix-list X permit 10.0.0.0/8 matches 10.0.0.0/8 and nothing else — not 10.1.0.0/16, which is inside the network but the wrong length. Add le 24 and the window becomes /8 through /24.

What do ge and le mean in a prefix list?

They set the range of prefix lengths the entry accepts, for prefixes that sit inside its network. The rules are: with neither, the window is exactly the entry's own length; with ge only, it runs from that value to /32 (or /128 for IPv6); with le only, from the entry's own length to that value; with both, from ge to le. NX-OS and IOS-XR also accept eq as shorthand for a single exact length.

So permit 10.0.0.0/8 ge 24 le 24 means "anything inside 10.0.0.0/8 that is exactly a /24", and permit 0.0.0.0/0 le 32 means "every IPv4 prefix" — the network test is vacuous and the window covers every length.

How do Junos firewall filters differ from Cisco access lists?

The evaluation order is the same — terms in configuration order, first match wins — but four behaviours differ in ways that change the answer. A term with no from clause matches every packet. A then containing only non-terminating actions such as count, log or policer still terminates, with an implicit accept: a term that only counts accepts the traffic. then next term continues evaluation instead of deciding. And a filter that matches nothing discards, rather than permitting.

Address lists differ too: they are order-independent and resolved by longest prefix match, with except marking a prefix as non-matching, and every list carries an implicit 0.0.0.0/0 except.

Why are some of my Junos route-filters never evaluated?

Because route filters inside one policy term are longest-match, not first-match. Junos finds the single longest configured prefix that contains the route — ignoring the match types entirely while it looks — and evaluates only that one.

If that longest match's match type then fails, the whole term is false and the shorter route filters in it never get a say, even though one of them would have matched. A term holding route-filter 10.0.0.0/8 upto /24 and route-filter 10.1.1.0/24 exact will not match 10.1.1.0/25: the /24 is the longer match, exact rejects a /25, and the /8 is never consulted. Configuring walkup changes this to fall back to less specific filters.

Can I test a whole subnet against an ACL, not just one address?

Yes, and the honest answer is often more than one verdict. Enter a prefix such as 10.1.0.0/16 and the matcher works out which line decides each part of it: if 10.1.1.0/24 is denied on line 10 and the rest of the block is permitted on line 20, you get both results with the exact address ranges attached to each.

The split is computed by set arithmetic over the address space, so every address in the prefix is accounted for exactly once and attributed to the line that really decides it.

What does a conditional result mean?

It means a line matches your address but also tests something you have not given, so the tool will not claim it decides. permit tcp 10.0.0.0/8 any eq 22 tells you nothing definite about 10.1.1.1 unless you also know the protocol and the destination port.

Such a line is listed separately as one that would take precedence for a packet where those conditions hold, and the walk continues past it to the first line that is definitely decided. Fill in the protocol, ports or the other end of the packet and the conditional lines resolve to a match or a miss one by one.