route-proto.tcl

来自「一款用来进行网络模拟的软件」· TCL 代码 · 共 748 行 · 第 1/2 页

TCL
748
字号
##  Copyright (c) 1997 by the University of Southern California#  All rights reserved.##  This program is free software; you can redistribute it and/or#  modify it under the terms of the GNU General Public License,#  version 2, as published by the Free Software Foundation.##  This program is distributed in the hope that it will be useful,#  but WITHOUT ANY WARRANTY; without even the implied warranty of#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the#  GNU General Public License for more details.##  You should have received a copy of the GNU General Public License along#  with this program; if not, write to the Free Software Foundation, Inc.,#  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.##  The copyright of this module includes the following#  linking-with-specific-other-licenses addition:##  In addition, as a special exception, the copyright holders of#  this module give you permission to combine (via static or#  dynamic linking) this module with free software programs or#  libraries that are released under the GNU LGPL and with code#  included in the standard release of ns-2 under the Apache 2.0#  license or under otherwise-compatible licenses with advertising#  requirements (or modified versions of such code, with unchanged#  license).  You may copy and distribute such a system following the#  terms of the GNU GPL for this module and the licenses of the#  other code concerned, provided that you include the source code of#  that other code when and as the GNU GPL requires distribution of#  source code.##  Note that people who make modified versions of this module#  are not obligated to grant this special exception for their#  modified versions; it is their choice whether to do so.  The GNU#  General Public License gives permission to release a modified#  version without this exception; this exception also makes it#  possible to release a modified version which carries forward this#  exception.# $Header: /cvsroot/nsnam/ns-2/tcl/rtglib/route-proto.tcl,v 1.31 2005/09/16 03:05:46 tomh Exp $## Author: <kannan@isi.edu> (this email address has deprecated.)### This file only contains the methods for dynamic routing.# Check ../lib/ns-route.tcl for the Simulator (static) routing support#set rtglibRNG [new RNG]$rtglibRNG seed 1Class rtObjectrtObject set unreach_ -1rtObject set maxpref_   255# This may not be called by all routing agents. For instance, DV calls # this one but static does not. As a result, static routing does not have# rtObject on any node.rtObject proc init-all args {    foreach node $args {	if { [$node rtObject?] == "" } {	    set rtobj($node) [new rtObject $node]	}    }    foreach node $args {	;# XXX        $rtobj($node) compute-routes    }}rtObject instproc init node {    $self next    $self instvar ns_ nullAgent_    $self instvar nextHop_ rtpref_ metric_ node_ rtVia_ rtProtos_    set ns_ [Simulator instance]    set nullAgent_ [$ns_ set nullAgent_]    $node init-routing $self    set node_ $node    foreach dest [$ns_ all-nodes-list] {	set nextHop_($dest) ""	if {$node == $dest} {	    set rtpref_($dest) 0	    set metric_($dest) 0	    set rtVia_($dest) "Agent/rtProto/Local" ;# make dump happy	} else {	    set rtpref_($dest) [$class set maxpref_]	    set metric_($dest) [$class set unreach_]	    set rtVia_($dest)    ""	    $node add-route [$dest id] $nullAgent_	}    }    $self add-proto Direct $node    $rtProtos_(Direct) compute-routes}rtObject instproc add-proto {proto node} {    $self instvar ns_ rtProtos_    set rtProtos_($proto) [new Agent/rtProto/$proto $node]    $ns_ attach-agent $node $rtProtos_($proto)    set rtProtos_($proto)}rtObject instproc lookup dest {    $self instvar nextHop_ node_    if {![info exists nextHop_($dest)] || $nextHop_($dest) == ""} {	return -1    } else {	return [[$nextHop_($dest) set toNode_] id]    }}rtObject instproc compute-routes {} {    # choose the best route to each destination from all protocols    $self instvar ns_ node_ rtProtos_ nullAgent_    $self instvar nextHop_ rtpref_ metric_ rtVia_    set protos ""    set changes 0    foreach p [array names rtProtos_] {	if [$rtProtos_($p) set rtsChanged_] {	    incr changes	    $rtProtos_($p) set rtsChanged_ 0	}	lappend protos $rtProtos_($p)    }    if !$changes return    set changes 0    foreach dst [$ns_ all-nodes-list] {	if {$dst == $node_} continue	set nh ""	set pf [$class set maxpref_]	set mt [$class set unreach_]	set rv ""	foreach p $protos {	    set pnh [$p set nextHop_($dst)]	    if { $pnh == "" } continue	    set ppf [$p set rtpref_($dst)]	    set pmt [$p set metric_($dst)]	    if {$ppf < $pf || ($ppf == $pf && $pmt < $mt) || $mt < 0} {		set nh  $pnh		set pf  $ppf		set mt  $pmt		set rv  $p	    }	}	if { $nh == "" } {	    # no route...  delete any existing routes	    if { $nextHop_($dst) != "" } {		$node_ delete-routes [$dst id] $nextHop_($dst) $nullAgent_		set nextHop_($dst) $nh		set rtpref_($dst)  $pf		set metric_($dst)  $mt		set rtVia_($dst)   $rv		incr changes	    }	} else {	    if { $rv == $rtVia_($dst) } {		# Current protocol still has best route.		# See if changed		if { $nh != $nextHop_($dst) } {		    $node_ delete-routes [$dst id] $nextHop_($dst) $nullAgent_		    set nextHop_($dst) $nh		    $node_ add-routes [$dst id] $nextHop_($dst)		    incr changes		}		if { $mt != $metric_($dst) } {		    set metric_($dst) $mt		    incr changes		}		if { $pf != $rtpref_($dst) } {		    set rtpref_($dst) $pf		}	    } else {		if { $rtVia_($dst) != "" } {		    set nextHop_($dst) [$rtVia_($dst) set nextHop_($dst)]		    set rtpref_($dst)  [$rtVia_($dst) set rtpref_($dst)]		    set metric_($dst)  [$rtVia_($dst) set metric_($dst)]		}		if {$rtpref_($dst) != $pf || $metric_($dst) != $mt} {		    # Then new prefs must be better, or		    # new prefs are equal, and new metrics are lower		    $node_ delete-routes [$dst id] $nextHop_($dst) $nullAgent_		    set nextHop_($dst) $nh		    set rtpref_($dst)  $pf		    set metric_($dst)  $mt		    set rtVia_($dst)   $rv		    $node_ add-routes [$dst id] $nextHop_($dst)		    incr changes		}	    }	}    }    foreach proto [array names rtProtos_] {	$rtProtos_($proto) send-updates $changes    }    #    # XXX    # detailed multicast routing hooks must come here.    # My idea for the hook will be something like:    # set mrtObject [$node_ mrtObject?]    # if {$mrtObject != ""} {    #    $mrtObject recompute-mroutes $changes    # }    # $changes == 0	if only interfaces changed state.  Look at how    #			Agent/rtProto/DV handles ifsUp_    # $changes > 0	if new unicast routes were installed.    #    $self flag-multicast $changes}rtObject instproc flag-multicast changes {    $self instvar node_    $node_ notify-mcast $changes}rtObject instproc intf-changed {} {    $self instvar ns_ node_ rtProtos_ rtVia_ nextHop_ rtpref_ metric_    foreach p [array names rtProtos_] {	$rtProtos_($p) intf-changed	$rtProtos_($p) compute-routes    }    $self compute-routes}rtObject instproc dump-routes chan {    $self instvar ns_ node_ nextHop_ rtpref_ metric_ rtVia_    if {$ns_ != ""} {	set time [$ns_ now]    } else {	set time 0.0    }    puts $chan [concat "Node:\t${node_}([$node_ id])\tat t ="		\	    [format "%4.2f" $time]]    puts $chan "  Dest\t\t nextHop\tPref\tMetric\tProto"    #foreach dest [lsort -command SplitObjectCompare [$ns_ all-nodes-list]] {    foreach dest [$ns_ all-nodes-list] {	if {[llength $nextHop_($dest)] > 1} {	    set p [split [$rtVia_($dest) info class] /]	    set proto [lindex $p [expr [llength $p] - 1]]	    foreach rt $nextHop_($dest) {		puts $chan [format "%-5s(%d)\t%-5s(%d)\t%3d\t%4d\t %s"	 \			$dest [$dest id] $rt [[$rt set toNode_] id]	 \			$rtpref_($dest) $metric_($dest) $proto]	    }	} elseif {$nextHop_($dest) != ""} {	    set p [split [$rtVia_($dest) info class] /]	    set proto [lindex $p [expr [llength $p] - 1]]	    puts $chan [format "%-5s(%d)\t%-5s(%d)\t%3d\t%4d\t %s"	 \		    $dest [$dest id]					 \		    $nextHop_($dest) [[$nextHop_($dest) set toNode_] id] \		    $rtpref_($dest) $metric_($dest) $proto]	} elseif {$dest == $node_} {	    puts $chan [format "%-5s(%d)\t%-5s(%d)\t%03d\t%4d\t %s"	\		    $dest [$dest id] $dest [$dest id] 0 0 "Local"]	} else {	    puts $chan [format "%-5s(%d)\t%-5s(%s)\t%03d\t%4d\t %s"	\		    $dest [$dest id] "" "-" 255 32 "Unknown"]	}    }}rtObject instproc rtProto? proto {    $self instvar rtProtos_    if [info exists rtProtos_($proto)] {	return $rtProtos_($proto)    } else {	return ""    }}rtObject instproc nextHop? dest {    $self instvar nextHop_    $self set nextHop_($dest)}rtObject instproc rtpref? dest {    $self instvar rtpref_    $self set rtpref_($dest)}rtObject instproc metric? dest {    $self instvar metric_    $self set metric_($dest)}#Class rtPeerrtPeer instproc init {addr port cls} {    $self next    $self instvar addr_ port_ metric_ rtpref_    set addr_ $addr    set port_ $port    foreach dest [[Simulator instance] all-nodes-list] {	set metric_($dest) [$cls set INFINITY]	set rtpref_($dest) [$cls set preference_]    }}rtPeer instproc addr? {} {    $self instvar addr_    return $addr_}rtPeer instproc port? {} {    $self instvar port_    return $port_}rtPeer instproc metric {dest val} {    $self instvar metric_    set metric_($dest) $val}rtPeer instproc metric? dest {    $self instvar metric_    return $metric_($dest)}rtPeer instproc preference {dest val} {    $self instvar rtpref_    set rtpref_($dest) $val}rtPeer instproc preference? dest {    $self instvar rtpref_    return $rtpref_($dest)}##Class Agent/rtProto -superclass AgentAgent/rtProto proc pre-init-all args {    # By default, do nothing when a person does $ns rtproto foo.}Agent/rtProto proc init-all args {    error "No initialization defined"}Agent/rtProto instproc init node {    $self next        $self instvar ns_ node_ rtObject_ preference_ ifs_ ifstat_    set ns_ [Simulator instance]    catch "set preference_ [[$self info class] set preference_]" ret    if { $ret == "" } {	set preference_ [$class set preference_]    }    foreach nbr [$node set neighbor_] {	set link [$ns_ link $node $nbr]	set ifs_($nbr) $link	set ifstat_($nbr) [$link up?]    }    set rtObject_ [$node rtObject?]}Agent/rtProto instproc compute-routes {} {    error "No route computation defined"}Agent/rtProto instproc intf-changed {} {    #NOTHING}Agent/rtProto instproc send-updates args {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?