Implementing Loop Prevention on CUBE

We work quite a lot with a single ITSP in our smaller deployments, but keep hitting a problem with number porting.  We’re repeatedly facing a problem whereby the number porting is done up front, and often in the case of BE6K installations includes numerous number ranges, BRI’s, analog extensions etc.  Often at the time of porting we need to account for 20+ different patterns across 5 or so sites.

The problem crops up when asking for all these ported patterns/ranges in a single list to place on the CUBE.  Quickly it appears that different people requested it, the porting requests were done piecemeal, etc – long story getting all the numbers up front can become a bit tricky.  Not that there is a good reason from it.  It’s a bit of a joke.  But this is what happens.

Come to porting, and we miss a pattern or five.  Now (my favourite part), the upstream provider for our ITSP starts crying because (and wait for it)… we have brought down their network.  They can’t seem to implement loop prevention, and somehow the looping that results from an inbound INVITE only matching the intended outbound dial-peers bombs the providers Media Server – but my little 2RU 2921 stands firm.  I kid you not. 🙂

So, after laughing for about 5min, let’s implement Loop Prevention on our side.  This can be done with COR Lists (vomit), but I prefer to use the newer features in IOS 15.4+, and stick to whats prescribed in the CVD BE6K Edge document.

Here’s the dial plan config that’s pretty much completely scalable – implemented with only 2 dial peers!


voice class uri 1 sip
host ipv4:<cucm-ip-sub-primary>
host ipv4:<cucm-ip-sub-secondary>
voice class uri 2 sip
host ipv4:<itsp-ip>
voice class e164-pattern-map 1
description *** To CUCM ***
e164 <internal-dn-range1>
e164 <internal-dn-range2>
e164 <internal-dn-range3>
voice class e164-pattern-map 2
description *** To ITSP ***
e164 .T
voice class dpg 1
dial-peer 100
voice class dpg 2
dial-peer 200
voice class server-group 1
ipv4 <cucm-ip-sub-primary>
ipv4 <cucm-ip-sub-secondary> pref 1
description *** CUCM ***
voice class server-group 2
ipv4 <itsp-ip>
description *** ITSP ***
dial-peer voice 100 voip
description *** CUCM ***
session protocol sipv2
session server-group 1
destination dpg 2
destination e164-pattern-map 1
incoming uri via 1
voice-class codec 1
dtmf-relay rtp-nte sip-kpml
no vad
dial-peer voice 200 voip
description *** ITSP ***
session protocol sipv2
session server-group 2
destination dpg 1
destination e164-pattern-map 2
incoming uri via 2
voice-class codec 1
voice-class sip bind control source-interface <external-interface>
voice-class sip bind media source-interface <external-interface>
no vad
dtmf-relay rtp-nte sip-kpml


Some Notes:

  • The loop prevention hinges on the face that you exclude dial peers using dial-peer groups.  An absolutely fantastic feature.
  • Outbound destinations are serviced by server groups – another brilliant addition.
  • Inbound matching is done using the URI Enhancements provided in 15.x and up
  • I tend to prefer to localize E.164 in CUCM for a Central Breakout Design.  I just like the extensible nature of Called and Calling Transformations.  I believe that this is more in line with the CVD/SRND – could be debated though.


A possible modification could drop the server groups (the limitation is that these only support IP), and instead route using DNS SRVs.  I like this approach a lot, and try and implement as such whenever possible.

What’s lovely about this is that the skeleton never changes – I get my patterns added to the e164 pattern map, adjust my IP’s and I’m good to go.


Voila!  CUBE implemented in under 5min.  Hope this helps some of you out there.



