Additional ACL Features

This section rounds out the introduction to ACLs and their configuration. This section covers five enhanced ACL features: remarks, throttling of logging updates, IP accounting, turbo ACLs, and sequenced ACLs. ACL remarks enable you to insert descriptions into your ACL statement grouping. Throttling logging information from ACL matches (with the log parameter) enables you to restrict the number of messages that the Cisco IOS generates on matches, reducing an overload on the router. IP accounting enables you to identify traffic that matches a deny statement in an ACL, providing more information about the dropped packet. Turbo ACLs allow the Cisco IOS to compile ACLs, making them more efficient and faster to process. Sequenced ACLs enable you to insert or delete a specific ACL entry in your statement grouping without having to delete the entire ACL and rebuild it. The following sections cover these enhanced features.

ACL Remarks

As of Cisco IOS 12.0(2)T, you can include remarks in your ACL statements. Before this, most administrators created a text configuration file with their ACLs, using comments to accomplish the same thing, as displayed in Example 7-12.

Example 7-12. Using Comments in Your Configuration

! This ACL is used to restrict access to the router:

access-list 1 permit

access-list 1 permit

! Activating it on the VTYs

line vty 0 4

  access-class 1 in

The problem with this approach is that when this was loaded into the Cisco IOS, the Cisco IOS ignored the comments. Therefore, you always had to look back to your text file to determine what an ACL was for or what a particular statement was intended to do.

Remarks are supported with both numbered and named ACLs. Here is the syntax for entering a remark in either one:

Router(config)# access-list ACL_# remark remark


Router(config)# ip access-list {standard | extended} ACL_name

Router(config-{std | ext}-nacl)# remark remark

The remark that you enter can be up to 100 characters in length. If you enter a remark that is longer than 100 characters, any extra characters automatically are truncated. When you enter a remark, it is inserted after the last ACL command that you entered. However, using sequenced ACLs, you can insert a remark or multiple remarks anywhere in your ACL statement grouping. Example 7-13 shows a simple example of an ACL that is used to restrict VTY access to a router.

Example 7-13. Using the remark Command in an ACL

Router(config)# access-list 1 remark This ACL restricts administrator

Router(config)# access-list 1 remark -----access to the router for

Router(config)# access-list 1 remark -----VTY access

Router(config)# access-list 1 remark -----

Router(config)# access-list 1 remark -----Allow Richard access

Router(config)# access-list 1 permit

Router(config)# access-list 1 remark -----Allow Natalie access

Router(config)# access-list 1 permit

As you can see from this example, it is much easier to understand what the ACL is used for and what each statement is doing.

Using ACL Remarks

One of the topics covered during a Cisco router course that I recently taught was how to use and configure ACLs. As you have seen so far in this chapter, configuring ACLs is not an easy process: You must be very familiar with TCP/IP and its various protocols and packet contents. A student in the class asked me to review one of the ACLs being used to restrict traffic from the Internet. The student then proceeded to pull out an eight-page ACL?with no comments.

First, an ACL this long is very difficult to troubleshoot. As you recall from the last chapter, a successful ACL design is kept simple. Second, it is difficult to determine what certain statements were used for (if they even had a use). Managing this ACL was nearly impossible.

To help this student, we discussed what the network was trying to accomplish from a policy perspective and then drew up a new ACL configuration. In this ACL configuration we put in remarks, to help the student remember the discussions we had and what specific statements or grouping of statements were used for. After the class, the student sent me an e-mail saying that the best part of the class was learning all the idiosyncrasies of ACLs and their configurations and enhancements.

Logging Updates

As I mentioned earlier with standard and extended ACLs, you can add the optional log parameter to a specific ACL statement(s), causing the Cisco IOS to generate a log message when a packet matches the condition in the statement. This is a very useful feature when you are trying to determine what kinds of traffic you are dropping (specifically, to see what hackers and curious individuals are attempting to send into your network).

