Cisconinja’s Blog

Archive for the ‘IPv6’ Category

RIP and RIPng Behavior with Lower AD Routes

Posted by Andy on May 6, 2009

Here we will look at the behavior of RIPv2 and RIPng for a route when a better administrative distance route exists.  The topology and configurations are shown below.  All interfaces on all routers run RIPv2 with no auto-summary and RIPng:

rip-topology

R1:
ipv6 unicast-routing
!
interface Loopback0
 ip address 1.1.1.1 255.255.255.0
 ipv6 address 2001:0:0:1::1/64
 ipv6 rip asdf enable
!
interface Serial0/0
 ip address 10.0.12.1 255.255.255.0
 ipv6 address 2001:0:0:12::1/64
 ipv6 rip asdf enable
!
router rip
 version 2
 passive-interface Loopback0
 network 1.0.0.0
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip asdf

R2:
ipv6 unicast-routing
!
interface Serial0/0
 ip address 10.0.12.2 255.255.255.0
 ipv6 address 2001:0:0:12::2/64
 ipv6 rip asdf enable
!
interface Serial0/1
 ip address 10.0.23.2 255.255.255.0
 ipv6 address 2001:0:0:23::2/64
 ipv6 rip asdf enable
!
router rip
 version 2
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip asdf

R3:
ipv6 unicast-routing
!
interface Serial0/0
 ip address 10.0.23.3 255.255.255.0
 ipv6 address 2001:0:0:23::3/64
 ipv6 rip asdf enable
!
router rip
 version 2
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip asdf

Next we will create an OSPF process between R1 and R2 and use it to advertise R1 Loopback1 to R2:

R1:
router ospf 1
 network 0.0.0.0 255.255.255.255 area 0
!
interface Loopback0
 ip ospf network point-to-point
 ipv6 ospf network point-to-point
 ipv6 ospf 1 area 0
!
interface Serial0/0
 ipv6 ospf 1 area 0

R2:
router ospf 1
 network 10.0.12.2 0.0.0.0 area 0
!
interface Serial0/0
 ipv6 ospf 1 area 0

R2 replaces the RIPv2 and RIPng routes to R1 Loopback0 with the OSPF routes because of their lower AD:

1-r2-route-table2

1-r2-route-table-ipv62

Although R2 still hears about R1’s loopback in RIP advertisements, it does not advertise it to R3 in either RIPv2 or RIPng and R3 therefore does not have a route to it.  The route must be present in the routing table in order for RIPv1/RIPv2 and RIPng to include it in advertisements:

R2#debug ip rip
Mar 1 00:22:09.267: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 00:22:09.271: 1.1.1.0/24 via 0.0.0.0 in 1 hops
Mar 1 00:22:16.471: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:22:16.471: RIP: build update entries
Mar 1 00:22:16.471: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0

R2#debug ipv6 rip
Mar 1 00:22:57.627: RIPng: response received from FE80::C601:9FF:FEFC:0 on Serial0/0 for asdf
Mar 1 00:22:57.627: src=FE80::C601:9FF:FEFC:0 (Serial0/0)
Mar 1 00:22:57.631: dst=FF02::9
Mar 1 00:22:57.631: sport=521, dport=521, length=52
Mar 1 00:22:57.631: command=2, version=1, mbz=0, #rte=2
Mar 1 00:22:57.631: tag=0, metric=1, prefix=2001:0:0:1::/64
Mar 1 00:22:57.631: tag=0, metric=1, prefix=2001:0:0:12::/64
Mar 1 00:23:13.255: RIPng: Sending multicast update on Serial0/1 for asdf
Mar 1 00:23:13.255: src=FE80::C602:9FF:FEFC:0
Mar 1 00:23:13.255: dst=FF02::9 (Serial0/1)
Mar 1 00:23:13.259: sport=521, dport=521, length=52
Mar 1 00:23:13.259: command=2, version=1, mbz=0, #rte=2
Mar 1 00:23:13.259: tag=0, metric=1, prefix=2001:0:0:12::/64
Mar 1 00:23:13.259: tag=0, metric=1, prefix=2001:0:0:23::/64

Let’s try creating a separate OSPF process between R2 and R3 and redistributing RIP into it:

R2:
interface Serial0/1
 ipv6 ospf 2 area 0
!
router ospf 2
 network 10.0.23.2 0.0.0.0 area 0
 redistribute rip metric 100 subnets
!
ipv6 router ospf 2
 redistribute rip asdf metric 100

R3:
interface Serial0/0
 ipv6 ospf 2 area 0
!
router ospf 2
 network 0.0.0.0 255.255.255.255 area 0

R1’s loopback is not redistributed into OSPF process #2 for the same reason – the route must be present in the routing table as a RIP route in order to be redistributed.  R3 still does not have a route to R1’s loopback:

 2-r3-route-table

2-r3-route-table-ipv6

 

One difference between RIPv2 and RIPng when there is a better AD route already in the routing table is that RIPng keeps the route in the RIP database, while RIPv2 does not:

3-r2-rip-db

3-r2-ripng-db

The significance of this is that if the better AD route is removed, the RIPng route is immediately installed in the routing table.  RIPv2 on the other hand must wait until it hears the next periodic update for the route – up to 30 seconds using default timers:

R2:
no ipv6 router ospf 1

R2#debug ipv6 routing
Mar 1 00:41:38.395: IPv6RT0: ospf 1, Delete 2001:0:0:1::/64 from table
Mar 1 00:41:38.399: IPv6RT0: rip asdf, Backup call for 2001:0:0:1::/64
Mar 1 00:41:38.399: IPv6RT0: rip asdf, Route add 2001:0:0:1::/64 [new]
Mar 1 00:41:38.399: IPv6RT0: rip asdf, Add 2001:0:0:1::/64 to table
Mar 1 00:41:38.399: IPv6RT0: rip asdf, Adding next-hop FE80::C601:9FF:FEFC:0 over Serial0/0 for 2001:0:0:1::/64, [120/2]
Mar 1 00:41:38.415: IPv6RT0: Event: 2001:0:0:1::/64, Del, owner ospf, previous None
Mar 1 00:41:38.415: IPv6RT0: Event: 2001:0:0:1::/64, Add, owner rip, previous None

R2:
no router ospf 1

R2#debug ip routing
R2#debug ip rip

Mar 1 00:44:02.743: RT: NET-RED 1.1.1.0/24
Mar 1 00:44:02.775: RT: delete route to 1.1.1.0/24
Mar 1 00:44:02.775: RT: NET-RED 1.1.1.0/24
Mar 1 00:44:02.775: RT: delete network route to 1.0.0.0
Mar 1 00:44:02.775: RT: NET-RED 1.0.0.0/8
Mar 1 00:44:27.987: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 00:44:27.991: 1.1.1.0/24 via 0.0.0.0 in 1 hops
Mar 1 00:44:27.991: RT: SET_LAST_RDB for 1.1.1.0/24
NEW rdb: via 10.0.12.1
Mar 1 00:44:27.995: RT: add 1.1.1.0/24 via 10.0.12.1, rip metric [120/1]
Mar 1 00:44:27.995: RT: NET-RED 1.1.1.0/24

Since R2 now has the RIPv2 and RIPng routes to R1 Loopback0 in the routing table, they are eligible for route advertisement and redistribution.  R3 learns the route from R2 through both RIP and OSPF and adds the lower AD OSPF routes.  Like we saw on R2 previously, the RIP route is kept in the RIPng database but not in the RIPv2 database:

4-r3-route-table

4-r3-route-table-ipv6

5-r3-rip-db

5-r3-ripng-db

Posted in IPv6, RIP | Leave a Comment »

RIP and RIPng Metrics

Posted by Andy on May 4, 2009

In this post we will look at a few things relating to metric calculations in RIPv2 and RIPng.  The topology and configurations are shown below.  All interfaces on all routers run RIPv2 with no auto-summary and RIPng:

rip-hop-count1

R1:
ipv6 unicast-routing
!
interface Loopback1
 ip address 1.1.1.1 255.255.255.0
 ipv6 address 2001:0:0:1111::1/64
 ipv6 rip asdf enable
!
interface Serial0/0
 ip address 10.0.12.1 255.255.255.0
 ipv6 address 2001:12::1/64
 ipv6 rip asdf enable
!
router rip
 version 2
 passive-interface default
 no passive-interface Serial0/0
 network 1.0.0.0
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip asdf

R2:
ipv6 unicast-routing
!
interface Loopback1
 ip address 2.2.2.2 255.255.255.0
 ipv6 address 2001:0:0:2222::2/64
 ipv6 rip asdf enable
!
interface Serial0/0
 ip address 10.0.12.2 255.255.255.0
 ipv6 address 2001:12::2/64
 ipv6 rip asdf enable
!
interface Serial0/1
 ip address 10.0.23.2 255.255.255.0
 ipv6 address 2001:23::2/64
 ipv6 rip asdf enable
!
router rip
 version 2
 passive-interface Loopback1
 network 2.0.0.0
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip asdf

R3:
ipv6 unicast-routing
!
interface Loopback1
 ip address 3.3.3.3 255.255.255.0
 ipv6 address 2001:0:0:3333::3/64
 ipv6 rip asdf enable
!
interface Serial0/0
 ip address 10.0.23.3 255.255.255.0
 ipv6 address 2001:23::3/64
 ipv6 rip asdf enable
!
interface Serial0/1
 ip address 10.0.34.3 255.255.255.0
 ipv6 address 2001:34::3/64
 ipv6 rip asdf enable
!
router rip
 version 2
 passive-interface Loopback1
 network 3.0.0.0
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip asdf

R4:
ipv6 unicast-routing
!
interface Loopback1
 ip address 4.4.4.4 255.255.255.0
 ipv6 address 2001:0:0:4444::4/64
 ipv6 rip asdf enable
!
interface Serial0/0
 ip address 10.0.34.4 255.255.255.0
 ipv6 address 2001:34::4/64
 ipv6 rip asdf enable
!
router rip
 version 2
 network 4.0.0.0
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip asdf

The routing tables of each router look like this:

1-r1-route-table

1-r2-route-table

1-r3-route-table

1-r4-route-table1

1-r1-route-table-ipv6

1-r2-route-table-ipv6

1-r3-route-table-ipv6

1-r4-route-table-ipv61

Notice that the RIPng routes are listed as 1 hop higher than the equivalent RIPv2 routes.  For example, R2 sees R1’s loopback as 1 hop in RIPv2 and 2 hops in RIPng.  Let’s take a look at the RIPv2 and RIPng updates on R2 being received from R1 and sent to R3:

R2#debug ip rip
Mar 1 00:46:36.895: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 00:46:36.895: 1.1.1.0/24 via 0.0.0.0 in 1 hops
Mar 1 00:46:40.167: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:46:40.167: RIP: build update entries
Mar 1 00:46:40.167: 1.1.1.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 00:46:40.171: 2.2.2.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:46:40.171: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0

R2#debug ipv6 rip
Mar 1 00:46:55.487: RIPng: response received from FE80::C601:9FF:FEFC:0 on Serial0/0 for asdf
Mar 1 00:46:55.487: src=FE80::C601:9FF:FEFC:0 (Serial0/0)
Mar 1 00:46:55.491: dst=FF02::9
Mar 1 00:46:55.491: sport=521, dport=521, length=52
Mar 1 00:46:55.491: command=2, version=1, mbz=0, #rte=2
Mar 1 00:46:55.491: tag=0, metric=1, prefix=2001:0:0:1111::/64
Mar 1 00:46:55.491: tag=0, metric=1, prefix=2001:12::/64
Mar 1 00:47:14.139: RIPng: Sending multicast update on Serial0/1 for asdf
Mar 1 00:47:14.139: src=FE80::C602:9FF:FEFC:0
Mar 1 00:47:14.139: dst=FF02::9 (Serial0/1)
Mar 1 00:47:14.143: sport=521, dport=521, length=92
Mar 1 00:47:14.143: command=2, version=1, mbz=0, #rte=4
Mar 1 00:47:14.143: tag=0, metric=1, prefix=2001:12::/64
Mar 1 00:47:14.143: tag=0, metric=1, prefix=2001:23::/64
Mar 1 00:47:14.143: tag=0, metric=1, prefix=2001:0:0:2222::/64
Mar 1 00:47:14.147: tag=0, metric=2, prefix=2001:0:0:1111::/64

Both updates look the same – R1’s loopback is received from R1 as metric 1 and advertised to R3 as metric 2.  The reason for the difference in metric in the routing table and RIP database is that RIPng metrics are incremented inbound before being added to the routing table/RIP database, while RIPv1 and RIPv2 metrics are incremented outbound.  Equivalent RIPng routes will always show up as 1 hop higher than RIPv2 routes if no offsets are applied.

 

Next we will look at a bug that is present in many IOS versions that results in RIPv1 and RIPv2 hop counts not incrementing.  We will turn RIPv2 auto-summary back on for R3 and R4:

R3:
router rip
 auto-summary

R4:
router rip
auto-summary

R3 stops advertising 1.1.1.0/24 and 2.2.2.0/24 and starts advertising 1.0.0.0/8 and 2.0.0.0/8 to R4.  After R4’s flush timer expires for the /24 routes, it’s routing table now looks like this:

2-r4-route-table

1.0.0.0/8 has the same metric as the old /24 route, but 2.0.0.0/8 is listed as metric 1 instead of metric 2.  Let’s take a look at sent and received updates in the direction of R1 to R4.  R3 receives the same routes and metrics from R2:

R3#debug ip rip
Mar 1 01:01:37.891: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 01:01:37.891: 1.1.1.0/24 via 0.0.0.0 in 2 hops
Mar 1 01:01:37.895: 2.2.2.0/24 via 0.0.0.0 in 1 hops
Mar 1 01:01:37.895: 10.0.12.0/24 via 0.0.0.0 in 1 hops

When the summarized routes are advertised to R4, 1.0.0.0/8 is incremented but 2.0.0.0/8 is advertised as metric 1, the same metric it was received as:

R3#debug ip rip
Mar 1 01:01:41.647: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.34.3)
Mar 1 01:01:41.647: RIP: build update entries
Mar 1 01:01:41.647: 1.0.0.0/8 via 0.0.0.0, metric 3, tag 0
Mar 1 01:01:41.651: 2.0.0.0/8 via 0.0.0.0, metric 1, tag 0
Mar 1 01:01:41.651: 3.0.0.0/8 via 0.0.0.0, metric 1, tag 0
Mar 1 01:01:41.651: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 01:01:41.651: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0

R4 receives the update from R3:

R4#debug ip rip
Mar 1 01:01:41.679: RIP: received v2 update from 10.0.34.3 on Serial0/0
Mar 1 01:01:41.679: 1.0.0.0/8 via 0.0.0.0 in 3 hops
Mar 1 01:01:41.683: 2.0.0.0/8 via 0.0.0.0 in 1 hops
Mar 1 01:01:41.683: 3.0.0.0/8 via 0.0.0.0 in 1 hops
Mar 1 01:01:41.683: 10.0.12.0/24 via 0.0.0.0 in 2 hops
Mar 1 01:01:41.687: 10.0.23.0/24 via 0.0.0.0 in 1 hops

When R4 sends an update out loopback1, 1.0.0.0/8 is again incremented and 2.0.0.0/8 is not.  3.0.0.0/8, which was received as metric 1, is also not incremented:

R4#debug ip rip
Mar 1 01:01:56.191: RIP: sending v2 update to 224.0.0.9 via Loopback1 (4.4.4.4)
Mar 1 01:01:56.191: RIP: build update entries
Mar 1 01:01:56.191: 1.0.0.0/8 via 0.0.0.0, metric 4, tag 0
Mar 1 01:01:56.195: 2.0.0.0/8 via 0.0.0.0, metric 1, tag 0
Mar 1 01:01:56.195: 3.0.0.0/8 via 0.0.0.0, metric 1, tag 0
Mar 1 01:01:56.195: 10.0.0.0/8 via 0.0.0.0, metric 1, tag 0

This bug, which prevents the hop count from incrementing, occurs whenever a received route has metric 1 and is summarized before being advertised.  If the received metric is greater than 1, the hop count continues to increment like normal.  This occurs for RIPv1 routes when they are summarized at classful boundaries, RIPv2 auto-summary routes, and RIPv2 interface summary routes.  The bug occurred in various 12.4 mainline IOS versions that were tested and no longer occurred in 12.4(20)T, so it appears to have been fixed in some 12.4 T-train release.

 

Summary routes in both RIPv2 and RIPng use the lowest metric of any child route within their range as the metric for the summary route.  To demonstrate this, we will first create a few more loopbacks on R1 and redistribute them into RIP with various metrics.  We will also turn auto-summary off again on R3 and R4:

R1:
router rip
 no network 1.0.0.0
!
interface Loopback1
 no ipv6 rip asdf enable
!
interface Loopback2
 ip address 1.1.2.1 255.255.255.0
 ipv6 address 2001:0:0:1112::1/64
!
interface Loopback3
 ip address 1.1.3.1 255.255.255.0
 ipv6 address 2001:0:0:1113::1/64
!
interface Loopback4
 ip address 1.1.4.1 255.255.255.0
 ipv6 address 2001:0:0:1114::1/64
!
ip access-list standard Loop1
 permit 1.1.1.0
ip access-list standard Loop2
 permit 1.1.2.0
ip access-list standard Loop3
 permit 1.1.3.0
ip access-list standard Loop4
 permit 1.1.4.0
!
route-map RIPv2 permit 10
 match ip address Loop1
 set metric 3
!
route-map RIPv2 permit 20
 match ip address Loop2
 set metric 4
!
route-map RIPv2 permit 30
 match ip address Loop3
 set metric 5
!
route-map RIPv2 permit 40
 match ip address Loop4
 set metric 6
!
router rip
 redistribute connected route-map RIPv2
!
ipv6 prefix-list Loop1 seq 5 permit 2001:0:0:1111::/64
!
ipv6 prefix-list Loop2 seq 5 permit 2001:0:0:1112::/64
!
ipv6 prefix-list Loop3 seq 5 permit 2001:0:0:1113::/64
!
ipv6 prefix-list Loop4 seq 5 permit 2001:0:0:1114::/64
!
route-map RIPng permit 10
match ipv6 address prefix-list Loop1
set metric 3
!
route-map RIPng permit 20
match ipv6 address prefix-list Loop2
set metric 4
!
route-map RIPng permit 30
match ipv6 address prefix-list Loop3
set metric 5
!
route-map RIPng permit 40
match ipv6 address prefix-list Loop4
set metric 6
!
ipv6 router rip asdf
 redistribute connected route-map RIPng

R3:
router rip
 no auto-summary

R4:
router rip
 no auto-summary

Before creating the summary routes, let’s verify that the redistributed routes have the correct metrics:

R1#debug ip rip
Mar 1 01:33:23.859: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.12.1)
Mar 1 01:33:23.859: RIP: build update entries
Mar 1 01:33:23.859: 1.1.1.0/24 via 0.0.0.0, metric 3, tag 0
Mar 1 01:33:23.863: 1.1.2.0/24 via 0.0.0.0, metric 4, tag 0
Mar 1 01:33:23.863: 1.1.3.0/24 via 0.0.0.0, metric 5, tag 0
Mar 1 01:33:23.863: 1.1.4.0/24 via 0.0.0.0, metric 6, tag 0

R1#debug ipv6 rip
Mar 1 01:33:54.007: RIPng: Sending multicast update on Serial0/0 for asdf
Mar 1 01:33:54.007: src=FE80::C601:9FF:FEFC:0
Mar 1 01:33:54.011: dst=FF02::9 (Serial0/0)
Mar 1 01:33:54.011: sport=521, dport=521, length=112
Mar 1 01:33:54.011: command=2, version=1, mbz=0, #rte=5
Mar 1 01:33:54.011: tag=0, metric=3, prefix=2001:0:0:1111::/64
Mar 1 01:33:54.011: tag=0, metric=1, prefix=2001:12::/64
Mar 1 01:33:54.015: tag=0, metric=4, prefix=2001:0:0:1112::/64
Mar 1 01:33:54.015: tag=0, metric=5, prefix=2001:0:0:1113::/64
Mar 1 01:33:54.015: tag=0, metric=6, prefix=2001:0:0:1114::/64

3-r4-route-table

3-r4-route-table-ipv6

Now we will create the summary routes:

R1:
interface Serial0/0
 ip summary-address rip 1.1.0.0 255.255.248.0
 ipv6 rip asdf summary-address 2001:0:0:1110::/60

Let’s check how the summaries are being advertised on R1:

R1#debug ip rip
Mar 1 01:33:11.163: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.12.1)
Mar 1 01:33:11.163: RIP: build update entries
Mar 1 01:33:11.163: 1.1.0.0/21 via 0.0.0.0, metric 4, tag 0

R1#debug ipv6 rip
Mar 1 01:33:43.747: RIPng: Sending multicast update on Serial0/0 for asdf
Mar 1 01:33:43.747: src=FE80::C601:9FF:FEFC:0
Mar 1 01:33:43.751: dst=FF02::9 (Serial0/0)
Mar 1 01:33:43.751: sport=521, dport=521, length=52
Mar 1 01:33:43.751: command=2, version=1, mbz=0, #rte=2
Mar 1 01:33:43.751: tag=0, metric=1, prefix=2001:12::/64
Mar 1 01:33:43.751: tag=0, metric=3, prefix=2001:0:0:1110::/60

