route-proto.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:20k
源码类别:

通讯编程

开发平台:

Visual C++

  1. #
  2. #  Copyright (c) 1997 by the University of Southern California
  3. #  All rights reserved.
  4. #
  5. #  This program is free software; you can redistribute it and/or
  6. #  modify it under the terms of the GNU General Public License,
  7. #  version 2, as published by the Free Software Foundation.
  8. #
  9. #  This program is distributed in the hope that it will be useful,
  10. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. #  GNU General Public License for more details.
  13. #
  14. #  You should have received a copy of the GNU General Public License along
  15. #  with this program; if not, write to the Free Software Foundation, Inc.,
  16. #  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  17. #
  18. #  The copyright of this module includes the following
  19. #  linking-with-specific-other-licenses addition:
  20. #
  21. #  In addition, as a special exception, the copyright holders of
  22. #  this module give you permission to combine (via static or
  23. #  dynamic linking) this module with free software programs or
  24. #  libraries that are released under the GNU LGPL and with code
  25. #  included in the standard release of ns-2 under the Apache 2.0
  26. #  license or under otherwise-compatible licenses with advertising
  27. #  requirements (or modified versions of such code, with unchanged
  28. #  license).  You may copy and distribute such a system following the
  29. #  terms of the GNU GPL for this module and the licenses of the
  30. #  other code concerned, provided that you include the source code of
  31. #  that other code when and as the GNU GPL requires distribution of
  32. #  source code.
  33. #
  34. #  Note that people who make modified versions of this module
  35. #  are not obligated to grant this special exception for their
  36. #  modified versions; it is their choice whether to do so.  The GNU
  37. #  General Public License gives permission to release a modified
  38. #  version without this exception; this exception also makes it
  39. #  possible to release a modified version which carries forward this
  40. #  exception.
  41. # $Header: /cvsroot/nsnam/ns-2/tcl/rtglib/route-proto.tcl,v 1.31 2005/09/16 03:05:46 tomh Exp $
  42. #
  43. # Author: <kannan@isi.edu> (this email address has deprecated.)
  44. #
  45. #
  46. # This file only contains the methods for dynamic routing.
  47. # Check ../lib/ns-route.tcl for the Simulator (static) routing support
  48. #
  49. set rtglibRNG [new RNG]
  50. $rtglibRNG seed 1
  51. Class rtObject
  52. rtObject set unreach_ -1
  53. rtObject set maxpref_   255
  54. # This may not be called by all routing agents. For instance, DV calls 
  55. # this one but static does not. As a result, static routing does not have
  56. # rtObject on any node.
  57. rtObject proc init-all args {
  58.     foreach node $args {
  59. if { [$node rtObject?] == "" } {
  60.     set rtobj($node) [new rtObject $node]
  61. }
  62.     }
  63.     foreach node $args { ;# XXX
  64.         $rtobj($node) compute-routes
  65.     }
  66. }
  67. rtObject instproc init node {
  68.     $self next
  69.     $self instvar ns_ nullAgent_
  70.     $self instvar nextHop_ rtpref_ metric_ node_ rtVia_ rtProtos_
  71.     set ns_ [Simulator instance]
  72.     set nullAgent_ [$ns_ set nullAgent_]
  73.     $node init-routing $self
  74.     set node_ $node
  75.     foreach dest [$ns_ all-nodes-list] {
  76. set nextHop_($dest) ""
  77. if {$node == $dest} {
  78.     set rtpref_($dest) 0
  79.     set metric_($dest) 0
  80.     set rtVia_($dest) "Agent/rtProto/Local" ;# make dump happy
  81. } else {
  82.     set rtpref_($dest) [$class set maxpref_]
  83.     set metric_($dest) [$class set unreach_]
  84.     set rtVia_($dest)    ""
  85.     $node add-route [$dest id] $nullAgent_
  86. }
  87.     }
  88.     $self add-proto Direct $node
  89.     $rtProtos_(Direct) compute-routes
  90. }
  91. rtObject instproc add-proto {proto node} {
  92.     $self instvar ns_ rtProtos_
  93.     set rtProtos_($proto) [new Agent/rtProto/$proto $node]
  94.     $ns_ attach-agent $node $rtProtos_($proto)
  95.     set rtProtos_($proto)
  96. }
  97. rtObject instproc lookup dest {
  98.     $self instvar nextHop_ node_
  99.     if {![info exists nextHop_($dest)] || $nextHop_($dest) == ""} {
  100. return -1
  101.     } else {
  102. return [[$nextHop_($dest) set toNode_] id]
  103.     }
  104. }
  105. rtObject instproc compute-routes {} {
  106.     # choose the best route to each destination from all protocols
  107.     $self instvar ns_ node_ rtProtos_ nullAgent_
  108.     $self instvar nextHop_ rtpref_ metric_ rtVia_
  109.     set protos ""
  110.     set changes 0
  111.     foreach p [array names rtProtos_] {
  112. if [$rtProtos_($p) set rtsChanged_] {
  113.     incr changes
  114.     $rtProtos_($p) set rtsChanged_ 0
  115. }
  116. lappend protos $rtProtos_($p)
  117.     }
  118.     if !$changes return
  119.     set changes 0
  120.     foreach dst [$ns_ all-nodes-list] {
  121. if {$dst == $node_} continue
  122. set nh ""
  123. set pf [$class set maxpref_]
  124. set mt [$class set unreach_]
  125. set rv ""
  126. foreach p $protos {
  127.     set pnh [$p set nextHop_($dst)]
  128.     if { $pnh == "" } continue
  129.     set ppf [$p set rtpref_($dst)]
  130.     set pmt [$p set metric_($dst)]
  131.     if {$ppf < $pf || ($ppf == $pf && $pmt < $mt) || $mt < 0} {
  132. set nh  $pnh
  133. set pf  $ppf
  134. set mt  $pmt
  135. set rv  $p
  136.     }
  137. }
  138. if { $nh == "" } {
  139.     # no route...  delete any existing routes
  140.     if { $nextHop_($dst) != "" } {
  141. $node_ delete-routes [$dst id] $nextHop_($dst) $nullAgent_
  142. set nextHop_($dst) $nh
  143. set rtpref_($dst)  $pf
  144. set metric_($dst)  $mt
  145. set rtVia_($dst)   $rv
  146. incr changes
  147.     }
  148. } else {
  149.     if { $rv == $rtVia_($dst) } {
  150. # Current protocol still has best route.
  151. # See if changed
  152. if { $nh != $nextHop_($dst) } {
  153.     $node_ delete-routes [$dst id] $nextHop_($dst) $nullAgent_
  154.     set nextHop_($dst) $nh
  155.     $node_ add-routes [$dst id] $nextHop_($dst)
  156.     incr changes
  157. }
  158. if { $mt != $metric_($dst) } {
  159.     set metric_($dst) $mt
  160.     incr changes
  161. }
  162. if { $pf != $rtpref_($dst) } {
  163.     set rtpref_($dst) $pf
  164. }
  165.     } else {
  166. if { $rtVia_($dst) != "" } {
  167.     set nextHop_($dst) [$rtVia_($dst) set nextHop_($dst)]
  168.     set rtpref_($dst)  [$rtVia_($dst) set rtpref_($dst)]
  169.     set metric_($dst)  [$rtVia_($dst) set metric_($dst)]
  170. }
  171. if {$rtpref_($dst) != $pf || $metric_($dst) != $mt} {
  172.     # Then new prefs must be better, or
  173.     # new prefs are equal, and new metrics are lower
  174.     $node_ delete-routes [$dst id] $nextHop_($dst) $nullAgent_
  175.     set nextHop_($dst) $nh
  176.     set rtpref_($dst)  $pf
  177.     set metric_($dst)  $mt
  178.     set rtVia_($dst)   $rv
  179.     $node_ add-routes [$dst id] $nextHop_($dst)
  180.     incr changes
  181. }
  182.     }
  183. }
  184.     }
  185.     foreach proto [array names rtProtos_] {
  186. $rtProtos_($proto) send-updates $changes
  187.     }
  188.     #
  189.     # XXX
  190.     # detailed multicast routing hooks must come here.
  191.     # My idea for the hook will be something like:
  192.     # set mrtObject [$node_ mrtObject?]
  193.     # if {$mrtObject != ""} {
  194.     #    $mrtObject recompute-mroutes $changes
  195.     # }
  196.     # $changes == 0 if only interfaces changed state.  Look at how
  197.     # Agent/rtProto/DV handles ifsUp_
  198.     # $changes > 0 if new unicast routes were installed.
  199.     #
  200.     $self flag-multicast $changes
  201. }
  202. rtObject instproc flag-multicast changes {
  203.     $self instvar node_
  204.     $node_ notify-mcast $changes
  205. }
  206. rtObject instproc intf-changed {} {
  207.     $self instvar ns_ node_ rtProtos_ rtVia_ nextHop_ rtpref_ metric_
  208.     foreach p [array names rtProtos_] {
  209. $rtProtos_($p) intf-changed
  210. $rtProtos_($p) compute-routes
  211.     }
  212.     $self compute-routes
  213. }
  214. rtObject instproc dump-routes chan {
  215.     $self instvar ns_ node_ nextHop_ rtpref_ metric_ rtVia_
  216.     if {$ns_ != ""} {
  217. set time [$ns_ now]
  218.     } else {
  219. set time 0.0
  220.     }
  221.     puts $chan [concat "Node:t${node_}([$node_ id])tat t ="
  222.     [format "%4.2f" $time]]
  223.     puts $chan "  Desttt nextHoptPreftMetrictProto"
  224.     #foreach dest [lsort -command SplitObjectCompare [$ns_ all-nodes-list]] {
  225.     foreach dest [$ns_ all-nodes-list] {
  226. if {[llength $nextHop_($dest)] > 1} {
  227.     set p [split [$rtVia_($dest) info class] /]
  228.     set proto [lindex $p [expr [llength $p] - 1]]
  229.     foreach rt $nextHop_($dest) {
  230. puts $chan [format "%-5s(%d)t%-5s(%d)t%3dt%4dt %s"  
  231. $dest [$dest id] $rt [[$rt set toNode_] id]  
  232. $rtpref_($dest) $metric_($dest) $proto]
  233.     }
  234. } elseif {$nextHop_($dest) != ""} {
  235.     set p [split [$rtVia_($dest) info class] /]
  236.     set proto [lindex $p [expr [llength $p] - 1]]
  237.     puts $chan [format "%-5s(%d)t%-5s(%d)t%3dt%4dt %s"  
  238.     $dest [$dest id]  
  239.     $nextHop_($dest) [[$nextHop_($dest) set toNode_] id] 
  240.     $rtpref_($dest) $metric_($dest) $proto]
  241. } elseif {$dest == $node_} {
  242.     puts $chan [format "%-5s(%d)t%-5s(%d)t%03dt%4dt %s"
  243.     $dest [$dest id] $dest [$dest id] 0 0 "Local"]
  244. } else {
  245.     puts $chan [format "%-5s(%d)t%-5s(%s)t%03dt%4dt %s"
  246.     $dest [$dest id] "" "-" 255 32 "Unknown"]
  247. }
  248.     }
  249. }
  250. rtObject instproc rtProto? proto {
  251.     $self instvar rtProtos_
  252.     if [info exists rtProtos_($proto)] {
  253. return $rtProtos_($proto)
  254.     } else {
  255. return ""
  256.     }
  257. }
  258. rtObject instproc nextHop? dest {
  259.     $self instvar nextHop_
  260.     $self set nextHop_($dest)
  261. }
  262. rtObject instproc rtpref? dest {
  263.     $self instvar rtpref_
  264.     $self set rtpref_($dest)
  265. }
  266. rtObject instproc metric? dest {
  267.     $self instvar metric_
  268.     $self set metric_($dest)
  269. }
  270. #
  271. Class rtPeer
  272. rtPeer instproc init {addr port cls} {
  273.     $self next
  274.     $self instvar addr_ port_ metric_ rtpref_
  275.     set addr_ $addr
  276.     set port_ $port
  277.     foreach dest [[Simulator instance] all-nodes-list] {
  278. set metric_($dest) [$cls set INFINITY]
  279. set rtpref_($dest) [$cls set preference_]
  280.     }
  281. }
  282. rtPeer instproc addr? {} {
  283.     $self instvar addr_
  284.     return $addr_
  285. }
  286. rtPeer instproc port? {} {
  287.     $self instvar port_
  288.     return $port_
  289. }
  290. rtPeer instproc metric {dest val} {
  291.     $self instvar metric_
  292.     set metric_($dest) $val
  293. }
  294. rtPeer instproc metric? dest {
  295.     $self instvar metric_
  296.     return $metric_($dest)
  297. }
  298. rtPeer instproc preference {dest val} {
  299.     $self instvar rtpref_
  300.     set rtpref_($dest) $val
  301. }
  302. rtPeer instproc preference? dest {
  303.     $self instvar rtpref_
  304.     return $rtpref_($dest)
  305. }
  306. #
  307. #Class Agent/rtProto -superclass Agent
  308. Agent/rtProto proc pre-init-all args {
  309.     # By default, do nothing when a person does $ns rtproto foo.
  310. }
  311. Agent/rtProto proc init-all args {
  312.     error "No initialization defined"
  313. }
  314. Agent/rtProto instproc init node {
  315.     $self next
  316.     
  317.     $self instvar ns_ node_ rtObject_ preference_ ifs_ ifstat_
  318.     set ns_ [Simulator instance]
  319.     catch "set preference_ [[$self info class] set preference_]" ret
  320.     if { $ret == "" } {
  321. set preference_ [$class set preference_]
  322.     }
  323.     foreach nbr [$node set neighbor_] {
  324. set link [$ns_ link $node $nbr]
  325. set ifs_($nbr) $link
  326. set ifstat_($nbr) [$link up?]
  327.     }
  328.     set rtObject_ [$node rtObject?]
  329. }
  330. Agent/rtProto instproc compute-routes {} {
  331.     error "No route computation defined"
  332. }
  333. Agent/rtProto instproc intf-changed {} {
  334.     #NOTHING
  335. }
  336. Agent/rtProto instproc send-updates args {
  337.     #NOTHING
  338. }
  339. Agent/rtProto proc compute-all {} {
  340.     #NOTHING
  341. }
  342. #
  343. # Static routing, the default
  344. #
  345. Class Agent/rtProto/Static -superclass Agent/rtProto
  346. Agent/rtProto/Static proc init-all args {
  347.     # The Simulator knows the entire topology.
  348.     # Hence, the current compute-routes method in the Simulator class is
  349.     # well suited.  We use it as is.
  350.     [Simulator instance] compute-routes
  351. }
  352. #
  353. # Session based unicast routing
  354. #
  355. Class Agent/rtProto/Session -superclass Agent/rtProto
  356. Agent/rtProto/Session proc init-all args {
  357.     [Simulator instance] compute-routes
  358. }
  359. Agent/rtProto/Session proc compute-all {} {
  360.     [Simulator instance] compute-routes
  361. }
  362. #
  363. #########################################################################
  364. #
  365. # Code below this line is experimental, and should be considered work
  366. # in progress.  None of this code is used in production test-suites, or
  367. # in the release yet, and hence should not be a problem to anyone.
  368. #
  369. Class Agent/rtProto/Direct -superclass Agent/rtProto
  370. Agent/rtProto/Direct instproc init node {
  371.     $self next $node
  372.     $self instvar ns_ rtpref_ nextHop_ metric_ ifs_
  373.     foreach node [$ns_ all-nodes-list] {
  374. set rtpref_($node) 255
  375. set nextHop_($node) ""
  376. set metric_($node) -1
  377.     }
  378.     foreach node [array names ifs_] {
  379. set rtpref_($node) [$class set preference_]
  380.     }
  381. }
  382. Agent/rtProto/Direct instproc compute-routes {} {
  383.     $self instvar ifs_ ifstat_ nextHop_ metric_ rtsChanged_
  384.     set rtsChanged_ 0
  385.     foreach nbr [array names ifs_] {
  386. if {$nextHop_($nbr) == "" && [$ifs_($nbr) up?] == "up"} {
  387.     set ifstat_($nbr) 1
  388.     set nextHop_($nbr) $ifs_($nbr)
  389.     set metric_($nbr) [$ifs_($nbr) cost?]
  390.     incr rtsChanged_
  391. } elseif {$nextHop_($nbr) != "" && [$ifs_($nbr) up?] != "up"} {
  392.     set ifstat_($nbr) 0
  393.     set nextHop_($nbr) ""
  394.     set metric_($nbr) -1
  395.     incr rtsChanged_
  396. }
  397.     }
  398. }
  399. #
  400. # Distance Vector Route Computation
  401. #
  402. # Class Agent/rtProto/DV -superclass Agent/rtProto
  403. Agent/rtProto/DV set UNREACHABLE [rtObject set unreach_]
  404. Agent/rtProto/DV set mid_   0
  405. Agent/rtProto/DV proc init-all args {
  406.     if { [llength $args] == 0 } {
  407. set nodeslist [[Simulator instance] all-nodes-list]
  408.     } else {
  409. eval "set nodeslist $args"
  410.     }
  411.     Agent set-maxttl Agent/rtProto/DV INFINITY
  412.     eval rtObject init-all $nodeslist
  413.     foreach node $nodeslist {
  414. set proto($node) [[$node rtObject?] add-proto DV $node]
  415.     }
  416.     foreach node $nodeslist {
  417. foreach nbr [$node neighbors] {
  418.     set rtobj [$nbr rtObject?]
  419.     if { $rtobj != "" } {
  420. set rtproto [$rtobj rtProto? DV]
  421. if { $rtproto != "" } {
  422.     $proto($node) add-peer $nbr [$rtproto set agent_addr_] [$rtproto set agent_port_]
  423. }
  424.     }
  425. }
  426.     }
  427. }
  428. Agent/rtProto/DV instproc init node {
  429.     global rtglibRNG
  430.     $self next $node
  431.     $self instvar ns_ rtObject_ ifsUp_
  432.     $self instvar preference_ rtpref_ nextHop_ nextHopPeer_ metric_ multiPath_
  433.     set UNREACHABLE [$class set UNREACHABLE]
  434.     foreach dest [$ns_ all-nodes-list] {
  435. set rtpref_($dest) $preference_
  436. set nextHop_($dest) ""
  437. set nextHopPeer_($dest) ""
  438. set metric_($dest)  $UNREACHABLE
  439.     }
  440.     set ifsUp_ ""
  441.     set multiPath_ [[$rtObject_ set node_] set multiPath_]
  442.     set updateTime [$rtglibRNG uniform 0.0 0.5]
  443.     $ns_ at $updateTime "$self send-periodic-update"
  444. }
  445. Agent/rtProto/DV instproc add-peer {nbr agentAddr agentPort} {
  446.     $self instvar peers_
  447.     $self set peers_($nbr) [new rtPeer $agentAddr $agentPort $class]
  448. }
  449. Agent/rtProto/DV instproc send-periodic-update {} {
  450.     global rtglibRNG
  451.     $self instvar ns_
  452.     $self send-updates 1 ;# Anything but 0
  453.     set updateTime [expr [$ns_ now] + 
  454.     ([$class set advertInterval] * [$rtglibRNG uniform 0.9 1.1])]
  455.     $ns_ at $updateTime "$self send-periodic-update"
  456. }
  457. Agent/rtProto/DV instproc compute-routes {} {
  458.     $self instvar ns_ ifs_ rtpref_ metric_ nextHop_ nextHopPeer_
  459.     $self instvar peers_ rtsChanged_ multiPath_
  460.     set INFINITY [$class set INFINITY]
  461.     set MAXPREF  [rtObject set maxpref_]
  462.     set UNREACH  [rtObject set unreach_]
  463.     set rtsChanged_ 0
  464.     foreach dst [$ns_ all-nodes-list] {
  465. set p [lindex $nextHopPeer_($dst) 0]
  466. if {$p != ""} {
  467.     set metric_($dst) [$p metric? $dst]
  468.     set rtpref_($dst) [$p preference? $dst]
  469. }
  470. set pf $MAXPREF
  471. set mt $INFINITY
  472. set nh(0) 0
  473. foreach nbr [lsort -dictionary [array names peers_]] {
  474.     set pmt [$peers_($nbr) metric? $dst]
  475.     set ppf [$peers_($nbr) preference? $dst]
  476.     # if peer metric not valid continue
  477.     # if peer pref higher continue
  478.     # if peer pref lower set to latest values
  479.     # else peer pref equal
  480.     # if peer metric higher continue
  481.     # if peer metric lower set to latest values
  482.     # else peer metrics equal append latest values
  483.     if { $pmt < 0 || $pmt >= $INFINITY || $ppf > $pf || $pmt > $mt } 
  484.     continue
  485.     if { $ppf < $pf || $pmt < $mt } {
  486. set pf $ppf
  487. set mt $pmt
  488. unset nh ;# because we must compute *new* next hops
  489.     }
  490.     set nh($ifs_($nbr)) $peers_($nbr)
  491. }
  492. catch "unset nh(0)"
  493. if { $pf == $MAXPREF && $mt == $INFINITY } continue
  494. if { $pf > $rtpref_($dst) ||
  495. ($metric_($dst) >= 0 && $mt > $metric_($dst)) }
  496. continue
  497. if {$mt >= $INFINITY} {
  498.     set mt $UNREACH
  499. }
  500. incr rtsChanged_
  501. if { $pf < $rtpref_($dst) || $mt < $metric_($dst) } {
  502.     set rtpref_($dst) $pf
  503.     set metric_($dst) $mt
  504.     set nextHop_($dst) ""
  505.     set nextHopPeer_($dst) ""
  506.     foreach n [array names nh] {
  507. lappend nextHop_($dst) $n
  508. lappend nextHopPeer_($dst) $nh($n)
  509. if !$multiPath_ break;
  510.     }
  511.     continue
  512. }
  513. set rtpref_($dst) $pf
  514. set metric_($dst) $mt
  515. set newNextHop ""
  516. set newNextHopPeer ""
  517. foreach rt $nextHop_($dst) {
  518.     if [info exists nh($rt)] {
  519. lappend newNextHop $rt
  520. lappend newNextHopPeer $nh($rt)
  521. unset nh($rt)
  522.     }
  523. }
  524. set nextHop_($dst) $newNextHop
  525. set nextHopPeer_($dst) $newNextHopPeer
  526. if { $multiPath_ || $nextHop_($dst) == "" } {
  527.     foreach rt [array names nh] {
  528. lappend nextHop_($dst) $rt
  529. lappend nextHopPeer_($dst) $nh($rt)
  530. if !$multiPath_ break
  531.     }
  532. }
  533.     }
  534.     set rtsChanged_
  535. }
  536. Agent/rtProto/DV instproc intf-changed {} {
  537.     $self instvar ns_ peers_ ifs_ ifstat_ ifsUp_ nextHop_ nextHopPeer_ metric_
  538.     set INFINITY [$class set INFINITY]
  539.     set ifsUp_ ""
  540.     foreach nbr [lsort -dictionary [array names peers_]] {
  541. set state [$ifs_($nbr) up?]
  542. if {$state != $ifstat_($nbr)} {
  543.     set ifstat_($nbr) $state
  544.     if {$state != "up"} {
  545. if ![info exists all-nodes] {
  546.     set all-nodes [$ns_ all-nodes-list]
  547. }
  548. foreach dest ${all-nodes} {
  549.     $peers_($nbr) metric $dest $INFINITY
  550. }
  551.     } else {
  552. lappend ifsUp_ $nbr
  553.     }
  554. }
  555.     }
  556. }
  557. Agent/rtProto/DV proc get-next-mid {} {
  558.     set ret [Agent/rtProto/DV set mid_]
  559.     Agent/rtProto/DV set mid_ [expr $ret + 1]
  560.     set ret
  561. }
  562. Agent/rtProto/DV proc retrieve-msg id {
  563.     set ret [Agent/rtProto/DV set msg_($id)]
  564.     Agent/rtProto/DV unset msg_($id)
  565.     set ret
  566. }
  567. Agent/rtProto/DV instproc send-updates changes {
  568.     $self instvar peers_ ifs_ ifsUp_
  569.     if $changes {
  570. set to-send-to [lsort -dictionary [array names peers_]]
  571.     } else {
  572. set to-send-to $ifsUp_
  573.     }
  574.     set ifsUp_ ""
  575.     foreach nbr ${to-send-to} {
  576. if { [$ifs_($nbr) up?] == "up" } {
  577.     $self send-to-peer $nbr
  578. }
  579.     }
  580. }
  581. Agent/rtProto/DV instproc send-to-peer nbr {
  582.     $self instvar ns_ rtObject_ ifs_ peers_
  583.     set INFINITY [$class set INFINITY]
  584.     foreach dest [$ns_ all-nodes-list] {
  585. set metric [$rtObject_ metric? $dest]
  586. if {$metric < 0} {
  587.     set update($dest) $INFINITY
  588. } else {
  589.     set update($dest) [$rtObject_ metric? $dest]
  590.     foreach nh [$rtObject_ nextHop? $dest] {
  591. if {$nh == $ifs_($nbr)} {
  592.     set update($dest) $INFINITY
  593. }
  594.     }
  595. }
  596.     }
  597.     ### modifed by Liang Guo, 11/11/99, what if there's no peer on that end?
  598.     ### needed when only part of the network nodes are using DV routing
  599.     if { $peers_($nbr) == "" } {
  600.         return
  601.     }
  602.     ##################### End ##########
  603.     set id [$class get-next-mid]
  604.     $class set msg_($id) [array get update]
  605.     # XXX Note the singularity below...
  606.     $self send-update [$peers_($nbr) addr?] [$peers_($nbr) port?] $id [array size update]
  607. }
  608. Agent/rtProto/DV instproc recv-update {peerAddr id} {
  609.     $self instvar peers_ ifs_ nextHopPeer_ metric_
  610.     $self instvar rtsChanged_ rtObject_
  611.     set INFINITY [$class set INFINITY]
  612.     set UNREACHABLE  [$class set UNREACHABLE]
  613.     set msg [$class retrieve-msg $id]
  614.     array set metrics $msg
  615.     foreach nbr [lsort -dictionary [array names peers_]] {
  616. if {[$peers_($nbr) addr?] == $peerAddr} {
  617.     set peer $peers_($nbr)
  618.     if { [array size metrics] > [Node set nn_] } {
  619. error "$class::$proc update $peerAddr:$msg:$count is larger than the simulation topology"
  620.     }
  621.     set metricsChanged 0
  622.     foreach dest [array names metrics] {
  623.                 set metric [expr $metrics($dest) + [$ifs_($nbr) cost?]]
  624. if {$metric > $INFINITY} {
  625.     set metric $INFINITY
  626. }
  627. if {$metric != [$peer metric? $dest]} {
  628.     $peer metric $dest $metric
  629.     incr metricsChanged
  630. }
  631.     }
  632.     if $metricsChanged {
  633. $self compute-routes
  634. incr rtsChanged_ $metricsChanged
  635. $rtObject_ compute-routes
  636.     } else {
  637. # dynamicDM multicast hack.
  638. # If we get a message from a neighbour, then something
  639. # at that neighbour has changed.  While this may not
  640. # cause any unicast changes on our end, dynamicDM
  641. # looks at neighbour's routing tables to compute
  642. # parent-child relationships, and has to do them
  643. # again.
  644. #
  645. $rtObject_ flag-multicast -1
  646.     }
  647.     return
  648. }
  649.     }
  650.     error "$class::$proc update $peerAddr:$msg:$count from unknown peer"
  651. }
  652. Agent/rtProto/DV proc compute-all {} {
  653.     # Because proc methods are not inherited from the parent class.
  654. }
  655. #
  656. # Manual routing
  657. #
  658. Class Agent/rtProto/Manual -superclass Agent/rtProto
  659. Agent/rtProto/Manual proc pre-init-all args {
  660.     Node enable-module Manual
  661. }
  662. Agent/rtProto/Manual proc init-all args {
  663.     # The user will do all routing.
  664. }
  665. ### Local Variables:
  666. ### mode: tcl
  667. ### tcl-indent-level: 4
  668. ### tcl-default-application: ns
  669. ### End: