Auto Draft

Control Plane Policing (CoPP) on Cisco IOS-XE: Protect Your Network’s Brain

Your routers and switches are under constant attack — and most of that attack traffic isn’t aimed at your data plane. It’s aimed at the CPU. SNMP floods, malformed BGP updates, SYN attacks against management SSH, OSPF packets with crafted headers — all of these are designed to overwhelm the one thing that keeps your network alive: the control plane. Control Plane Policing (CoPP) is Cisco’s answer to this problem, and it’s one of the most effective hardening controls you can deploy. Yet I’m consistently surprised by how many production networks have none of it configured.

This post is the CoPP reference guide I wish had existed when I first started deploying it in enterprise environments. We’ll cover what the control plane actually is, how CoPP works conceptually, and — most importantly — a production-ready CoPP template with real IOS-XE syntax you can adapt and deploy today. I’ll also cover the show commands you need to verify it’s working and how to tune it without accidentally taking down your routing protocols. If you’re not sure which IOS variant you’re running and whether it supports CoPP, check out our Cisco IOS vs IOS-XE vs IOS-XR breakdown first.

What Is the Control Plane — and Why Does It Need Policing?

In Cisco architecture, network traffic is divided into three planes:

  • Data plane (forwarding plane): Transit traffic that passes through the device. Your router forwards it in hardware (ASICs/FPGAs) without involving the CPU. This is the bulk of what flows through a network device.
  • Management plane: Traffic destined to the device for management purposes — SSH sessions, SNMP queries, syslog, NETCONF, HTTP to the management API.
  • Control plane: Traffic that the device’s CPU must process to maintain network state — BGP updates, OSPF hellos and LSAs, EIGRP, STP BPDUs, ARP, ICMP directed at the device, DHCP, HSRP/VRRP, and anything else that requires the Routing Engine (RP) to take action.

The data plane is hardware-accelerated and essentially impervious to packet floods. The control plane is not. The Route Processor CPU that handles OSPF, BGP, ARP, and SSH is a shared resource, and if it gets overwhelmed, your routing adjacencies drop, your switches start flooding, and your network falls apart — even though the underlying physical connectivity is fine.

This is exactly the class of vulnerability exploited in recent Cisco advisories: the CVE-2025-20352 SNMP stack overflow (which sends crafted SNMP packets to cause a DoS), the IOS-XE OSPFv2 DoS vulnerability (malformed OSPF packets crash the OSPF process), and various ICMP/routing-protocol-based exhaustion attacks. CoPP won’t patch a software bug, but it will rate-limit the attack traffic so the CPU can stay functional while you patch.

How CoPP Works

CoPP uses the familiar MQC (Modular QoS CLI) framework — the same class-map/policy-map structure used for traffic QoS. The difference is that instead of applying the policy to a physical interface, you apply it to the logical control-plane interface. Traffic that would normally hit the CPU is classified and policed before it gets there.

The flow is:

  1. Packets destined for the RP CPU are intercepted before reaching it.
  2. CoPP class maps match this traffic by protocol, ACL, or DSCP.
  3. The CoPP policy map applies policers (not queues — CoPP polices, not queues).
  4. Conforming traffic passes to the CPU normally. Exceeding traffic is either dropped or marked down.

The key distinction from regular QoS: CoPP uses police statements, not bandwidth or priority. You’re setting a maximum rate ceiling on each class of traffic reaching the CPU, not guaranteeing bandwidth.

A Production CoPP Template for IOS-XE

The following template is based on Cisco’s recommended CoPP policy for enterprise IOS-XE deployments, adapted from real production use. I’ll walk through it class by class. Adjust the police rates to match your network’s actual traffic levels — the values here are conservative starting points.

Step 1: Define ACLs for Protocol Classification

! ── BGP: TCP port 179 to/from this router ──
ip access-list extended ACL-CoPP-BGP
 permit tcp any host <ROUTER-LOOPBACK-IP> eq 179
 permit tcp any host <ROUTER-LOOPBACK-IP> gt 1023 established
 permit tcp host <ROUTER-LOOPBACK-IP> any eq 179

! ── OSPF: Protocol 89 directed to this router or to 224.0.0.5/6 ──
ip access-list extended ACL-CoPP-OSPF
 permit ospf any host <ROUTER-IP>
 permit ospf any host 224.0.0.5
 permit ospf any host 224.0.0.6