RIPng used the lowest child metric (3) as the metric for the summary route.  RIPv2, however, gave it a metric of 4.  This relates to another possible bug, where routes redistributed into RIPv2 that are manually summarized have an additional hop added to the metric.  Some additional info can be found here.  Let’s try putting the RIPv2 summary on R2 instead and see if this goes away:

R1:
interface Serial0/0
 no ip summary-address rip 1.1.0.0 255.255.248.0

R2#debug ip rip
Mar 1 01:46:25.751: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 01:46:25.755: 1.1.1.0/24 via 0.0.0.0 in 3 hops
Mar 1 01:46:25.755: 1.1.2.0/24 via 0.0.0.0 in 4 hops
Mar 1 01:46:25.755: 1.1.3.0/24 via 0.0.0.0 in 5 hops
Mar 1 01:46:25.755: 1.1.4.0/24 via 0.0.0.0 in 6 hops
Mar 1 01:46:47.503: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 01:46:47.503: RIP: build update entries
Mar 1 01:46:47.503: 1.1.1.0/24 via 0.0.0.0, metric 4, tag 0
Mar 1 01:46:47.507: 1.1.2.0/24 via 0.0.0.0, metric 5, tag 0
Mar 1 01:46:47.507: 1.1.3.0/24 via 0.0.0.0, metric 6, tag 0
Mar 1 01:46:47.507: 1.1.4.0/24 via 0.0.0.0, metric 7, tag 0
Mar 1 01:46:47.507: 2.2.2.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 01:46:47.511: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0

R2:
interface Serial0/1
 ip summary-address rip 1.1.0.0 255.255.248.0

R2#debug ip rip
Mar 1 01:47:41.935: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 01:47:41.935: RIP: build update entries
Mar 1 01:47:41.935: 1.1.0.0/21 via 0.0.0.0, metric 4, tag 0
Mar 1 01:47:41.939: 2.2.2.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 01:47:41.939: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0

R2 now correctly uses the lowest child metric as the metric for the summary.

4-r4-route-table

4-r4-route-table-ipv6

 

 

As mentioned earlier, the bug where routes received with a hop count of 1 are not incremented applies to manual summary routes also.  If any child route has a metric of 1 the summary route metric will not be incremented.  To demonstrate this we will change the seed metric of R1 Loopback1 to 1:

R1:
route-map RIPv2 permit 10
 match ip address Loop1
 set metric 1

R2#debug ip rip
Mar 1 02:02:15.843: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 02:02:15.843: 1.1.1.0/24 via 0.0.0.0 in 1 hops
Mar 1 02:02:15.847: 1.1.2.0/24 via 0.0.0.0 in 4 hops
Mar 1 02:02:15.847: 1.1.3.0/24 via 0.0.0.0 in 5 hops
Mar 1 02:02:15.847: 1.1.4.0/24 via 0.0.0.0 in 6 hops
Mar 1 02:02:27.599: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 02:02:27.599: RIP: build update entries
Mar 1 02:02:27.599: 1.1.0.0/21 via 0.0.0.0, metric 1, tag 0
Mar 1 02:02:27.603: 2.2.2.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 02:02:27.603: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0

The advertised metric remains at 1.

Posted in IPv6, RIP | Leave a Comment »

RIP Timers

Posted by Andy on April 27, 2009

This post will take a look at the various timers used in RIP and RIPng, and some of the differences between how they are supposed to work and how they actually do work .  RIPv2 with no auto-summary and RIPng are enabled for every interface on each router.  The topology and configurations of each router are shown below:

rip-timers3

R1:
ipv6 unicast-routing
!
interface Serial0/0
 ip address 10.0.12.1 255.255.255.0
 ipv6 address 2001:DB8:0:12::1/64
 ipv6 address FE80::1 link-local
 ipv6 rip test enable
!
router rip
 version 2
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip test

R2:
ipv6 unicast-routing
!
interface Serial0/0
 ip address 10.0.12.2 255.255.255.0
 ipv6 address 2001:DB8:0:12::2/64
 ipv6 address FE80::2 link-local
 ipv6 rip test enable
!
interface Serial0/1
 ip address 10.0.23.2 255.255.255.0
 ipv6 address 2001:DB8:0:23::2/64
 ipv6 address FE80::2 link-local
 ipv6 rip test enable
!
router rip
 version 2
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip test

R3:
ipv6 unicast-routing
!
interface FastEthernet0/0
 ip address 10.0.34.3 255.255.255.0
 ipv6 address 2001:DB8:0:34::3/64
 ipv6 address FE80::3 link-local
 ipv6 rip test enable
!
interface Serial0/0
 ip address 10.0.23.3 255.255.255.0
 ipv6 address 2001:DB8:0:23::3/64
 ipv6 address FE80::3 link-local
 ipv6 rip test enable
!
router rip
 version 2
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip test

R4:
ipv6 unicast-routing
!
interface Loopback0
 ip address 4.4.4.4 255.255.255.0
 ipv6 address 2001:DB8:0:4444::4/64
 ipv6 address FE80::4 link-local
 ipv6 rip test enable
!
interface FastEthernet0/0
 ip address 10.0.34.4 255.255.255.0
 ipv6 address 2001:DB8:0:34::4/64
 ipv6 address FE80::4 link-local
 ipv6 rip test enable
!
router rip
 version 2
 passive-interface Loopback0
 network 4.0.0.0
 network 10.0.0.0
 no auto-summary
!
ipv6 router rip test

The update interval configured under the routing process controls when RIP updates are sent.  Updates are sent at the configured interval minus a random amount of time up to 15% of the update interval.  For RIPv1/RIPv2, the update period can also be controlled per interface using ip rip advertise.  This command is nowhere to be found in Cisco’s documentation, but it does just what it sounds like it should.  Here R2 is configured to send updates out S0/1 every 10 seconds (minus the random jitter time), while S0/0 continues to use the default of 30 seconds:

R2:
interface Serial0/1
 ip rip advertise 10

R2#debug ip rip
Mar 1 00:10:55.471: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 00:10:55.471: RIP: build update entries
Mar 1 00:10:55.471: 4.4.4.0/24 via 0.0.0.0, metric 3, tag 0
Mar 1 00:10:55.471: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:10:55.471: 10.0.34.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 00:11:00.967: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:11:00.967: RIP: build update entries
Mar 1 00:11:00.967: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:11:09.515: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:11:09.515: RIP: build update entries
Mar 1 00:11:09.515: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:11:19.343: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:11:19.343: RIP: build update entries
Mar 1 00:11:19.343: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:11:23.023: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 00:11:23.023: RIP: build update entries
Mar 1 00:11:23.023: 4.4.4.0/24 via 0.0.0.0, metric 3, tag 0
Mar 1 00:11:23.027: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:11:23.027: 10.0.34.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 00:11:29.131: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:11:29.131: RIP: build update entries
Mar 1 00:11:29.131: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:11:38.599: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:11:38.599: RIP: build update entries
Mar 1 00:11:38.599: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:11:47.939: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 00:11:47.939: RIP: build update entries
Mar 1 00:11:47.939: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0

RIPng does not have a way of controlling the update period per interface.  RIPv1/RIPv2 also support the configuration of a flash update threshold, designed to suppress flash updates from being sent if the next periodic update is due to be sent in less than the configured interval.  We will configure R4 with a flash update threshold of 30 seconds and shutdown it’s loopback interface:

R4:
router rip
 flash-update-threshold 30

1-rip-flash-interval1

R4:
interface Loopback0
 shutdown

R4#debug ip rip
Mar 1 00:31:23.931: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.4)
Mar 1 00:31:23.931: RIP: build flash update entries
Mar 1 00:31:23.931: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:31:32.103: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.4)
Mar 1 00:31:32.103: RIP: build update entries
Mar 1 00:31:32.103: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0

Unfortunately the command does not seem to work.  With an update period of 30 seconds and flash update threshold of 30 seconds, all flash updates should be suppressed.  R4 sends a flash update about the unreachable network out F0/0, even though the periodic update is due about 9 seconds later.  A search showed that some other people have run into this problem as well:

flash-update-threshold??

Flash-update-threshold, has anyone seen this work in a lab?

 

The invalid/timeout timer is 180 seconds by default in RIPv2:

2-r3-show-ip-protocols1

The invalid timer is reset for a route each time an update is received for it from the best route source.  The current routing table on R3 looks like this:

2-r3-show-ip-route1

R3 has learned 2 routes from RIP.  4.4.4.0/24 was learned on F0/0 from R4 and 10.0.12.0/24 was learned on S0/0 from R2.  As expected, both routes were last heard from less than 30 seconds ago since no updates were missed.  Now we will shut down R4 F0/0 so that R3 stops receiving RIP updates from it:

R4:
interface FastEthernet0/0
 shutdown

R3 receives the last update from R4 at 00:52:06.079, just prior to shutting down the interface:

R3#debug ip rip
Mar 1 00:52:06.079: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 00:52:06.079: 4.4.4.0/24 via 0.0.0.0 in 1 hops

Since no updates about 4.4.4.0/24 are received from R4, the timer for the route continues incrementing:

3-r3-show-ip-route1

Just over 180 seconds after the last update was received, log messages show that the route has been deleted and entered holddown.  We can also see that a flash update is sent for the route a couple seconds later, using poison-reverse rules to advertise it as unreachable out both S0/0 and F0/0.  The route continues to be included in periodic updates out each interface as well:

R3#debug ip rip
R3#debug ip routing
Mar 1 00:55:09.315: RT: delete route to 4.4.4.0 via 10.0.34.4, rip metric [120/1]
Mar 1 00:55:09.315: RT: SET_LAST_RDB for 4.4.4.0/24
OLD rdb: via 11.13.11.13
Mar 1 00:55:09.319: RT: no routes to 4.4.4.0, entering holddown
Mar 1 00:55:09.319: RT: NET-RED 4.4.4.0/24
Mar 1 00:55:11.323: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 00:55:11.323: RIP: build flash update entries
Mar 1 00:55:11.323: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:55:11.327: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 00:55:11.327: RIP: build flash update entries
Mar 1 00:55:11.327: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:55:27.775: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 00:55:27.775: RIP: build update entries
Mar 1 00:55:27.775: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:55:27.779: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 00:55:27.779: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:55:30.955: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 00:55:30.955: RIP: build update entries
Mar 1 00:55:30.955: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:55:30.955: 10.0.34.0/24 via 0.0.0.0, metric 1, tag 0

There are a couple confusing things about the debug outputs shown above.  First, although it says the route has been deleted from the routing table, it actually is still in both the routing table and RIP database at this point.  The route is listed as “possibly down”, but continues to be used for forwarding packets:

4-r3-show-ip-route1

4-r3-rip-database1

R3#debug ip packet
R3#ping 4.4.4.4 repeat 1

Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 4.4.4.4, timeout is 2 seconds:

Mar 1 00:55:48.871: IP: tableid=0, s=10.0.34.3 (local), d=4.4.4.4 (FastEthernet0/0), routed via RIB
Mar 1 00:55:48.871: IP: s=10.0.34.3 (local), d=4.4.4.4 (FastEthernet0/0), len 100, sending

Another possibly confusing thing is that the output shows the route entering holddown.  We will look at what happens when a route enters holddown and the circumstances that cause the holddown timer to be used later, but for now it is important to note that the behavior we are seeing – the route showing up as possibly down in both the routing table and RIP database, and poison-reverse being used to advertise the route as unreachable immediately in flash updates and then periodically in regular updates – is caused by the invalid timer expiring, not by entering the holddown state.  To show this, we will set the holddown timer to 0.  We will also reduce the invalid timer to 120 and keep the other timers at their defaults:

R3:
router rip
 timers basic 30 120 0 240

5-r3-show-ip-protocols1

After bringing R4 F0/0 back up and allowing the network to converge, we will shut it down again:

R4:
interface FastEthernet0/0
 shutdown

R3 receives the last update from R4 at 01:12:57.635, just prior to the shutdown:

R3#debug ip rip
Mar 1 01:12:57.635: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 01:12:57.639: 4.4.4.0/24 via 0.0.0.0 in 1 hops

A little over 120 seconds later, the route again shows up as possibly down in the routing table and RIP database, and is advertised as unreachable:

R3#debug ip routing
R3#debug ip rip

Mar 1 01:14:59.551: RT: delete route to 4.4.4.0 via 10.0.34.4, rip metric [120/1]
Mar 1 01:14:59.555: RT: SET_LAST_RDB for 4.4.4.0/24
OLD rdb: via 11.13.11.13
Mar 1 01:14:59.555: RT: no routes to 4.4.4.0, entering holddown
Mar 1 01:14:59.555: RT: NET-RED 4.4.4.0/24
Mar 1 01:15:01.559: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 01:15:01.559: RIP: build flash update entries
Mar 1 01:15:01.559: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 01:15:01.563: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 01:15:01.563: RIP: build flash update entries
Mar 1 01:15:01.563: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 01:15:03.639: RT: 4.4.4.0 came out of holddown
Mar 1 01:15:15.451: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 01:15:15.451: RIP: build update entries
Mar 1 01:15:15.451: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 01:15:15.455: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 01:15:15.455: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 01:15:21.479: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 01:15:21.479: RIP: build update entries
Mar 1 01:15:21.479: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 01:15:21.483: 10.0.34.0/24 via 0.0.0.0, metric 1, tag 0

5-r3-show-ip-route1

5-r3-rip-database1

 

 

There are a few differences in the use of the invalid timer in RIPng, mostly related to naming and display output.  Instead of the invalid timer, RIPng (at least in IOS syntax) calls it the route timeout or expiration timer.  Instead of counting upward from the time the last route update was heard, RIPng counts downward starting at the value of the invalid timer, and the timer is only shown in the RIP database:

6-r3-ripng-database1

Like RIPv1 and RIPv2, RIPng uses a 180 second invalid timer by default:

6-r3-ripng1

We will shut down R4 F0/0 so that R3 stops receiving updates from it:

R4:
interface FastEthernet0/0
 shutdown

Note: RIPng on R4 would sometimes send a flash update advertising all known networks as unreachable as it was shutdown.  I’m not sure why it happened sometimes and not others, but it may be necessary to filter the route inbound on R3 or outbound on R4 instead of shutting down R4 F0/0 in order to see the invalid timer expire if this keeps occuring.

R3 receives the last update from R4 at 01:33:14.979, just prior to the shutdown:

R3#debug ipv6 rip
Mar 1 01:33:14.979: RIPng: response received from FE80::4 on FastEthernet0/0 for test
Mar 1 01:33:14.979: src=FE80::4 (FastEthernet0/0)
Mar 1 01:33:14.979: dst=FF02::9
Mar 1 01:33:14.979: sport=521, dport=521, length=52
Mar 1 01:33:14.983: command=2, version=1, mbz=0, #rte=2
Mar 1 01:33:14.983: tag=0, metric=1, prefix=2001:DB8:0:4444::/64
Mar 1 01:33:14.983: tag=0, metric=1, prefix=2001:DB8:0:34::/64

180 seconds later, the invalid timer expires and the route is removed from the routing table. Flash updates are sent about the unreachable route 1 second later, followed by the regular periodic updates a few seconds after that:

R3#debug ipv6 routing
R3#debug ipv6 rip

Mar 1 01:36:14.983: IPv6RT0: rip test, Delete backup for 2001:DB8:0:34::/64
Mar 1 01:36:14.983: RIPng: 2001:DB8:0:34::/64, expired, ttg is 0
Mar 1 01:36:14.983: RIPng: Deleting 2001:DB8:0:34::/64
Mar 1 01:36:14.983: IPv6RT0: rip test, Delete 2001:DB8:0:4444::/64 from table
Mar 1 01:36:14.983: RIPng: 2001:DB8:0:4444::/64, expired, ttg is 120
Mar 1 01:36:14.983: RIPng: Triggered update requested
Mar 1 01:36:14.983: RIPng: Next RIB walk in 2000
Mar 1 01:36:14.983: IPv6RT0: Event: 2001:DB8:0:4444::/64, Del, owner rip, previous None
Mar 1 01:36:15.983: RIPng: generating triggered update for test
Mar 1 01:36:15.983: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 01:36:15.983: src=FE80::3
Mar 1 01:36:15.983: dst=FF02::9 (Serial0/0)
Mar 1 01:36:15.987: sport=521, dport=521, length=32
Mar 1 01:36:15.987: command=2, version=1, mbz=0, #rte=1
Mar 1 01:36:15.987: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 01:36:15.991: RIPng: Suppressed null multicast update on FastEthernet0/0 for test
Mar 1 01:36:16.983: RIPng: Next RIB walk in 118000
Mar 1 01:36:29.099: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 01:36:29.099: src=FE80::3
Mar 1 01:36:29.099: dst=FF02::9 (Serial0/0)
Mar 1 01:36:29.103: sport=521, dport=521, length=72
Mar 1 01:36:29.103: command=2, version=1, mbz=0, #rte=3
Mar 1 01:36:29.103: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 01:36:29.103: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 01:36:29.103: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 01:36:29.107: RIPng: Sending multicast update on FastEthernet0/0 for test
Mar 1 01:36:29.107: src=FE80::3
Mar 1 01:36:29.107: dst=FF02::9 (FastEthernet0/0)
Mar 1 01:36:29.111: sport=521, dport=521, length=72
Mar 1 01:36:29.111: command=2, version=1, mbz=0, #rte=3
Mar 1 01:36:29.111: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 01:36:29.111: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 01:36:29.111: tag=0, metric=2, prefix=2001:DB8:0:12::/64

7-r3-show-ipv6-route1 

7-r3-ripng-database1

As shown in the routing table above, when the invalid timer expires the route is immediately removed from the routing table, unlike RIPv1 and RIPv2.  In the RIPng database, it is listed as expired, and 2 additional timers that we will look at shortly are now listed as well for the failed route.  One other difference compared to RIPv1/RIPv2 is that by default RIPng does not use poison-reverse.  When R3 sent flash updates about the unreachable route, the update on F0/0 was suppressed (the message at 01:36:15.991) because the only route to be advertised in the flash update was known on that interface.  The periodic update on F0/0 (at 01:36:29.111) also does not include a route entry for 2001:db8:0:4444::/64.  Poison-reverse can be enabled at the routing process in RIPng as shown below:

R3:
ipv6 router rip test
 poison-reverse

However, this is not the same as RIPv1/2 behavior.  RIPv1/2 use poison-reverse only for unreachable routes, with all other routes using simple split-horizon rules (if split-horizon is enabled).  RIPng uses split-horizon with poison-reverse for all non-directly-connected routes regardless of their metric if it is enabled.  With all interfaces once again enabled and the network converged, R3’s routing table and RIPng updates look like this:

8-r3-show-ipv6-route1

R3#debug ipv6 rip
Mar 1 01:42:38.311: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 01:42:38.311: src=FE80::3
Mar 1 01:42:38.311: dst=FF02::9 (Serial0/0)
Mar 1 01:42:38.315: sport=521, dport=521, length=92
Mar 1 01:42:38.315: command=2, version=1, mbz=0, #rte=4
Mar 1 01:42:38.315: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 01:42:38.315: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 01:42:38.315: tag=0, metric=16, prefix=2001:DB8:0:12::/64
Mar 1 01:42:38.319: tag=0, metric=2, prefix=2001:DB8:0:4444::/64
Mar 1 01:42:38.319: RIPng: Sending multicast update on FastEthernet0/0 for test
Mar 1 01:42:38.319: src=FE80::3
Mar 1 01:42:38.323: dst=FF02::9 (FastEthernet0/0)
Mar 1 01:42:38.323: sport=521, dport=521, length=92
Mar 1 01:42:38.323: command=2, version=1, mbz=0, #rte=4
Mar 1 01:42:38.323: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 01:42:38.323: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 01:42:38.327: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 01:42:38.327: tag=0, metric=16, prefix=2001:DB8:0:4444::/64

2001:db8:0:12::/64, known on S0/0, is advertised back out S0/0 as unreachable.  2001:db8:0:4444::/64, known on F0/0, is advertised back out F0/0 as unreachable.

 

Next we will look at the flush timer, first in RIPv1/2.  The flush timer controls when a route that has not been updated is removed entirely from the routing table and RIP database.  We will be using the same scenario again, where R4 F0/0 fails.  First we will set the timers back to their defaults:

R3:
router rip
 default timers basic

The default flush timer is 240 seconds in RIPv1/2:

9-r3-show-ip-protocols

Now we will shut down R4 F0/0 again:

R4:
interface FastEthernet0/0
 shutdown

R3 receives the last update from R4 at 00:25:11.695, just prior to the shutdown:

R3#debug ip rip
Mar 1 00:25:11.695: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 00:25:11.695: 4.4.4.0/24 via 0.0.0.0 in 1 hops

A little over 180 seconds later, the invalid timer expires.  Like we saw earlier, the route is listed as possibly down in the routing table and RIP database, and is advertised as unreachable using poison-reverse.  The route continues to be advertised in periodic updates until the flush timer expires, after approximately 240 seconds:

R3#debug ip routing
R3#debug ip rip
Mar 1 00:28:14.927: RT: delete route to 4.4.4.0 via 10.0.34.4, rip metric [120/1]
Mar 1 00:28:14.927: RT: SET_LAST_RDB for 4.4.4.0/24
OLD rdb: via 11.13.11.13
Mar 1 00:28:14.931: RT: no routes to 4.4.4.0, entering holddown
Mar 1 00:28:14.931: RT: NET-RED 4.4.4.0/24
Mar 1 00:28:16.931: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 00:28:16.931: RIP: build flash update entries
Mar 1 00:28:16.931: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:28:16.931: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 00:28:16.931: RIP: build flash update entries
Mar 1 00:28:16.931: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:28:38.879: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 00:28:38.879: RIP: build update entries
Mar 1 00:28:38.879: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:28:38.883: 10.0.34.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:28:40.039: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 00:28:40.039: RIP: build update entries
Mar 1 00:28:40.039: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:28:40.039: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 00:28:40.039: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:29:08.763: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 00:29:08.763: RIP: build update entries
Mar 1 00:29:08.763: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:29:08.767: 10.0.34.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:29:09.463: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 00:29:09.463: RIP: build update entries
Mar 1 00:29:09.463: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 00:29:09.463: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 00:29:09.467: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 00:29:14.931: RT: delete subnet route to 4.4.4.0/24
Mar 1 00:29:14.931: RT: NET-RED 4.4.4.0/24
Mar 1 00:29:14.935: RT: delete network route to 4.0.0.0
Mar 1 00:29:14.935: RT: NET-RED 4.0.0.0/8

Using default timers, this means the route is advertised as unreachable for 60 seconds.  Once the flush timer expires and the 2nd delete message appears in the logs, the route is removed and no longer included in updates or used for forwarding.

 

In RIPng, the flush timer is called the garbage collection timer.  The garbage collect timer is 120 seconds by default and does not start until the invalid timer expires, unlike RIPv1/2 where the flush timer begins at the time the last update was received:

10-r3-ripng

Now we will shut down R4 F0/0 again:

R4:
interface FastEthernet0/0
 shutdown

R3 receives the last update from R4 at 00:31:20.699, just prior to the shutdown:

R3#debug ipv6 rip
Mar 1 00:31:20.699: RIPng: response received from FE80::4 on FastEthernet0/0 for test
Mar 1 00:31:20.699: src=FE80::4 (FastEthernet0/0)
Mar 1 00:31:20.703: dst=FF02::9
Mar 1 00:31:20.703: sport=521, dport=521, length=52
Mar 1 00:31:20.703: command=2, version=1, mbz=0, #rte=2
Mar 1 00:31:20.703: tag=0, metric=1, prefix=2001:DB8:0:4444::/64
Mar 1 00:31:20.703: tag=0, metric=1, prefix=2001:DB8:0:34::/64

180 seconds later, the invalid timer expires, and the behavior that we saw earlier when the RIPng invalid timer expires begins.  The RIP database shows how long the route will continue to be advertised (the garbage collect timer).  The route continues to be advertised in periodic updates using simple split-horizon rules until the garbage collect timer expires, after approximately 300 total seconds:

R3#debug ipv6 routing
R3#debug ipv6 rip

Mar 1 00:34:20.703: IPv6RT0: rip test, Delete backup for 2001:DB8:0:34::/64
Mar 1 00:34:20.703: RIPng: 2001:DB8:0:34::/64, expired, ttg is 0
Mar 1 00:34:20.703: RIPng: Deleting 2001:DB8:0:34::/64
Mar 1 00:34:20.707: IPv6RT0: rip test, Delete 2001:DB8:0:4444::/64 from table
Mar 1 00:34:20.707: RIPng: 2001:DB8:0:4444::/64, expired, ttg is 120
Mar 1 00:34:20.707: RIPng: Triggered update requested
Mar 1 00:34:20.707: RIPng: Next RIB walk in 2000
Mar 1 00:34:20.711: IPv6RT0: Event: 2001:DB8:0:4444::/64, Del, owner rip, previous None
Mar 1 00:34:21.707: RIPng: generating triggered update for test
Mar 1 00:34:21.707: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 00:34:21.707: src=FE80::3
Mar 1 00:34:21.707: dst=FF02::9 (Serial0/0)
Mar 1 00:34:21.711: sport=521, dport=521, length=32
Mar 1 00:34:21.711: command=2, version=1, mbz=0, #rte=1
Mar 1 00:34:21.711: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 00:34:21.715: RIPng: Suppressed null multicast update on FastEthernet0/0 for test

10-r3-ripng-database

R3#debug ipv6 routing
R3#debug ipv6 rip

Mar 1 00:34:26.715: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 00:34:26.715: src=FE80::3
Mar 1 00:34:26.715: dst=FF02::9 (Serial0/0)
Mar 1 00:34:26.719: sport=521, dport=521, length=72
Mar 1 00:34:26.719: command=2, version=1, mbz=0, #rte=3
Mar 1 00:34:26.719: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:34:26.719: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:34:26.719: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 00:34:26.723: RIPng: Sending multicast update on FastEthernet0/0 for test
Mar 1 00:34:26.723: src=FE80::3
Mar 1 00:34:26.723: dst=FF02::9 (FastEthernet0/0)
Mar 1 00:34:26.727: sport=521, dport=521, length=72
Mar 1 00:34:26.727: command=2, version=1, mbz=0, #rte=3
Mar 1 00:34:26.727: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:34:26.727: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:34:26.727: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 00:34:56.207: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 00:34:56.207: src=FE80::3
Mar 1 00:34:56.207: dst=FF02::9 (Serial0/0)
Mar 1 00:34:56.211: sport=521, dport=521, length=72
Mar 1 00:34:56.211: command=2, version=1, mbz=0, #rte=3
Mar 1 00:34:56.211: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:34:56.211: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:34:56.211: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 00:34:56.215: RIPng: Sending multicast update on FastEthernet0/0 for test
Mar 1 00:34:56.215: src=FE80::3
Mar 1 00:34:56.215: dst=FF02::9 (FastEthernet0/0)
Mar 1 00:34:56.219: sport=521, dport=521, length=72
Mar 1 00:34:56.219: command=2, version=1, mbz=0, #rte=3
Mar 1 00:34:56.219: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:34:56.219: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:34:56.219: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 00:35:23.631: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 00:35:23.631: src=FE80::3
Mar 1 00:35:23.631: dst=FF02::9 (Serial0/0)
Mar 1 00:35:23.635: sport=521, dport=521, length=72
Mar 1 00:35:23.635: command=2, version=1, mbz=0, #rte=3
Mar 1 00:35:23.635: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:35:23.635: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:35:23.635: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 00:35:23.639: RIPng: Sending multicast update on FastEthernet0/0 for test
Mar 1 00:35:23.639: src=FE80::3
Mar 1 00:35:23.639: dst=FF02::9 (FastEthernet0/0)
Mar 1 00:35:23.643: sport=521, dport=521, length=72
Mar 1 00:35:23.643: command=2, version=1, mbz=0, #rte=3
Mar 1 00:35:23.643: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:35:23.643: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:35:23.643: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 00:35:53.387: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 00:35:53.387: src=FE80::3
Mar 1 00:35:53.387: dst=FF02::9 (Serial0/0)
Mar 1 00:35:53.391: sport=521, dport=521, length=72
Mar 1 00:35:53.391: command=2, version=1, mbz=0, #rte=3
Mar 1 00:35:53.391: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:35:53.391: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:35:53.391: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 00:35:53.395: RIPng: Sending multicast update on FastEthernet0/0 for test
Mar 1 00:35:53.395: src=FE80::3
Mar 1 00:35:53.395: dst=FF02::9 (FastEthernet0/0)
Mar 1 00:35:53.399: sport=521, dport=521, length=72
Mar 1 00:35:53.399: command=2, version=1, mbz=0, #rte=3
Mar 1 00:35:53.399: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:35:53.399: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:35:53.399: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 00:36:19.371: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 00:36:19.371: src=FE80::3
Mar 1 00:36:19.371: dst=FF02::9 (Serial0/0)
Mar 1 00:36:19.375: sport=521, dport=521, length=72
Mar 1 00:36:19.375: command=2, version=1, mbz=0, #rte=3
Mar 1 00:36:19.375: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:36:19.375: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:36:19.375: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 00:36:19.379: RIPng: Sending multicast update on FastEthernet0/0 for test
Mar 1 00:36:19.379: src=FE80::3
Mar 1 00:36:19.379: dst=FF02::9 (FastEthernet0/0)
Mar 1 00:36:19.383: sport=521, dport=521, length=72
Mar 1 00:36:19.383: command=2, version=1, mbz=0, #rte=3
Mar 1 00:36:19.383: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 00:36:19.383: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 00:36:19.383: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 00:36:20.703: RIPng: Deleting 2001:DB8:0:4444::/64
Mar 1 00:36:20.703: RIPng: Next RIB walk in 159284

11-r3-ripng-database

 

 

Next we will look at the holddown timer, first in RIPv1/2.  The holddown timer prevents updates for a route from being accepted until it expires under certain conditions.  By default, the holddown timer is 180 seconds:

12-r3-show-ip-protocols

For testing out the holddown timer, we will add an additional link between R1 and R4:

rip-timers22

R1:
interface Serial0/1
 ip address 10.0.14.1 255.255.255.0
 ipv6 address 2001:DB8:0:14::1/64
 ipv6 address FE80::1 link-local
 ipv6 rip test enable
 

R4:
interface Serial0/0
 ip address 10.0.14.4 255.255.255.0
 ipv6 address 2001:DB8:0:14::4/64
 ipv6 address FE80::4 link-local
 ipv6 rip test enable

The holddown timer is perhaps the most confusing and poorly explained of the RIP timers.  The sources I’ve looked at each say slightly different things about what it does, none of which is completely correct.  We will first look at what the holddown timer doesn’t do by testing out what various sources say about it.  From Routing TCP/IP Volume 1:

If the distance to a destination increases (for example, the hop count increases from two to four), the router sets a holddown timer for that route. Until the timer expires, the router will not accept any new updates for the route.

and also:

The third timer is the holddown timer, although RFC 1058 does not call for the use of holddowns. The Cisco implementation of RIP does use them. An update with a hop count higher than the metric recorded in the route table will cause the route to go into holddown for 180 seconds (again, six update periods).

This says if the metric from the current best source increases, the route is placed in holddown.  R3 currently has a 1 hop route to 4.4.4.0/24 through R4.  We will offset the metric for the route by 1 outbound on R4 and see if the route gets placed in holddown:

R4:
access-list 1 permit 4.4.4.0

!
router rip
 offset-list 1 out 1 FastEthernet0/0

R3#debug ip routing
R3#debug ip rip

Mar 1 02:38:09.167: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 02:38:09.171: 4.4.4.0/24 via 0.0.0.0 in 2 hops
Mar 1 02:38:09.171: RT: rip's 4.4.4.0/24 (via 10.0.34.4) metric changed from distance/metric [120/1] to [120/2]
Mar 1 02:38:09.171: RT: NET-RED 4.4.4.0/24
Mar 1 02:38:09.175: 10.0.12.0/24 via 0.0.0.0 in 2 hops
Mar 1 02:38:09.175: 10.0.14.0/24 via 0.0.0.0 in 1 hops
Mar 1 02:38:11.175: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 02:38:11.175: RIP: build flash update entries - suppressing null update
Mar 1 02:38:11.175: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 02:38:11.179: RIP: build flash update entries
Mar 1 02:38:11.179: 4.4.4.0/24 via 0.0.0.0, metric 3, tag 0

12-r3-show-ip-route

Instead of placing the route in holddown, R3 accepts the increased metric immediately, records it in the RIP database and routing table, and sends a flash update on S0/0 2 seconds later about the increased metric.

 

 

From the 12.4 Command Reference:

A route enters into a holddown state when an update packet is received that indicates the route is unreachable. The route is marked inaccessible and advertised as unreachable. However, the route is still used for forwarding packets. When holddown expires, routes advertised by other sources are accepted and the route is no longer inaccessible.

Based on this description, if we shut down R4’s loopback so that it is advertised as unreachable, R3 should place the route into holddown.  If we bring it back up a few seconds later, the update should be ignored by R3.  Let’s test this out:

R4:
interface Loopback0
 shutdown

R3#debug ip routing
R3#debug ip rip

Mar 1 02:56:04.723: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 02:56:04.723: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 02:56:04.727: RT: del 4.4.4.0/24 via 10.0.34.4, rip metric [120/2]
Mar 1 02:56:04.727: RT: delete subnet route to 4.4.4.0/24
Mar 1 02:56:04.727: RT: NET-RED 4.4.4.0/24
Mar 1 02:56:04.731: RT: delete network route to 4.0.0.0
Mar 1 02:56:04.731: RT: NET-RED 4.0.0.0/8
Mar 1 02:56:06.731: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 02:56:06.731: RIP: build flash update entries
Mar 1 02:56:06.731: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 02:56:06.735: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 02:56:06.735: RIP: build flash update entries
Mar 1 02:56:06.735: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0

R4:
interface Loopback0
 no shutdown

R3#debug ip routing
R3#debug ip rip

Mar 1 02:56:19.587: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 02:56:19.587: 4.4.4.0/24 via 0.0.0.0 in 2 hops
Mar 1 02:56:19.591: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.34.4
Mar 1 02:56:19.591: RT: add 4.4.4.0/24 via 10.0.34.4, rip metric [120/2]
Mar 1 02:56:19.591: RT: NET-RED 4.4.4.0/24
Mar 1 02:56:21.595: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 02:56:21.595: RIP: build flash update entries - suppressing null update
Mar 1 02:56:21.595: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 02:56:21.599: RIP: build flash update entries
Mar 1 02:56:21.599: 4.4.4.0/24 via 0.0.0.0, metric 3, tag 0

R3 receives the flash update from R4 advertising 4.4.4.0/24 as unreachable, removes it from the routing table, and sends a flash update on S0/0 advertising it as unreachable.  When R4’s loopback comes back up and R3 receives a flash update advertising it as reachable 15 seconds later, R3 accepts the update immediately – so the route is clearly not in holddown.  The count-to-infinity problem – which the holddown timer is supposed to prevent – can even occur in this scenario with some unlucky timing of updates.  With all interfaces back up and the network converged, we will shutdown the R4 loopback again:

R4:
interface Loopback0
 shutdown

R3 receives the flash update from R4 at 03:11:03.063 and immediately deletes the route:

R3#debug ip routing
R3#debug ip rip

Mar 1 03:11:03.063: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 03:11:03.063: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 03:11:03.063: RT: del 4.4.4.0/24 via 10.0.34.4, rip metric [120/2]
Mar 1 03:11:03.063: RT: delete subnet route to 4.4.4.0/24
Mar 1 03:11:03.063: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:03.063: RT: delete network route to 4.0.0.0
Mar 1 03:11:03.063: RT: NET-RED 4.0.0.0/8
Mar 1 03:11:03.067: 10.0.12.0/24 via 0.0.0.0 in 2 hops
Mar 1 03:11:03.067: 10.0.14.0/24 via 0.0.0.0 in 1 hops

R2’s periodic update timer for the R2-R3 link happens to expire right after this.  R2 has not gotten the flash update yet that 4.4.4.0/24 is unreachable, so R2’s update includes 4.4.4.0/24 with a metric of 3.  R3 receives the periodic update from R2 at 03:11:04.987, approximately 1.9 seconds after the flash update was received from R4:

R3#debug ip routing
R3#debug ip rip

Mar 1 03:11:04.987: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:04.987: 4.4.4.0/24 via 0.0.0.0 in 3 hops
Mar 1 03:11:04.991: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.23.2
Mar 1 03:11:04.991: RT: add 4.4.4.0/24 via 10.0.23.2, rip metric [120/3]
Mar 1 03:11:04.995: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:04.995: 10.0.12.0/24 via 0.0.0.0 in 1 hops
Mar 1 03:11:04.995: 10.0.14.0/24 via 0.0.0.0 in 2 hops

At 03:11:05.063, exactly 2 seconds after the flash update from R4 was received, R3 sends a flash update for 4.4.4.0/24 – however the flash update does not list the route as unreachable, which caused the flash update to occur in the first place, but rather in it’s current state.  This is key to what allows the problem to occur.  Flash updates are delayed for 2 seconds and once the delay period expires, updates are sent for the route in whatever current state it is in.  R3 increments the metric and sends a flash update for the route back to R4.  R3 does not send a flash update for the route to R2 due to split-horizon rules:

R3#debug ip rip
Mar 1 03:11:05.063: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:05.063: RIP: build flash update entries
Mar 1 03:11:05.063: 4.4.4.0/24 via 0.0.0.0, metric 4, tag 0
Mar 1 03:11:05.067: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:05.067: RIP: build flash update entries - suppressing null update

R4 receives the update from R3, adds the route to the RIP database and routing table, and starts the 2 second delay for it’s flash update about the route:

R4#debug ip routing
R4#debug ip rip

Mar 1 03:11:05.203: RIP: received v2 update from 10.0.34.3 on FastEthernet0/0
Mar 1 03:11:05.203: 4.4.4.0/24 via 0.0.0.0 in 4 hops
Mar 1 03:11:05.207: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.34.3
Mar 1 03:11:05.207: RT: add 4.4.4.0/24 via 10.0.34.3, rip metric [120/4]
Mar 1 03:11:05.207: RT: NET-RED 4.4.4.0/24
 

R2 receives a flash update from R1 at about the same time advertising the route as unreachable. R2 removes the route from the routing table and also starts it’s 2 second flash update delay for the route:

R2#debug ip routing
R2#debug ip rip

Mar 1 03:11:05.739: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 03:11:05.739: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 03:11:05.743: RT: del 4.4.4.0/24 via 10.0.12.1, rip metric [120/2]
Mar 1 03:11:05.743: RT: delete subnet route to 4.4.4.0/24
Mar 1 03:11:05.743: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:05.747: RT: delete network route to 4.0.0.0
Mar 1 03:11:05.747: RT: NET-RED 4.0.0.0/8

On R4, the 2 second delay for the flash update expires from the time it was received with a hop-count of 4 from R3.  No further updates about the route have been received during the delay period, so the hop-count is incremented and the route is advertised to R1:

R4#debug ip rip
Mar 1 03:11:07.211: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.4)
Mar 1 03:11:07.211: RIP: build flash update entries - suppressing null update
Mar 1 03:11:07.211: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.14.4)
Mar 1 03:11:07.215: RIP: build flash update entries
Mar 1 03:11:07.215: 4.4.4.0/24 via 0.0.0.0, metric 5, tag 0

On R2, the 2 second delay expires as well from the time it was received with an unreachable metric from R1.  No further changes have occurred so the route is advertised as unreachable out all interfaces:

R2#debug ip rip
Mar 1 03:11:07.747: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 03:11:07.747: RIP: build flash update entries
Mar 1 03:11:07.747: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:07.751: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 03:11:07.751: RIP: build flash update entries
Mar 1 03:11:07.751: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
 

R3 receives the flash update from R2, deletes the route, and starts the 2 second flash update delay.  However, the update arrives too late, as R3 already incorrectly advertised the route to R4 approximately 3 seconds earlier.  This results in 2 circles of updates, 1 advertising the route as unreachable and 1 with an incrementing hop-count.  The 2 updates will circulate approximately every 8 seconds (4x the flash update delay) and the route will be continually added and removed until eventually the incrementing hop-count reaches 16:

R3#debug ip routing
R3#debug ip rip
Mar 1 03:11:08.143: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:08.143: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 03:11:08.147: RT: del 4.4.4.0/24 via 10.0.23.2, rip metric [120/3]
Mar 1 03:11:08.147: RT: delete subnet route to 4.4.4.0/24
Mar 1 03:11:08.147: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:08.151: RT: delete network route to 4.0.0.0
Mar 1 03:11:08.151: RT: NET-RED 4.0.0.0/8
Mar 1 03:11:10.151: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:10.151: RIP: build flash update entries
Mar 1 03:11:10.151: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:10.155: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:10.155: RIP: build flash update entries
Mar 1 03:11:10.155: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:11.235: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:11.235: 4.4.4.0/24 via 0.0.0.0 in 7 hops
Mar 1 03:11:11.239: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.23.2
Mar 1 03:11:11.239: RT: add 4.4.4.0/24 via 10.0.23.2, rip metric [120/7]
Mar 1 03:11:11.239: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:13.243: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:13.243: RIP: build flash update entries
Mar 1 03:11:13.243: 4.4.4.0/24 via 0.0.0.0, metric 8, tag 0
Mar 1 03:11:13.247: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:13.247: RIP: build flash update entries - suppressing null update
Mar 1 03:11:14.483: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:14.483: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 03:11:14.483: RT: del 4.4.4.0/24 via 10.0.23.2, rip metric [120/7]
Mar 1 03:11:14.487: RT: delete subnet route to 4.4.4.0/24
Mar 1 03:11:14.487: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:14.487: RT: delete network route to 4.0.0.0
Mar 1 03:11:14.487: RT: NET-RED 4.0.0.0/8
Mar 1 03:11:16.487: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:16.487: RIP: build flash update entries
Mar 1 03:11:16.487: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:16.491: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:16.491: RIP: build flash update entries
Mar 1 03:11:16.491: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:19.375: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:19.375: 4.4.4.0/24 via 0.0.0.0 in 11 hops
Mar 1 03:11:19.375: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.23.2
Mar 1 03:11:19.379: RT: add 4.4.4.0/24 via 10.0.23.2, rip metric [120/11]
Mar 1 03:11:19.379: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:21.379: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:21.379: RIP: build flash update entries
Mar 1 03:11:21.379: 4.4.4.0/24 via 0.0.0.0, metric 12, tag 0
Mar 1 03:11:21.383: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:21.383: RIP: build flash update entries - suppressing null update
Mar 1 03:11:22.587: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:22.587: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 03:11:22.587: RT: del 4.4.4.0/24 via 10.0.23.2, rip metric [120/11]
Mar 1 03:11:22.591: RT: delete subnet route to 4.4.4.0/24
Mar 1 03:11:22.591: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:22.591: RT: delete network route to 4.0.0.0
Mar 1 03:11:22.595: RT: NET-RED 4.0.0.0/8
Mar 1 03:11:24.595: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:24.595: RIP: build flash update entries
Mar 1 03:11:24.595: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:24.599: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:24.599: RIP: build flash update entries
Mar 1 03:11:24.599: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0 
Mar 1 03:11:27.619: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:27.619: 4.4.4.0/24 via 0.0.0.0 in 15 hops
Mar 1 03:11:27.623: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.23.2
Mar 1 03:11:27.623: RT: add 4.4.4.0/24 via 10.0.23.2, rip metric [120/15]
Mar 1 03:11:27.627: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:29.627: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:29.627: RIP: build flash update entries
Mar 1 03:11:29.627: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:29.631: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:29.631: RIP: build flash update entries - suppressing null update
Mar 1 03:11:30.139: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 03:11:30.139: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 03:11:30.139: RT: del 4.4.4.0/24 via 10.0.23.2, rip metric [120/15]
Mar 1 03:11:30.139: RT: delete subnet route to 4.4.4.0/24
Mar 1 03:11:30.143: RT: NET-RED 4.4.4.0/24
Mar 1 03:11:30.143: RT: delete network route to 4.0.0.0
Mar 1 03:11:30.143: RT: NET-RED 4.0.0.0/8
Mar 1 03:11:32.147: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 03:11:32.147: RIP: build flash update entries
Mar 1 03:11:32.147: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 03:11:32.151: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 03:11:32.151: RIP: build flash update entries
Mar 1 03:11:32.151: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0

 

 

From Cisco Press ICND 2:

After hearing a poisoned route, start a holddown timer for that one route. Until the timer expires, do not believe any other routing information about the failed route, because believing that information may cause a routing loop. However, information learned from the neighbor that originally advertised the working route can be believed before the holddown timer expires.

This says the same thing as the command reference, with the addition of allowing information from the original route source to be believed during the holddown.  We will test this out on R2.  With all interfaces up again, R2 currently has a 2-hop route to 4.4.4.0/24 through R1:

13-r2-show-ip-route

The route through R3 is 3 hops because of the offset-list we applied on R4 F0/0 earlier, so it is not in the routing table or RIP database.  If the route is advertised as unreachable by R1, and then R2 receives an update from R3 advertising it as metric 3, it should be ignored based on the definition above.  To test this out, we will first shut down R4 F0/0 and then shut down R4’s loopback:

R4:
interface FastEthernet0/0
 shutdown
!
interface Loopback0
 shutdown

R4 sends a flash update advertising the route as unreachable, and R1 sends a flash update to R2.  R3 does not receive an update from R4 so it will continue advertising 4.4.4.0/24 to R2 as reachable until the invalid timer expires for the route:

R2#debug ip routing
R2#debug ip rip

Mar 1 04:09:43.699: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 04:09:43.699: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 04:09:43.703: RT: del 4.4.4.0/24 via 10.0.12.1, rip metric [120/2]
Mar 1 04:09:43.703: RT: delete subnet route to 4.4.4.0/24
Mar 1 04:09:43.703: RT: NET-RED 4.4.4.0/24
Mar 1 04:09:43.707: RT: delete network route to 4.0.0.0
Mar 1 04:09:43.707: RT: NET-RED 4.0.0.0/8
Mar 1 04:09:43.707: 10.0.14.0/24 via 0.0.0.0 in 1 hops
Mar 1 04:09:45.707: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 04:09:45.707: RIP: build flash update entries
Mar 1 04:09:45.707: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:09:45.711: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 04:09:45.711: RIP: build flash update entries
Mar 1 04:09:45.711: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:09:55.147: RIP: received v2 update from 10.0.23.3 on Serial0/1
Mar 1 04:09:55.147: 4.4.4.0/24 via 0.0.0.0 in 3 hops
Mar 1 04:09:55.151: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.23.3
Mar 1 04:09:55.151: RT: add 4.4.4.0/24 via 10.0.23.3, rip metric [120/3]
Mar 1 04:09:55.155: RT: NET-RED 4.4.4.0/24
Mar 1 04:09:55.155: 10.0.14.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:09:55.155: 10.0.34.0/24 via 0.0.0.0 in 1 hops
Mar 1 04:09:57.155: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 04:09:57.155: RIP: build flash update entries
Mar 1 04:09:57.155: 4.4.4.0/24 via 0.0.0.0, metric 4, tag 0
Mar 1 04:09:57.159: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 04:09:57.159: RIP: build flash update entries - suppressing null update

R2 receives one of R3’s periodic updates about 12 seconds after hearing of the unreachable route from R1 and, despite what the book says, accepts the information immediately from R3.  Until the invalid timer expires on R3, all 4 routers have incorrect routing information.  R4 now believes it has a 5-hop route to it’s own former network through R1:

14-r4-show-ip-route

If R4 F0/0 comes back up before the invalid expires on R3, a different type of count-to-infinity problem occurs.  R3 still believes it has a route to 4.4.4.0/24 through R4 since it did not receive the update advertising it as unreachable while R4 F0/0 was down.  R4 believes it knows 4.4.4.0/24 through R1, so split-horizon will not prevent R4 from advertising it to R3 now that F0/0 is back up.  An increased metric received does not cause holddown to occur as we saw earlier, so when R3 receives an update from R4, a single circle of updates occurs with the metric increasing by 5 each time (4 routers + 1 from the offset) until it reaches 16:

R2#debug ip routing
R2#debug ip rip

Mar 1 04:11:08.355: RIP: received v2 update from 10.0.23.3 on Serial0/1
Mar 1 04:11:08.355: 4.4.4.0/24 via 0.0.0.0 in 8 hops
Mar 1 04:11:08.359: RT: rip's 4.4.4.0/24 (via 10.0.23.3) metric changed from distance/metric [120/3] to [120/8]
Mar 1 04:11:08.359: RT: NET-RED 4.4.4.0/24
Mar 1 04:11:10.363: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 04:11:10.363: RIP: build flash update entries
Mar 1 04:11:10.363: 4.4.4.0/24 via 0.0.0.0, metric 9, tag 0
Mar 1 04:11:10.367: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 04:11:10.367: RIP: build flash update entries - suppressing null update
Mar 1 04:11:16.475: RIP: received v2 update from 10.0.23.3 on Serial0/1
Mar 1 04:11:16.479: 4.4.4.0/24 via 0.0.0.0 in 13 hops
Mar 1 04:11:16.479: RT: rip's 4.4.4.0/24 (via 10.0.23.3) metric changed from distance/metric [120/8] to [120/13]
Mar 1 04:11:16.479: RT: NET-RED 4.4.4.0/24
Mar 1 04:11:18.483: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 04:11:18.483: RIP: build flash update entries
Mar 1 04:11:18.483: 4.4.4.0/24 via 0.0.0.0, metric 14, tag 0
Mar 1 04:11:18.487: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 04:11:18.487: RIP: build flash update entries - suppressing null update
Mar 1 04:11:24.703: RIP: received v2 update from 10.0.23.3 on Serial0/1
Mar 1 04:11:24.703: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 04:11:24.703: RT: del 4.4.4.0/24 via 10.0.23.3, rip metric [120/13]
Mar 1 04:11:24.703: RT: delete subnet route to 4.4.4.0/24
Mar 1 04:11:24.703: RT: NET-RED 4.4.4.0/24
Mar 1 04:11:24.707: RT: delete network route to 4.0.0.0
Mar 1 04:11:24.707: RT: NET-RED 4.0.0.0/8
Mar 1 04:11:26.707: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 04:11:26.707: RIP: build flash update entries
Mar 1 04:11:26.707: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:11:26.707: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 04:11:26.707: RIP: build flash update entries
Mar 1 04:11:26.707: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0

 

 

So what exactly causes holddown to occur?  Earlier when we looked at the invalid timer, we saw the route placed into holddown when the invalid timer expired.  As it turns out, this is the only time that the holddown timer is used.  Let’s look at an example where we can see this being used.  We will shut down R4 F0/0.  The last update is received at 04:36:16.207.  After 180 seconds, the invalid expires and we see the message about the route entering holddown:

R3#debug ip rip
Mar 1 04:36:16.207: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 04:36:16.211: 4.4.4.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:36:16.211: 10.0.12.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:36:16.211: 10.0.14.0/24 via 0.0.0.0 in 1 hops

R4:
interface FastEthernet0/0
 shutdown

R3#debug ip routing
R3#debug ip rip
Mar 1 04:39:19.843: RT: delete route to 4.4.4.0 via 10.0.34.4, rip metric [120/2]
Mar 1 04:39:19.843: RT: SET_LAST_RDB for 4.4.4.0/24
OLD rdb: via 11.13.11.13
Mar 1 04:39:19.843: RT: no routes to 4.4.4.0, entering holddown
Mar 1 04:39:19.843: RT: NET-RED 4.4.4.0/24
Mar 1 04:39:19.843: RT: delete route to 10.0.14.0 via 10.0.34.4, rip metric [120/1]
Mar 1 04:39:19.843: RT: SET_LAST_RDB for 10.0.14.0/24
OLD rdb: via 11.13.11.13
Mar 1 04:39:19.843: RT: no routes to 10.0.14.0, entering holddown
Mar 1 04:39:19.843: RT: NET-RED 10.0.14.0/24
Mar 1 04:39:21.843: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 04:39:21.843: RIP: build flash update entries
Mar 1 04:39:21.843: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:39:21.843: 10.0.14.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:39:21.843: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 04:39:21.843: RIP: build flash update entries
Mar 1 04:39:21.843: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:39:21.843: 10.0.14.0/24 via 0.0.0.0, metric 16, tag 0

R3 receives an update from R2 advertising 4.4.4.0/24 with hop-count 3 a few seconds later, but the update is ignored because the route is in holddown:

R3#debug ip routing
Mar 1 04:39:38.135: RIP: received v2 update from 10.0.23.2 on Serial0/0
Mar 1 04:39:38.135: 4.4.4.0/24 via 0.0.0.0 in 3 hops
Mar 1 04:39:38.139: 10.0.12.0/24 via 0.0.0.0 in 1 hops
Mar 1 04:39:38.139: 10.0.14.0/24 via 0.0.0.0 in 2 hops

Let’s bring R4 F0/0 back up and see if R3 accepts the update from the original source:

R4:
interface FastEthernet0/0
 no shutdown

R3#debug ip rip
Mar 1 04:40:01.583: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 04:40:01.583: 4.4.4.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:40:01.587: 10.0.12.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:40:01.587: 10.0.14.0/24 via 0.0.0.0 in 1 hops

R3 ignores the update from the original source as well during the holddown period and continues advertising the route as unreachable out both interfaces:

R3#debug ip rip
Mar 1 04:40:05.363: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 04:40:05.363: RIP: build update entries
Mar 1 04:40:05.363: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:40:05.367: 10.0.14.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:40:05.367: 10.0.34.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 04:40:13.039: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 04:40:13.039: RIP: build update entries
Mar 1 04:40:13.039: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:40:13.043: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 04:40:13.043: 10.0.14.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:40:13.043: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0

60 seconds after the invalid expired, the flush timer expires and the route is deleted:

R3#debug ip routing
Mar 1 04:40:19.843: RT: delete subnet route to 4.4.4.0/24
Mar 1 04:40:19.843: RT: NET-RED 4.4.4.0/24
Mar 1 04:40:19.843: RT: delete network route to 4.0.0.0
Mar 1 04:40:19.843: RT: NET-RED 4.0.0.0/8
Mar 1 04:40:19.843: RT: delete subnet route to 10.0.14.0/24
Mar 1 04:40:19.843: RT: NET-RED 10.0.14.0/24

When R3 receives the next periodic update from R4 a few seconds later, 4.4.4.0/24 and 10.0.14.0/24 are added back to the routing table and RIP database:

R3#debug ip routing
R3#debug ip rip
Mar 1 04:40:30.083: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 04:40:30.083: 4.4.4.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:40:30.087: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.34.4
Mar 1 04:40:30.087: RT: add 4.4.4.0/24 via 10.0.34.4, rip metric [120/2]
Mar 1 04:40:30.087: RT: NET-RED 4.4.4.0/24
Mar 1 04:40:30.091: 10.0.12.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:40:30.091: 10.0.14.0/24 via 0.0.0.0 in 1 hops
Mar 1 04:40:30.095: RT: SET_LAST_RDB for 10.0.14.0/24
NEW rdb: via 10.0.34.4
Mar 1 04:40:30.095: RT: add 10.0.14.0/24 via 10.0.34.4, rip metric [120/1]
Mar 1 04:40:30.095: RT: NET-RED 10.0.14.0/24

Wait a minute, if the holddown timer is 180 seconds by default shouldn’t updates be ignored for another 120 seconds?  If the flush timer expires before the holddown timer does, the route no longer exists in either the RIP database or routing table so any updates will be accepted for it.  Therefore, the effective holddown period is the lesser of the configured holddown timer and the flush minus the invalid timer.  Let’s repeat this with a holddown timer of 30 seconds to demonstrate this:

R3:
router rip
 timers basic 30 180 30 240

R3#debug ip rip
Mar 1 04:50:25.167: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 04:50:25.167: 4.4.4.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:50:25.171: 10.0.12.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:50:25.171: 10.0.14.0/24 via 0.0.0.0 in 1 hops

R4:
interface FastEthernet0/0
 shutdown

The routes enter holddown at 04:53:27.827:

R3#debug ip routing
R3#debug ip rip

Mar 1 04:53:27.823: RT: delete route to 4.4.4.0 via 10.0.34.4, rip metric [120/2]
Mar 1 04:53:27.823: RT: SET_LAST_RDB for 4.4.4.0/24
OLD rdb: via 11.13.11.13
Mar 1 04:53:27.827: RT: no routes to 4.4.4.0, entering holddown
Mar 1 04:53:27.827: RT: NET-RED 4.4.4.0/24
Mar 1 04:53:27.827: RT: delete route to 10.0.14.0 via 10.0.34.4, rip metric [120/1]
Mar 1 04:53:27.831: RT: SET_LAST_RDB for 10.0.14.0/24
OLD rdb: via 11.13.11.13
Mar 1 04:53:27.831: RT: no routes to 10.0.14.0, entering holddown
Mar 1 04:53:27.831: RT: NET-RED 10.0.14.0/24
Mar 1 04:53:29.827: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 04:53:29.827: RIP: build flash update entries
Mar 1 04:53:29.827: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:53:29.831: 10.0.14.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:53:29.831: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 04:53:29.831: RIP: build flash update entries
Mar 1 04:53:29.831: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 04:53:29.835: 10.0.14.0/24 via 0.0.0.0, metric 16, tag 0

After bringing R4 F0/0 back up, R3 receives a periodic update from R4 a little over 30 seconds after the routes entered holddown.  We see a log message stating that the routes have come out of holddown and the new routing information has been accepted:

R3#debug ip routing
R3#debug ip rip

Mar 1 04:53:59.203: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 04:53:59.203: 4.4.4.0/24 via 0.0.0.0 in 2 hops
Mar 1 04:53:59.203: RT: 4.4.4.0 came out of holddown
Mar 1 04:53:59.203: RT: SET_LAST_RDB for 4.4.4.0/24
NEW rdb: via 10.0.34.4
Mar 1 04:53:59.203: RT: add 4.4.4.0/24 via 10.0.34.4, rip metric [120/2]
Mar 1 04:53:59.203: RT: NET-RED 4.4.4.0/24
Mar 1 04:53:59.203: 10.0.12.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 04:53:59.207: 10.0.14.0/24 via 0.0.0.0 in 1 hops
Mar 1 04:53:59.207: RT: 10.0.14.0 came out of holddown
Mar 1 04:53:59.207: RT: SET_LAST_RDB for 10.0.14.0/24
NEW rdb: via 10.0.34.4
Mar 1 04:53:59.207: RT: add 10.0.14.0/24 via 10.0.34.4, rip metric [120/1]
Mar 1 04:53:59.211: RT: NET-RED 10.0.14.0/24
Mar 1 04:54:01.203: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 04:54:01.203: RIP: build flash update entries - suppressing null update
Mar 1 04:54:01.203: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 04:54:01.207: RIP: build flash update entries
Mar 1 04:54:01.207: 4.4.4.0/24 via 0.0.0.0, metric 3, tag 0
Mar 1 04:54:01.207: 10.0.14.0/24 via 0.0.0.0, metric 2, tag 0

 

So now we’ve seen how the holddown timer actually works, but this brings up another question:  If the route isn’t being placed in holddown when an unreachable update is received, what exactly is happening and how does the router know how long to pass the unreachable advertisement along?  The behavior is similar to when the invalid timer first expires on a router, with 2 exceptions:

1.  The route is not placed in holddown

2.  The route is maintained only in the RIP database.  It is removed from the routing table immediately and therefore not used to forward packets.

A router receiving an unreachable advertisement keeps the route in the RIP database for (flush – invalid) seconds and continues including it in updates as long as it is there.  This means that when an unreachable route is received, the actual values of the flush and invalid are not important for controlling how long the route continues to be advertised, only the difference between them.  To demonstrate this, we will change the flush and invalid timers on R1, R2, and R3.  The flush timer on R1 will be lowered to 180, the same as the invalid.  The invalid timer on R2 will be lowered to 60 while keeping the default flush of 240.  The invalid and flush will both be set to very high values on R3 while maintaining the difference of 60 between the two:

R1:
router rip
 timers basic 30 180 180 180

R2:
router rip
 timers basic 30 60 180 240

R3:
router rip
 timers basic 30 10000 180 10060

We will then shut down R4’s loopback.  All other interfaces are up, so the other 3 routers will learn of the failed route by an unreachable advertisement rather than by their invalid timer expiring:

R4:
interface Loopback0
 shutdown

Each of the routers hears of the failed route at approximately 05:34:33.  R1, whose (flush – invalid) is 0 seconds, keeps the failed route in the RIP database just long enough to send a flash update out all interfaces.  There is no log message showing when a route is removed from the RIP database, but we can see that at the first periodic update the route is no longer included:

R1#debug ip routing
R1#debug ip rip

Mar 1 05:34:32.799: RIP: received v2 update from 10.0.14.4 on Serial0/1
Mar 1 05:34:32.799: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 05:34:32.799: RT: del 4.4.4.0/24 via 10.0.14.4, rip metric [120/1]
Mar 1 05:34:32.803: RT: delete subnet route to 4.4.4.0/24
Mar 1 05:34:32.803: RT: NET-RED 4.4.4.0/24
Mar 1 05:34:32.803: RT: delete network route to 4.0.0.0
Mar 1 05:34:32.807: RT: NET-RED 4.0.0.0/8
Mar 1 05:34:32.807: 10.0.23.0/24 via 0.0.0.0 in 2 hops
Mar 1 05:34:32.807: 10.0.34.0/24 via 0.0.0.0 in 1 hops
Mar 1 05:34:34.807: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.1)
Mar 1 05:34:34.807: RIP: build flash update entries
Mar 1 05:34:34.807: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:34:34.811: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.14.1)
Mar 1 05:34:34.811: RIP: build flash update entries
Mar 1 05:34:34.811: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:34:46.087: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.14.1)
Mar 1 05:34:46.087: RIP: build update entries
Mar 1 05:34:46.087: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0

Mar 1 05:34:46.091: 10.0.23.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:34:48.039: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.12.1)
Mar 1 05:34:48.039: RIP: build update entries
Mar 1 05:34:48.039: 10.0.14.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:34:48.043: 10.0.34.0/24 via 0.0.0.0, metric 2, tag 0

R2’s flush – invalid is 180 seconds, which is approximately how long the route continues to be advertised for.  Only the last of it’s periodic updates that include 4.4.4.0/24 and the first of it’s periodic updates that exclude it are shown to keep the output shorter:

R2#debug ip routing
R2#debug ip rip
Mar 1 05:34:35.691: RIP: received v2 update from 10.0.12.1 on Serial0/0
Mar 1 05:34:35.691: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 05:34:35.691: RT: del 4.4.4.0/24 via 10.0.12.1, rip metric [120/2]
Mar 1 05:34:35.695: RT: delete subnet route to 4.4.4.0/24
Mar 1 05:34:35.695: RT: NET-RED 4.4.4.0/24
Mar 1 05:34:35.695: RT: delete network route to 4.0.0.0
Mar 1 05:34:35.695: RT: NET-RED 4.0.0.0/8
Mar 1 05:34:37.699: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 05:34:37.699: RIP: build flash update entries
Mar 1 05:34:37.699: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:34:37.703: RIP: sending v2 flash update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 05:34:37.703: RIP: build flash update entries
Mar 1 05:34:37.703: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0

15-r2-show-ip-route

15-r2-rip-database

R2#debug ip rip
R2#debug ip routing

Mar 1 05:37:11.683: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 05:37:11.683: RIP: build update entries
Mar 1 05:37:11.683: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:37:11.687: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:37:11.687: 10.0.14.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:37:13.375: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 05:37:13.375: RIP: build update entries
Mar 1 05:37:13.375: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:37:13.379: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:37:13.379: 10.0.34.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:37:39.963: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.12.2)
Mar 1 05:37:39.963: RIP: build update entries
Mar 1 05:37:39.963: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:37:39.967: 10.0.34.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:37:40.167: RIP: sending v2 update to 224.0.0.9 via Serial0/1 (10.0.23.2)
Mar 1 05:37:40.167: RIP: build update entries
Mar 1 05:37:40.167: 10.0.12.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:37:40.167: 10.0.14.0/24 via 0.0.0.0, metric 2, tag 0

16-r2-rip-database

R3’s flush – invalid is 60 seconds, and even though we set them to very high values, we can see that the failed route is advertised for 60 seconds just like the default.  Again, only the last periodic update including 4.4.4.0/24 and first periodic update excluding it are shown:

R3#debug ip routing
R3#debug ip rip

Mar 1 05:34:35.407: RIP: received v2 update from 10.0.34.4 on FastEthernet0/0
Mar 1 05:34:35.407: 4.4.4.0/24 via 0.0.0.0 in 16 hops (inaccessible)
Mar 1 05:34:35.411: RT: del 4.4.4.0/24 via 10.0.34.4, rip metric [120/2]
Mar 1 05:34:35.411: RT: delete subnet route to 4.4.4.0/24
Mar 1 05:34:35.411: RT: NET-RED 4.4.4.0/24
Mar 1 05:34:35.415: RT: delete network route to 4.0.0.0
Mar 1 05:34:35.415: RT: NET-RED 4.0.0.0/8
Mar 1 05:34:37.415: RIP: sending v2 flash update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 05:34:37.415: RIP: build flash update entries
Mar 1 05:34:37.415: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:34:37.419: RIP: sending v2 flash update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 05:34:37.419: RIP: build flash update entries
Mar 1 05:34:37.419: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:35:35.875: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 05:35:35.875: RIP: build update entries
Mar 1 05:35:35.875: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:35:35.879: 10.0.14.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:35:35.879: 10.0.34.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:35:37.163: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 05:35:37.163: RIP: build update entries
Mar 1 05:35:37.163: 4.4.4.0/24 via 0.0.0.0, metric 16, tag 0
Mar 1 05:35:37.167: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:35:37.167: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:36:02.035: RIP: sending v2 update to 224.0.0.9 via Serial0/0 (10.0.23.3)
Mar 1 05:36:02.035: RIP: build update entries
Mar 1 05:36:02.035: 10.0.14.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:36:02.039: 10.0.34.0/24 via 0.0.0.0, metric 1, tag 0
Mar 1 05:36:05.587: RIP: sending v2 update to 224.0.0.9 via FastEthernet0/0 (10.0.34.3)
Mar 1 05:36:05.587: RIP: build update entries
Mar 1 05:36:05.587: 10.0.12.0/24 via 0.0.0.0, metric 2, tag 0
Mar 1 05:36:05.591: 10.0.23.0/24 via 0.0.0.0, metric 1, tag 0

 

 

Next, we will look at the holddown timer in RIPng.  The holddown timer in RIPng is quite a bit different than in RIPv1/v2.  The default setting for the holddown timer is 0 seconds, so it is not even used in RIPng unless explicitly configured:

17-r3-ripng

If it is enabled, the holddown timer in RIPng works similarly to how the holddown timer in RIPv1/v2 is supposed to work.  Holddown in RIPng is activated by either of the following:

1.  The invalid timer expiring (same as RIPv1/v2)

2.  An unreachable route advertisement being received from the best route source 

We’ve already seen a route placed in holddown when the invalid expired in RIPv2, so let’s try it with an unreachable route advertisement in RIPng.  We will set a holddown timer of 60 seconds on R3 to test this out and keep the other timers at their defaults:

R3:
ipv6 router rip test
 timers 30 180 60 120

Next we will shutdown R4’s loopback:

R4:
interface Loopback0
 shutdown

R3 deletes the route to 4.4.4.0/24 right away after receiving an update from R4.  In the RIP database, we see that the holddown timer has begun counting down:

R3#debug ipv6 routing
R3#debug ipv6 rip

Mar 1 01:39:28.967: RIPng: response received from FE80::4 on FastEthernet0/0 for test
Mar 1 01:39:28.967: src=FE80::4 (FastEthernet0/0)
Mar 1 01:39:28.967: dst=FF02::9
Mar 1 01:39:28.971: sport=521, dport=521, length=92
Mar 1 01:39:28.971: command=2, version=1, mbz=0, #rte=4
Mar 1 01:39:28.971: tag=0, metric=1, prefix=2001:DB8:0:14::/64
Mar 1 01:39:28.971: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 01:39:28.971: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 01:39:28.971: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 01:39:28.975: RIPng: 2001:DB8:0:4444::/64, path FE80::4/FastEthernet0/0 unreachable
Mar 1 01:39:28.975: IPv6RT0: rip test, Delete 2001:DB8:0:4444::/64 from table
Mar 1 01:39:28.975: RIPng: 2001:DB8:0:4444::/64, expired, ttg is 60
Mar 1 01:39:28.979: RIPng: Triggered update requested
Mar 1 01:39:28.979: IPv6RT0: Event: 2001:DB8:0:4444::/64, Del, owner rip, previous None
Mar 1 01:39:29.979: RIPng: generating triggered update for test
Mar 1 01:39:29.979: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 01:39:29.979: src=FE80::3
Mar 1 01:39:29.979: dst=FF02::9 (Serial0/0)
Mar 1 01:39:29.979: sport=521, dport=521, length=32
Mar 1 01:39:29.979: command=2, version=1, mbz=0, #rte=1
Mar 1 01:39:29.979: tag=0, metric=16, prefix=2001:DB8:0:4444::/64
Mar 1 01:39:29.979: RIPng: Suppressed null multicast update on FastEthernet0/0 for test

17-r3-ripng-database

If we bring R4’s loopback back up before the holddown expires, R3 receives a flash update from R4.  R3 also receives a flash update from R2 since R1 and R2 are using default timers and therefore did not place the route into holddown.  R3 ignores the flash updates from both routers, and even generates log messages showing that the updates were ignored because of holddown:

R3#debug ipv6 rip
Mar 1 01:39:43.867: RIPng: response received from FE80::4 on FastEthernet0/0 for test
Mar 1 01:39:43.867: src=FE80::4 (FastEthernet0/0)
Mar 1 01:39:43.871: dst=FF02::9
Mar 1 01:39:43.871: sport=521, dport=521, length=32
Mar 1 01:39:43.871: command=2, version=1, mbz=0, #rte=1
Mar 1 01:39:43.871: tag=0, metric=1, prefix=2001:DB8:0:4444::/64
Mar 1 01:39:43.871: RIPng: 2001:DB8:0:4444::/64, held-down, ignoring update
Mar 1 01:39:47.815: RIPng: response received from FE80::2 on Serial0/0 for test
Mar 1 01:39:47.815: src=FE80::2 (Serial0/0)
Mar 1 01:39:47.819: dst=FF02::9
Mar 1 01:39:47.819: sport=521, dport=521, length=32
Mar 1 01:39:47.819: command=2, version=1, mbz=0, #rte=1
Mar 1 01:39:47.819: tag=0, metric=3, prefix=2001:DB8:0:4444::/64
Mar 1 01:39:47.819: RIPng: 2001:DB8:0:4444::/64, held-down, ignoring update

The next periodic update is ignored as well.  The first periodic update that arrives after the holddown timer has expired is accepted and the route is added back to the routing table (R2’s update arrives earlier so the metric changes when R4’s update arrives):

R3#debug ipv6 routing
R3#debug ipv6 rip

Mar 1 01:40:37.131: RIPng: response received from FE80::2 on Serial0/0 for test
Mar 1 01:40:37.131: src=FE80::2 (Serial0/0)
Mar 1 01:40:37.131: dst=FF02::9
Mar 1 01:40:37.131: sport=521, dport=521, length=92
Mar 1 01:40:37.135: command=2, version=1, mbz=0, #rte=4
Mar 1 01:40:37.135: tag=0, metric=1, prefix=2001:DB8:0:12::/64
Mar 1 01:40:37.135: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 01:40:37.135: tag=0, metric=2, prefix=2001:DB8:0:14::/64
Mar 1 01:40:37.135: tag=0, metric=3, prefix=2001:DB8:0:4444::/64
Mar 1 01:40:37.139: RIPng: 2001:DB8:0:4444::/64, metric changed to 4
Mar 1 01:40:37.139: RIPng: 2001:DB8:0:4444::/64, added path FE80::2/Serial0/0
Mar 1 01:40:37.139: IPv6RT0: rip test, Route add 2001:DB8:0:4444::/64 [new]
Mar 1 01:40:37.143: IPv6RT0: rip test, Add 2001:DB8:0:4444::/64 to table
Mar 1 01:40:37.143: IPv6RT0: rip test, Adding next-hop FE80::2 over Serial0/0 for 2001:DB8:0:4444::/64, [120/4]
Mar 1 01:40:37.143: RIPng: Triggered update requested
Mar 1 01:40:37.147: IPv6RT0: Event: 2001:DB8:0:4444::/64, Add, owner rip, previous None
Mar 1 01:40:37.779: RIPng: response received from FE80::4 on FastEthernet0/0 for test
Mar 1 01:40:37.779: src=FE80::4 (FastEthernet0/0)
Mar 1 01:40:37.783: dst=FF02::9
Mar 1 01:40:37.783: sport=521, dport=521, length=92
Mar 1 01:40:37.783: command=2, version=1, mbz=0, #rte=4
Mar 1 01:40:37.783: tag=0, metric=1, prefix=2001:DB8:0:14::/64
Mar 1 01:40:37.783: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 01:40:37.787: tag=0, metric=1, prefix=2001:DB8:0:4444::/64
Mar 1 01:40:37.787: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 01:40:37.787: RIPng: 2001:DB8:0:4444::/64, metric changed to 2
Mar 1 01:40:37.787: RIPng: 2001:DB8:0:4444::/64, added path FE80::4/FastEthernet0/0
Mar 1 01:40:37.791: IPv6RT0: rip test, Route add 2001:DB8:0:4444::/64 [better metric 2, 4]
Mar 1 01:40:37.791: IPv6RT0: rip test, Adding next-hop FE80::4 over FastEthernet0/0 for 2001:DB8:0:4444::/64, [120/2]
Mar 1 01:40:37.791: RIPng: Triggered update requested, delaying
Mar 1 01:40:37.795: IPv6RT0: Event: 2001:DB8:0:4444::/64, Mod, owner rip, previous None
Mar 1 01:40:38.143: RIPng: generating triggered update for test
Mar 1 01:40:38.143: RIPng: Sending multicast update on Serial0/0 for test
Mar 1 01:40:38.143: src=FE80::3
Mar 1 01:40:38.143: dst=FF02::9 (Serial0/0)
Mar 1 01:40:38.147: sport=521, dport=521, length=32
Mar 1 01:40:38.147: command=2, version=1, mbz=0, #rte=1
Mar 1 01:40:38.147: tag=0, metric=2, prefix=2001:DB8:0:4444::/64
Mar 1 01:40:38.151: RIPng: Suppressed null multicast update on FastEthernet0/0 for test

This partially agrees with what the last two sources had to say about how the holddown timer was supposed to work in RIPv1/v2 (however the route does not continue to be used for forwarding during the holddown and information from the original source is not accepted prior to the holddown expiring, as they say).  The Routing TCP/IP Volume 1 description of the holddown timer, which said that when a metric increases the route should be placed in holddown, still does not happen in RIPng.  R3’s current routing table looks like this:

18-r3-show-ipv6-route

R3’s best route to 2001:db8:0:14::/64 is 2 hops through R4.  We will change the hop-count added to routes received on R3 F0/0 from 1 to 7:

R3:
interface FastEthernet0/0
 ipv6 rip test metric-offset 7

When the next periodic update arrives from R4 on F0/0, R3 immediately updates the metric for the route and continues to keep it in the routing table:

R3#debug ipv6 routing
R3#debug ipv6 rip

Mar 1 01:55:46.315: RIPng: response received from FE80::4 on FastEthernet0/0 for test
Mar 1 01:55:46.315: src=FE80::4 (FastEthernet0/0)
Mar 1 01:55:46.319: dst=FF02::9
Mar 1 01:55:46.319: sport=521, dport=521, length=92
Mar 1 01:55:46.319: command=2, version=1, mbz=0, #rte=4
Mar 1 01:55:46.319: tag=0, metric=1, prefix=2001:DB8:0:34::/64
Mar 1 01:55:46.319: tag=0, metric=1, prefix=2001:DB8:0:14::/64
Mar 1 01:55:46.319: tag=0, metric=1, prefix=2001:DB8:0:4444::/64
Mar 1 01:55:46.323: tag=0, metric=2, prefix=2001:DB8:0:12::/64
Mar 1 01:55:46.323: RIPng: 2001:DB8:0:34::/64, metric changed to 8
Mar 1 01:55:46.323: RIPng: 2001:DB8:0:14::/64, metric changed to 8
Mar 1 01:55:46.323: IPv6RT0: rip test, Route add 2001:DB8:0:14::/64 [worse metric 8, 2]
Mar 1 01:55:46.327: RIPng: 2001:DB8:0:4444::/64, metric changed to 8
Mar 1 01:55:46.327: IPv6RT0: rip test, Route add 2001:DB8:0:4444::/64 [worse metric 8, 2]
Mar 1 01:55:46.327: RIPng: Triggered update requested
Mar 1 01:55:46.331: IPv6RT0: Event: 2001:DB8:0:14::/64, Mod, owner rip, previous None
Mar 1 01:55:46.331: IPv6RT0: Event: 2001:DB8:0:4444::/64, Mod, owner rip, previous None

A periodic update arrives just after this from R2, advertising the route as metric 2 (3 after R3 adds 1 to it).  R3 replaces the route from R4 with this one immediately:

R3#debug ipv6 routing
R3#debug ipv6 rip
Mar 1 01:55:47.003: RIPng: response received from FE80::2 on Serial0/0 for test
Mar 1 01:55:47.003: src=FE80::2 (Serial0/0)
Mar 1 01:55:47.007: dst=FF02::9
Mar 1 01:55:47.007: sport=521, dport=521, length=72
Mar 1 01:55:47.007: command=2, version=1, mbz=0, #rte=3
Mar 1 01:55:47.007: tag=0, metric=1, prefix=2001:DB8:0:12::/64
Mar 1 01:55:47.007: tag=0, metric=1, prefix=2001:DB8:0:23::/64
Mar 1 01:55:47.007: tag=0, metric=2, prefix=2001:DB8:0:14::/64
Mar 1 01:55:47.011: RIPng: 2001:DB8:0:14::/64, metric changed to 3
Mar 1 01:55:47.011: RIPng: 2001:DB8:0:14::/64, added path FE80::2/Serial0/0
Mar 1 01:55:47.011: IPv6RT0: rip test, Route add 2001:DB8:0:14::/64 [better metric 3, 8]
Mar 1 01:55:47.015: IPv6RT0: rip test, Adding next-hop FE80::2 over Serial0/0 for 2001:DB8:0:14::/64, [120/3]
Mar 1 01:55:47.015: RIPng: Triggered update requested, delaying
Mar 1 01:55:47.019: IPv6RT0: Event: 2001:DB8:0:14::/64, Mod, owner rip, previous None

Posted in IPv6, RIP | Leave a Comment »

Static Routing – differences between specifying an exit interface, an IP address, and both

Posted by Andy on April 5, 2009

In this post we will look at some of the differences between configuring static routes with an exit interface, an IP address, and both an exit interface and an IP address.  The topology and initial configurations are shown below:

static-routing-topology

R1:
ipv6 unicast-routing
!
interface FastEthernet0/0
 mac-address 0000.0000.0001
 ip address 10.0.13.1 255.255.255.0
 ipv6 address 2001:DB8:0:13::1/64
 ipv6 address FE80::1 link-local
!
interface Serial0/0
 ip address 10.0.12.1 255.255.255.0
 ipv6 address 2001:DB8:0:12::1/64
 ipv6 address FE80::1 link-local

R2:
ipv6 unicast-routing
!
interface Serial0/0
 ip address 10.0.12.2 255.255.255.0
 ipv6 address 2001:DB8:0:12::2/64
 ipv6 address FE80::2 link-local
!
interface Serial0/1
 ip address 10.0.23.2 255.255.255.0
 ipv6 address 2001:DB8:0:23::2/64
 ipv6 address FE80::2 link-local

R3:
ipv6 unicast-routing
!
interface FastEthernet0/0
 mac-address 0000.0000.0003
 ip address 10.0.13.3 255.255.255.0
 ipv6 address 2001:DB8:0:13::3/64
 ipv6 address FE80::3 link-local
!
interface Serial0/0
 ip address 10.0.23.3 255.255.255.0
 ipv6 address 2001:DB8:0:23::3/64
 ipv6 address FE80::3 link-local
!
interface Loopback0
 ip address 3.3.3.3 255.255.255.0
 ipv6 address 2001:DB8:0:3::3/64
 ipv6 address FE80::3 link-local

First we will configure a static route to R3’s loopback on R1 by specifying an outgoing interface:

R1:
ip route 3.3.3.0 255.255.255.0 FastEthernet0/0
ipv6 route 2001:DB8:0:3::/64 FastEthernet0/0

R1#debug ip routing
R1#debug ipv6 routing

Mar 1 00:08:07.339: RT: SET_LAST_RDB for 3.3.3.0/24
NEW rdb: is directly connected

Mar 1 00:08:07.343: RT: add 3.3.3.0/24 via 0.0.0.0, static metric [1/0]
Mar 1 00:08:07.343: RT: NET-RED 3.3.3.0/24

Mar 1 00:08:55.963: IPv6RT0: static, Route add 2001:DB8:0:3::/64 [new]
Mar 1 00:08:55.963: IPv6RT0: static, Add 2001:DB8:0:3::/64 to table
Mar 1 00:08:55.967: IPv6RT0: static, Adding next-hop :: over FastEthernet0/0 for 2001:DB8:0:3::/64, [1/0]
Mar 1 00:08:55.967: IPv6RT0: Event: 2001:DB8:0:3::/64, Add, owner static, previous None

The IPv4 route shows up in the routing table as directly connected to F0/0:

1-r1-show-ip-route

Some sources say that the default AD for IPv4 static routes with only an exit interface specified is 0, but as shown below the AD is 1, so this may have been changed at some point in IOS:

1-r1-show-ip-route-3

The IPv6 route is listed in the routing table as pointing to an unspecified address with an exit interface of F0/0:

1-r1-show-ipv6-route

IPv4 static routes configured with only an exit interface on a broadcast network rely on proxy-ARP to determine the next hop.  If we attempt to send traffic to 5 different addresses on the 3.3.3.0/24 subnet, R1 sends an ARP for each of them and R3 replies using proxy-ARP:

R1#ping 3.3.3.1
R1#ping 3.3.3.2
R1#ping 3.3.3.3
R1#ping 3.3.3.4
R1#ping 3.3.3.5

1-r1-show-arp

This could result in a large amount of broadcast traffic and a large ARP cache on R1, especially if the static route was a default route used for internet traffic.

IPv6 uses NDP for address resolution, which does not have a similar function to proxy-ARP for answering requests on behalf of other nodes.  Therefore, R3 does not reply to neighbor solicitations sent by R1 for addresses on the 2001:db8:0:3::/64 subnet.  Even if the NS is for 2001:db8:0:3::3 (R3’s loopback address), R3 does not send an NA because NDP messages are link-local in scope and the NS arrives on the wrong interface:

R1#ping 2001:db8:0:3::3
. . . . .

If we add a static neighbor cache entry on R1 for the address, R1 does not need to send an NS to determine the layer-2 address and R3’s loopback is now reachable:

R1:
ipv6 neighbor 2001:DB8:0:3::3 FastEthernet0/0 0000.0000.0003

1-r1-show-neighbor

R1#ping 2001:db8:0:3::3
!!!!!

Obviously this is not scalable as it would require a static neighbor cache entry using R3’s layer-2 address for every IPv6 address that could potentially be reached by the static route on R1.

If F0/0 goes down on R1, both static routes are removed from the routing table:

R1:
interface FastEthernet0/0
 shutdown

Mar 1 00:25:01.907: IPv6RT0: connected, Delete 2001:DB8:0:13::1/128 from table
Mar 1 00:25:01.911: IPv6RT0: connected, Delete 2001:DB8:0:13::/64 from table
Mar 1 00:25:01.915: IPv6RT0: static, Delete 2001:DB8:0:3::/64 from table
Mar 1 00:25:01.919: RT: is_up: FastEthernet0/0 0 state: 6 sub state: 1 line: 1 has_route: True
Mar 1 00:25:01.923: RT: interface FastEthernet0/0 removed from routing table
Mar 1 00:25:01.923: RT: del 10.0.13.0/24 via 0.0.0.0, connected metric [0/0]
Mar 1 00:25:01.923: RT: delete subnet route to 10.0.13.0/24
Mar 1 00:25:01.927: RT: NET-RED 10.0.13.0/24
Mar 1 00:25:01.927: RT: Pruning routes for FastEthernet0/0 (1)
Mar 1 00:25:01.959: RT: delete route to 3.3.3.0 via 0.0.0.0, FastEthernet0/0
Mar 1 00:25:01.959: RT: no routes to 3.3.3.0, flushing
Mar 1 00:25:01.959: RT: NET-RED 3.3.3.0/24
Mar 1 00:25:01.963: RT: delete network route to 3.0.0.0
Mar 1 00:25:01.963: RT: NET-RED 3.0.0.0/8
Mar 1 00:25:01.967: IPv6RT0: Event: 2001:DB8:0:13::1/128, Del, owner connected, previous None
Mar 1 00:25:01.967: IPv6RT0: Event: 2001:DB8:0:13::/64, Del, owner connected, previous None
Mar 1 00:25:01.967: IPv6RT0: Event: 2001:DB8:0:3::/64, Del, owner static, previous None