18 thoughts on “Implementing Loop Prevention on CUBE

  1. It’s awesome, Jonathan! You summarized plenty of Cisco Best Practices documents in a single config, very good job. Thank you for sharing this publicly. 🙂


    1. Hi Yorick

      Thank you very much for your feedback – glad that you found value out of this article! I have implemented a number of CUBE’s with this set-up with high levels of success.

      Please let me know if you have any thoughts on it’s improvement/extensions – feedback is always welcome!

      – Jonathan


      1. I have actually one comment/question. In the Cisco doc, it’s said that the Outbound dial-peer must have a destination-pattern configured, even if it’s not used for matching.
        So I understand that the destination criteria is never evaluated by the IOS to select the Outbound DP, when the selected Inbound DP is configured to use a DPG.

        In conclusion, I think that the e164-pattern-map commands are not useful here. As soon as the Inbound DP is matched, the Outbound DP is matched automatically.

        What do you think?


  2. You will always need a dial-peer for the inbound and outbound legs.

    As you can see, I achieve the trivial CUBE configuration with only 2 dial-peers. This means that each dial-peer acts as inbound/outbound depending on the call flow direction. The The e164-pattern-map’s are ONLY used for outbound.

    So, in our ITSP > INTERNAL CUCM call flow:

    – Dial-peer 200 is matched based on the URI presented from the ITSP – I suggest matching on “via” header.
    – This dial-peer specifies voice class dpg 1 that only allows outbound routing via dial-peer 100.
    – Dial-peer 100, in turn, has an e164-pattern-map that lists the PATTERNS that the can be matched the RURI of the INVITE received from the ITSP.
    – If there is a match against any of the listed patterns, the call is routed out dial-peer 100.
    – If not, the call fails with a 404 NOT FOUND sent to the ITSP, which is what we want in this case to ensure Loop Prevention!

    As you can see the e164-pattern-map is a key config requirement. If it confuses you, remember all that it is doing is consolidating multiple destination-patterns into a single dial-peer – before we would have had to duplicate dial-peers for different destinations. This new feature allows you to decouple “what pattern is being matched” from “where the call is routed”.



    1. Thank you Jonathan for this good recap. I got the logic behind this whole config and I would have done it the same way, mixing DPG and E164-map exactly like you. But, I’m very confused by the Cisco documentation that explains the things a bit differently that the way we would do it.

      Look at this up-to-date guide:

      It’s said: “The destination-pattern command is required on the outbound dial peer even matching is not done based on this command.”

      Also: “Once an incoming call is matched by an inbound dial peer with an active destination dial-peer group, dial peers from this group are used to route the incoming call. No other outbound dial-peer provisioning to select outbound dial peers is used.”

      And in the config details: “Configures a destination pattern. This step is required even though the value is not used for dial-peer matching.”

      And finally in the example, the destination-pattern values seem very dummy, and unrelated to the “incoming called-number value” configured in the inbound dial-peer.

      So, in my understanding, when we force the match of the oubound DP based on the inbound DP, the destination patterns (or E164-map) seem simply ignored.

      In the next weeks I’ll have to implement a new CUBE, so I’ll test it in real-life and see what is the correct behavior.

      Thank you.


      1. Ignore this, in my opinion it’s a mistake in the guide, or the guide was written before considering e164-pattern-maps. My post is a working config, and I’ve deployed as such on numerous occasions.

        Regarding the destination-pattern matching, again please see my comments regarding outbound dial-peer matching. Nothing has ever changed in this logic, even with the introduction of pattern-maps.

        Let me know how your new CUBE goes! Please feel free to ping me if you have any questions. Always happy to help! 🙂


  3. Hi Jonathan,

    Thanks for this great article! This simplifies dial-peers considerably and reduces the risk of calls looping. There are some great commands that help with this now.

    I have been running some tests in a lab and whilst I can get inbound and outbound calls routing as expected the ‘e164-pattern-map’ on the dial-peers seems to have no effect strangely. If I add numbers into the pattern maps it’s as if it ignores them and lets any number through regardless. If I remove the e164-pattern-map from the dial-peers the calls still flow as well.

    At present inbound calls to unknown numbers are being forwarded to my UCM server which just sends back a 404 as expected.

    Any thoughts would be much appreciated.



  4. Hi Mark

    Thanks for your comment.

    “voice class dpg” controls reachability for inbound dial peers. If you are getting a 404, it probably means that it’s not matching an inbound dial peer. I’d suggest running “debug voip dialpeer” to confirm this. You should see the dpg matching in the debug.

    voice class “e164-pattern-map” is simply an aggregator for outbound dial-peers. If your dpg provides reachability to your dial peer that has the pattern map, then your outbound routing should work correctly.

    Share a config, maybe I can help.



    1. Hi Jonathan,

      Thanks for your reply.

      I am wondering if this is a Cisco bug. If I run a debug voip dialpeer it is matching the relevant dial peer regardless of what is in the e164-pattern-map. It is as if it is mapped via the incoming URI to the dial peer it completely ignores the e164-pattern-map for the destination dpg and just forwards to the destination dpg regardless.

      Whilst inbound and outbound calling works as expected with your configuration above I can’t filter unknown numbers from going to my UCM server to the pattern map being ignored.

      The config I have is exactly the same as yours above apart from some translation rules I am running for called/calling numbers.

      You can also see in the dial-peer voice configuration the destination being mapped with the e164-pattern-map correctly:

      peer type = voice, system default peer = FALSE, information type = voice,
      description = `*** Cisco UCM Cluster ***’,
      tag = 100, destination-pattern = `’,
      destination e164-pattern-map tag = 1 status = valid,
      destination dpg tag = 2 status = valid,

      peer type = voice, system default peer = FALSE, information type = voice,
      description = `*** SIP Provider ***’,
      tag = 200, destination-pattern = `’,
      destination e164-pattern-map tag = 2 status = valid,
      destination dpg tag = 1 status = valid,

      A bit odd…

      Any further thoughts would be appreciated before I fault this out to TAC.



      1. Hi Mark

        So before you go to TAC…

        let’s assume the call is from CUCM and you want to dial the PSTN. The incoming called number is +1234567890.

        – call matches inbound dial peer by matching voice class uri with the CUCM IP Address (in my example this is on dial-peer 100). Called number does not take precedence over uri.

        – dial-peer 100 has a voice class dpg 2 -> this limits reachability to dial-peer 200 for outbound dial peer matching (only 200 is specified in the dpg config)

        – dial-peer 200 has an e164-pattern-map that includes a pattern “.T”. +1234567890 matched on .T and the call routes.

        I think there may be an error in your understanding here? I’ve never seen a problem with pattern matching across several versions. If you’re certain this is a problem, maybe do an IOS upgrade on your router (assuming this is in a lab?). May be faster.

        – Jonathan


  5. Hi Jonathan,

    I’m not so worried about the outbound routing as that is set to allow .T anyway. The call flow I am testing is as follows:

    There is an incoming call from the PSTN to CUCM. The incoming called number is +1234557890.

    – call matches inbound dial peer by matching voice class uri with the SIP provider IP Address (in your example this is on dial-peer 200).

    – dial-peer 200 has a voice class dpg 1 -> this limits reachability to dial-peer 100 for outbound dial peer matching (only 100 is specified in the dpg config)

    – dial-peer 200 has an e164-pattern-map that includes a pattern “+0112233445” only which should therefore block “+1234557890” and send back a 404 immediately. -> This isn’t happening and the call is then sent to the IP address of the UCM server (via session server-group 1) with the UCM server giving the 404 instead.

    I have just upgraded from 15.4(3)M3 to 15.4(3)M6 in the last 5 minutes on my test SBC’s and it has unfortunately made no difference.



      1. I haven’t had a chance to follow this up with TAC yet. I will let you know once I have.


  6. I just tested this on a 2911 and didn’t have to implement E164 maps at all. Logic being we only have one SIP provider who should only be sending us what we own and we only have one CUCM cluster, so we just send everything to it.

    So glad I found this as I was about to head down the road of having to implement dozens if not over a hundred dial peers for DID ranges that must have been ordered by a masochist. Now, I only have TWO dial peers. Amazing.

    In case it helps anyone here is what I implemented my test setup. Just a chopped down version of this page really. Use your imagination for the server-groups and incoming uri:

    voice class dpg 1
    dial-peer 1000
    voice class dpg 2
    dial-peer 2000

    dial-peer voice 1000 voip
    description CUCM
    session protocol sipv2
    session server-group 10
    destination dpg 2
    incoming uri via CUCM
    voice-class sip bind control source-interface GigabitEthernet0/0
    voice-class sip bind media source-interface GigabitEthernet0/0
    dtmf-relay rtp-nte sip-notify
    codec g711ulaw
    no vad
    dial-peer voice 2000 voip
    description ITSP
    call-block translation-profile incoming BlockInbound
    call-block disconnect-cause incoming invalid-number
    session protocol sipv2
    session server-group 999
    destination dpg 1
    incoming uri via FreePBX
    voice-class sip bind control source-interface GigabitEthernet0/2
    voice-class sip bind media source-interface GigabitEthernet0/2
    dtmf-relay rtp-nte sip-notify
    codec g711ulaw
    no vad


    1. Hey Jim

      Glad it helped you as well! I like your config by the way. The e164-maps eliminate the “trust” in your ITSP with your assumption. If you get sent gibberish, this prevents it from being backhauled to your SIP server. I prefer this method as it adds to your application-layer boundary. I see that you’re maybe doing something similar with a translation-profile though.

      – Jonathan


  7. This is an excellent post. Thanks, Jonathan. Looking forward to Jim’s response re translation profiles configs to block unwanted incoming numbers from ITSP.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s