! ── EIGRP: Protocol 88 ──
ip access-list extended ACL-CoPP-EIGRP
 permit eigrp any host 224.0.0.10
 permit eigrp any host <ROUTER-IP>

! ── HSRP / VRRP ──
ip access-list extended ACL-CoPP-HSRP
 permit udp any host 224.0.0.2 eq 1985
 permit udp any host 224.0.0.102 eq 1985
 permit vrrp any host 224.0.0.18

! ── SNMP: UDP 161/162 ──
ip access-list extended ACL-CoPP-SNMP
 permit udp <MGMT-SUBNET> <MGMT-WILDCARD> any eq 161
 permit udp any any eq 162

! ── SSH / Telnet / HTTPS management ──
ip access-list extended ACL-CoPP-MGMT
 permit tcp <MGMT-SUBNET> <MGMT-WILDCARD> any eq 22
 permit tcp <MGMT-SUBNET> <MGMT-WILDCARD> any eq 23
 permit tcp <MGMT-SUBNET> <MGMT-WILDCARD> any eq 443
 permit tcp <MGMT-SUBNET> <MGMT-WILDCARD> any eq 830

! ── ICMP: ping and traceroute ──
ip access-list extended ACL-CoPP-ICMP
 permit icmp any any echo
 permit icmp any any echo-reply
 permit icmp any any traceroute
 permit icmp any any ttl-exceeded
 permit icmp any any port-unreachable

! ── NTP ──
ip access-list extended ACL-CoPP-NTP
 permit udp any any eq 123
 permit udp any eq 123 any

! ── DHCP / BOOTP ──
ip access-list extended ACL-CoPP-DHCP
 permit udp any host 255.255.255.255 eq 67
 permit udp any any eq 67
 permit udp any any eq 68

! ── ARP is handled at L2, not in CoPP for IOS-XE routers ──
! ── On switches, ARP inspection handles this separately ──

Step 2: Build the CoPP Class Maps

One class map per traffic type. Using match-any so any matching condition qualifies the packet:

class-map match-any CM-CoPP-BGP
 match access-group name ACL-CoPP-BGP

class-map match-any CM-CoPP-OSPF
 match access-group name ACL-CoPP-OSPF

class-map match-any CM-CoPP-EIGRP
 match access-group name ACL-CoPP-EIGRP

class-map match-any CM-CoPP-HSRP
 match access-group name ACL-CoPP-HSRP

class-map match-any CM-CoPP-SNMP
 match access-group name ACL-CoPP-SNMP

class-map match-any CM-CoPP-MGMT
 match access-group name ACL-CoPP-MGMT

class-map match-any CM-CoPP-ICMP
 match access-group name ACL-CoPP-ICMP

class-map match-any CM-CoPP-NTP
 match access-group name ACL-CoPP-NTP

class-map match-any CM-CoPP-DHCP
 match access-group name ACL-CoPP-DHCP

class-map match-any CM-CoPP-FRAGMENTED
 match ip fragmented

class-map match-any CM-CoPP-UNDESIRABLE
 match access-group name ACL-CoPP-UNDESIRABLE

Step 3: The CoPP Policy Map

This is where the policing rates are set. The conform-action transmit / exceed-action drop pair is the standard CoPP posture — legitimate protocol traffic almost never exceeds these rates in a healthy network:

policy-map PM-CoPP
 !
 ! ── BGP: Critical — keep rate generous for large routing tables ──
 class CM-CoPP-BGP
  police rate 64000 bps burst 8000 byte
   conform-action transmit
   exceed-action transmit
   ! NOTE: Start with transmit on exceed for BGP — don't drop BGP during tuning
 !
 ! ── OSPF: Medium rate — adjacencies need consistent hellos ──
 class CM-CoPP-OSPF
  police rate 32000 bps burst 4000 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── EIGRP ──
 class CM-CoPP-EIGRP
  police rate 32000 bps burst 4000 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── HSRP/VRRP ──
 class CM-CoPP-HSRP
  police rate 16000 bps burst 2000 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── SNMP: Rate-limit — key target for DoS (see CVE-2025-20352) ──
 class CM-CoPP-SNMP
  police rate 32000 bps burst 4000 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── SSH/Telnet/HTTPS Management ──
 class CM-CoPP-MGMT
  police rate 32000 bps burst 4000 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── ICMP: Allow pings but prevent ping floods ──
 class CM-CoPP-ICMP
  police rate 8000 bps burst 1500 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── NTP ──
 class CM-CoPP-NTP
  police rate 8000 bps burst 1500 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── DHCP ──
 class CM-CoPP-DHCP
  police rate 32000 bps burst 4000 byte
   conform-action transmit
   exceed-action drop
 !
 ! ── Fragmented IP: Should be near-zero in a well-run network ──
 class CM-CoPP-FRAGMENTED
  police rate 4000 bps burst 1000 byte
   conform-action drop
   exceed-action drop
 !
 ! ── Everything else: catch-all best effort ──
 class class-default
  police rate 8000 bps burst 1500 byte
   conform-action transmit
   exceed-action drop