2-r1-show-ip-route

2-r1-show-ipv6-route

 

Next we will change the static route statements to use a next-hop address instead of an exit interface:

R1:
interface FastEthernet0/0
 no shutdown
!
no ip route 3.3.3.0 255.255.255.0 FastEthernet0/0
no ipv6 route 2001:DB8:0:3::/64 FastEthernet0/0
ip route 3.3.3.0 255.255.255.0 10.0.13.3
ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:13::3

The IPv4 and IPv6 routes are both listed in the routing table with a next-hop address only.  In order to find the outgoing interface, a recursive lookup is performed on the next-hop address:

3-r1-show-ip-route

3-r1-show-ipv6-route1

If we send traffic to 5 different addresses on the 3.3.3.0/24 subnet again, R3 only needs to send an ARP request for the first one to determine the layer-2 address for the specified next-hop, 10.0.13.3:

R1#ping 3.3.3.1
R1#ping 3.3.3.2
R1#ping 3.3.3.3
R1#ping 3.3.3.4
R1#ping 3.3.3.5

3-r1-show-arp

Likewise, if we send traffic to 5 different addresses on the 2001:db8:0:3::/64 subnet, R1 only needs to determine the L2 address for the specified next-hop, 2001:db8:0:3::3:

R1#ping 2001:db8:0:3::1
R1#ping 2001:db8:0:3::2
R1#ping 2001:db8:0:3::3
R1#ping 2001:db8:0:3::4
R1#ping 2001:db8:0:3::5

3-r1-show-neighbor

The static routes remain in the routing table as long as the next-hop can be resolved to a valid route in the routing table.  In this case, if F0/0 goes down on R1, the directly connected routes to 10.0.13.0/24 and 2001:db8:0:13::/64 are removed.  Since these are the only routes that can be used to resolve the next hop addresses, the static routes are also removed:

R1:
interface FastEthernet0/0
 shutdown

4-r1-show-ip-route2

4-r1-show-ipv6-route4

However, consider what would happen instead if RIP were being used on the 2 serial links and the fast ethernet link.  We will enable RIP and RIPng for each of these links on each router:

R1:
router rip
 network 10.0.0.0
!
ipv6 router rip test
!
interface FastEthernet0/0
 ipv6 rip test enable
!
interface Serial0/0
 ipv6 rip test enable

R2:
router rip
 network 10.0.0.0
!
ipv6 router rip test
!
interface Serial0/0
 ipv6 rip test enable
!
interface Serial0/1
 ipv6 rip test enable

R3:
router rip
 network 10.0.0.0
!
ipv6 router rip test
!
interface FastEthernet0/0
 ipv6 rip test enable
!
interface Serial0/0
 ipv6 rip test enable

Now we will shut down R1’s F0/0 again:

R1:
interface FastEthernet0/0
 shutdown

R1 deletes the routing table entries for 3.3.3.0/24 and 2001:db8:0:3::/64 like before:

R1#debug ip routing
R1#debug ipv6 routing

Mar 1 01:02:07.947: IPv6RT0: connected, Delete 2001:DB8:0:13::1/128 from table
Mar 1 01:02:07.951: IPv6RT0: static, Route add 2001:DB8:0:3::/64 [owner]
Mar 1 01:02:07.951: IPv6RT0: connected, Delete 2001:DB8:0:13::/64 from table
Mar 1 01:02:07.951: IPv6RT0: rip test, Backup call for 2001:DB8:0:13::/64
Mar 1 01:02:07.955: IPv6RT0: rip test, Route add 2001:DB8:0:13::/64 [new]
Mar 1 01:02:07.955: IPv6RT0: rip test, Add 2001:DB8:0:13::/64 to table
Mar 1 01:02:07.955: IPv6RT0: rip test, Adding next-hop FE80::3 over FastEthernet0/0 for 2001:DB8:0:13::/64, [120/2]
Mar 1 01:02:07.963: IPv6RT0: rip test, Delete 2001:DB8:0:13::/64 from table
Mar 1 01:02:07.963: IPv6RT0: Delete next-hop FE80::3/FastEthernet0/0 for 2001:DB8:0:23::/64
Mar 1 01:02:07.963: IPv6RT0: static, Delete 2001:DB8:0:3::/64 from table
Mar 1 01:02:07.971: RT: is_up: FastEthernet0/0 0 state: 6 sub state: 1 line: 1 has_route: True
Mar 1 01:02:07.971: RT: del 10.0.23.0/24 via 10.0.13.3, rip metric [120/1]
Mar 1 01:02:07.975: RT: NET-RED 10.0.23.0/24
Mar 1 01:02:07.975: RT: interface FastEthernet0/0 removed from routing table
Mar 1 01:02:07.975: RT: del 10.0.13.0/24 via 0.0.0.0, connected metric [0/0]
Mar 1 01:02:07.979: RT: delete subnet route to 10.0.13.0/24
Mar 1 01:02:07.979: RT: NET-RED 10.0.13.0/24
Mar 1 01:02:07.983: IPv6RT0: Event: 2001:DB8:0:13::1/128, Del, owner connected, previous None
Mar 1 01:02:07.983: IPv6RT0: Event: 2001:DB8:0:13::/64, Del, owner connected, previous None
Mar 1 01:02:07.983: IPv6RT0: Event: 2001:DB8:0:23::/64, Path, owner rip, previous None
Mar 1 01:02:07.987: IPv6RT0: Event: 2001:DB8:0:3::/64, Del, owner static, previous None
Mar 1 01:02:08.607: %SYS-5-CONFIG_I: Configured from console by console
Mar 1 01:02:08.979: RT: del 3.3.3.0/24 via 10.0.13.3, static metric [1/0]
Mar 1 01:02:08.979: RT: delete subnet route to 3.3.3.0/24
Mar 1 01:02:08.983: RT: NET-RED 3.3.3.0/24
Mar 1 01:02:08.983: RT: delete network route to 3.0.0.0
Mar 1 01:02:08.983: RT: NET-RED 3.0.0.0/8
Mar 1 01:02:09.943: %LINK-5-CHANGED: Interface FastEthernet0/0, changed state to administratively down
Mar 1 01:02:09.947: RT: is_up: FastEthernet0/0 0 state: 6 sub state: 1 line: 1 has_route: False
Mar 1 01:02:10.943: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/0, changed state to down
Mar 1 01:02:10.947: RT: is_up: FastEthernet0/0 0 state: 6 sub state: 1 line: 1 has_route: False

A few seconds later, R1 receives a RIPng update from R2 which includes a route to 2001:db8:0:13::/64 from R3. R1 also receives a RIP update from R2 which includes a route to 10.0.13.0/24 that was learned from R3. R1 adds these routes to it’s routing table:


Mar 1 01:02:19.919: IPv6RT0: rip test, Route add 2001:DB8:0:13::/64 [new]
Mar 1 01:02:19.919: IPv6RT0: rip test, Add 2001:DB8:0:13::/64 to table
Mar 1 01:02:19.919: IPv6RT0: rip test, Adding next-hop FE80::2 over Serial0/0 for 2001:DB8:0:13::/64, [120/3]
Mar 1 01:02:19.919: IPv6RT0: Event: 2001:DB8:0:13::/64, Add, owner rip, previous None

Mar 1 01:02:24.587: RT: SET_LAST_RDB for 10.0.13.0/24
NEW rdb: via 10.0.12.2

Mar 1 01:02:24.591: RT: add 10.0.13.0/24 via 10.0.12.2, rip metric [120/2]
Mar 1 01:02:24.591: RT: NET-RED 10.0.13.0/24

A few seconds later, R1 realizes that it now has a valid route to the next hop for each of it’s static routes and adds both routes to the routing table:

Mar 1 01:02:56.135: RT: SET_LAST_RDB for 3.3.3.0/24
NEW rdb: via 10.0.13.3

Mar 1 01:02:56.135: RT: add 3.3.3.0/24 via 10.0.13.3, static metric [1/0]
Mar 1 01:02:56.139: RT: NET-RED 3.3.3.0/24

Mar 1 01:03:00.223: IPv6RT0: static, Route add 2001:DB8:0:3::/64 [new]
Mar 1 01:03:00.223: IPv6RT0: static, Add 2001:DB8:0:3::/64 to table
Mar 1 01:03:00.223: IPv6RT0: static, Adding next-hop 2001:DB8:0:13::3 over Null for 2001:DB8:0:3::/64, [1/0]
Mar 1 01:03:00.227: IPv6RT0: Event: 2001:DB8:0:3::/64, Add, owner static, previous None

5-r1-show-ip-route

5-r1-show-ipv6-route1

R2 does not have a route to 3.3.3.0/24 or 2001:db8:0:3::/64 so traffic to these subnets from R1 will fail.  Even if R2 did have a route, it may be undesirable for these routes to be installed on R1 in the event that F0/0 on R1 goes down because traffic must traverse 2 slow serial links to reach it’s destination.  Another example of a situation that could occur is if R1 had a default route pointing out of a different interface to an ISP and F0/0 went down, the next-hop for the static route would resolve to the default route and R1 would keep the static routes in the routing table and send traffic destined for R3’s subnet out the interface connected to the ISP.

 

By specifying both an exit interface and a next-hop address, this behavior can be changed.  We will remove both static routes on R1 and add new static routes specifying both:

R1:
interface FastEthernet0/0
 no shutdown
!
no ip route 3.3.3.0 255.255.255.0 10.0.13.3
no ipv6 route 2001:DB8:0:3::/64 2001:DB8:0:13::3
ip route 3.3.3.0 255.255.255.0 FastEthernet0/0 10.0.13.3
ipv6 route 2001:DB8:0:3::/64 FastEthernet0/0 2001:DB8:0:13::3

The IPv4 and IPv6 static routes are listed in the routing table with both their outgoing interface and next-hop address:

6-r1-show-ip-route

6-r1-show-ipv6-route1

Using this method avoids the problems that we saw occur when specifying only the exit interface on a broadcast network.  It also will only keep the static routes in the routing table if the exit interface is up (which may or may not be desirable, depending on the situation).  If we shutdown F0/0 on R1 again, R1 learns the routes to 10.0.13.0/24 and 2001:db8:0:13::/64 again via RIP and RIPng.  However, R1 does not install the static routes even though their next-hop addresses resolve to known routes because F0/0 is down:

R1:
interface FastEthernet0/0
 shutdown

7-r1-show-ip-route

7-r1-show-ipv6-route

Having reachability to the next-hop address does not actually have anything to do with the static routes being installed or not when both an exit interface and an IP address are used.  We will bring F0/0 back up on R1 and then change the static routes to use a next-hop that is known out of a different interface:

R1:
interface FastEthernet0/0
 no shutdown
!
no ip route 3.3.3.0 255.255.255.0 FastEthernet0/0 10.0.13.3
no ipv6 route 2001:DB8:0:3::/64 FastEthernet0/0 2001:DB8:0:13::3
ip route 3.3.3.0 255.255.255.0 FastEthernet0/0 10.0.12.2
ipv6 route 2001:DB8:0:3::/64 FastEthernet0/0 2001:DB8:0:12::2

The IP address in the static route statements points to a directly connected network known out of S0/0.  Nevertheless, both routes are installed in the routing table and traffic matching the route will use F0/0:

8-r1-show-ip-route

8-r1-show-ipv6-route

Even if the next-hop is an address for which R1 has no matching route, the static route is still installed in the routing table:

R1:
no ip route 3.3.3.0 255.255.255.0 FastEthernet0/0 10.0.12.2
no ipv6 route 2001:DB8:0:3::/64 FastEthernet0/0 2001:DB8:0:12::2
ip route 3.3.3.0 255.255.255.0 FastEthernet0/0 5.5.5.5
ipv6 route 2001:DB8:0:3::/64 FastEthernet0/0 5555:5555:5555:5555::5

9-r1-show-ip-route

9-r1-show-ipv6-route

Traffic to these static routes will fail since R1 attempts to use ARP/NDP to perform address resolution on the invalid next-hop address out of the configured exit interface, but if the exit interface were instead a point-to-point interface, the configuration would work even though the next-hop address is incorrect.

Posted in IPv6, Static Routing | Leave a Comment »

IPv6 Default Router Preference

Posted by Andy on March 12, 2009

In my post on IPv6 Neighbor Discovery, we saw that a Cisco router acting as a host would, by default, use the first router that it learned of as it’s default router for sending traffic to off-link destinations.  The default router preference (DRP) extension allows routers to use previously unused bits in the RA message to tell hosts what preference they should use for that router.  The DRP extension was not introduced until 12.4(2)T.  We will look at what happens when one router (R1) implements the DRP extension and another router (R2) does not.  We will also look at how 3 hosts using various IOS versions react.  The topology is shown below:

ipv6-default-router-preference

First we will configure link-local addresses on each device, global addresses on R1 and R2, and configure R2 to route IPv6 unicast packets:

R1:
interface FastEthernet0/0
 ipv6 address FE80::1 link-local
 ipv6 address 2001:DB8:0:1::1/64

R2:
interface FastEthernet0/0
 ipv6 address FE80::2 link-local
 ipv6 address 2001:DB8:0:1::2/64
!
ipv6 unicast-routing

HostA:
interface FastEthernet0/0
 ipv6 address FE80::A link-local

HostB:
interface FastEthernet0/0
 ipv6 address FE80::B link-local

HostC:
interface FastEthernet0/0
 ipv6 address FE80::C link-local

Next we will configure each host to obtain an address through stateless autoconfiguration:

HostA:
interface FastEthernet0/0
 ipv6 address autoconfig

HostB:
interface FastEthernet0/0
 ipv6 address autoconfig

HostC:
interface FastEthernet0/0
 ipv6 address autoconfig

Each host autoconfigures itself an address on the 2001:db8:0:1::/64 subnet and learns R2 as the default router:

1-hosta-show-int

2-hostb-show-int1

3-hostc-show-int

Now we will enable R1 to begin sending RA messages on the link:

R1:
ipv6 unicast-routing

The hosts learn of R1 as a router, but still prefer R2 as their default router because it was learned first:

4-hosta-show-routers

5-hostb-show-routers

6-hostc-show-routers

7-hosta-show-int1

8-hostb-show-int1

9-hostc-show-int

Next we will try to change the DRP so that R1 is preferred.  R2 does not support the DRP extension so we will have to make the change on R1 by setting the router preference to high:

R1:
interface FastEthernet0/0
 ipv6 nd router-preference high

After changing the router preference on R1, R1’s RA messages look like this:

10-r1-ra-wireshark1

R2’s RA messages look like this:

11-r2-ra-wireshark

The 4th and 5th bits of the flags are used to carry the router preference.  R1 sets the bits to 01 to indicate a preference of high.  A router that does not implement DRP sets the bits to 00, which is interpreted by devices that understand DRP as a preference of medium.  A preference of low would set the bits to 10.  HostA understands the router preference bits and changes it’s default router to be R1:

12-hosta-show-routers

HostA#debug ipv6 nd
Mar 1 00:17:55.879: ICMPv6-ND: Received RA from FE80::1 on FastEthernet0/0
Mar 1 00:17:55.879: ICMPv6-ND: Selected new default router FE80::1 on FastEthernet0/0

13-hosta-show-int

HostB understands the router preference, but does not change it’s default router:

14-hostb-show-routers

15-hostb-show-int

HostC has no knowledge of the router preference bits or their meaning and also does not change it’s default router:

16-hostc-show-routers

17-hostc-show-int

Posted in IPv6 | Leave a Comment »

IPv6 General Prefixes

Posted by Andy on March 10, 2009

This post will look at how general prefixes in IPv6 work.  We will use 1 router configured with 2 different subnets X:X:X:Y::/64, where X is the 48 bit prefix assigned by the ISP and Y is the 16 bit subnet ID/Site-Level Aggregator.  We will also configure 2 hosts to use stateless autoconfiguration, 1 for each subnet:

ipv6-general-prefix-topology

First we will configure link-local addresses on each device:

R1:
interface FastEthernet0/0
 ipv6 address FE80::1 link-local
!
interface FastEthernet0/1
 ipv6 address FE80::2 link-local

HostA:
interface FastEthernet0/0
 ipv6 address FE80::A link-local

HostB:
interface FastEthernet0/0
 ipv6 address FE80::B link-local

Suppose that we’ve been given the prefix 2001:db8:aaaa::/48 from an ISP.  We will define this prefix globally as a general prefix:

R1:
ipv6 general-prefix ISP-prefix 2001:DB8:AAAA::/48

Next, we will configure global unicast addresses on R1 by using the ISP prefix that we just defined:

R1:
interface FastEthernet0/0
 ipv6 address ISP-prefix ::1:0:0:0:1/64

R1#debug ipv6 nd
*Mar 1 00:59:51.019: ICMPv6-ND: Adding prefix 2001:DB8:AAAA:1::1/64 to FastEthernet0/0
*Mar 1 00:59:51.019: ICMPv6-ND: Sending NS for 2001:DB8:AAAA:1::1 on FastEthernet0/0
*Mar 1 00:59:52.019: ICMPv6-ND: DAD: 2001:DB8:AAAA:1::1 is unique.
*Mar 1 00:59:52.019: ICMPv6-ND: Sending NA for 2001:DB8:AAAA:1::1 on FastEthernet0/0
*Mar 1 00:59:52.023: ICMPv6-ND: Address 2001:DB8:AAAA:1::1/64 is up on FastEthernet0/0

R1 prepends the general prefix to the address that was entered to obtain the full address.  We could enter anything in the first 48-bits of the interface address with the same result since the first 48-bits will be overwritten by the general prefix:

R1:
interface FastEthernet0/1
 ipv6 address ISP-prefix 2345:6789:ABCD:2::2/64

R1#debug ipv6 nd
*Mar 1 01:00:27.099: ICMPv6-ND: Adding prefix 2001:DB8:AAAA:2::2/64 to FastEthernet0/1
*Mar 1 01:00:27.099: ICMPv6-ND: Sending NS for 2001:DB8:AAAA:2::2 on FastEthernet0/1
*Mar 1 01:00:28.099: ICMPv6-ND: DAD: 2001:DB8:AAAA:2::2 is unique.
*Mar 1 01:00:28.099: ICMPv6-ND: Sending NA for 2001:DB8:AAAA:2::2 on FastEthernet0/1
*Mar 1 01:00:28.103: ICMPv6-ND: Address 2001:DB8:AAAA:2::2/64 is up on FastEthernet0/1

R1 now has the following addresses configured:

1-r1-show-int-brief

Before configuring R1 to act as a router, we will make some changes to a few default timers so that later on we will be able to see the effects of changing prefixes faster.  By default, IPv6 prefixes are advertised in RA messages with a valid lifetime of 30 days and a preferred lifetime of 7 days.  Even if the prefix is removed from RAs, hosts will continue to use addresses that have been autoconfigured with the prefix until the lifetime expires.  We will reduce the valid lifetime to 300 seconds and the preferred lifetime to 200 seconds.  We will also reduce the interval that unsolicited RAs are sent at from the default of 200 seconds to 60 seconds:

R1:
interface FastEthernet0/0
 ipv6 nd ra-interval 60
 ipv6 nd prefix default 300 200
!
interface FastEthernet0/1
 ipv6 nd ra-interval 60
 ipv6 nd prefix default 300 200

Next, we will enable unicast IPv6 routing and sending of RA messages on R1:

R1:
ipv6 unicast-routing

R1 begins sending RA messages with the configured lifetime values in the prefix option TLV:

R1#debug ipv6 nd
*Mar 1 01:24:42.007: ICMPv6-ND: Sending RA to FF02::1 on FastEthernet0/0
*Mar 1 01:24:42.007: ICMPv6-ND: MTU = 1500
*Mar 1 01:24:42.007: ICMPv6-ND: prefix = 2001:DB8:AAAA:1::/64 onlink autoconfig
*Mar 1 01:24:42.011: ICMPv6-ND: 300/200 (valid/preferred)
*Mar 1 01:24:42.011: ICMPv6-ND: Sending RA to FF02::1 on FastEthernet0/1
*Mar 1 01:24:42.011: ICMPv6-ND: MTU = 1500
*Mar 1 01:24:42.011: ICMPv6-ND: prefix = 2001:DB8:AAAA:2::/64 onlink autoconfig
*Mar 1 01:24:42.015: ICMPv6-ND: 300/200 (valid/preferred)

Next, we will configure HostA and HostB to use stateless autoconfiguration:

HostA:
interface FastEthernet0/0
 ipv6 address autoconfig

HostB:
interface FastEthernet0/0
 ipv6 address autoconfig

Each host obtains the expected address and learns the lifetime of the prefix:

2-hosta-show-int

3-hostb-show-int

Now suppose that we have changed ISPs and our new ISP gives us the prefix 2001:db8:bbbb::/48.  We will add this prefix to the general prefix that we defined on R1:

R1:
ipv6 general-prefix ISP-prefix 2001:DB8:BBBB::/48

R1 configures itself an address in the new prefix as well and begins advertising both prefixes in RAs:

4-r1-show-int-brief

After hearing the next RA, both hosts configure themselves an address in the new prefix as well:

5-hosta-show-int1

6-hostb-show-int

Next we will remove the prefix of the first ISP on R1:

R1:
no ipv6 general-prefix ISP-prefix 2001:DB8:AAAA::/48

