July 3, 2013 by James

Migrating from IOS to IOS-XE – interface rate-limit

Historically I've used simple access-lists and interface rate-limit commands to act as a backstop preventing the network being overwhelmed by runaway traffic flows (UDP from DNS reflection attacks being the flavour of the month).

On standard IOS boxes (7206-NPEG2 in this case) it was quite simple to follow the recommendations in the secure IOS template published on the excellent Team Cymru website.

However – on the newer ASR's etc running IOS-XE you can't use the rate-limit command to refer to a specific access list – something like:

rate-limit input access-group 150 2010000 250000 250000 conform-action transmit exceed-action drop

Instead – and this is no bad thing – you'll need to use class-based QoS to achieve the desired effect.  This adds a couple of steps, but does allow more flexibility, and if you're using netflow (and why wouldn't you) you can then view how well your policies are working.  Here's a simple example:

The first thing to do is define an access list that will match the traffic you're interested in. In this example, we'll be monitoring and controlling UDP traffic.

R6(config)#no access-list 150
R6(config)#access-list 150 remark match_udp acl
R6(config)#access-list 150 permit udp any any

Now we'll need to specify a class map to identify the traffic we're interested in by referencing the access-lists we just created.  

R6(config)#class-map match-all match_udp
R6(config-cmap)# match access-group 150

The match-all statement allow some logical control of the statements that follow – AND and OR are possible with match-all  / match-an

Then configure the policy map – this can contain multiple class maps (is this getting convoluted enough yet ?)

I've called the policy-map 'protection' – something descriptive is always useful !  I'm using the same control rates as mentioned above – obviously you'll need to adjust that to suit.  2Mb/s of UDP just might not be enough !  I'd recommend establishing a baseline for normal levels and then adding a safety factor  – this is quite a blunt instrument and should just act as the endstop.

R6(config)#policy-map protection
R6(config-pmap)# class match_udp
R6(config-pmap-c)#police cir 2010000 bc 250000 be 250000
R6(config-pmap-c-police)#conform-action transmit
R6(config-pmap-c-police)#exceed-action drop
R6(config-pmap-c-police)#violate-action drop

The final thing to do is apply the policy map to an interface of your choosing.  Two caveats of course:

1. If the link is saturated with traffic then this isn't going to help much – you'll need to do something upstream.

2. You can only apply these policies on certain types of interfaces – and etherchannel interfaces are NOT supported (in the default flow based load sharing mode, anyway

To apply the policy:

R6#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R6(config)#int fastEthernet 0/0
R6(config-if)#service-policy input protection

The final and very important step is to verify the configuration changes:

R6#show policy-map interface fast0/0

  Service-policy input: protection

    Class-map: match_udp (match-all)
      0 packets, 0 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: access-group 150
          cir 2010000 bps, bc 250000 bytes, be 250000 bytes
        conformed 0 packets, 0 bytes; actions:
        exceeded 0 packets, 0 bytes; actions:
        violated 0 packets, 0 bytes; actions:
        conformed 0 bps, exceed 0 bps, violate 0 bps

Keep an eye on this !   You want to make sure that you're not dropping valid traffic.  Of course, if you're getting flooded then there's just going to be a bunfight – it's possible to add deny statements to the access lists that will exclude traffic from the matching – remember in this case the access lists aren't being used to permit or deny traffic – they're being used to mark or ignore traffic.   




More information is available from Cisco – here