Step 4: Apply CoPP to the Control Plane

control-plane
 service-policy input PM-CoPP

That single stanza is what activates CoPP. There’s no interface to apply it to — the control-plane keyword is a virtual interface representing all traffic destined for the RP CPU.

CoPP on Catalyst 9000 Series: What’s Different

The Catalyst 9000 family (9300, 9400, 9500, 9600) implements CoPP in hardware using the UADP (Unified Access Data Plane) ASIC. The behavior is the same conceptually, but there are a few platform-specific considerations:

  • System-default CoPP: Catalyst 9K ships with a default CoPP policy already applied. Before deploying your own, check what’s already there with show policy-map control-plane. Replacing the default entirely is fine — just don’t leave the control plane unprotected during the swap.
  • Hardware vs software policing: On the 9K, CoPP is enforced in the ASIC before packets reach the RP. This means even a wire-rate flood is rate-limited before the CPU sees it — a significant advantage over older software-only CoPP implementations.
  • IPv6 is separate: CoPP ACLs must include IPv6 entries separately. If you have IPv6 routing (OSPFv3, BGP for IPv6), add matching ipv6 access-list entries and include them in your class maps.
  • Per-ASIC instances: On chassis-based 9600 with multiple line cards, CoPP is instantiated per-ASIC. The show platform hardware fed active qos policy target control-plane command shows per-ASIC hit counts.

Verifying CoPP with Show Commands

After deploying CoPP, these are the commands you’ll use daily to monitor and tune it. Run these periodically — or script them with EEM/Python — to catch anomalies early:

! ── See the overall CoPP policy and counters ──
show policy-map control-plane

! Sample output (truncated):
!
! Control Plane
!
!   Service-policy input: PM-CoPP
!
!     Class-map: CM-CoPP-BGP (match-any)
!       5 packets, 320 bytes
!       5 minute offered rate 0000 bps, drop rate 0000 bps
!       Match: access-group name ACL-CoPP-BGP
!       police:
!           rate 64000 bps, burst 8000 byte
!         conformed 5 packets, 320 bytes; actions: transmit
!         exceeded 0 packets, 0 bytes; actions: transmit
!
!     Class-map: CM-CoPP-SNMP (match-any)
!       12503 packets, 1250300 bytes
!       5 minute offered rate 85000 bps, drop rate 52000 bps
!       Match: access-group name ACL-CoPP-SNMP
!       police:
!           rate 32000 bps, burst 4000 byte
!         conformed 4820 packets, 481800 bytes; actions: transmit
!         exceeded 7683 packets, 768300 bytes; actions: drop

! ── If you see high drop rates on SNMP, BGP, or OSPF, investigate the source ──
! ── High drops on class-default is normal (background noise traffic) ──


! ── Clear counters to get a fresh baseline ──
clear counters

! ── Check input on the control-plane interface ──
show interfaces control-plane

! ── On Catalyst 9K: hardware-level counters ──
show platform hardware fed active qos policy target control-plane

! ── Identify what's in class-default (to tune it into proper classes) ──
show policy-map control-plane | section class-default

! ── Check for CPU spikes that preceded a CoPP event ──
show processes cpu sorted | head
show processes cpu history

Tuning CoPP Without Breaking Your Routing Protocols

The most common mistake when deploying CoPP in an existing network is being too aggressive with policing rates before you understand your baseline traffic. Here’s a safe rollout process:

  1. Deploy in monitor mode first. Change all exceed-action drop to exceed-action transmit. This lets you measure without affecting traffic. Let it run for 24–48 hours.
  2. Baseline your rates. Run show policy-map control-plane periodically. Note the offered rate for each class. Your police rates should be 2–3× the normal offered rate to handle bursts.
  3. Enable dropping class by class. Start with classes you’re most confident about (ICMP, fragmented, class-default). Leave BGP and OSPF in transmit-on-exceed mode until you’re sure your rates are right.
  4. Watch for adjacency flaps. If OSPF or BGP drops after enabling strict policing, check show policy-map control-plane — high drop counts on those classes indicate your police rate is too low for your network’s routing table update frequency. This is especially relevant for BGP in environments with full routing tables — see our Understanding BGP guide for context on update message volumes.
  5. Lock it down once stable. Once you’ve validated rates over a week or two in production, set exceed-action drop on all classes.

