[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [ns] Re: Regarding
Anirban,
Please try again with these modified CtrMcast.tcl and CtrMcastComp.tcl.
-Polly
On Mon, 28 Feb 2000, Anirban Chakrabarti wrote:
> Hi,
> This does change the core, but the senders are still sending to the old
> core, so the receivers get disconnected. Most probably the senders are not
> understanding that the core has changed. Can you suggest something?
> Thanks for the help
> Anirban
#
# tcl/ctr-mcast/CtrMcast.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 Polly Huang (USC/ISI), http://www-scf.usc.edu/~bhuang
#
#
########## CtrMcast Class: Individual Node join-group, leave-group, etc #####
Class CtrMcast -superclass McastProtocol
CtrMcast instproc init { sim node } {
$self next $sim $node
$self instvar ns_ node_
$self instvar agent_ defaultTree_ decapagent_
$self instvar c_rp_ c_bsr_ priority_
set agent_ [$ns_ set MrtHandle_]
set defaultTree_ "RPT"
set decapagent_ [new Agent/Decapsulator]
$ns_ attach-agent $node_ $decapagent_
### config PIM nodes
set c_rp_ 1
set c_bsr_ 1
set priority_ 0
}
CtrMcast instproc join-group { group } {
$self next $group
$self instvar node_ ns_ agent_
$self instvar defaultTree_
if { [$agent_ treetype? $group] == "" } {
$agent_ treetype $group $defaultTree_
$agent_ add-new-group $group
}
$agent_ add-new-member $group $node_
foreach src [$agent_ sources? $group] {
$agent_ compute-branch $src $group $node_
}
}
CtrMcast instproc leave-group { group } {
$self next $group
$self instvar node_ ns_ agent_ defaultTree_
$agent_ remove-member $group $node_
foreach src [$agent_ sources? $group] {
$agent_ prune-branch $src $group $node_
}
}
CtrMcast instproc handle-cache-miss { srcID group iface } {
$self instvar ns_ agent_ node_
$self instvar defaultTree_ encapagent_
if { [$agent_ treetype? $group] == "" } {
$agent_ treetype $group $defaultTree_
#$agent_ add-new-member $group $node_
}
if { [$node_ id] == $srcID } {
set RP [$self get_rp $group]
if {[$agent_ treetype? $group] == "RPT" && $srcID != [$RP id]} {
if ![info exists encapagent_] {
set encapagent_ [new Agent/Encapsulator]
$ns_ attach-agent $node_ $encapagent_
set ctrmcast [[$RP getArbiter] getType "CtrMcast"]
$ns_ connect $encapagent_ [$ctrmcast set decapagent_]
### create (S,G,iif=-1) entry
$node_ add-mfc-reg $srcID $group -1 $encapagent_
} else {
set ctrmcast [[$RP getArbiter] getType "CtrMcast"]
$ns_ connect $encapagent_ [$ctrmcast set decapagent_]
}
}
if [$agent_ new-source? $group $node_] {
$agent_ compute-tree $node_ $group
}
} elseif [SessionSim set MixMode_] {
set srcnode [$ns_ get-node-by-id $srcID]
if [$agent_ new-source? $group $srcnode] {
$agent_ compute-tree $srcnode $group
}
}
return 1 ;#call again
}
CtrMcast instproc drop { replicator src group iface } {
#packets got dropped only due to null oiflist
}
CtrMcast instproc handle-wrong-iif { srcID group iface } {
warn "$self: $proc for <S: $srcID, G: $group, if: $iface>?"
return 0 ;#call once
}
CtrMcast instproc notify { dummy } {
}
##### Two functions to help get RP for a group #####
##### get_rp {group} #####
##### hash {rp group} #####
CtrMcast instproc get_rp group {
$self instvar rpset_ agent_
if ![info exists rpset_] {
[$agent_ set ctrrpcomp] compute-rpset
assert [info exists rpset_]
}
set returnrp -1
set hashval -1
foreach rp $rpset_ {
if {[$self hash $rp $group] > $hashval} {
set hashval [$self hash $rp $group]
set returnrp $rp
}
}
set returnrp ;# return
}
CtrMcast instproc hash {rp group} {
$rp id
}
CtrMcast instproc set-rpset args {
eval $self set rpset_ "$args"
}
CtrMcast instproc get_bsr {} {
warn "$self: CtrMcast doesn't require a BSR"
}
CtrMcast instproc set_c_bsr { prior } {
$self instvar c_bsr_ priority_
set c_bsr_ 1
set priority_ $prior
}
CtrMcast instproc set_c_rp {} {
$self instvar c_rp_
set c_rp_ 1
}
CtrMcast instproc unset_c_rp {} {
$self instvar c_rp_
set c_rp_ 0
}
##################### MultiNode: add-mfc-reg ################
Node instproc add-mfc-reg { src group iif oiflist } {
$self instvar multiclassifier_ Regreplicator_
#XXX node addr is in upper 24 bits
if [info exists Regreplicator_($group)] {
foreach oif $oiflist {
$Regreplicator_($group) insert $oif
}
return 1
}
set r [new Classifier/Replicator/Demuxer]
$r set node_ $self
$r set srcID_ $src
set Regreplicator_($group) $r
foreach oif $oiflist {
$r insert $oif
}
# Install the replicator. We do this only once and leave
# it forever. Since prunes are data driven, we want to
# leave the replicator in place even when it's empty since
# the replicator::drop callback triggers the prune.
#
$multiclassifier_ add-rep $r $src $group $iif
}
Node instproc getRegreplicator group {
$self instvar Regreplicator_
if [info exists Regreplicator_($group)] {
return $Regreplicator_($group)
} else {
return -1
}
}
#
# tcl/ctr-mcast/CtrMcastComp.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 Polly Huang (USC/ISI), http://www-scf.usc.edu/~bhuang
#
#
########## CtrMcastComp Class ##################################
########## init {}
########## compute-tree {src group Ttype}
########## compute-branch {src group member Ttype}
Class CtrMcastComp
CtrMcastComp instproc init sim {
$self instvar ns_
set ns_ $sim
$self init-groups
$ns_ maybeEnableTraceAll $self {}
}
CtrMcastComp instproc id {} {
return 0
}
CtrMcastComp instproc trace { f nop {op ""} } {
$self instvar ns_ dynT_
if {$op == "nam" && [info exists dynT_]} {
foreach tr $dynT_ {
$tr namattach $f
}
} else {
lappend dynT_ [$ns_ create-trace Generic $f $self $self $op]
}
}
##### Main computation functions #####
CtrMcastComp instproc reset-mroutes {} {
$self instvar ns_
foreach node [$ns_ all-nodes-list] {
foreach group [$self groups?] {
set class_info [$node info class]
if {$class_info != "LanNode"} {
$node clearReps * $group
}
# *,G match catches all sources.
# foreach src [$self sources? $group] {
# $node clearReps [$src id] $group
# }
}
}
}
CtrMcastComp instproc compute-mroutes {} {
$self reset-mroutes
foreach group [$self groups?] {
foreach src [$self sources? $group] {
$self compute-tree $src $group
set ctrmcast [[$src getArbiter] getType "CtrMcast"]
$ctrmcast handle-cache-miss [$src id] $group -1
}
}
}
CtrMcastComp instproc compute-tree { src group } {
foreach mem [$self members? $group] {
$self compute-branch $src $group $mem
}
}
CtrMcastComp instproc compute-branch { src group nodeh } {
$self instvar ns_
### set (S,G) join target
set tt [$self treetype? $group]
if { $tt == "SPT" } {
set target $src
} elseif { $tt == "RPT" } {
set target [$self get_rp $nodeh $group]
}
for {
set downstreamtmp ""
set tmp $nodeh
} { $downstreamtmp != $target } {
set downstreamtmp $tmp
set tmp [$tmp rpf-nbr $target]
} {
if {[SessionSim set MixMode_] && $downstreamtmp != "" && ![$ns_ detailed-link? [$tmp id] [$downstreamtmp id]]} {
# puts "joining into session area"
break
}
### set iif : RPF link interface label
if {$tmp == $target} {
# at src or RP
set iif -1
} else {
set rpfl [$ns_ link [$tmp rpf-nbr $target] $tmp]
if {[SessionSim set MixMode_] && $rpfl == ""} {
# in mix mode: default -1 unless find a
# detailed link on the rpf path
set iif -1
set ttmp $tmp
while {$ttmp != $target} {
set rpfl [$ns_ link [$ttmp rpf-nbr $target] $ttmp]
if {$rpfl != ""} {
set iif [$rpfl if-label?]
break
}
set ttmp [$ttmp rpf-nbr $target]
}
} else {
# in regular detailed mode
set iif [$rpfl if-label?]
}
}
### set oif : RPF link
set oiflist ""
if { $downstreamtmp != "" } {
set rpfnbr [$downstreamtmp rpf-nbr $target]
if { $rpfnbr == $tmp } {
set rpflink [$ns_ link $tmp $downstreamtmp]
if {$rpflink != ""} {
set oiflist [$tmp link2oif $rpflink]
}
}
}
if { [set r [$tmp getReps [$src id] $group]] != "" } {
if [$r is-active] {
# puts "reach merging point, $group [$src id] [$target id] [$tmp id] [$nodeh id], iif $iif, oif $oiflist"
if { $oiflist != "" } {
$r insert [lindex $oiflist 0]
}
break
} else {
# puts "hasn't reached merging point, $group [$src id] [$target id] [$tmp id] [$nodeh id], iif $iif, oif $oiflist"
# so continue to insert the oif
if { $oiflist != "" } {
$r insert [lindex $oiflist 0]
}
}
} else {
# hasn't reached merging point,
# puts "so keep creating (S,G) like a graft, $group [$src id] [$target id] [$tmp id] [$nodeh id], iif $iif, oif $oiflist"
$tmp add-mfc [$src id] $group $iif $oiflist
}
}
}
CtrMcastComp instproc prune-branch { src group nodeh } {
$self instvar ns_
### set (S,G) prune target
set tt [$self treetype? $group]
if { $tt == "SPT" } {
set target $src
} elseif { $tt == "RPT" } {
set target [$self get_rp $nodeh $group]
}
for {
set downstreamtmp ""
set tmp $nodeh
} { $downstreamtmp != $target } {
set downstreamtmp $tmp
set tmp [$tmp rpf-nbr $target]
} {
set iif -1
set oif ""
if { $downstreamtmp != "" } {
set rpfnbr [$downstreamtmp rpf-nbr $target]
if { $rpfnbr == $tmp } {
set oif [$tmp link2oif [$ns_ link $tmp $downstreamtmp]]
}
}
if { [set r [$tmp getReps [$src id] $group]] != "" } {
if { $oif != "" } {
$r disable $oif
}
if [$r is-active] {
break
}
} else {
break
}
}
}
# notify(): adapt to rtglib dynamics
CtrMcastComp instproc notify {} {
$self instvar ctrrpcomp
### need to add a delay before recomputation
$ctrrpcomp compute-rpset
$self compute-mroutes
}
#
# utility functions to track Source, Group, and Member State
#
CtrMcastComp instproc init-groups {} {
$self set Glist_ ""
}
CtrMcastComp instproc add-new-group group {
$self instvar Glist_
set group [expr $group]
if ![info exist Glist_] {
set Glist_ ""
}
if {[lsearch $Glist_ $group] < 0} {
lappend Glist_ $group
}
}
CtrMcastComp instproc add-new-member {group node} {
$self instvar Mlist_
set group [expr $group]
$self add-new-group $group
if ![info exist Mlist_($group)] {
set Mlist_($group) ""
}
if {[lsearch $Mlist_($group) $node] < 0} {
lappend Mlist_($group) $node
}
}
CtrMcastComp instproc new-source? {group node} {
$self instvar Slist_
set group [expr $group]
$self add-new-group $group
if ![info exist Slist_($group)] {
set Slist_($group) ""
}
if {[lsearch $Slist_($group) $node] < 0} {
lappend Slist_($group) $node
return 1
} else {
return 0
}
}
CtrMcastComp instproc groups? {} {
$self set Glist_
}
CtrMcastComp instproc members? group {
$self instvar Mlist_
set group [expr $group]
if ![info exists Mlist_($group)] {
set Mlist_($group) ""
}
set Mlist_($group)
}
CtrMcastComp instproc sources? group {
$self instvar Slist_
set group [expr $group]
if ![info exists Slist_($group)] {
set Slist_($group) ""
}
set Slist_($group)
}
CtrMcastComp instproc remove-member {group node} {
$self instvar Mlist_ Glist_
set group [expr $group]
set k [lsearch $Mlist_($group) $node]
if {$k < 0} {
puts "warning: removing non-member"
} else {
set Mlist_($group) [lreplace $Mlist_($group) $k $k]
}
if { $Mlist_($group) == "" } {
set k [lsearch $Glist_ $group]
if {$k < 0} {
puts "warning: removing non-existing group"
} else {
set Glist_ [lreplace $Glist_ $k $k]
}
}
}
CtrMcastComp instproc treetype? group {
$self instvar treetype_
set group [expr $group]
if [info exists treetype_($group)] {
return $treetype_($group)
} else {
return ""
}
}
CtrMcastComp instproc treetype {group tree} {
$self set treetype_([expr $group]) $tree
}
CtrMcastComp instproc switch-treetype group {
$self instvar treetype_ dynT_
set group [expr $group]
if [info exists dynT_] {
foreach tr $dynT_ {
$tr annotate "$group switch tree type"
}
}
set treetype_($group) "SPT"
$self add-new-group $group
$self compute-mroutes
}
CtrMcastComp instproc set_c_rp args {
$self instvar ns_
foreach n [$ns_ all-nodes-list] {
set arbiter [$n getArbiter]
#NS creates a virtual node per LAN. This node does
#not have any the multicast features set.
if {$arbiter != ""} {
set ctrmcast [$arbiter getType "CtrMcast"]
$ctrmcast instvar c_rp_
$ctrmcast unset_c_rp
}
}
foreach node $args {
set arbiter [$node getArbiter]
set ctrmcast [$arbiter getType "CtrMcast"]
$ctrmcast set_c_rp
}
}
CtrMcastComp instproc set_c_bsr args {
foreach node $args {
set tmp [split $node :]
set node [lindex $tmp 0]
set prior [lindex $tmp 1]
set arbiter [$node getArbiter]
set ctrmcast [$arbiter getType "CtrMcast"]
$ctrmcast set_c_bsr $prior
}
}
CtrMcastComp instproc get_rp { node group } {
set ctrmcast [[$node getArbiter] getType "CtrMcast"]
$ctrmcast get_rp $group
}
CtrMcastComp instproc get_bsr { node } {
set arbiter [$node getArbiter]
set ctrmcast [$arbiter getType "CtrMcast"]
$ctrmcast get_bsr
}