📄 pim-recvr.tcl
字号:
# # tcl/pim/pim-recvr.tcl # # Copyright (C) 1997 by USC/ISI # All rights reserved. # # Redistribution and use in source and binary forms are permitted # provided that the above copyright notice and this paragraph are # duplicated in all such forms and that any documentation, advertising # materials, and other materials related to such distribution and use # acknowledge that the software was developed by the University of # Southern California, Information Sciences Institute. The name of the # University may not be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # # Contributed by Ahmed Helmy, Ported by Polly Huang (USC/ISI), # http://www-scf.usc.edu/~bhuang # #PIM instproc drop { replicator src dst } { $self instvar Node # XXX set ignore to avoid further calls on drop $replicator set ignore 1}# upcall handler [cache misses, wrong iifs,.. whole pkts.. ]# don't use "args", it adds another level of listing.. ! use argslist.. !!!PIM instproc upcall { argslist } { # the args are passed as code, srcID, group, iface # puts "pim $self upcall $argslist" set code [lindex $argslist 0] ## remove code from the args list set argslist [lreplace $argslist 0 0] switch $code { "CACHE_MISS" { $self handle-cache-miss $argslist } "WRONG_IIF" { $self handle-wrong-iif $argslist } default { puts "no match for upcall, code is $code" } }}PIM instproc handle-wrong-iif { argslist } { #puts "WRONG IIF $argslist" $self instvar MRTArray Node set srcID [lindex $argslist 0] set group [lindex $argslist 1] set iface [lindex $argslist 2] if { ! [info exists MRTArray($srcID:$group)] } { #puts "_node [$Node id] proto $self: error, wrongiif & no S,G" return 0 } set flags [$MRTArray($srcID:$group) getflags] if { ! [expr $flags & [PIM set CACHE]] } { #puts "_node [$Node id] proto $self: error, wrongiif & no cache" return 0 } if [expr $flags & [PIM set IIF_REG]] { #puts "IIF_REG set checking for switch to spt" # XXX to be completed # if { $iface == iif on RPF nbr towards scrID } { } # better make getting iif towards src modular to use elsewhere too if [expr $flags & [PIM set SPT]] { # should never happen #puts "_node [$Node id] proto $self: error, spt and iifreg!" } # XXX set SPT bit, turn off iif_reg & change iif in cache set flags [expr $flags & ~[PIM set IIF_REG] | [PIM set SPT]] # change iif in cache and SG entry !! return 1 } # XXX if { iif(WC) != iif(SG) && iface == iif(SG) } { # switch to spt, and prune off of shared tree # } # where iif(SG) is iif towards RPF nbr to the src ! # if iface is in oiflist(computeoifs) then trigger assert set oifs [$self compute-oif-ids $MRTArray($srcID:$group)] if { [set idx [$self index $oifs $iface]] != -1 } { set code [expr {($flags & [PIM set SG]) ? "SG" : "WC"}] set oiface [$Node label2iface $iface] $self send-assert $srcID $group $code $oiface } else { # puts "wrong iif, but iface not in oiflist !!!" return 0 }}# this draws heavily from process_cacheMiss in route.cPIM instproc handle-cache-miss { argslist } { $self instvar Node MRTArray set srcID [lindex $argslist 0] set group [lindex $argslist 1] set iface [lindex $argslist 2] if [$self DR $srcID $iface] { if [info exists MRTArray($group)] { set RP [$MRTArray($group) getRP] } else { set RP [lindex [$self getMap $group] 0] } if { $RP != [$Node id] } { # XXX allow turning off registers for SPTs.. ! $self instvar RegisterOff if [info exists RegisterOff] { #puts "RegisterOff" $self findSG $srcID $group 1 0 $MRTArray($srcID:$group) setiif -1 $self change-cache $srcID $group "SG" -1 } else { $self findSG $srcID $group 1 [PIM set REG] # now we don't do RPF checks in regs... need igmp! $MRTArray($srcID:$group) setiif -1 $self change-cache $srcID $group "REG" -1 } return 1 } elseif { [info exists MRTArray($group)] || [info exists MRTArray($srcID:$group)] } { #puts "_node [$Node id] I am the RP" # should do a longest match later.. $self findSG $srcID $group 1 0 # may add a list of cache entries to the *,G entry.. ! $MRTArray($srcID:$group) setiif -1 $self change-cache $srcID $group "SG" -1 } } elseif { [set ent [$self longest_match $srcID $group]] != 0 } { # XXX note: can do like implem, always install the # rite iif in cache,... move iif into change-cache ! later! # check iif set iif [$ent getiif] if { $iif == -2 } { #puts "_node [$Node id] proto $self, err: iif -2" return -1 } if { $iface == $iif || $iif == -1 } { $self findSG $srcID $group 1 0 $MRTArray($srcID:$group) setiif $iface # may add a list of cache entries to the *,G entry.. ! $self change-cache $srcID $group "SG" $iface } elseif { [$ent getType] == "SGEnt" && ! [expr [$ent getflags] & [PIM set SPT]] } { if [info exists MRTArray($group)] { set WCiif [$MRTArray($group) getiif] if { $iface == $WCiif } { $self change-cache $srcID $group "SG" $iface # puts "matched on SG, but iif is WC" } } } else { # puts "wrong iif in cache miss !!!" } }}PIM instproc DR { srcID iface } { $self instvar Node # now only check if local if { $srcID != [$Node id] } { return 0 } return 1}PIM instproc recv-join { msg } { $self instvar Node MRTArray set dst [lindex $msg 0] # check if I am the dst.. o.w. perform join suppression.. ! later #puts "node [$Node id] recv-join msg $msg" if { [$Node id] != $dst } { # puts "node [$Node id] rxvd join destined to $dst" return 0 } set code [lindex $msg 1] set source [lindex $msg 2] set group [lindex $msg 3] set origin [lindex $msg 4] # may chk if grp valid before processing... merely safety.. ! later! switch $code { "WC" { # process *,G join # puts "node [$Node id] got *,G join" # check the hash for the grp if [$self findWC $group 0] { set notfound 0 set hashedRP [lindex [$MRTArray($group) getMap] 0] } else { set notfound 1 set hashedRP [lindex [$self getMap $group] 0] } if { $hashedRP != $source } { # puts "hash mismatch dropping join" return 0 } if $notfound { if { ! [$self findWC $group 1] } { # puts "failed findWC $group.. XXX" return 0 } $self send-join "WC" 0 $group set ent $MRTArray($group) set iif [$self get-iif-label [$ent getNextHop]] $ent setiif $iif } $self add-oif $MRTArray($group) $origin "WC" return 1 } "SG" { # process S,G join # XXX just for source specific for now .. check XXX set notfound 1 if [$self findSG $source $group 0 [PIM set SG]] { set notfound 0 } if $notfound { $self findSG $source $group 1 [PIM set SG] $self send-join "SG" $source $group set ent $MRTArray($srcID:$group) set iif [$self get-iif-label [$ent getNextHop]] $ent setiif $iif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -