Feb
15

The leading question:

"Is it possible (and if so, how) to redistribute or originate a default route based on time of day?"

The short answer is "Sure, why not?"...  But the longer answer has to do with how do we warp the forces of the universe to make that happen???

Well, start with what we know.  We know we can do time-ranges in access-lists, right?  Can we do them in standard access-lists (what we see used for redistribution all the time)?

Rack1R1(config-if)#exit
Rack1R1(config)#access-list 1 permit 172.16.0.0 0.15.255.255 ?
log  Log matches against this entry
<cr>

Rack1R1(config)#

Nope.  There's a bummer.  So we will need to use EXTENDED ACL's in order to make this work.  So now we are reaching the point of "Yes, it can be done, but it will make my head hurt." as the answer.   :)

First, as a little review, check out a blog we did last year providing some information on that sort of thing in conjunction with a distribute-list in different routing protocols.

http://blog.internetworkexpert.com/2008/01/04/using-extended-access-lists-in-a-distribute-list/

After you've had a little time to review that stuff, let's move on with the testing! I have nabbed my routers in a configured state already. I just recently finished with creating more detailed solutions for Mock Lab 4 (it's a fun one!), so that's the topology that I have going right now. Specifics should really matter, I was just hunting for any particular spot of redistribution in order to see what we could accomplish here.

On R3 I happen to have found some redistribution between OSPF and RIP that looks like fun.

R3 Starting:

Rack1R3(config)#do sh run | s router
router ospf 1
log-adjacency-changes
area 0 authentication message-digest
area 123 virtual-link 150.1.1.1 message-digest-key 1 md5 CISCO
redistribute rip metric-type 1 subnets route-map Red-RIP
network 145.1.3.3 0.0.0.0 area 0
network 145.1.13.3 0.0.0.0 area 123
network 145.1.23.3 0.0.0.0 area 123
network 150.1.3.3 0.0.0.0 area 0
router rip
version 2
redistribute ospf 1 metric 7 route-map RIP-R6
passive-interface default
no passive-interface FastEthernet0/0
network 145.1.0.0
distribute-list 11 out FastEthernet0/0
no auto-summary
Rack1R3(config)#

Rack1R3(config)#do sh run | s route-map
redistribute rip metric-type 1 subnets route-map Red-RIP
redistribute ospf 1 metric 7 route-map RIP-R6
route-map RIP-R6 permit 10
match ip address prefix-list R4-R5-Link
set metric 2
route-map RIP-R6 permit 20
set metric 10
route-map Red-RIP deny 10
match ip address prefix-list NAT-Route
route-map Red-RIP permit 20
set metric-type type-1
Rack1R3(config)#

All devices have "debug ip routing" turned on.

Rack1R3(config)#do sh clock
*02:02:28.984 UTC Sun Feb 15 2009
Rack1R3(config)#

No NTP is running, so we can deal with the current clock settings.   So let's look at our route-maps...  The one called RIP-R6 is going from OSPF to RIP.

Rack1R3(config)#do sh ip ro os
51.0.0.0/32 is subnetted, 1 subnets
O E2    51.51.51.51 [110/20] via 145.1.23.2, 3w2d, Serial1/3.23
O E1 204.12.1.0/24 [110/865] via 145.1.23.2, 1w6d, Serial1/3.23
[110/865] via 145.1.13.1, 1w6d, Serial1/2.13
145.1.0.0/16 is variably subnetted, 20 subnets, 2 masks
O IA    145.1.17.0/24 [110/782] via 145.1.13.1, 3w2d, Serial1/2.13
O E1    145.1.5.0/24 [110/865] via 145.1.23.2, 1w6d, Serial1/3.23
[110/865] via 145.1.13.1, 1w6d, Serial1/2.13
O       145.1.7.0/24 [110/783] via 145.1.13.1, 3w2d, Serial1/2.13
O       145.1.12.0/24 [110/845] via 145.1.23.2, 3w2d, Serial1/3.23
[110/845] via 145.1.13.1, 3w2d, Serial1/2.13
O       145.1.48.0/24 [110/847] via 145.1.23.2, 3w2d, Serial1/3.23
[110/847] via 145.1.13.1, 3w2d, Serial1/2.13
O IA    145.1.58.0/24 [110/846] via 145.1.23.2, 3w2d, Serial1/3.23
[110/846] via 145.1.13.1, 3w2d, Serial1/2.13
O E1    145.1.45.5/32 [110/867] via 145.1.23.2, 3w2d, Serial1/3.23
[110/867] via 145.1.13.1, 3w2d, Serial1/2.13
O E1    145.1.45.4/32 [110/865] via 145.1.23.2, 3w2d, Serial1/3.23
[110/865] via 145.1.13.1, 3w2d, Serial1/2.13
O E1    145.1.45.0/24 [110/865] via 145.1.23.2, 3w2d, Serial1/3.23
[110/865] via 145.1.13.1, 3w2d, Serial1/2.13
O       145.1.47.0/24 [110/1782] via 145.1.13.1, 3w2d, Serial1/2.13
O IA    145.1.125.5/32 [110/845] via 145.1.23.2, 3w2d, Serial1/3.23
[110/845] via 145.1.13.1, 3w2d, Serial1/2.13
O IA    145.1.125.1/32 [110/781] via 145.1.13.1, 3w2d, Serial1/2.13
O E1    145.1.125.0/24 [110/867] via 145.1.23.2, 1w6d, Serial1/3.23
[110/867] via 145.1.13.1, 1w6d, Serial1/2.13
O IA    145.1.125.2/32 [110/781] via 145.1.23.2, 3w2d, Serial1/3.23
O IA 192.10.1.0/24 [110/782] via 145.1.23.2, 3w2d, Serial1/3.23
150.1.0.0/16 is variably subnetted, 7 subnets, 3 masks
O       150.1.7.7/32 [110/783] via 145.1.13.1, 3w2d, Serial1/2.13
O       150.1.4.4/32 [110/848] via 145.1.23.2, 3w2d, Serial1/3.23
[110/848] via 145.1.13.1, 3w2d, Serial1/2.13
O       150.1.2.2/32 [110/782] via 145.1.23.2, 3w2d, Serial1/3.23
O       150.1.1.1/32 [110/782] via 145.1.13.1, 3w2d, Serial1/2.13
O IA    150.1.0.0/20 [110/846] via 145.1.23.2, 3w2d, Serial1/3.23
[110/846] via 145.1.13.1, 3w2d, Serial1/2.13
Rack1R3(config)#

We have quite a few OSPF routes, so we can always pick on a few others just to play.   But let's change things around momentarily.

Rack1R3(config)#do sh run | in prefix-list
ip prefix-list NAT-Route seq 5 permit 145.1.133.0/24
ip prefix-list R4-R5-Link seq 5 permit 145.1.45.0/24
match ip address prefix-list R4-R5-Link
match ip address prefix-list NAT-Route
Rack1R3(config)#

Right now, we're matching a Prefix List...  That will need to change.  Let's create a time-range as well.

R3

time-range First12
periodic daily 0:00 to 11:59
exit

access-list 101 permit ip host 145.1.45.0 host 255.255.255.0 time-range First12

route-map RIP-R6 permit 10
no match ip address prefix-list R4-R5-Link
match ip address 101
set metric 2

Rack1R3(config)#do sh access-list 101
Extended IP access list 101
10 permit ip host 145.1.45.0 host 255.255.255.0 time-range First12 (active) (2 matches)
Rack1R3(config)#

So we're active now.  This is good.   We'll see this route via other paths in this lab, but the metric here is the key.  And we'll notice this change as well.  Since we started re-advertising the route:

Rack1R6(config-router)#
*Feb 15 03:17:13.656: RT: rip's 145.1.45.0/24 (via 145.1.36.3) metric changed from distance/metric [120/10] to [120/2]
*Feb 15 03:17:13.656: RT: NET-RED 145.1.45.0/24
Rack1R6(config-router)#

Notice the metric change.   Now let's go back to R3 and change the time!

Rack1R3#clock set 15:00:00 feb 15 2009
Rack1R3#
*Feb 15 15:00:00.000: %SYS-6-CLOCKUPDATE: System clock has been updated from 02:22:08 UTC Sun Feb 15 2009 to 15:00:00 UTC Sun Feb 15 2009, configured from console by console.
Rack1R3#

Rack1R3(config)#do sh access-list 101
Extended IP access list 101
10 permit ip host 145.1.45.0 host 255.255.255.0 time-range First12 (inactive) (2 matches)
Rack1R3(config)#

Notice that now we are inactive on our time.     **Time Passes**

Well, 20 minutes later and still no update.   Our problem with this is that change IN THE ROUTING TABLE trigger changes to redistribution.  We still learn this route via OSPF and therefore nothing has changed.  If we were to trigger a change in OSPF that would lead to a status change, we would see the route withdrawn.

How do you trigger a status change?  Clear it.

Rack1R3(config)#do clear ip route 145.1.45.0
Rack1R3(config)#
Feb 15 15:12:28.719: RT: del 145.1.45.0/24 via 145.1.23.2, ospf metric [110/865]
Feb 15 15:12:28.719: RT: del 145.1.45.0/24 via 145.1.13.1, ospf metric [110/865]
Feb 15 15:12:28.719: RT: delete subnet route to 145.1.45.0/24
Feb 15 15:12:28.719: RT: NET-RED 145.1.45.0/24
Feb 15 15:12:28.723: RT: SET_LAST_RDB for 145.1.45.0/24
NEW rdb: via 145.1.13.1

Feb 15 15:12:28.723: RT: add 145.1.45.0/24 via 145.1.13.1, ospf metric [110/867]
Feb 15 15:12:28.723: RT: NET-RED 145.1.45.0/24
Feb 15 15:12:28.723: RT: add 145.1.45.0/24 via 145.1.23.2, ospf metric [110/867]
Feb 15 15:12:28.723: RT: NET-RED 145.1.45.0/24
Feb 15 15:12:28.723: RT:ospf's 145.1.45.0/24 (via 145.1.13.1) metric changed from distance/metric [110/867] to [110/865]
Feb 15 15:12:28.723: RT: del 145.1.45.0/24 via 145.1.23.2, ospf metric [110/867]
Feb 15 15:12:28.723: RT: NET-RED 145.1.45.0/24
Feb 15 15:12:28.723: RT: NET-RED 145.1.45.0/24
Feb 15 15:12:28.727: RT: add 145.1.45.0/24 via 145.1.23.2, ospf metric [110/865]
Feb 15 15:12:28.727: RT: NET-RED 145.1.45.0/24
Rack1R3(config)#

From R3's perspective, notice that it comes back just as it was before.

Rack1R6(config-router)#
*Feb 15 03:32:27.576: RT: rip's 145.1.45.0/24 (via 145.1.36.3) metric changed from distance/metric [120/2] to [120/10]
*Feb 15 03:32:27.576: RT: NET-RED 145.1.45.0/24
Rack1R6(config-router)#

On R6 though, it changed because the criteria changed.   What if we change the clock and do it again?  (By the way, subsequent 'clear ip route' commands on R3 make no difference on R6 as long as the time range is still inactive)

Rack1R3(config)#do clock set 3:00:00 feb 15 2009
Rack1R3(config)#
Rack1R3(config)#
Feb 15 03:00:00.000: %SYS-6-CLOCKUPDATE: System clock has been updated from 15:14:57 UTC Sun Feb 15 2009 to 03:00:00 UTC Sun Feb 15 2009, configured from console by console.
Rack1R3(config)#
Rack1R3(config)#do sh access-list 101
Extended IP access list 101
10 permit ip host 145.1.45.0 host 255.255.255.0 time-range First12 (active) (2 matches)
Rack1R3(config)#

Back to active now.  Clearing....

Rack1R6(config-router)#
*Feb 15 03:35:24.672: RT: rip's 145.1.45.0/24 (via 145.1.36.3) metric changed from distance/metric [120/10] to [120/2]
*Feb 15 03:35:24.672: RT: NET-RED 145.1.45.0/24
Rack1R6(config-router)#

Back to a metric of 2 on R6.  So the redistribution is happening again...  So....  Can the router trigger itself?  Do we have mechanisms to do so?  You betchya!  But it's not perfectly simple!   But then again, you would be a CCIE if everything were always simple!  Or more importantly, EVERYONE would be a CCIE if it were simple!

We can use EEM (Embedded Event Manager, complicated) or KRON (time scheduler, easier) to trigger things.   My vote is kron!  In the unix world you'd know this as cron.

R3

kron policy-list ChgRedist
cli clear ip route 145.1.45.0
exit

kron occurrence Midnight at 0:00 recurring
policy-list ChgRedist
kron occurrence Noon at 12:00 recurring
policy-list ChgRedist
exit

Rack1R3(config)#do sh kron schedule
Kron Occurrence Schedule
Midnight inactive, will run again in 0 days 20:55:41 at 0 :00 on
Noon inactive, will run again in 0 days 08:55:41 at 12:00 on

Rack1R3(config)#

Rack1R3(config)#do clock set 11:58:00 feb 15 2009
Feb 15 11:58:00.000: %SYS-6-CLOCKUPDATE: System clock has been updated from 03:05:50 UTC Sun Feb 15 2009 to 11:58:00 UTC Sun Feb 15 2009, configured from console by console.
Rack1R3(config)#do sh kron schedule
Kron Occurrence Schedule
Midnight inactive, will run again in 0 days 12:01:55 at 0 :00 on
Noon inactive, will run again in 0 days 00:01:55 at 12:00 on

Rack1R3(config)#

Rack1R3(config)#do deb kron all
All kron debug flags are on

Rack1R3(config)#

Now we just wait and see!  (Pretend you've been staring at this for two minutes now!)

Rack1R3(config)#
Feb 15 11:59:59.999: Major 1, Minor 0
Feb 15 11:59:59.999: Timer Event Noon
Feb 15 11:59:59.999: Kron delay for next Noon 60000
Feb 15 11:59:59.999: Call parse_cmd 'clear ip route 145.1.45.0'
Feb 15 11:59:59.999: RT: del 145.1.45.0/24 via 145.1.23.2, ospf metric [110/865]
Feb 15 11:59:59.999: RT: del 145.1.45.0/24 via 145.1.13.1, ospf metric [110/865]
Feb 15 11:59:59.999: RT: delete subnet route to 145.1.45.0/24
Feb 15 11:59:59.999: RT: NET-RED 145.1.45.0/24
Feb 15 12:00:00.003: Kron CLI return 0
''
Feb 15 12:00:00.003: Major 4, Minor 7
Feb 15 12:00:00.003: Respond to end of CLI Process
Feb 15 12:00:00.003: RT: SET_LAST_RDB for 145.1.45.0/24
NEW rdb: via 145.1.13.1

Rack1R3(config)#
Feb 15 12:00:00.003: RT: add 145.1.45.0/24 via 145.1.13.1, ospf metric [110/867]
Feb 15 12:00:00.003: RT: NET-RED 145.1.45.0/24
Feb 15 12:00:00.003: RT: add 145.1.45.0/24 via 145.1.23.2, ospf metric [110/867]
Feb 15 12:00:00.003: RT: NET-RED 145.1.45.0/24
Feb 15 12:00:00.003: RT: ospf's 145.1.45.0/24 (via 145.1.13.1) metric changed from distance/metric [110/867] to [110/865]
Feb 15 12:00:00.007: RT: del 145.1.45.0/24 via 145.1.23.2, ospf metric [110/867]
Feb 15 12:00:00.007: RT: NET-RED 145.1.45.0/24
Feb 15 12:00:00.007: RT: NET-RED 145.1.45.0/24
Feb 15 12:00:00.007: RT: add 145.1.45.0/24 via 145.1.23.2, ospf metric [110/865]
Feb 15 12:00:00.007: RT: NET-RED 145.1.45.0/24
Rack1R3(config)#

That looks like the router magically did what we wanted it to on R3! And on R6:

Rack1R6(config-router)#
*Feb 15 03:43:46.695: RT: rip's 145.1.45.0/24 (via 145.1.36.3) metric changed from distance/metric [120/2] to [120/10]
*Feb 15 03:43:46.695: RT: NET-RED 145.1.45.0/24
Rack1R6(config-router)#

Bingo!  Exactly what you wanted.

Rack1R3(config)#do sh kron sched
Kron Occurrence Schedule
Midnight inactive, will run again in 0 days 11:58:24 at 0 :00 on
Noon inactive, will run again in 0 days 23:59:24 at 12:00 on

Rack1R3(config)#

And in 12 hours'ish we'll see the process reverse itself.  So yes, you CAN have redistribution on a timed basis, it's just not necessarily a pretty thing!

May
02

A voice lab rack usually utilizes dedicated piece of hardware to simulate PSTN switch. Commonly, you can find a Cisco router in this role, with a number of E1/T1 cards set to emulate ISDN network side. It perfectly suits the function, switching ISDN connections between the endpoints. Additionally, it is often required to have an “independent” PSTN phone connected to the PSTN switch, in order to represent “outside” dialing patterns - such as 911, 999, 411 1-800/900 numbers. The most obvious way to do this is to enable a CallManager Express on the PSTN router, and register either hardware IP Phone or any of IP Soft-phones (such as IP Blue or CIPC) with the CME system.

However, there is another way to accomplish the same goal using IOS functionality solely. It relies on the IP-to-IP gateway feature, called “RTP loopback” session target. It is intended to be used for VoIP call testing, but could be easily utilized to loopback incoming PSTN calls to themselves. Let’s say we want PSTN router to respond to incoming calls to an emergency number 911. Here is how a configuration would look like:

PSTN:
voice service voip
allow-connections h323 to h323
!
interface Loopback0
ip address 177.254.254.254 255.255.255.255
!
dial-peer voice 911 voip
destination-pattern 911
session target ipv4:177.254.254.254
incoming called-number 999
tech-prefix 1#
!
dial-peer voice 1911 voip
destination-pattern 1#911
session target loopback:rtp
incoming called-number 1#911

The trick is that only IP-to-IP calls could be looped back. Because of that, we need to redirect the incoming PSTN call to the router itself first, in order to establish an incoming VoIP call leg.

While this approach permits VoIP call testing, it lacks one important feature, available with the “real” PSTN phone: placing calls from the PSTN phone to the in-rack phones. However, you can always use “csim start” command on the PSTN router to overcome this obstacle. Have fun!

Feb
15

Quite many people don't pay attention to the difference in handling packets on interfaces configured for NAT inside and outside. Here is an example to demonstrate how NAT "domains" interact with routing. Consider three routers connected in the following manner:

nat-inside-outside

For this scenario we have no routing configured. Let's use static NAT to provide connectivity between R1 and R2. R2 would see R1 as a host on local connected segment with the IP address 155.1.23.1 and R1 would see R2 as a host on it's local segment with the IP address 155.1.13.2. This goal could be achieved with the following configuration:

R3:
!
interface Serial 1/0.301 point-to-point
ip address 155.1.13.3 255.255.255.0
ip nat inside
no ip route-cache
!
interface Serial 1/0.302 multipoint
ip address 155.1.23.3 255.255.255.0
frame-relay map ip 155.1.23.2 302
ip nat outside
no ip route-cache

!
! Static NAT: translations are effectively bi-directional
!
ip nat inside source static 155.1.13.1 155.1.23.1
ip nat outside source static 155.1.23.2 155.1.13.2

R2:
!
! Add a Frame-Relay mapping for the new IP (representing R1)
! so that R2 would know how to reach the address over multipoint FR interface
!
interface Serial 1/0.203 multipoint
ip address 155.1.23.2 255.255.255.0
frame-relay map ip 155.1.23.3 203
frame-relay map ip 155.1.23.2 203

Let's see how it's working. Note that we disabled route-cache on both interfaces to intercept packets via CPU.

Rack1R3#debug ip nat detailed
IP NAT detailed debugging is on

Rack1R3#debug ip packet detail
IP packet debugging is on (detailed)

Rack1R2#ping 155.1.23.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 155.1.23.1, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)

Hmm...it fails. Look at the debugging output on R3:

Rack1R3#
!
! Packet on NAT outside (o - for outside) hits the interface
!
NAT*: o: icmp (155.1.23.2, 16) -> (155.1.23.1, 16) [84]

!
! Source and destination for the packet rewritten according to NAT rules
!
NAT*: s=155.1.23.2->155.1.13.2, d=155.1.23.1 [84]
NAT*: s=155.1.13.2, d=155.1.23.1->155.1.13.1 [84]

!
! The packet is routed after translation (with new source and destination IPs). Note that routing decision
! and the actual forwarding take place only after translation rules were triggered by NAT tables
!
P: tableid=0, s=155.1.13.2 (Serial1/0.302), d=155.1.13.1 (Serial1/0.301), routed via RIB
IP: s=155.1.13.2 (Serial1/0.302), d=155.1.13.1 (Serial1/0.301), g=155.1.13.1, len 100, forward
ICMP type=8, code=0
!
! The response packet from R1 comes in - to destination 155.1.13.2 - routed via RIB (to the same interface)
! But no NAT rules were triggered since the destination interface is the same as input interface!
!
IP: tableid=0, s=155.1.13.1 (Serial1/0.301), d=155.1.13.2 (Serial1/0.301), routed via RIB
IP: s=155.1.13.1 (Serial1/0.301), d=155.1.13.2 (Serial1/0.301), len 100, rcvd 3
ICMP type=0, code=0

OK hold here for a second.. Now we recall that for inside NAT routing is tried first, and only then the packet is translated according to the NAT rules. This is how the NAT order of operations works on the inside. So now it's clear: IOS first tries to route packet to 155.1.13.2 - which is the same interface as it came in.. therefore the inside->outside translation never occurs! To fix this, let's add a static route on R3:

R3:
ip route 155.1.13.2 255.255.255.255 155.1.23.2

Verification:

Rack1R2#ping 155.1.23.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 155.1.23.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/33/52 ms

Rack1R3#
!
! Outside: translate & route
!
NAT*: o: icmp (155.1.23.2, 17) -> (155.1.23.1, 17) [89]
NAT*: s=155.1.23.2->155.1.13.2, d=155.1.23.1 [89]
NAT*: s=155.1.13.2, d=155.1.23.1->155.1.13.1 [89]

!
! Routing decision and forwarding
!
IP: tableid=0, s=155.1.13.2 (Serial1/0.302), d=155.1.13.1 (Serial1/0.301), routed via RIB
IP: s=155.1.13.2 (Serial1/0.302), d=155.1.13.1 (Serial1/0.301), g=155.1.13.1, len 100, forward
ICMP type=8, code=0
!
! Inside: Routing decision - the packet is routed using our fixup static route
!
IP: tableid=0, s=155.1.13.1 (Serial1/0.301), d=155.1.13.2 (Serial1/0.302), routed via RIB

!
! NAT rule (i - for inside) is triggered by the packet
!
NAT: i: icmp (155.1.13.1, 17) -> (155.1.13.2, 17) [89]

!
! Source and destination addresses rewritten in the "opposite" direction
!
NAT: s=155.1.13.1->155.1.23.1, d=155.1.13.2 [89]
NAT: s=155.1.23.1, d=155.1.13.2->155.1.23.2 [89]

!
! Packet is sent to R2 (with the new source and destination) - forwarding takes place
!
IP: s=155.1.23.1 (Serial1/0.301), d=155.1.23.2 (Serial1/0.302), g=155.1.23.2, len 100, forward
ICMP type=0, code=0

Nice. So now we know the difference for sure: packets on the NAT outside are first translated and then routed. On the inside interface routing decision kicks in first and only then translation rules get applied followed by forwarding. Before we finish with that, recall new 12.3T feature called NAT Virtual Interface. With this feature we can now configure any interface as "NAT enabled" an get rid of those "inside" and "outside" domains . All NAT traffic passed through new virtual interface called NVI, in symmetric manner. Let's reconfigure out task using this new concepts.

R3:
interface Serial 1/0.301 point-to-point
no ip nat inside
ip nat enable
!
interface Serial 1/0.302 multipoint
no ip nat outside
ip nat enable

!
! Remove old rules
!
no ip nat inside source static 155.1.13.1 155.1.23.1
no ip nat outside source static 155.1.23.2 155.1.13.2

!
! Add "domainless" rules
!
ip nat source static 155.1.13.1 155.1.23.1
ip nat source static 155.1.23.2 155.1.13.2

no ip route 155.1.13.2 255.255.255.255 155.1.23.2

Verification:

Rack1R2#ping 155.1.23.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 155.1.23.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/40/60 ms

Rack1R3#
!
! Routing decision it taken: packet classified for NAT, since destination is in NAT table
! Note that no actual forwarding occurs, just routing decision to send packet
!
IP: tableid=0, s=155.1.23.2 (Serial1/0.302), d=155.1.23.1 (Serial1/0.302), routed via RIB

!
! Packet translated according to NAT rules (note "i" for inside NAT)
!
NAT: i: icmp (155.1.23.2, 19) -> (155.1.23.1, 19) [95]
NAT: s=155.1.23.2->155.1.13.2, d=155.1.23.1 [95]
NAT: s=155.1.13.2, d=155.1.23.1->155.1.13.1 [95]

!
! Another routing decision, for translated packet - now actual forwarding occurs
!
IP: tableid=0, s=155.1.13.2 (Serial1/0.302), d=155.1.13.1 (Serial1/0.301), routed via RIB
IP: s=155.1.13.2 (Serial1/0.302), d=155.1.13.1 (Serial1/0.301), g=155.1.13.1, len 100, forward
ICMP type=8, code=0

!
! Response comes in, first routing decision - NAT table entry matched
!
IP: tableid=0, s=155.1.13.1 (Serial1/0.301), d=155.1.13.2 (Serial1/0.301), routed via RIB

!
! Packet translated ("i" - inside NAT)
!
NAT: i: icmp (155.1.13.1, 19) -> (155.1.13.2, 19) [95]
NAT: s=155.1.13.1->155.1.23.1, d=155.1.13.2 [95]
NAT: s=155.1.23.1, d=155.1.13.2->155.1.23.2 [95]

!
! Another routing decision, for post-translated packet, followed by forwarding
!
IP: tableid=0, s=155.1.23.1 (Serial1/0.301), d=155.1.23.2 (Serial1/0.302), routed via RIB
IP: s=155.1.23.1 (Serial1/0.301), d=155.1.23.2 (Serial1/0.302), g=155.1.23.2, len 100, forward
ICMP type=0, code=0

So what's the difference with NVI? First, we see that now NAT behaves symmetrically. Next, we see that NAT translation tables are used to take a "routing decision" to send packet to virtual interface. Packet is translated there and then another routing decision takes place, followed by packet forwarding. So the difference from the old model is that now routing decision is taken twice: before and after translation. This allows to get rid of any static routes needed by "legacy" NAT, since lookup is performed after translation.

To summarize: Domain-based NAT uses different orders of operations for inside and outside domain. NVI based NAT is symmetrical and performs routing lookup twice: first to send packet to NVI, second to route packet using the post-translated addresses.

Links:

NAT Order of Operation

Jan
25

Sometimes people need to conditionally advertise routes into BGP table based on time of day. Say, we may want to adversite IGP prefix 150.1.1.0/24 with community 1:100 during daytime and with community 1:200 at the other time. Back in days, the procedure was easy - you had to create time based ACL, and use it in route-map to set communities:

time-range DAY
periodic daily 9:00 to 18:00

access-list 101 permit ip any any time-range DAY

route-map SET_COMMUNITY 10
match ip address 101
set community 1:100
!
route-map SET_COMMUNITY 20
set community 1:200

This construct worked fine back in days with 12.2T and 12.3 IOSes up to 12.3(17)T. However, since 12.3(17)T, BGP scanner behavior has changed significally. Up to the new version, redistribution into BGP table was based on BGP scanner periodically polling the IGP routes every scan-interval (one minute by default). With the new IOS code, redistribution is purely event driven: a new route is added/deleted from BGP table based on event, signaled by IGP (e.g. IGP route withdrawn, next-hop change etc). This change in BGP scanner behavior was not clearly documented, unlike the related BGP support for next-hop address tracking feature. Ovbsiously, a change in time-range is not treated as an IGP event, hence the filter does not work anymore.

Still, there is a number of workarounds. Here is one of them: we use time-based ACL to filter or permit ICMP packets, and advertise routers based on that virtual "reachability" info.

First, we create time-range and time-based access-list:

time-range DAY
periodic daily 9:00 to 18:00
!
access-list 101 permit ip any any time-range DAY

Next we create a special loopback interface, which is used send ICMP echo packets to "ourself" and attach the ACL to the interface to filter incoming (looped back) packets:

interface Loopback0
ip address 150.1.1.1 255.255.255.255
ip access-group 101 in

We create a new IP SLA monitor, to send ICMP echo packets over loopback interface. If the time-based ACL permit pings, the monitor state will be "reachable"

ip sla monitor 1
type echo protocol ipIcmpEcho 150.1.1.1
timeout 100
frequency 1

Next we track our "pinger" state. The first tracker is "on" when the loopback is "open" by packet filter, the second one is active when the time-based ACL filters packets:

track 1 rtr 1 reachability
!
! Inverse logic
!
track 2 list boolean and
object 1 not

The we create two static routes, bound to the mentioned trackets. That is, the static route with tag 100 is only active when loopback is "open", i.e. time-based ACL permits packets. The other static route is active only when time-range is inactive (the second tracker tells that the destination is "reachable"):

ip route 150.1.1.0 255.255.255.0 Loopback0 150.1.1.254 tag 100 track 1
ip route 150.1.1.0 255.255.255.0 Loopback0 150.1.1.253 tag 200 track 2

Now we redistribute static routes into BGP, based on tag values, and also set communities based on the tags:

router bgp 1
redistribute static route-map STATIC_TO_BGP
!
route-map STATIC_TO_BGP permit 10
match tag 100
set community 1:100
!
route-map STATIC_TO_BGP permit 20
match tag 200
set community 1:200

This is also a funny example of how you can tie up together multiple IOS features at the same time.

Subscribe to INE Blog Updates

New Blog Posts!