Pro tip: On networks where SNMP polling is heavy (lots of monitoring tools hitting the router), you’ll often find SNMP is your highest-volume class. Don’t set the SNMP rate too low — a NMS like PRTG or LibreNMS polling every 30 seconds across hundreds of OIDs can legitimately generate significant SNMP traffic. Baseline it first.

Why CoPP Would Have Mitigated Recent Cisco CVEs

Looking at recent Cisco security advisories, it’s striking how many of them are control-plane attacks where CoPP would have reduced or eliminated the impact:

  • CVE-2025-20352 (SNMP DoS/RCE): An attacker sends crafted SNMP packets to trigger a stack overflow. A CoPP policy limiting SNMP to your management subnet — and rate-limiting it — would both restrict who can send SNMP packets and limit the flood rate, buying time before patching.
  • IOS-XE OSPFv2 DoS: Malformed OSPF packets sent from an adjacent segment crash the OSPF process. CoPP limits OSPF ingress rate and can restrict OSPF source addresses (combined with OSPF MD5/SHA authentication — always authenticate your IGP). It won’t block a valid-looking crafted packet, but rate limiting buys time.
  • IOS-XE Privilege Escalation via management interface: CoPP combined with strict management ACLs (limiting SSH/HTTPS to known management subnets) is a defense-in-depth layer against exploitation of management-plane vulnerabilities.

CoPP is not a substitute for patching — patch your devices. But in an enterprise where you have hundreds of devices to patch on a maintenance window schedule, CoPP is what keeps the network alive until you get there. Pair it with solid home network security practices and the layered defense approach covered in our Home Network Security guide for a more complete picture.

Quick Reference: Essential CoPP Show Commands

! View all CoPP classes and current packet/byte counters
show policy-map control-plane

! View only the input policy (cleaner output)
show policy-map control-plane input

! Check if a specific class is dropping traffic
show policy-map control-plane | section CM-CoPP-SNMP

! Catalyst 9K: ASIC-level CoPP stats
show platform hardware fed switch active qos policy target control-plane

! ISR 4K / ASR 1K: CPU utilization context
show processes cpu | include CoPP
show platform packet-trace summary

! Verify CoPP is applied
show control-plane host open-ports
show running-config | section control-plane

What CoPP Doesn’t Do

A few important limitations to keep in mind:

  • CoPP doesn’t filter data-plane traffic. If someone is flooding a customer VLAN, CoPP won’t stop it. Use ACLs, PACL, or hardware QoS for data-plane attacks.
  • CoPP doesn’t replace authentication. Always use OSPF MD5/SHA-256 authentication, BGP MD5, SSH key-based auth, and SNMP v3. CoPP is rate-limiting, not access control.
  • CoPP doesn’t protect against logical attacks. A valid BGP UPDATE with a crafted path attribute can still crash a vulnerable BGP process — CoPP won’t block a single well-formed malicious packet. Patch your software.
  • CoPP requires ongoing tuning. As your network evolves (new monitoring tools, new routing sessions, new protocols), revisit your CoPP rates. An overly-restrictive CoPP policy in a changed network is a silent headache.

Wrapping Up

Control Plane Policing is one of those foundational security controls that every network should have but that often gets skipped because it’s “not urgent.” Then there’s an SNMP flood, or someone starts scanning your management subnet with crafted packets, and suddenly the OSPF adjacencies that have been stable for years start flapping — and nobody can figure out why until they look at CPU utilization.

The template in this post is a solid starting point. Adapt the ACLs to your actual management subnet, customize the police rates after baselining your traffic, and roll it out class-by-class. Then set up a periodic show policy-map control-plane check in your monitoring system — unexpected spikes in any class are worth investigating before they become incidents.

Got questions about tuning CoPP for your specific environment, or want to share a gotcha you’ve hit in production? Drop it in the comments below.

Enjoying this post?

Get more guides like this delivered straight to your inbox. No spam, just tech and trails.