I mentioned that logging affects the performance of your router: It no longer can use high-speed switching methods such as CEF. Another issue with the default logging function is that the Cisco IOS displays a message on the first matching packet, but it displays another message on a subsequent match only after a 5-minute interval has expired. The problem with this is that if someone is probing or attacking a particular device or part of your network, you probably will see only a small number of log messages.

As of 12.0(2)T, you can change the logging threshold. To change the threshold of logging, use the following command:

Router(config)# ip access-list log-update threshold #_of_matches

This command defines a threshold for how often a log message is generated. When you specify the value for the number of matches, the Cisco IOS generates a log message after each number of matches. For example, if you set the number of matches to 5, the Cisco IOS generates a log message on the first match, then a message after five subsequent matches, then another message after another five subsequent matches, and so on. This enables you to control how much logging your router generates.

One caveat with the configuration of this command is that, even if you configure a threshold, the Cisco IOS clears its cache of counts after a 5-minute period. As an example, assume that you set a threshold of five packets. Someone sends a packet that matches on a condition with logging enabled, so, because this is the first match, the Cisco IOS generates a message. This person sends two more packets, totaling three. Because the threshold of five has not been reached no additional messages are generated. At this point, the 5-minute period expires and the Cisco IOS clears its matching count cache, setting all counts to 0 for the ACL. The person then sends his fourth packet. From the Cisco IOS perspective, this is counted as the first packet, and it causes a logging message to be generated.


If you are under an attack, you might want to set up this threshold to gather more logging information about what is occurring. Be careful, though, of setting the logging update threshold to a very small value, such as 1. Doing this causes your Cisco IOS to generate a lot more log messages. With a massive DoS attack by a hacker, this easily could flood your router and bring it to its knees, if not crash it. Cisco recommends not setting this to 1.

IP Accounting and ACLs

The IP accounting feature has been around since Cisco IOS 10.0. Actually, IP accounting initially was intentioned to gather traffic statistics for accounting purposes. However, an option was added to it to log statistics for access violations. This feature enables you to get more information about traffic that matches a deny statement in an ACL (available in Cisco IOS 10.3).

Configuration of Accounting

To enable accounting for logging violations, configure the following:

Router(config)# interface type [slot_#/]port_#

Router(config-if)# ip accounting access-violations

When you enable IP accounting for access violations, the Cisco IOS keeps track of the source and destination address that matched the deny statement, as well as the number of packets and bytes and the ACL number or name that was matched. To view your access-violation accounting information, use the show ip accounting access-violations command.


One restriction with IP accounting is that it can gather accounting information for only transit information?traffic that is not destined to the router itself or traffic that the router itself generates.

IP accounting also works with process, fast, and CEF switching, but it disables autonomous and SSE switching.

Example 7-14 shows a sample of a router filtering ICMP traffic, with accounting enabled, as well as its verification.

Example 7-14. Using IP Accounting to Log ACL Matches

Router(config)# access-list 100 deny icmp any any

Router(config)# access-list 100 permit ip any any

Router(config)# interface fastethernet0

Router(config-if)# ip address

Router(config-if)# ip access-group 100 in

Router(config-if)# ip accounting access-violations

Router(config-if)# end

Router# show ip accounting access-violations

   Source           Destination         Packets     Bytes   ACL               4       240   100

Accounting data age is 9