R1#debug ipv6 nd
*Mar 1 01:51:00.083: ICMPv6-ND: Deleting prefix 2001:DB8:AAAA:1::1/64 from FastEthernet0/0
*Mar 1 01:51:00.083: ICMPv6-ND: Address 2001:DB8:AAAA:1::1/64 is down on FastEthernet0/0
*Mar 1 01:51:00.083: ICMPv6-ND: Deleting prefix 2001:DB8:AAAA:2::2/64 from FastEthernet0/1
*Mar 1 01:51:00.087: ICMPv6-ND: Address 2001:DB8:AAAA:2::2/64 is down on FastEthernet0/1

R1 removes the address and stops advertising the prefix in RAs.  After 200 seconds, the preferred lifetime for the prefix expires on the hosts and the address is marked as deprecated:

HostA#debug ipv6 nd
*Mar 1 01:54:14.927: ICMPv6-ND: Deprecating 2001:DB8:AAAA:1::A from FastEthernet0/0

HostB#debug ipv6 nd
*Mar 1 01:53:50.035: ICMPv6-ND: Deprecating 2001:DB8:AAAA:2::B from FastEthernet0/0

7-hosta-show-int

8-hostb-show-int

300 seconds after the last RA containing the old prefix was received, the valid lifetime for the prefix expires and the old address is removed:

R1#debug ipv6 nd
*Mar 1 01:55:54.927: ICMPv6-ND: Invalidating 2001:DB8:AAAA:1::A from FastEthernet0/0
*Mar 1 01:55:54.927: ICMPv6-ND: Address 2001:DB8:AAAA:1::A/64 is down on FastEthernet0/0

R2#debug ipv6 nd
*Mar 1 01:55:30.035: ICMPv6-ND: Invalidating 2001:DB8:AAAA:2::B from FastEthernet0/0
*Mar 1 01:55:30.035: ICMPv6-ND: Address 2001:DB8:AAAA:2::B/64 is down on FastEthernet0/0

9-hosta-show-int

10-hostb-show-int

 

Although this method is very easy for changing prefixes, it could result in a period of unreachability during the transition.  Let’s look at what happens in the scenario we just used when a host tries to reach a remote network during the transition.  We will start with the configuration prior to removing the ISP A prefix on R1:

R1:
ipv6 unicast-routing
ipv6 general-prefix ISP-prefix 2001:DB8:AAAA::/48
ipv6 general-prefix ISP-prefix 2001:DB8:BBBB::/48
!
interface FastEthernet0/0
 ipv6 address ISP-prefix ::1:0:0:0:1/64
 ipv6 address FE80::1 link-local
 ipv6 nd ra-interval 60
 ipv6 nd prefix default 300 200
!
interface FastEthernet0/1
 ipv6 address ISP-prefix 2345:6789:ABCD:2::2/64
 ipv6 address FE80::2 link-local
 ipv6 nd ra-interval 60
 ipv6 nd prefix default 300 200

HostA:
interface FastEthernet0/0
 ipv6 address FE80::A link-local
 ipv6 address autoconfig

HostB:
interface FastEthernet0/0
 ipv6 address FE80::B link-local
 ipv6 address autoconfig

Next we will create a loopback on R1 to simulate a remote network:

R1:
interface Loopback0
 ipv6 address 2001:DB8:0:1::1/64

Now we will initiate a continuous ping to R1’s loopback from HostA:

HostA#ping 2001:db8:0:1::1 repeat 1000000
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(continues)

Hosts (or at least Cisco routers acting as hosts) seem to prefer using the address that they autoconfigured first as the source address for reaching remote networks if multiple global addresses are configured. In this case, HostA uses the ISP A address, 2001:db8:aaaa:1::a, as the source address for traffic sent to R1’s loopback:

11-hosta-wireshark

Now we will remove the ISP A prefix from the general prefix on R1 like before:

R1:
no ipv6 general-prefix ISP-prefix 2001:DB8:AAAA::/48

The host immediately stops receiving ping replies:

HostA#............................... (continues)

Return traffic in this case is dropped at R1 because R1 no longer has a route back to the 2001:db8:aaaa:1::/64 network.  This continues until the preferred lifetime for the old prefix expires on the host and the host begins using the ISP B address to reach remote networks:

HostA#debug ipv6 nd
Mar 1 02:09:33.924: ICMPv6-ND: Deprecating 2001:DB8:AAAA:1::A from FastEthernet0/0
!!!!!!!!!!!!!!!!!!!!!!!!!!
Success rate is 98 percent (7799/7895), round-trip min/avg/max = 0/27/1852 ms

96 echo-requests timed out waiting for a reply.  With the default echo-request timeout of 2 seconds, this is roughly equal to the 200 seconds that it took for the preferred lifetime of the ISP A prefix to expire on the host.

 

Let’s look at a way that this could be avoided if we needed to maintain full reachability during the transition period.  We will start from the same point again, with the ISP B prefix just added to R1:

R1:
ipv6 unicast-routing
ipv6 general-prefix ISP-prefix 2001:DB8:AAAA::/48
ipv6 general-prefix ISP-prefix 2001:DB8:BBBB::/48
!
interface FastEthernet0/0
 ipv6 address ISP-prefix ::1:0:0:0:1/64
 ipv6 address FE80::1 link-local
 ipv6 nd ra-interval 60
 ipv6 nd prefix default 300 200
!
interface FastEthernet0/1
 ipv6 address ISP-prefix 2345:6789:ABCD:2::2/64
 ipv6 address FE80::2 link-local
 ipv6 nd ra-interval 60
 ipv6 nd prefix default 300 200

HostA:
interface FastEthernet0/0
 ipv6 address FE80::A link-local
 ipv6 address autoconfig

HostB:
interface FastEthernet0/0
 ipv6 address FE80::B link-local
 ipv6 address autoconfig

We will initiate the ping from HostA to R1’s loopback again

HostA#ping 2001:db8:0:1::1 repeat 1000000
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(continues)

Before removing the prefix on R1 this time, we will prevent it from being advertised in RAs:

R1:
interface FastEthernet0/0
 ipv6 nd prefix 2001:DB8:AAAA:1::/64 no-advertise
!
interface FastEthernet0/1
 ipv6 nd prefix 2001:DB8:AAAA:2::/64 no-advertise

R1#debug ipv6 nd
*Mar 1 02:20:51.403: ICMPv6-ND: Updating prefix 2001:DB8:AAAA:1::/64 to FastEthernet0/0
*Mar 1 02:20:51.403: ICMPv6-ND: Prefix change 0x401 -> 0x104
*Mar 1 02:20:51.407: ICMPv6-ND: Prefix Information change 0xE0 -> 0xE0
*Mar 1 02:21:16.271: ICMPv6-ND: Updating prefix 2001:DB8:AAAA:2::/64 to FastEthernet0/1
*Mar 1 02:21:16.271: ICMPv6-ND: Prefix change 0x401 -> 0x104
*Mar 1 02:21:16.271: ICMPv6-ND: Prefix Information change 0xE0 -> 0xE0

R1 stops including a TLV for the ISP A prefixes in it’s RAs.  After approximately 200 seconds, HostA’s preferred lifetime for the prefix expires and the address is deprecated:

Mar 1 02:23:46.460: ICMPv6-ND: Deprecating 2001:DB8:AAAA:1::A from FastEthernet0/0

At this point, HostA begins immediately using the address from the ISP B prefix instead of the ISP A prefix as it’s source address for traffic sent to remote destinations:

12-hosta-wireshark

The host continues receiving ping replies with no problems:

HostA#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! (continues)

Now we will remove the ISP A prefix from R1:

R1:
no ipv6 general-prefix ISP-prefix 2001:DB8:AAAA::/48

R1 removes the addresses associated with the ISP A prefix from both interfaces:

13-r1-show-int

Not a single packet is lost during the transition:

HostA#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Success rate is 100 percent (9134/9134), round-trip min/avg/max = 0/28/224 ms

Posted in IPv6 | 1 Comment »

IPv6 Neighbor Discovery

Posted by Andy on March 7, 2009

This post will look at how Neighbor Discovery works in IPv6.  The topology is shown below:

ipv6-nd-topology

First we will configure the MAC address of each router’s interface to 0000.0000.XXXX where X is the router number in order to make EUI-64 format addresses easier to work with:

R1:
interface FastEthernet0/0
 mac-address 0000.0000.1111

R2:
interface FastEthernet0/0
 mac-address 0000.0000.2222

R3:
interface FastEthernet0/0
 mac-address 0000.0000.3333

Next we will configure a global unicast address on R1:

R1:
interface FastEthernet0/0
 ipv6 address 2001:123::1/64

R1 assigns itself the configured address as well as a link-local address using the EUI-64 format:

1-r1-showint

We can see the sequence of events that takes place when the address configuration command is entered using debug ipv6 nd:


R1#debug ipv6 nd
*Mar 1 00:48:09.683: ICMPv6-ND: Adding prefix 2001:123::1/64 to FastEthernet0/0
*Mar 1 00:48:10.683: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:1111 on FastEthernet0/0
*Mar 1 00:48:11.683: ICMPv6-ND: DAD: FE80::200:FF:FE00:1111 is unique.
*Mar 1 00:48:11.683: ICMPv6-ND: Sending NA for FE80::200:FF:FE00:1111 on FastEthernet0/0
*Mar 1 00:48:11.683: ICMPv6-ND: Address FE80::200:FF:FE00:1111/10 is up on FastEthernet0/0
*Mar 1 00:48:11.691: ICMPv6-ND: Sending NS for 2001:123::1 on FastEthernet0/0
*Mar 1 00:48:12.691: ICMPv6-ND: DAD: 2001:123::1 is unique.
*Mar 1 00:48:12.691: ICMPv6-ND: Sending NA for 2001:123::1 on FastEthernet0/0
*Mar 1 00:48:12.691: ICMPv6-ND: Address 2001:123::1/64 is up on FastEthernet0/0

We will examine this process step by step in a moment when we configure R2 to act as a host on the network.  For now, we will configure R1 to act as a router on the network:

R1:
ipv6 unicast-routing

After entering this, we can see that several new lines appear at the bottom of the show ipv6 interface output:

2-r1-showint

This information relates to the sending of Router Advertisement (RA) messages by R1.  As soon as ipv6 unicast-routing is configured, R1 begins sending unsolicited RA messages approximately every 200 seconds:

R1#debug ipv6 nd
*Mar 1 00:55:55.031: ICMPv6-ND: Sending RA to FF02::1 on FastEthernet0/0
*Mar 1 00:55:55.031: ICMPv6-ND: MTU = 1500
*Mar 1 00:55:55.035: ICMPv6-ND: prefix = 2001:123::/64 onlink autoconfig
*Mar 1 00:55:55.035: ICMPv6-ND: 2592000/604800 (valid/preferred)

These RAs are sourced from R1’s link local address and sent to the all IPv6 nodes multicast group:

3-r1-wireshark-ra

The ICMPv6 Type value identifies the message as an RA.  There are several other pieces of information within the RA that could be important to hosts on the link.  The main one we are interested in right now is the first flag bit, which has not been set.  This tells hosts they should attempt to use stateless autoconfiguration to obtain their IPv6 addresses.  We can also see that 3 optional TLVs have been included in the RA message in order to tell hosts on the link about the router’s MAC address, the MTU of the link, and the global prefix used on the link:

4-r1-wireshark-ra

Next, let’s configure R2 to automatically obtain an IPv6 address through stateless autoconfiguration:

R2:
interface FastEthernet0/0
 ipv6 address autoconfig

A similar sequence of events takes place on R2 after entering the address command to what we saw earlier on R1:

 R2#debug ipv6 nd
*Mar 1 01:45:52.175: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:45:53.175: ICMPv6-ND: DAD: FE80::200:FF:FE00:2222 is unique.
*Mar 1 01:45:53.175: ICMPv6-ND: Sending NA for FE80::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:45:53.175: ICMPv6-ND: Address FE80::200:FF:FE00:2222/10 is up on FastEthernet0/0
*Mar 1 01:45:55.179: ICMPv6-ND: Sending RS on FastEthernet0/0
*Mar 1 01:45:55.199: ICMPv6-ND: Received RA from FE80::200:FF:FE00:1111 on FastEthernet0/0
*Mar 1 01:45:55.203: ICMPv6-ND: DELETE -> INCMP: FE80::200:FF:FE00:1111
*Mar 1 01:45:55.203: ICMPv6-ND: INCMP -> STALE: FE80::200:FF:FE00:1111
*Mar 1 01:45:55.207: ICMPv6-ND: Sending NS for 2001:123::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:45:55.207: ICMPv6-ND: Autoconfiguring 2001:123::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:45:56.207: ICMPv6-ND: DAD: 2001:123::200:FF:FE00:2222 is unique.
*Mar 1 01:45:56.207: ICMPv6-ND: Sending NA for 2001:123::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:45:56.211: ICMPv6-ND: Address 2001:123::200:FF:FE00:2222/64 is up on FastEthernet0/0

Let’s look at this process step by step.  After telling R2 to use autoconfiguration to obtain an address, R2 first calculates it’s EUI-64 interface ID on F0/0 from it’s MAC address and appends this to the link local prefix (FE80::/10).  R2 marks this address as tentative (shown as ‘TEN’) and sends a neighbor solicitation (NS) message to this address to verify that it isn’t a duplicate before R2 starts to use it:

6-r2-showint

*Mar 1 01:45:52.175: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0 

The NS message is sourced from an unspecified IPv6 address (::) since R2 does not have a valid IPv6 address yet and is sent to the solicited node multicast group for the tentative address (FF02::1:FF00:2222).

7-r2-wireshark-ns

Any node with an address that ended in the same 24 bits would be required to join this group and would hear the NS message.  The node would then examine the target address contained within the NS to see if the full address matched it’s own or not, and if it did would prevent R2 from using it.  Since no other nodes are using this address, R2 does not get a reply back.  After waiting 1 second without a reply, R2 determines that the address must be unique:

*Mar 1 01:45:53.175: ICMPv6-ND: DAD: FE80::200:FF:FE00:2222 is unique.

At the same time R2 begins using the address and removes the tentative marker from it.  R2 also sends an unsolicited neighbor advertisement (NA) to advertise it’s new link-local address:

*Mar 1 01:45:53.175: ICMPv6-ND: Sending NA for FE80::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:45:53.175: ICMPv6-ND: Address FE80::200:FF:FE00:2222/10 is up on FastEthernet0/0
 

8-r2-showint

 9-r2-wireshark-na1

The source address is set to R2’s link local address and the destination address is the all IPv6 nodes multicast address.  The target address is set to R2’s link local so other nodes know which address the advertisement is for, and the NA message includes an option TLV to specify R2’s MAC address.  The override flag has also been set, telling receivers that this information should override the information in their neighbor cache for this entry.

After a couple seconds, R2 sends a router solicitation (RS) to request that any routers on the link send an RA:

*Mar 1 01:45:55.179: ICMPv6-ND: Sending RS on FastEthernet0/0

R2 uses it’s link-local address as the source and the all routers IPv6 multicast address as the destination.  R2 also includes it’s MAC address as an option TLV:

10-r2-wireshark-rs

R1 receives the RS and sends a solicited RA in response rather than waiting up to 200 seconds for it’s next unsolicited RA.  Some sources say that this is unicast to the IPv6 address of the node that sent the RS, but my tests showed that the destination address (FF02::1) and every other part of the packet was identical to an unsolicted RA.  R2 receives the RA from R1 a few milliseconds after sending it’s RS:

*Mar 1 01:45:55.199: ICMPv6-ND: Received RA from FE80::200:FF:FE00:1111 on FastEthernet0/0

The next two debug messages relate to the neighbor cache, which we will ignore for now.  R2 learns R1’s link-local address and adds it as a default router.  R2 also learns the link prefix from the received RA and prepends it to it’s EUI-64 interface ID.  Just like with the link-local address, R2 marks the address as tentative and sends an NS as part of the Duplicate Address Detection procedure:

11-r2-showint
 
*Mar 1 01:45:55.207: ICMPv6-ND: Sending NS for 2001:123::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:45:55.207: ICMPv6-ND: Autoconfiguring 2001:123::200:FF:FE00:2222 on FastEthernet0/0

The NS packet is identical to the one shown earlier, other than the target address now being set to R2’s tentative global unicast address instead of the link-local address.  When no reply for the address comes back after 1 second, R2 determines that this address is also unique:

*Mar 1 01:45:56.207: ICMPv6-ND: DAD: 2001:123::200:FF:FE00:2222 is unique.

R2 then sends an unsolicited NA to advertise it’s new address.  The NA is identical to the one that R2 sent for it’s link-local address earlier other than the source IPv6 address and target address in the ICMPv6 option being set to R2’s global unicast address instead of the link-local address:

*Mar 1 01:45:56.207: ICMPv6-ND: Sending NA for 2001:123::200:FF:FE00:2222 on FastEthernet0/0

Finally, R2 is able to remove the tentative marking on the address:

*Mar 1 01:45:56.211: ICMPv6-ND: Address 2001:123::200:FF:FE00:2222/64 is up on FastEthernet0/0

12-r2-showint

If multiple prefixes are configured on the link, R1 includes an additional TLV in it’s RA messages for each prefix:

R1:
interface FastEthernet0/0
 ipv6 address 3001:123::1/64

R1#debug ipv6 nd
*Mar 1 01:31:19.691: ICMPv6-ND: Sending RA to FF02::1 on FastEthernet0/0
*Mar 1 01:31:19.691: ICMPv6-ND: MTU = 1500
*Mar 1 01:31:19.691: ICMPv6-ND: prefix = 2001:123::/64 onlink autoconfig
*Mar 1 01:31:19.691: ICMPv6-ND: 2592000/604800 (valid/preferred)
*Mar 1 01:31:19.695: ICMPv6-ND: prefix = 3001:123::/64 onlink autoconfig
*Mar 1 01:31:19.695: ICMPv6-ND: 2592000/604800 (valid/preferred)

R2 goes through the same process detailed above for the new prefix and configures itself a global address using that prefix as well:

13-r2-showint

If another node on the link attempts to use the same IPv6 address, Duplicate Address Detection prevents this from happening.  Before testing this out, first we will get rid of the additional prefix that we created:

R1:
interface FastEthernet0/0
 no ipv6 address 3001:123::1/64

R2:
interface FastEthernet0/0
 no ipv6 address autoconfig

A few seconds later…

R2:
interface FastEthernet0/0
 ipv6 address autoconfig

Next we will configure R3 to use the same MAC address as R2 and to obtain an IPv6 address through stateless autoconfiguration:

R3:
interface FastEthernet0/0
 mac-address 0000.0000.2222
 ipv6 address autoconfig

R3#debug ipv6 nd
*Mar 1 01:48:21.775: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 01:48:21.907: ICMPv6-ND: Received NA for FE80::200:FF:FE00:2222 on FastEthernet0/0 from FE80::200:FF:FE00:2222
*Mar 1 01:48:21.915: ICMPv6-ND: DAD: duplicate link-local FE80::200:FF:FE00:2222 on FastEthernet0/0,interface stalled
*Mar 1 01:48:21.915: %IPV6-4-DUPLICATE: Duplicate address FE80::200:FF:FE00:2222 on FastEthernet0/0

 
R3 follows the same process shown earlier, calculating it’s EUI-64 interface ID and appending the interface ID to the link-local prefix.  R3 then sends a NS for the tentative address that it came up with to the solicited-node multicast group.  Since R2 has joined this group, it receives the NS and finds it’s own address as the target.  R2 sends an NA immediately to the all nodes multicast address.  R3 receives the NA from R2 before it’s 1 second DAD timer expires, and R3 realizes the address is a duplicate.  R3 marks the address as a duplicate and does not begin using it:

14-r3-showint

The MAC address would have to be changed on R3 or a different IPv6 address would have to be manually configured.  Notice also that R3 does not even attempt to assign itself a global address through autoconfiguration until it has a non-duplicate link-local address.  If we change the link-local address used on R3 manually and continue to use stateless autoconfiguration, this not only fixes the duplicate link-local address but also results in R3 assigning itself a non-duplicate global address:

R3:
interface FastEthernet0/0
 ipv6 address FE80::3 link-local

*Mar 1 02:10:27.483: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
*Mar 1 02:10:28.483: ICMPv6-ND: DAD: FE80::3 is unique.
*Mar 1 02:10:28.483: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0
*Mar 1 02:10:28.483: ICMPv6-ND: Address FE80::3/10 is up on FastEthernet0/0
*Mar 1 02:10:30.483: ICMPv6-ND: Sending RS on FastEthernet0/0
*Mar 1 02:10:30.523: ICMPv6-ND: Received RA from FE80::200:FF:FE00:1111 on FastEthernet0/0
*Mar 1 02:10:30.523: ICMPv6-ND: DELETE -> INCMP: FE80::200:FF:FE00:1111
*Mar 1 02:10:30.527: ICMPv6-ND: INCMP -> STALE: FE80::200:FF:FE00:1111
*Mar 1 02:10:30.527: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0
*Mar 1 02:10:30.531: ICMPv6-ND: Autoconfiguring 2001:123::3 on FastEthernet0/0
*Mar 1 02:10:31.527: ICMPv6-ND: DAD: 2001:123::3 is unique.
*Mar 1 02:10:31.527: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0
*Mar 1 02:10:31.531: ICMPv6-ND: Address 2001:123::3/64 is up on FastEthernet0/0

This shows that the interface ID for the link-local address is derived from the MAC address unless manually configured.  The interface ID for a global address, however, is derived from the interface ID used for the link-local address – so if the link-local address has been manually configured, global addresses will use the same interface ID rather than applying the MAC to EUI-64 conversion to obtain an interface ID.  This applies to interfaces that are manually configured to use EUI-64 as well:

R3:
interface FastEthernet0/0
 no ipv6 address

A few seconds later…

R3:
interface FastEthernet0/0
 ipv6 address 2001:123::/64 eui-64

*Mar 1 02:26:49.463: ICMPv6-ND: Adding prefix 2001:123::200:FF:FE00:2222/64 to FastEthernet0/0
*Mar 1 02:26:50.463: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0
*Mar 1 02:26:50.515: ICMPv6-ND: Received NA for FE80::200:FF:FE00:2222 on FastEthernet0/0 from FE80::200:FF:FE00:2222
*Mar 1 02:26:50.523: ICMPv6-ND: DAD: duplicate link-local FE80::200:FF:FE00:2222 on FastEthernet0/0,interface stalled
*Mar 1 02:26:50.523: %IPV6-4-DUPLICATE: Duplicate address FE80::200:FF:FE00:2222 on FastEthernet0/0

15-r3-showint

R3:
interface FastEthernet0/0
 ipv6 address FE80::3 link-local

*Mar 1 02:30:37.027: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
*Mar 1 02:30:38.027: ICMPv6-ND: DAD: FE80::3 is unique.
*Mar 1 02:30:38.027: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0
*Mar 1 02:30:38.027: ICMPv6-ND: Address FE80::3/10 is up on FastEthernet0/0
*Mar 1 02:30:38.031: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0
*Mar 1 02:30:39.031: ICMPv6-ND: DAD: 2001:123::3 is unique.
*Mar 1 02:30:39.031: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0
*Mar 1 02:30:39.031: ICMPv6-ND: Address 2001:123::3/64 is up on FastEthernet0/0

16-r3-showint

Next, we will add a second router to the link.  R1 and R2 will be configured as routers:

R1:
ipv6 unicast-routing
!
interface FastEthernet0/0
 mac-address 0000.0000.1111
 ipv6 address 2001:123::1/64
 ipv6 address FE80::1 link-local

R2:
ipv6 unicast-routing
!
interface FastEthernet0/0
 mac-address 0000.0000.2222
 ipv6 address 2001:123::2/64
 ipv6 address FE80::2 link-local

R3 will be configured to use stateless autoconfiguration:

R3:
interface FastEthernet0/0
 mac-address 0000.0000.3333
 ipv6 address FE80::3 link-local
 ipv6 address autoconfig

When R3 sends out an RS, it receives an RA from both R1 and R2. In this case, the RA from R2 arrives a few milliseconds before the RA from R1:

R3#debug ipv6 nd
*Mar 1 02:45:26.139: ICMPv6-ND: Received RA from FE80::2 on FastEthernet0/0
*Mar 1 02:45:26.147: ICMPv6-ND: Received RA from FE80::1 on FastEthernet0/0

What a host does when there are multiple routers is implementation specific; for a Cisco router acting as a host, it appears that only the first RA received is used as the default router:

17-r3-showint

 

Next we will look at how Neighbor Unreachability Detection works.  The Layer-2 address for IPv6 nodes is stored in the neighbor cache, similar to the ARP cache of IPv4.  The current neighbor cache of R3 is shown below:

18-r3-neighbors1

R3 has entries for R1 and R2’s link-local addresses, both in a STALE state.  This means that these addresses were reachable previously, but the Reachable Time has expired since the last confirmation of their reachability.  Let’s try to ping R1’s link-local address on R3:

19-r3-ping

R3#debug ipv6 icmp
R3#debug ipv6 nd

Mar 1 03:47:37.073: ICMPv6: Sending echo request to FE80::1
Mar 1 03:47:37.073: ICMPv6-ND: STALE -> DELAY: FE80::1
Mar 1 03:47:37.117: ICMPv6: Received echo reply from FE80::1
Mar 1 03:47:42.073: ICMPv6-ND: DELAY -> PROBE: FE80::1
Mar 1 03:47:42.073: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0
Mar 1 03:47:42.169: ICMPv6: Received ICMPv6 packet from FE80::1, type 135
Mar 1 03:47:42.173: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1
Mar 1 03:47:42.173: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0
Mar 1 03:47:42.173: ICMPv6: Received ICMPv6 packet from FE80::1, type 136
Mar 1 03:47:42.173: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1
Mar 1 03:47:42.177: ICMPv6-ND: PROBE -> REACH: FE80::1
Mar 1 03:48:12.179: ICMPv6-ND: REACH -> STALE: FE80::1

R1#debug ipv6 icmp
R1#debug ipv6 nd

Mar 1 03:47:37.095: ICMPv6: Received echo request from FE80::3
Mar 1 03:47:37.095: ICMPv6: Sending echo reply to FE80::3
Mar 1 03:47:37.095: ICMPv6-ND: STALE -> DELAY: FE80::3
Mar 1 03:47:42.095: ICMPv6-ND: DELAY -> PROBE: FE80::3
Mar 1 03:47:42.095: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
Mar 1 03:47:42.115: ICMPv6: Received ICMPv6 packet from FE80::3, type 135
Mar 1 03:47:42.119: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3
Mar 1 03:47:42.119: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0
Mar 1 03:47:42.215: ICMPv6: Received ICMPv6 packet from FE80::3, type 136
Mar 1 03:47:42.215: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3
Mar 1 03:47:42.215: ICMPv6-ND: PROBE -> REACH: FE80::3
Mar 1 03:48:12.215: ICMPv6-ND: REACH -> STALE: FE80::3

R3 sends an echo request to R1 immediately, using the Layer-2 address from the STALE entry in the neighbor cache.  R3 also changes the state of the entry from STALE to DELAY, meaning at least 1 packet has been sent to this address and R3 is now awaiting confirmation of reachability:

R3:
Mar 1 03:47:37.073: ICMPv6: Sending echo request to FE80::1
Mar 1 03:47:37.073: ICMPv6-ND: STALE -> DELAY: FE80::1

R1 receives the echo request a few milliseconds later and sends an echo reply back, also using the STALE entry that it has in the neighbor cache for R3.  Sending an echo reply causes the state to change to DELAY since R1 is now awaiting confirmation of reachability:

R1:
Mar 1 03:47:37.095: ICMPv6: Received echo request from FE80::3
Mar 1 03:47:37.095: ICMPv6: Sending echo reply to FE80::3
Mar 1 03:47:37.095: ICMPv6-ND: STALE -> DELAY: FE80::3

R3 receives the echo reply from R1 a few milliseconds later:

R3:
Mar 1 03:47:37.117: ICMPv6: Received echo reply from FE80::1

However, this does not count as a confirmation of reachablity and the cache entry remains in the DELAY state.  The only ways that reachability can be confirmed are:

1.  Hints from an upper-layer protocol show that the connection is making forward progress – for example increasing, non-duplicate TCP acknowledgements are received.

2.  A solicited NA is received in response to an NS.  The NA must be solicited because an unsolicited NA would only confirm 1-way reachability.

Since reachability has not been confirmed, R3 stays in the DELAY state waiting for reachability confirmation for a total of 5 seconds.  After 5 seconds, R3 changes to the PROBE state and actively tries to confirm reachability by sending an NS to the address in question:

R3:
Mar 1 03:47:42.073: ICMPv6-ND: DELAY -> PROBE: FE80::1
Mar 1 03:47:42.073: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0

R1’s 5 second timer expires just a few milliseconds later and it also changes the entry to the PROBE state and sends an NS to R1’s address:

R1:
Mar 1 03:47:42.095: ICMPv6-ND: DELAY -> PROBE: FE80::3
Mar 1 03:47:42.095: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

R1 receives R3’s NS and sends an NA with the solicited flag set:

R1:
Mar 1 03:47:42.115: ICMPv6: Received ICMPv6 packet from FE80::3, type 135
Mar 1 03:47:42.119: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3
Mar 1 03:47:42.119: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0

R3 also receives R1’s NS and sends an NA with the solicited flag set:

R3:
Mar 1 03:47:42.169: ICMPv6: Received ICMPv6 packet from FE80::1, type 135
Mar 1 03:47:42.173: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1
Mar 1 03:47:42.173: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0

R3 receives the solicited NA from R1.  This confirms 2-way reachability, so R3 changes the state of the entry to REACH:

R3:
Mar 1 03:47:42.173: ICMPv6: Received ICMPv6 packet from FE80::1, type 136
Mar 1 03:47:42.173: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1
Mar 1 03:47:42.177: ICMPv6-ND: PROBE -> REACH: FE80::1

Likewise, R1 receives the solicited NA from R3 and now has confirmed 2-way reachability, so R1 changes the state of the entry to REACH:

R1:
Mar 1 03:47:42.215: ICMPv6: Received ICMPv6 packet from FE80::3, type 136
Mar 1 03:47:42.215: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3
Mar 1 03:47:42.215: ICMPv6-ND: PROBE -> REACH: FE80::3

After the Reachable Time expires (30 seconds by default) without further 2-way reachability confirmation, the state of the entry changes back to STALE:

R3:
Mar 1 03:48:12.179: ICMPv6-ND: REACH -> STALE: FE80::1

R1:
Mar 1 03:48:12.215: ICMPv6-ND: REACH -> STALE: FE80::3

For traffic that does not offer a positive confirmation of 2-way reachability, this results in each device sending an NS and solicited NA to each other approximately every 35 seconds (Reachable Time + Delay time):

R3#ping fe80::1 repeat 1000000

R1#debug ipv6 nd
Mar 1 04:36:48.634: ICMPv6-ND: STALE -> DELAY: FE80::3
Mar 1 04:36:53.622: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3
Mar 1 04:36:53.622: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0
Mar 1 04:36:53.634: ICMPv6-ND: DELAY -> PROBE: FE80::3
Mar 1 04:36:53.634: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
Mar 1 04:36:53.710: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3
Mar 1 04:36:53.710: ICMPv6-ND: PROBE -> REACH: FE80::3
Mar 1 04:37:23.710: ICMPv6-ND: REACH -> STALE: FE80::3
Mar 1 04:37:23.714: ICMPv6-ND: STALE -> DELAY: FE80::3
Mar 1 04:37:28.666: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3
Mar 1 04:37:28.666: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0
Mar 1 04:37:28.710: ICMPv6-ND: DELAY -> PROBE: FE80::3
Mar 1 04:37:28.710: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
Mar 1 04:37:28.738: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3
Mar 1 04:37:28.742: ICMPv6-ND: PROBE -> REACH: FE80::3
Mar 1 04:37:58.742: ICMPv6-ND: REACH -> STALE: FE80::3
Mar 1 04:37:58.762: ICMPv6-ND: STALE -> DELAY: FE80::3
Mar 1 04:38:03.754: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3
Mar 1 04:38:03.758: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0
Mar 1 04:38:03.762: ICMPv6-ND: DELAY -> PROBE: FE80::3
Mar 1 04:38:03.762: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
Mar 1 04:38:03.818: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3
Mar 1 04:38:03.818: ICMPv6-ND: PROBE -> REACH: FE80::3

The Reachable Time can be advertised in RAs so that hosts know what value to use.  However, Cisco routers that are acting as hosts do not seem to learn the timer from their default router.  R1 and R2 begin advertising a 10 second Reachable Time in RAs, but R3 continues using 30 seconds:

R1:
interface FastEthernet0/0
 ipv6 nd reachable-time 10000

R2:
interface FastEthernet0/0
 ipv6 nd reachable-time 10000

20-r1-showint

21-r2-showint

22-r3-showint

R3#ping fe80::1 repeat 1

R1:
Mar 1 05:04:55.730: ICMPv6-ND: PROBE -> REACH: FE80::3
Mar 1 05:05:05.730: ICMPv6-ND: REACH -> STALE: FE80::3

R3:
Mar 1 05:04:55.646: ICMPv6-ND: PROBE -> REACH: FE80::1
Mar 1 05:05:25.647: ICMPv6-ND: REACH -> STALE: FE80::1

The only way to get R3 to use a non-default Reachable Time is to manually configure it in the same way as R1 and R2.

 

Next, let’s try to ping R1’s global unicast address from R3.  R1 and R3 both start with STALE entries for the link-local addresses of the other 2 devices in their neighbor cache:

23-r1-neighbors

24-r3-neighbors

25-r3-ping

The following sequence of events takes place after sending the echo request from R3:

R3#debug ipv6 nd
Mar 1 06:01:00.486: ICMPv6-ND: DELETE -> INCMP: 2001:123::1
Mar 1 06:01:00.486: ICMPv6-ND: Sending NS for 2001:123::1 on FastEthernet0/0
Mar 1 06:01:00.642: ICMPv6-ND: Received NA for 2001:123::1 on FastEthernet0/0 from 2001:123::1
Mar 1 06:01:00.642: ICMPv6-ND: INCMP -> REACH: 2001:123::1
Mar 1 06:01:05.594: ICMPv6-ND: Received NS for 2001:123::3 on FastEthernet0/0 from FE80::1
Mar 1 06:01:05.594: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0
Mar 1 06:01:05.594: ICMPv6-ND: STALE -> DELAY: FE80::1
Mar 1 06:01:10.595: ICMPv6-ND: DELAY -> PROBE: FE80::1
Mar 1 06:01:10.595: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0
Mar 1 06:01:10.639: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1
Mar 1 06:01:10.639: ICMPv6-ND: PROBE -> REACH: FE80::1
Mar 1 06:01:15.615: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1
Mar 1 06:01:15.615: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0
Mar 1 06:01:30.716: ICMPv6-ND: REACH -> STALE: 2001:123::1
Mar 1 06:01:40.641: ICMPv6-ND: REACH -> STALE: FE80::1

R1#debug ipv6 nd
Mar 1 06:01:00.578: ICMPv6-ND: Received NS for 2001:123::1 on FastEthernet0/0 from 2001:123::3
Mar 1 06:01:00.578: ICMPv6-ND: DELETE -> INCMP: 2001:123::3
Mar 1 06:01:00.578: ICMPv6-ND: INCMP -> STALE: 2001:123::3
Mar 1 06:01:00.578: ICMPv6-ND: Sending NA for 2001:123::1 on FastEthernet0/0
Mar 1 06:01:00.582: ICMPv6-ND: STALE -> DELAY: 2001:123::3
Mar 1 06:01:05.582: ICMPv6-ND: DELAY -> PROBE: 2001:123::3
Mar 1 06:01:05.582: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0
Mar 1 06:01:05.626: ICMPv6-ND: Received NA for 2001:123::3 on FastEthernet0/0 from 2001:123::3
Mar 1 06:01:05.626: ICMPv6-ND: PROBE -> REACH: 2001:123::3
Mar 1 06:01:10.610: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3
Mar 1 06:01:10.610: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0
Mar 1 06:01:10.610: ICMPv6-ND: STALE -> DELAY: FE80::3
Mar 1 06:01:15.610: ICMPv6-ND: DELAY -> PROBE: FE80::3
Mar 1 06:01:15.610: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
Mar 1 06:01:15.754: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3
Mar 1 06:01:15.754: ICMPv6-ND: PROBE -> REACH: FE80::3
Mar 1 06:01:35.626: ICMPv6-ND: REACH -> STALE: 2001:123::3
Mar 1 06:01:45.754: ICMPv6-ND: REACH -> STALE: FE80::3

There are a few differences here compared to when we pinged R1’s link-local address.  R3 does not know what Layer-2 address to use yet for 2001:123::1.  R3 creates an incomplete (INCMP) entry for the address in the neighbor cache and sends an NS for the address.  When R1 receives the NS, it creates an entry for R3’s global address and answers with a solicited NA.  R3 receives the solicited NA which confirms reachability and tells R3 the Layer-2 address to use.  R3 can now send the echo request to R1.  R1 does not receive confirmation of 2-way reachability to R3’s global unicast address however, so 5 seconds after sending the NA to R3, R1 sends an NS for R3’s global unicast address sourced from R1’s link-local address which starts a chain reaction.  R3 replies to the NS with a solicited NA, which confirms reachability on R1 to R3’s global unicast address and causes the entry on R3 for R1’s link-local to change to the DELAY state.  After another 5 seconds, R3 sends an NS sourced from it’s link-local address for R1’s link-local address since it has not received reachability confirmation yet.  R1 replies with a solicited NA, confirming reachability for R3 to R1’s link-local address and causing R1 to change the state of R3’s link-local entry to DELAY.  After 5 seconds, R1 sends an NS for R3’s link-local and R3 answers with a solicited NA to confirm reachability.  In total, 4 NS and 4 solicited NA were sent between the 2 devices:

26-r3-wireshark

 

Yet another situation occurs when the devices already have an entry for the address in their neighbor cache.  In this case, R1 and R3 both have an entry for the other’s global unicast address since it was just pinged:

27-r1-neighbors

28-r3-neighbors

29-r3-ping

This time, the following sequence of events occurs:

R3#debug ipv6 nd
Mar 1 06:38:39.142: ICMPv6-ND: STALE -> DELAY: 2001:123::1
Mar 1 06:38:39.234: ICMPv6-ND: ULP indication 2001:123::1
Mar 1 06:38:39.234: ICMPv6-ND: DELAY -> REACH: 2001:123::1
Mar 1 06:38:44.146: ICMPv6-ND: Received NS for 2001:123::3 on FastEthernet0/0 from FE80::1
Mar 1 06:38:44.146: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0
Mar 1 06:38:44.146: ICMPv6-ND: STALE -> DELAY: FE80::1
Mar 1 06:38:49.146: ICMPv6-ND: DELAY -> PROBE: FE80::1
Mar 1 06:38:49.146: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0
Mar 1 06:38:49.182: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1
Mar 1 06:38:49.182: ICMPv6-ND: PROBE -> REACH: FE80::1
Mar 1 06:38:54.206: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1
Mar 1 06:38:54.206: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0
Mar 1 06:39:09.234: ICMPv6-ND: REACH -> STALE: 2001:123::1
Mar 1 06:39:19.182: ICMPv6-ND: REACH -> STALE: FE80::1

R1#debug ipv6 nd
Mar 1 06:38:39.130: ICMPv6-ND: STALE -> DELAY: 2001:123::3
Mar 1 06:38:44.130: ICMPv6-ND: DELAY -> PROBE: 2001:123::3
Mar 1 06:38:44.130: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0
Mar 1 06:38:44.166: ICMPv6-ND: Received NA for 2001:123::3 on FastEthernet0/0 from 2001:123::3
Mar 1 06:38:44.166: ICMPv6-ND: PROBE -> REACH: 2001:123::3
Mar 1 06:38:49.166: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3
Mar 1 06:38:49.166: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0
Mar 1 06:38:49.166: ICMPv6-ND: STALE -> DELAY: FE80::3
Mar 1 06:38:54.166: ICMPv6-ND: DELAY -> PROBE: FE80::3
Mar 1 06:38:54.166: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0
Mar 1 06:38:54.198: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3
Mar 1 06:38:54.198: ICMPv6-ND: PROBE -> REACH: FE80::3
Mar 1 06:39:14.166: ICMPv6-ND: REACH -> STALE: 2001:123::3
Mar 1 06:39:24.198: ICMPv6-ND: REACH -> STALE: FE80::3

This time, R3 does not have to send an NS before it can send the echo request because it already has a STALE entry for R1’s global address.  The most interesting difference, however, is in the 2nd and 3rd debug messages shown on R3:

R3:
Mar 1 06:38:39.234: ICMPv6-ND: ULP indication 2001:123::1
Mar 1 06:38:39.234: ICMPv6-ND: DELAY -> REACH: 2001:123::1

When R3 receives an echo reply from R1, it considers this to be confirmation of reachability (shown as ‘ULP indication’) and immediately changes the entry to the REACH state.  For whatever reason, an echo reply to an echo request from a global unicast address counts as upper-layer protocol confirmation, but an echo reply to an echo request from a link-local address does not (as we saw earlier).  In total 3 NS and 3 solicited NA are sent between the 2 devices:

30-r3-wireshark

 

Next let’s look at an example of redirects being used as part of NDP in IPv6.  R3 is still using R2 as it’s default router, so we will create a loopback on R1 and advertise it to R2 with OSPFv3:

R1:
ipv6 router ospf 1
 router-id 1.1.1.1
!
interface Loopback0
 ipv6 address 2001:1::1/64
 ipv6 ospf network point-to-point
 ipv6 ospf 1 area 0
!
interface FastEthernet0/0
 ipv6 ospf 1 area 0

R2:
ipv6 router ospf 1
 router-id 2.2.2.2
!
interface FastEthernet0/0
 ipv6 ospf 1 area 0

R2 now has a route to R1’s loopback using R1’s link-local as the next hop:

31-r2-showroute

On R3, we attempt to ping R1’s loopback:

32-r3-ping

R3 sends the packet to it’s default router, R2.  R2 sends the packet to R1 and also sends a redirect back to R3 telling it to use R1 in the future for that address:

R2#debug ipv6 icmp
Mar  1 07:00:27.290: ICMPv6: Sending REDIRECT for 2001:1::1, target FE80::1 on FastEthernet0/0

Several NS and solicited NA are also sent between the 3 devices to confirm reachability:

33-r3-wireshark

According to RFC 2461 on IPv6 Neighbor Discovery:

A host receiving a valid redirect SHOULD update its Destination Cache accordingly so that subsequent traffic goes to the specified target. If no Destination Cache entry exists for the destination, an implementation SHOULD create such an entry. 

However, a Cisco router acting as a host apparently does not follow this recommendation, as R3 continues trying to send all traffic for R1’s loopback to R2 and R2 continues sending redirects.

Posted in IPv6 | Leave a Comment »