#!/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 LAN assert 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: # - Assert resolution of parallel paths to a multiaccess LAN # # # N1 N2 # +--- A ---+ # | A1 A2 | N3 # S -----+ +--- C ------- R # S1 | | C1 C2 R1 # +--- B ---+ # B1 B2 # # # This script should be executed on router A. # # # 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 # 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 # canejo set A 128.223.163.129 set A1 128.223.163.129 set A2 128.223.91.129 # seaside set B 128.223.163.126 set B1 128.223.163.126 set B2 128.223.91.126 # rincon set C 128.223.91.127 set C1 128.223.91.127 set C2 128.223.226.127 set Aconfig /root/gated-confs/pimdm_assert.conf #set Agated /home/kurtw/gated-multi/src/gated/gated set Agated /home/kurtw/gated-snapshots/gated-multi-snapshot980320/src/gated/gated set Bconfig /root/gated-confs/pimdm_assert.conf set Bgated /home/kurtw/gated-multi/src/gated/gated set Cconfig /root/gated-confs/pimdm_assert.conf set Cgated /home/kurtw/gated-multi/src/gated/gated set G 225.1.2.3 # # Shouldn't need to change anything below here # trap shutdown SIGINT proc shutdown {} { cleanup exit } proc cleanup {} { global A B C A1 B1 C1 puts "-----------------------------------------------------------------------" puts "Cleaning up..." stop_gated $C stop_gated $A stop_gated $B puts "ok" } # 0) Clean up puts "-----------------------------------------------------------------------" puts "Step 0: Clean up" cleanup # 1) Start gated on routers A, B and C with equal links costs for interfaces # on N1 puts "-----------------------------------------------------------------------" puts "Step 1a: Start gated on router $A with $A1 cost of 1" 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 lo0 {\n\ priority 5;\n\ enable;\n\ };\n\ interface $A1 cost 1 {\n\ priority 5;\n\ enable;\n\ };\n\ interface $A2 cost 1 {\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 with $B1 cost of 1" 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 lo0 {\n\ priority 5;\n\ enable;\n\ };\n\ interface $B1 cost 1 {\n\ priority 5;\n\ enable;\n\ };\n\ interface $B2 cost 1 {\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" } puts "-----------------------------------------------------------------------" puts "Step 1c: Start gated on router $C and wait 60 seconds" save_file $C $Cconfig "\ traceoptions \"/var/log/gated.test.log\" replace all;\n\ interfaces { interface all passive; };\n\ router-id $C;\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 $C $Bgated $Cconfig] == 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 BifIndex1 [IP2IntfIndex $B $B1] set BifIndex2 [IP2IntfIndex $B $B2] set CifIndex1 [IP2IntfIndex $C $C1] set CifIndex2 [IP2IntfIndex $C $C2] # 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, # C1 and B2. set ret [snmpget $A ${pimNeighborEntry}.2.${C1}] if { $ret == $AifIndex2 } { puts "ok" } else { puts "failed" exit } set ret [snmpget $A ${pimNeighborEntry}.2.${B2}] if { $ret == $AifIndex2 } { puts "ok" } else { puts "failed" exit } # 3) Verify that B doesn't consider N2 a leaf network for the N1 route. puts "-----------------------------------------------------------------------" puts "Step 3: Verify that $B doesn't consider $N2 a leaf network for the $N1 route." # Check that B has neighbors on N2 besides its own interface, specifically, # C1 and A2. set ret [snmpget $B ${pimNeighborEntry}.2.${C1}] if { $ret == $BifIndex2 } { puts "ok" } else { puts "failed" exit } set ret [snmpget $B ${pimNeighborEntry}.2.${A2}] if { $ret == $BifIndex2 } { puts "ok" } else { puts "failed" exit } # 4) Verify that C considers N3 a leaf network. puts "-----------------------------------------------------------------------" puts "Step 4: Verify that $C considers $N3 a leaf network." # Check that C has NO neighbors on N3 except its own interface, C2. set ret [snmpget $C ${pimNeighborEntry}.2.${C2}] if { $ret == $CifIndex2 } { puts "ok" } else { puts "failed" exit } set ret [snmpget $C ${pimNeighborEntry}.2.${R1}] if { $ret == "no_such_variable" } { puts "ok for $R1" } else { puts "failed" exit } # 5) Join group G from host R, and wait 1 second. # This will have no effect on routing since there is no router state for G puts "-----------------------------------------------------------------------" puts -nonewline "Step 5: 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 # Since pref and metric to S should be equal, winner is router with # highest IP address. if {[ipaddrcmp $A2 $B2] == -1} { set winner $B set winner_ifaddr $B2 set winner_ifIndex $BifIndex2 set loser $A set loser_ifaddr $A2 set loser_ifIndex $AifIndex2 } else { set winner $A set winner_ifaddr $A2 set winner_ifIndex $AifIndex2 set loser $B set loser_ifaddr $B2 set loser_ifIndex $BifIndex2 } puts "-----------------------------------------------------------------------" puts "Assert winner: $winner_ifaddr" # Due to the fact that gated's mbr always triggers a graft when creating # an (S,G) entry with outgoing interfaces (as PIMDM spec), we need to send # two data packets to stabilize the assert state. The first packet will # flood (S,G) state with oifs, triggering grafts on all routers). Then # the assert winner is chosen and the loser prunes. However, if the # graft is recieved by the loser after the loser prunes, the assert loser # will still have forwarding state. But subsequent data packets will # trigger another assert which will prune the losing oif for the remainder # of the assert timeout period. So we send __2__ pings here. # 6) Ping group G from host S, and wait 1 second puts "-----------------------------------------------------------------------" puts -nonewline "Step 6: Ping group $G from host $S on interface $S1" set ret [send_ping $S $username $S1 $G] puts "Wait 6 seconds for assert winner ($winner) to receive join from $C" sleep 6 puts "Then send another ping to stabilize assert state, and wait 10 seconds." set ret [send_ping $S $username $S1 $G] sleep 10 # 7) Verify that the winner now has N2 in the oiflist of (S,G). puts "-----------------------------------------------------------------------" puts "Step 7: Verify that $winner now has $N2 in the oiflist of ($S,$G)" puts -nonewline " Querying ipMRouteNextHopState table..." set ret [snmpget $winner ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${winner_ifIndex}.${G}] if { $ret == "2" } { puts "ok" } else { puts "failed with $N2 state value $ret" exit } # 8) Verify that loser now has empty oiflist for (S,G). puts "-----------------------------------------------------------------------" puts "Step 8: Verify that $loser has ($S,$G) forwarding state with null oif-list" puts -nonewline " : Querying ${loser}'s ipMRouteUpstreamNeighbor table..." set ret [snmpget $loser ${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 ${loser}'s ipMRouteNextHopState object..." set ret [snmpget $loser ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${loser_ifIndex}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # 9) Verify that downstream router now has forwarding state the the winner # as the upstream neighbor. puts "-----------------------------------------------------------------------" puts "Step 9: Verify that $C has assert winner as upstream nbr and $N3 in the oiflist for ($S,$G)" puts -nonewline " : Querying ${C}'s ipMRouteUpstreamNeighbor table..." set ret [snmpget $C ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if { $ret == "IpAddress: $winner_ifaddr" } { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts -nonewline " Querying ${C}'s ipMRouteNextHopState table..." set ret [snmpget $C ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${CifIndex2}.${G}] if { $ret == "2" } { puts "ok" } else { puts "failed with $N2 state value $ret" exit } sleep 10 # 10) Leave group G on host R. puts "-----------------------------------------------------------------------" puts "Step 10: Leave group $G on host $R and wait 6 seconds..." if { [mtest_leave $R $username $G $R1] == 0 } { puts "failed" exit } puts "ok" sleep 7 # Now verify the assert winner is pruned for (S,G) puts "-----------------------------------------------------------------------" puts "Step 11: Verify that $winner has ($S,$G) forwarding state with null oif-list" puts -nonewline " : Querying ${winner}'s ipMRouteUpstreamNeighbor table..." set ret [snmpget $winner ${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 ${winner}'s ipMRouteNextHopState object..." set ret [snmpget $winner ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${winner_ifIndex}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # Now verify the the downstream router, C, is pruned for (S,G) puts "-----------------------------------------------------------------------" puts "Step 12: Verify that $C has ($S,$G) forwarding state with null oif-list" puts -nonewline " : Querying ${C}'s ipMRouteUpstreamNeighbor table..." set ret [snmpget $C ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if { $ret == "IpAddress: $winner_ifaddr" } { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts -nonewline " : Querying ${C}'s ipMRouteNextHopState object..." set ret [snmpget $C ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${CifIndex2}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # 13) # Wait for (S,G) state to timeout puts "-----------------------------------------------------------------------" puts "Step 13: Waiting for ($S1,$G) state to time out" sleep 300 # Now, repeat the assert process with no receivers to be sure that # both upstream routers prune. # 14) Ping group G from host S, and wait 1 second puts "-----------------------------------------------------------------------" puts -nonewline "Step 14: Ping group $G from host $S on interface $S1" set ret [send_ping $S $username $S1 $G] sleep 6 set ret [send_ping $S $username $S1 $G] puts "-----------------------------------------------------------------------" puts "Wait 10 seconds for assert winner ($winner) to prune $N2" sleep 10 # 15) Verify that winner now has empty oiflist for (S,G). puts "-----------------------------------------------------------------------" puts "Step 15: Verify that $winner has ($S,$G) forwarding state with null oif-list" puts -nonewline " : Querying ${winner}'s ipMRouteUpstreamNeighbor table..." set ret [snmpget $winner ${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 ${winner}'s ipMRouteNextHopState object..." set ret [snmpget $winner ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${winner_ifIndex}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # 16) Verify that loser now has empty oiflist for (S,G). puts "-----------------------------------------------------------------------" puts "Step 16: Verify that $loser has ($S,$G) forwarding state with null oif-list" puts -nonewline " : Querying ${loser}'s ipMRouteUpstreamNeighbor table..." set ret [snmpget $loser ${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 ${loser}'s ipMRouteNextHopState object..." set ret [snmpget $loser ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${loser_ifIndex}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # 17) Verify that downstream router now has null oiflist puts "-----------------------------------------------------------------------" puts "Step 17: Verify that $C has assert winner as upstream nbr and null oiflist for ($S,$G)" puts -nonewline " : Querying ${C}'s ipMRouteUpstreamNeighbor table..." set ret [snmpget $C ${ipMRouteUpstreamNeighbor}.${G}.${S1}.255.255.255.255 ] if { $ret == "IpAddress: $winner_ifaddr" } { puts "ok" } else { puts "failed with upstream neighbor value $ret" exit } puts -nonewline " : Querying ${C}'s ipMRouteNextHopState object..." set ret [snmpget $C ${ipMRouteNextHopState}.${G}.${S1}.255.255.255.255.${CifIndex2}.${G}] if { $ret == "no_such_variable" } { puts "ok" } else { puts "failed with return code $ret" exit } # 18) Halt gated on A, B, and C puts "-----------------------------------------------------------------------" puts "Step 18: Halt gated on $A, $B and $C" puts -nonewline "Step 16a: Halt gated on $B..." if { [stop_gated $B] == 0 } { puts "failed" exit } else { puts "ok" } puts "-----------------------------------------------------------------------" puts -nonewline "Step 16b: Halt gated on $C..." if { [stop_gated $C] == 0 } { puts "failed" exit } else { puts "ok" } puts "-----------------------------------------------------------------------" puts -nonewline "Step 16c: Halt gated on $A..." if { [stop_gated $A] == 0 } { puts "failed" exit } else { puts "ok" } puts "TEST SUCCESSFULLY COMPLETED!"