#!/usr/local/bin/expect -f source ../gated.tcl # pim.tcl defines MIB variables and redefines some function from gated.tcl source pim.tcl # This script tests for correct PIMv2 flood and prune functionality among # GateD routers. # # This script must be run as root on the control machine and ssh must # be set up all all machines to allow root to connect via ssh without # a password (i.e. a .shosts file must be set up). # # Tests: # - Data flood, (S,G) state creation, and data forwarding # - Negative cache state-triggered prune transmission and PIM-Prune receipt # - Delayed prune handling on LAN links (test P-to-P links separately) # - IGMP and Graft receipt-triggered Graft transmission # - Graft handling # - (S,G) state timeout # # # N1 N2 N3 # Host ----+--- Router -------- Router ---+---- Host # S | A1 A A2 | B1 B B2 | R # | | | # | | | # Control C1+ | | # Host C2----------------+ | # C3-------------------------------+ # Note that C should not forward packets (links C2 and C3 are optional if # script is run on router N1 or host S.) # # # This section needs to be configured with the machine information # # username for remote actions not requiring root access (e.g. ping) set username kurtw # OSPF area set ospfarea 128.223.163.0 # networks set N1 128.223.163/24 set N2 128.223.91/24 set N3 128.223.226/24 # canejo (control host) set C 128.223.163.129 set C1 128.223.163.129 set C2 128.223.91.129 set C3 128.223.226.129 # peabody (sending host) set S 128.223.163.125 set S1 128.223.163.125 # makaha (receiving host) set R 128.223.226.128 set R1 128.223.226.128 # seaside set A 128.223.163.126 set A1 128.223.163.126 set A2 128.223.91.126 # rincon set B 128.223.91.127 set B1 128.223.91.127 set B2 128.223.226.127 set Aconfig /root/gated-confs/pimdm_flood_prune.conf set Agated /home/kurtw/gated-multi/src/gated/gated set Bconfig /root/gated-confs/pimdm_flood_prune.conf set Bgated /home/kurtw/gated-multi/src/gated/gated set G 225.1.2.3 # # Shouldn't need to change anything below here # # Delay for igmp-leave triggered prune to propogate upstream # 3 seconds x number_hops + C set leavewait 8 set igmp ${experimental}.59.1.1 set ipMRoute ${experimental}.60.1.1 set igmpInterfaceQuerier ${igmp}.1.1.5 set igmpInterfaceQueryInterval ${igmp}.1.1.2 set igmpInterfaceQueryMaxResponseTime ${igmp}.1.1.6 set igmpInterfaceRobustness ${igmp}.1.1.14 set igmpCacheLastReporter ${igmp}.2.1.4 set ipMRouteEntry ${ipMRoute}.2.1 set ipMRouteNextHopEntry ${ipMRoute}.3.1 set ipMRouteInterfaceEntry ${ipMRoute}.4.1 set ipMRouteBoundaryEntry ${ipMRoute}.5.1 set ipMRouteUpstreamNeighbor ${ipMRoute}.2.1.4 set ipMRouteNextHopState ${ipMRoute}.3.1.6 trap shutdown SIGINT proc shutdown {} { cleanup exit } proc cleanup {} { global A B A1 B1 puts "-----------------------------------------------------------------------" puts "Cleaning up..." stop_gated $B stop_gated $A puts "ok" } # 0) Clean up puts "-----------------------------------------------------------------------" puts "Step 0: Clean up" cleanup # 1) Start gated on routers A and B puts "-----------------------------------------------------------------------" puts "Step 1a: Start gated on router $A" save_file $A $Aconfig "\ traceoptions \"/var/log/gated.test.log\" replace all;\n\ interfaces { interface all passive; };\n\ router-id $A;\n\ icmp {};\n\ igmp yes {};\n\ ospf yes {\n\ defaults {\n\ ribs unicast multicast;\n\ };\n\ area $ospfarea {\n\ authtype none;\n\ interface all {\n\ priority 5;\n\ enable;\n\ };\n\ };\n\ };\n\ pim yes {\n\ dense \"dm0\" { interface all enable; };\n\ };\n\ " if { [start_gated $A $Agated $Aconfig] == 0 } { puts "failed" exit } else { puts "ok" } puts "-----------------------------------------------------------------------" puts "Step 1b: Start gated on router $B and wait 60 seconds" save_file $B $Bconfig "\ traceoptions \"/var/log/gated.test.log\" replace all;\n\ interfaces { interface all passive; };\n\ router-id $B;\n\ icmp {};\n\ igmp yes {};\n\ ospf yes {\n\ defaults {\n\ ribs unicast multicast;\n\ };\n\ area $ospfarea {\n\ authtype none;\n\ interface all {\n\ priority 5;\n\ enable;\n\ };\n\ };\n\ };\n\ pim yes {\n\ dense \"dm0\" { interface all enable; };\n\ };\n\ " if { [start_gated $B $Bgated $Bconfig] == 0 } { puts "failed" exit } else { puts "ok" } # wait for unicast routes to stablize sleep 60 set AifIndex1 [IP2IntfIndex $A $A1] set AifIndex2 [IP2IntfIndex $A $A2] set BifIndex2 [IP2IntfIndex $B $B1] set BifIndex3 [IP2IntfIndex $B $B2] # 2) Verify that A doesn't consider N2 a leaf network for the N1 route. puts "-----------------------------------------------------------------------" puts "Step 2: Verify that $A doesn't consider $N2 a leaf network for the $N1 route." # Check that A has neighbors on N2 besides its own interface, specifically, B1. set ret [snmpget $A ${pimNeighborEntry}.2.${B1}] if { $ret == $AifIndex2 } { puts "ok" } else { puts "failed" exit } # 3) Verify that B considers N3 a leaf network. puts "-----------------------------------------------------------------------" puts "Step 3: Verify that $B considers $N3 a leaf network." # Check that B has NO neighbors on N3 except its own interface, B2. set ret [snmpget $B ${pimNeighborEntry}.2.${R1}] if { $ret == "no_such_variable" } { puts "ok for $R1" } else { puts "failed" exit } # 4) Ping group G from host S, and wait 1 second puts "-----------------------------------------------------------------------" puts -nonewline "Step 4: Ping group $G from host $S on interface $S1 and wait 5 seconds..." set ret [send_ping $S $username $S1 $G] sleep 5 # 5) Verify that both A and B have (S,G) forwarding state with null oif-list # 5a) Verify that A has (S,G) forwarding state with null oif-list puts "-----------------------------------------------------------------------" puts "Step 5a: Verify that $A has ($S1,$G) forwarding state with null oif-list" puts -nonewline " : Querying $A's ipMRouteUpstreamNeighbor table..." set ret [snmpget $A ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if { $ret == "IpAddress: $S1" || $ret == "IpAddress: 0.0.0.0"} { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts -nonewline " : Querying $A's ipMRouteNextHopState object..." set ret [snmpget $A ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${AifIndex2}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } puts "-----------------------------------------------------------------------" puts "Step 5b: Verify that $B has ($S1,$G) null oif-list" puts -nonewline " : Querying $B's ipMRouteUpstreamNeighbor table..." set ret [snmpget $B ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if { $ret == "IpAddress: $A2" } { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts -nonewline " : Querying $B's ipMRouteNextHopState object..." set ret [snmpget $B ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${BifIndex3}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # 6) Join group G from host R, and wait 1 second. puts "-----------------------------------------------------------------------" puts -nonewline "Step 6: Join group $G from host $R, and wait 3 seconds..." if { [mtest_join $R $username $G $R1] == 0 } { puts "join failed" exit } puts "ok" sleep 3 # 7) Verify that A now has N2 in the oiflist of (S,G). puts "-----------------------------------------------------------------------" puts "Step 7: Verify that $A now has $N2 in the oiflist of ($S,$G)" puts -nonewline " Querying ipMRouteNextHopState table..." set ret [snmpget $A ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${AifIndex2}.${G}] if { $ret == "2" } { puts "ok" } else { puts "failed with $N2 state value $ret" exit } # 8) Verify that B now has N3 in the oiflist of (S,G). puts "-----------------------------------------------------------------------" puts "Step 8: Verify that $B now has $N3 in the oiflist of ($S,$G)" puts -nonewline " Querying ipMRouteNextHopState table..." set ret [snmpget $B ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${BifIndex3}.${G}] if { $ret == "2" } { puts "ok" } else { puts "failed with $N3 state value $ret" exit } # 9) Leave group G on host R and wait 11 seconds. puts "-----------------------------------------------------------------------" puts "Step 9: Leave group $G on host $R and wait $leavewait seconds..." if { [mtest_leave $R $username $G $R1] == 0 } { puts "failed" exit } puts "ok" # 10) Verify that A has forwarding state on N2. Prune should be delayed by # 3 seconds (or 5 seconds for RFC2177) on LAN. puts "-----------------------------------------------------------------------" puts "Step 10: Verify that $A STILL has $N2 in the oiflist of ($S,$G)" puts -nonewline " Querying ipMRouteNextHopState table..." set ret [snmpget $A ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${AifIndex2}.${G}] if { $ret == "2" } { puts "ok" } else { puts "failed with $N2 state value $ret" exit } sleep $leavewait # 11) Verify that both A and B have (S,G) forwarding state with null oif-list # 11a) Verify that A has (S,G) forwarding state with null oif-list puts "-----------------------------------------------------------------------" puts "Step 11a: Verify that $A has ($S1,$G) forwarding state with null oif-list" puts -nonewline " : Querying $A's ipMRouteUpstreamNeighbor table..." set ret [snmpget $A ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if { $ret == "IpAddress: $S1" || $ret == "IpAddress: 0.0.0.0"} { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts -nonewline " : Querying $A's ipMRouteNextHopState object..." set ret [snmpget $A ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${AifIndex2}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } puts "-----------------------------------------------------------------------" puts "Step 11b: Verify that $B has ($S1,$G) null oif-list" puts -nonewline " : Querying $B's ipMRouteUpstreamNeighbor table..." set ret [snmpget $B ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if { $ret == "IpAddress: $A2" } { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts -nonewline " : Querying $B's ipMRouteNextHopState object..." set ret [snmpget $B ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${BifIndex3}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # Wait for state to time out puts "-----------------------------------------------------------------------" puts "Waiting for ($S1,$G) state to time out" sleep 300 # Step 12: Verify that (S,G) state times out on A and B # 12a) Verify that A has timed out its (S,G) state puts "-----------------------------------------------------------------------" puts "Step 12a: Verifying that $A has timed out its ($S1,$G) state" puts -nonewline " : Querying $A's ipMRouteUpstreamNeighbor table..." set ret [snmpget $A ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if {$ret == "no_such_variable"} { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts "-----------------------------------------------------------------------" puts "Step 12b: Verifying that $B has timed out its ($S1,$G) state" puts -nonewline " : Querying $B's ipMRouteUpstreamNeighbor table..." set ret [snmpget $B ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if {$ret == "no_such_variable"} { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } # 13) Halt gated on A and B. puts "-----------------------------------------------------------------------" puts "Step 13: Halt gated on $A and $B" puts -nonewline "Step 13a: Halt gated on $B..." if { [stop_gated $B] == 0 } { puts "failed" exit } else { puts "ok" } puts "-----------------------------------------------------------------------" puts -nonewline "Step 13b: Halt gated on $A..." if { [stop_gated $A] == 0 } { puts "failed" exit } else { puts "ok" } puts "TEST SUCCESSFULLY COMPLETED!"