In this example, all ICMP traffic is filtered, but everything else is permitted. Notice that IP accounting is enabled on the fastethernet0 interface. In the output of the show ip accounting access-violations command, tried pinging a remote destination (, which was filtered by the router's ACL, and its accounting information was recorded: Four packets, totaling 240 bytes, were dropped by ACL 100.

Restriction of Accounting Information

Remember that any packet that matches a deny statement (or the implicit deny) generates or updates an accounting record when access violations are enabled. Because IP accounting can generate a large amount of information, you will want to restrict it to a reasonable amount that the router can handle. You can use three commands to restrict the amount of accounting information:

  • ip accounting-list? Filters accounting information based on the addresses listed

  • ip accounting-threshold? Defines the maximum number of accounting records that the router will create

  • ip accounting-transits? Limits the number of transit records that the router stores

Filtering Accounting Information

To limit accounting information to just specific hosts, use the ip accounting-list command:

Router(config)# ip accounting-list IP_address wildcard_mask

With this command, enter an IP address or network number, and qualify it with a wildcard mask (this is the same wildcard mask used with standard and extended ACL statements). You must configure both of these parameters. You also can specify more than one record to capture traffic from a multitude of sources or destinations.


Restricting accounting data is useful if you know that an attack is occurring to or from a specific device. Normally, you might not know what device is creating the attack, but you easily can find out which internal device (or network or subnet) is bearing the brunt of the attack. Knowing this information, you can restrict accounting information with your device's IP address or your internal network number. By using this command, you can focus your accounting information on just the matches on deny statements for specific devices.

Defining Thresholds

By default, the Cisco IOS stores up to 512 entries in its internal accounting database. An entry is basically a source-destination address pairing. With 512 entries, this takes up 12,928 bytes of memory. This number of address pairings is actually not very much, so you can increase this using this command:

Router(config)# ip accounting-threshold threshold_value

The threshold value is the maximum number of entries that you want the Cisco IOS to store in the accounting database. It can range from 0 to 4,294,967,295!


Be careful not to set the accounting threshold value to too large of a size. Setting this value too high can cause a router to consume all its free memory, creating buffer overflow problems and possible crashes.

Limiting Number of Transit Records

Besides limiting the number of accounting records or the devices for which accounting records are created and maintained, you can limit the number of transit records that the Cisco IOS maintains.

One problem of using the ip accounting-list command is that only devices included in the list have accounting information maintained for them. In certain instances you still want accounting information displayed for other devices, but you want to control the amount of additional accounting records that this creates in memory.

The ip accounting-transits command accomplishes this task:

Router(config)# ip accounting-transits #_of_records

With this command, the default number of transit records kept defaults to 0. Therefore, accounting information is generated only when a device listed in the ip accounting-list command matches a deny statement. As an example, you might want to keep accounting records for certain devices, but allow up to 100 other devices to generate records. To accomplish this, use this configuration:

Router(config)# ip accounting-transits 100

In this example, up to 100 additional address-pairs are kept in the accounting database besides the ones specified in the ip accounting-list command(s).


Other commands for IP accounting have nothing to do with security. This section focuses only on the ones that can be used to help with security auditing and logging.

Turbo ACLs

Normally, ACLs are searched sequentially, from the first to the last entry, when trying to find a match on a condition. However, very long ACLs can slow down the search process to find a match on a condition. In addition, depending on the packet contents, one packet might match on one of the first statements in an ACL, while another might match on one of last statements in an ACL, producing a variable delay in latency that then affects delay-sensitive traffic.

Cisco developed turbo ACLs to speed up the processing of ACLs and to produce a more defined latency period during ACL processing. This feature is available only on the 7100, 7200, 7500, and 12,000 Gigabit Switch routers. Turbo ACLs are basically ACLs that are compiled into a lookup table that still maintains first-match requirements (remember, order of statements is important). The Cisco IOS uses packet headers to match against these table entries in a small number of lookups, which is independent of the number of ACLs in the original list.

Turbo ACLs provide these two advantages:

  • The time to find a match is fixed, so latency is smaller and consistent. This is important with very large ACLs and mixed types of data traffic.

  • For ACLs that have three or more entries, turbo ACLs reduce the CPU processing cycles required to find a match. Actually, the CPU load to find any match is fixed, no matter how many ACL statements are in the ACL list. Therefore, the larger the list is, the better the performance gain is.

Turbo ACLS have limitations, of course. For example, you cannot use timed entries or reflexive entries in ACLs (discussed in Chapter 8). In addition, when you compile an ACL, you need an additional 2 to 4 MB of memory to hold the compiled contents. The show access-list compiled command displays the memory overhead used by the compiled ACL(s).

Turbo ACLs were introduced in Cisco IOS 12.0(6)S and on the 7200 in 12.1(1)E. They have been integrated into 12.1(5)T. By default, turbo ACLS are disabled on a router that supports them. To compile your ACLs on a supported router, use this command:

Router(config)# access-list compiled

This command has no parameters; in other words, you cannot choose which ACLs are compiled and which ones are not. Instead, if an ACL can be compiled, the Cisco IOS compiles it automatically. When compiling, the Cisco IOS scans the ACL and then compiles the ACL, if the Cisco IOS can. For large and complex ACLs, it might take a few seconds (or minutes) for the compilation to complete. After an ACL is compiled, any changes that you make to the ACL automatically trigger a recompilation of the ACL. While an ACL is being compiled or recompiled, the Cisco IOS uses the uncompiled ACL to filter traffic.

After you have enabled a turbo ACL on your router, you can use the show access-list compiled command to verify its successful configuration and operation, as displayed in Example 7-15.

Example 7-15. Using the show access-lists compiled Command

Router# show access-lists compiled

Compiled ACL statistics:

4 ACLs loaded, 4 compiled tables

 ACL         State   Tables Entries Config Fragment Redundant Memory

1        Operational    1       2       1        0         0     1Kb

100      Operational    1      15       9        7         1     1Kb

101      Operational    1      13       6        6         0     1Kb

102      Operational    1       2       1        0         0     1Kb

First level lookup tables:

Block      Use               Rows   Columns Memory used

  0   TOS/Protocol           6/16     12/16      66048

  1   IP Source (MS)        10/16     12/16      66048

  2   IP Source (LS)        27/32     12/16     132096

  3   IP Dest (MS)           3/16     12/16      66048

  4   IP Dest (LS)           9/16     12/16      66048

  5   TCP/UDP Src Port       1/16     12/16      66048

  6   TCP/UDP Dest Port      3/16     12/16      66048

  7   TCP Flags/Fragment     3/16     12/16      66048


An ACL can be placed in five states:

  • Operational? The ACL has been compiled successfully.

  • Deleted? The ACL is empty (no entries).

  • Unsuitable? The ACL cannot be compiled because it contains time-range, reflexive, or dynamic entries.

  • Building? The ACL is currently being compiled, which might take a few seconds to complete.

  • Out of memory? The router does not have enough memory to compile the ACL.

Sequenced ACLs

For years, customers have been complaining about how difficult it is to maintain ACLs: adding, modifying, or deleting statements in an ACL. I detailed how this was done using a text editor, in Chapter 6. I have been using this process for more than a decade now, and I always have found it to be a tedious, error-prone process.

Hallelujah! Cisco has implemented a feature that enables you to delete specific entries in an ACL, as well as insert entries anywhere you want within an ACL. Cisco calls this feature sequenced ACLs. This makes your ACL-editing process much simpler. Actually, sequenced ACLs are not a new ACL type: They use normal standard or extended named ACLs (numbered ACLs are not supported). This feature was introduced in Cisco IOS 12.2(14)S and has been integrated into 12.2(15)T and 12.3(2)T.


Sequenced ACLs work only with named standard or extended ACLs. However, you can create a named ACL and give it a number as its name, such as ip access-list extended 100. This is common with old-school administrators who have been dealing with ACLs for years. Likewise, you can take a normal numbered ACL and treat it like a named ACL, using the ip access-list {standard | extended} command, where you reference the number in the name field.

ACLs and Sequencing

With sequenced ACLs, each ACL entry is associated with a sequence number. Sequence numbers then can be used to insert an ACL into the middle of an existing list or to delete an existing statement in the list. And if you do not like the sequence numbers that the Cisco IOS assigns to the list, you can resequence them with your own numbering scheme. This ensures that you always can insert ACL statements into a list.

Working with sequenced ACLs is a simple process. However, you need to be aware of some things when adding or deleting entries in a sequenced ACL. First, all ACL statements have sequence numbers?even if you did not assign them any. If you upgrade your Cisco IOS to one that supports sequenced ACLs, the Cisco IOS automatically assigns a sequence number to each statement. The first statement in the list is assigned a sequence number of 10, and every subsequent statement's sequence number is 10 more than the previous one. For example, if you had three statements in your ACL, the default sequence numbers would be 10, 20, and 30. Of course, you do not have to use the standard sequencing that Cisco assigns to ACLs. For route-processor cards and line cards, any sequencing or resequencing that you do automatically is synchronized by the route processor card to all the line cards.

You can create your own sequencing process. For example, you can have ACL sequence numbers incrementing by 100 instead of 10. However, the maximum sequence number that can be assigned is 2,147,483,647. If you exceed this number, you will see the following error message:

Exceeded maximum sequence number.

If you enter an ACL statement without specifying a sequence number, the router uses the default increment of 10 when adding the statement to the end of the list. This applies to a new ACL grouping as well. If you enter an ACL command that already is in the list but that has a different sequence number, the router ignores your input. If you enter a new ACL statement, where it is a unique command in the list, but you have specified a sequence number that is already in use, you will see the following error message:

Duplicate sequence number.

In this case, the Cisco IOS aborts your command, and you need to assign a different sequence number to your statement.


Any sequence numbers that are applied to an ACL are not saved to NVRAM. Each time that the router boots up, the Cisco IOS applies the default sequencing scheme, assigning a sequence number of 10 for the first statement and incrementing sequence numbers by 10 for subsequent statements. Cisco did this to ensure backward compatibility for older Cisco IOS versions that do not support sequence numbers. Therefore, if you resequence your list to multiples of 100, this is not saved when you execute the copy running-config startup-config command.

Resequencing ACLs

Remember that you do not have to sequence a named ACL first; the Cisco IOS does this automatically by starting at 10 and incrementing each statement's sequence number by 10 for following statements. Optionally, you can implement your own sequencing method using the following command:

Router(config)# ip access-list resequence ACL_name

  starting_seq_# increment

As an example, if you want to resequence the ACL named 100, you would follow these steps. First, display the current ACL with the show access-list command, as shown in Example 7-16 (this is the same ACL that I used previously for the network in Figure 7-2).

Example 7-16. Displaying the Sequence Numbers for ACLs

Router# show access-list 100

Extended IP access list 100

  10 permit tcp any host eq www

  20 permit udp any host eq domain

  30 permit tcp any host eq smtp

  40 permit tcp any eq smtp host established

  50 permit tcp any host eq ftp

  60 permit tcp any host eq ftp-data

  70 permit tcp any eq www established

  80 permit udp any eq domain

  90 deny ip any any

Notice that the ACL statements use the default sequencing. In this example, I am going to change the sequence numbers to start at 1 and increment by 1. Here is the command to change the sequencing:

Router(config)# ip access-list resequence 100 1 1

To verify the configuration, redisplay the ACL as displayed in Example 7-17.

Example 7-17. Viewing Updated ACL Sequence Numbers

Router# show ip access-list 100

Extended IP access list 100

  1 permit tcp any host eq www

  2 permit udp any host eq domain

  3 permit tcp any host eq smtp

  4 permit tcp any eq smtp host established

  5 permit tcp any host eq ftp

  6 permit tcp any host eq ftp-data

  7 permit tcp any eq www established

  8 permit udp any eq domain

  9 deny ip any any

Notice that the sequence numbers have changed. At any given time, you can resequence the numbers in your ACL.

Deleting an Entry in a Sequenced ACL

Deleting a sequenced ACL entry is just as simple as resequencing it. If you want to delete a specific entry in the ACL, first display the entries with the show access-list command and note the sequence number to the left of the statement that you want to delete. Next, enter the subconfiguration mode for the named ACL, and then delete the command by prefacing the sequence number of the statement with the no parameter. Here is a simple breakdown:

Router# show access-listX

  <--output omitted-->

Router# configure terminal

Router(config)# ip access-list {standard | extended} ACL_name

Router(config-{std | ext}-nacl)# no sequence_#

As you can see from this example, deleting an entry is straightforward. To illustrate this, in Example 7-18, I delete entry number 9 from the resequencing Example 7-17.

Example 7-18. Deleting a Specific Sequenced ACL Entry

Router(config)# ip access-list extended 100

Router(config-ext-nacl)#no 9

Router(config-ext-nacl)# end

Router# show access-list 100

Extended IP access list 100

    1 permit tcp any host eq www

    2 permit udp any host eq domain

    3 permit tcp any host eq smtp

    4 permit tcp any eq smtp host established

    5 permit tcp any host eq ftp

    6 permit tcp any host eq ftp-data

    7 permit tcp any eq www established

    8 permit udp any eq domain

As you can see in this example, deleting entry 9 was as simple as entering no 9.

Inserting an Entry in a Sequenced ACL

Inserting an entry in a sequenced ACL is also very simple. If you want to insert an entry in the ACL, first display the entries with the show access-list command and note the two sequence numbers of the statements where you want to insert your new ACL statement. Choose a number between these two sequence numbers; if there is no room, resequence the ACL. Next, enter the subconfiguration mode for the named ACL and then enter your sequence number for the new ACL, the action (permit or deny), and the condition. Basically, this is exactly the same as adding a normal named ACL statement, with the exception of putting the sequence number at the beginning of the line. Here is a simple breakdown:

Router# show access-list

<--output omitted-->

Router# configure terminal

Router(config)# ip access-list {standard | extended} ACL_name

Router(config-{std | ext}-nacl)# sequence_# {permit | deny} condition

As you can see from this example, inserting an entry is straightforward. To illustrate this, in Example 7-19 I add back entry number 9 from the deletion example in Example 7-18, using a sequence number of 50 for this entry.

Example 7-19. Previewing an ACL Before Inserting an ACL Statement

Router# show access-list 100

Extended IP access list 100

    1 permit tcp any host eq www

    2 permit udp any host eq domain

    3 permit tcp any host eq smtp

    4 permit tcp any eq smtp host established

    5 permit tcp any host eq ftp

    6 permit tcp any host eq ftp-data

    7 permit tcp any eq www established

    8 permit udp any eq domain

As you can see from this ACL, sequence number 50 does not exist, so in Example 7-20, I add the statement that I previously deleted back into the ACL.

Example 7-20. Inserting an ACL Statement

Router(config)# ip access-list extended 100

Router(config-ext-nacl)# 50 deny ip any any

As you can see, I added my new statement with a sequence number of 50. Next, I view my ACL configuration to verify the statement's placement within the ACL, as displayed in Example 7-21.

Example 7-21. Verifying the Statement's Placement Within the ACL

Router# show access-list 100

Extended IP access list 100

    1 permit tcp any host eq www

    2 permit udp any host eq domain

    3 permit tcp any host eq smtp

    4 permit tcp any eq smtp host established

    5 permit tcp any host eq ftp

    6 permit tcp any host eq ftp-data

    7 permit tcp any eq www established

    8 permit udp any eq domain

    50 deny ip any any

In this example, my new statement is placed in the correct location.

From these last two sections, you can see that editing an ACL is a breeze when using sequence numbers. It takes the wonderful pain out of editing ACLs and reduces the number of stories that I can tell my students about stupid editing mistakes I have made using the old method.