ns-mpls-ldpagent.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:14k
源码类别:

通讯编程

开发平台:

Visual C++

  1. # -*- Mode:tcl; tcl-indent-level:8; tab-width:8; indent-tabs-mode:t -*-
  2. #
  3. # Time-stamp: <2000-09-11 14:54:38 haoboy>
  4. #  This program is free software; you can redistribute it and/or
  5. #  modify it under the terms of the GNU General Public License,
  6. #  version 2, as published by the Free Software Foundation.
  7. #
  8. #  This program is distributed in the hope that it will be useful,
  9. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. #  GNU General Public License for more details.
  12. #
  13. #  You should have received a copy of the GNU General Public License along
  14. #  with this program; if not, write to the Free Software Foundation, Inc.,
  15. #  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  16. #
  17. #  The copyright of this module includes the following
  18. #  linking-with-specific-other-licenses addition:
  19. #
  20. #  In addition, as a special exception, the copyright holders of
  21. #  this module give you permission to combine (via static or
  22. #  dynamic linking) this module with free software programs or
  23. #  libraries that are released under the GNU LGPL and with code
  24. #  included in the standard release of ns-2 under the Apache 2.0
  25. #  license or under otherwise-compatible licenses with advertising
  26. #  requirements (or modified versions of such code, with unchanged
  27. #  license).  You may copy and distribute such a system following the
  28. #  terms of the GNU GPL for this module and the licenses of the
  29. #  other code concerned, provided that you include the source code of
  30. #  that other code when and as the GNU GPL requires distribution of
  31. #  source code.
  32. #
  33. #  Note that people who make modified versions of this module
  34. #  are not obligated to grant this special exception for their
  35. #  modified versions; it is their choice whether to do so.  The GNU
  36. #  General Public License gives permission to release a modified
  37. #  version without this exception; this exception also makes it
  38. #  possible to release a modified version which carries forward this
  39. #  exception.
  40. #  Original source contributed by Gaeil Ahn. See below.
  41. #
  42. #  $Header: /cvsroot/nsnam/ns-2/tcl/mpls/ns-mpls-ldpagent.tcl,v 1.3 2005/09/16 03:05:45 tomh Exp $
  43. ###########################################################################
  44. # Copyright (c) 2000 by Gaeil Ahn                                   #
  45. # Everyone is permitted to copy and distribute this software.   #
  46. # Please send mail to fog1@ce.cnu.ac.kr when you modify or distribute     #
  47. # this sources.   #
  48. ###########################################################################
  49. #############################################################
  50. #                                                           #
  51. #     File: File for LDP protocol                           #
  52. #     Author: Gaeil Ahn (fog1@ce.cnu.ac.kr), Jan. 2000      #
  53. #                                                           #
  54. #############################################################
  55. Agent/LDP instproc set-mpls-module { mod } {
  56. $self set module_ $mod
  57. }
  58. Agent/LDP instproc get-request-msg {msgid src fec pathvec} {
  59. $self instvar node_ module_
  60. set pathvec [split $pathvec "_"]
  61. if {[lsearch $pathvec [$node_ id]] > -1} {
  62. # loop detected
  63. set ldpagent [$module_ get-ldp-agent $src]
  64. $ldpagent new-msgid
  65. $ldpagent send-notification-msg "LoopDetected" -1           
  66. return
  67. }
  68. set nexthop [$module_ get-nexthop $fec]
  69. if {$src == $nexthop} {
  70. #  message from downstream node
  71. $self request-msg-from-downstream $msgid $src $fec $pathvec
  72. } else {
  73. #  message from upstream node
  74. $self request-msg-from-upstream $msgid $src $fec $pathvec
  75. }
  76. }
  77. Agent/LDP instproc request-msg-from-downstream {msgid src fec pathvec} {
  78. $self instvar module_
  79. #  1. allocate label (upstream label allocation)
  80. set outlabel [$module_ get-outgoing-label $fec -1]
  81. if { $outlabel < 0 } {
  82. if { $fec == $src } {
  83. # This is a penultimate hop
  84. set outlabel 0
  85. } else {
  86. set outlabel [$module_ new-outgoing-label]
  87. }     
  88. $module_ out-label-install $fec -1 $src $outlabel             
  89. } else {
  90. set outIface [$module_ get-outgoing-iface $fec -1]
  91. if { $src != $outIface} {
  92. # wrong LIB information, let's fix it up
  93. $module_ out-label-install $fec -1 $src $outlabel
  94. }
  95. #  2. reply a allocated label to $src
  96. set ldpagent [$module_ get-ldp-agent $src]
  97. $ldpagent new-msgid
  98. $ldpagent send-mapping-msg $fec $outlabel "*" $msgid
  99. #  3. trigger label distribution (control-driven-trigger)
  100. #     not support on-demand mode in control-driven-trigger
  101. $module_ ldp-trigger-by-control $fec $pathvec
  102. }
  103. Agent/LDP instproc request-msg-from-upstream {msgid src fec pathvec} {
  104. $self instvar module_
  105. #  ldp agent for src
  106. set ldpagent [$module_ get-ldp-agent $src]
  107. # This is a egress LSR
  108. if { [$module_ is-egress-lsr $fec] == 1 } {
  109.                 $ldpagent new-msgid
  110.                 $ldpagent send-mapping-msg $fec 0 "*" $msgid
  111.                 return
  112. }
  113. set inlabel  [$module_ get-incoming-label $fec -1]
  114. set outlabel [$module_ get-outgoing-label $fec -1]
  115. #
  116. # ordered-control mode
  117. #
  118. if { [Classifier/Addr/MPLS ordered-control?] == 1 } {
  119. if { $outlabel > -1 } {
  120. if { $inlabel < 0 } {
  121. set inlabel [$module_ new-incoming-label]
  122. }
  123. $ldpagent new-msgid
  124. $ldpagent send-mapping-msg $fec inlabel "*" $msgid
  125. } else {
  126. $module_ ldp-trigger-by-data $msgid $src $fec $pathvec
  127. }
  128. return
  129. }
  130. #
  131. #  independent-control mode
  132. #
  133. #  1. allocate label (upstream label allocation)
  134. if { $inlabel < 0 } {
  135. set inlabel [$module_ new-incoming-label]
  136. $module_ in-label-install $fec -1 $src $inlabel
  137. } else {
  138. set inIface [$module_ get-incoming-iface $fec -1]
  139. if { $src != $inIface} {
  140. set classifier [$module_ set classifier_]
  141. set dontcare [$classifier set dont_care_]
  142. $module_ in-label-install $fec -1 -1 $dontcare
  143. }
  144. #  2. reply a allocated label to $src
  145. $ldpagent new-msgid
  146. $ldpagent send-mapping-msg $fec $inlabel "*" $msgid
  147. #  3. trigger label distribution (data-driven-trigger)
  148. #     support on-demand mode in data-driven-trigger
  149. $module_ ldp-trigger-by-data $msgid $src $fec $pathvec
  150. }
  151. Agent/LDP instproc get-cr-request-msg {msgid src fec pathvec er lspid rc} {
  152. $self instvar node_ module_
  153. #
  154. #  CR-LDP:  used to setup explicit-LSP
  155. #
  156. set pathvec [split $pathvec "_"]
  157. if {[lsearch $pathvec [$node_ id]] > -1} {
  158. # loop detected
  159. set ldpagent [$module_ get-ldp-agent $src]
  160. $ldpagent new-msgid
  161. $ldpagent send-notification-msg "NoRoute" $lspid
  162. return
  163. }
  164. # reserve a required resources using $rc
  165. # if a reservation fails, send notificaiton-msg
  166. #  ldp agent for src
  167. set ldpagent [$module_ get-ldp-agent $src]
  168. #  if a outgoing label for the fec exists ingnore this request-msg and
  169. #  send cr-mapping-msg.
  170. set inlabel [$module_ get-incoming-label $fec $lspid]
  171. set outlabel [$module_ get-outgoing-label $fec $lspid]
  172. if { $outlabel > -1 } {
  173.                 if { $inlabel < 0 } {
  174. set inlabel [$module_ new-incoming-label]
  175. $module_ in-label-install $fec $lspid $src $inlabel
  176.                 }
  177.                 $ldpagent new-msgid
  178.                 $ldpagent send-cr-mapping-msg $fec $inlabel $lspid $msgid
  179.                 return
  180. }
  181. $module_ ldp-trigger-by-explicit-route $msgid $src $fec $pathvec $er 
  182. $lspid $rc
  183. }
  184. Agent/LDP instproc get-cr-mapping-msg {msgid src fec label lspid reqmsgid} {
  185. $self instvar node_ trace_ldp_ module_
  186. # select a upstream-node to receive a mapping-msg in msgtbl
  187. # and clear the msgtbl entry
  188. set prvsrc   [$self msgtbl-get-src       $reqmsgid]
  189. set prvmsgid [$self msgtbl-get-reqmsgid  $reqmsgid]
  190. set labelop  [$self msgtbl-get-labelop   $reqmsgid]
  191. if {$labelop == 2} {
  192. set tunnelid [$self msgtbl-get-erlspid   $reqmsgid]
  193. } else {
  194. set tunnelid -1
  195. }
  196. $self msgtbl-clear $reqmsgid
  197. if { $trace_ldp_ } {
  198. puts "$src -> [$node_ id] : prvsrc($prvsrc)"
  199. }
  200. # allocate outgoing-label
  201. if { $labelop == 2 } {
  202. # stack operation
  203. $module_ out-label-install $fec $lspid $src $label
  204. $module_ erlsp-stacking $lspid $tunnelid
  205. } elseif {$labelop == 1} {
  206. # only pass label
  207. set ldpagent [$module_ get-ldp-agent $prvsrc]
  208. $ldpagent new-msgid
  209. $ldpagent send-cr-mapping-msg $fec $label $lspid $prvmsgid
  210. return
  211. } else {
  212. # use the label
  213. $module_ out-label-install $fec $lspid  $src $label
  214. }
  215. if {$prvsrc == [$node_ id]} {
  216. return
  217. }
  218. # allocate incoming-label            
  219. set inlabel [$module_ new-incoming-label]
  220. $module_ in-label-install $fec $lspid $prvsrc $inlabel
  221. # find a ldpagent for a upstream-node, continually send a 
  222. # mapping-msg to the node
  223. set ldpagent [$module_ get-ldp-agent $prvsrc]
  224. $ldpagent new-msgid
  225. $ldpagent send-cr-mapping-msg $fec $inlabel $lspid $prvmsgid
  226. }
  227. # msgid    : the msgid of a mapping message sent by dstination
  228. # reqmsgid : the msgid of a request message sent by me before
  229. Agent/LDP instproc get-mapping-msg {msgid src fec label pathvec reqmsgid} {
  230. $self instvar node_ trace_ldp_ module_
  231. if { $trace_ldp_ } {
  232. puts "[[Simulator instance] now]: <mapping-msg> $src ->
  233. [$node_ id] : fec($fec), label($label) [$module_ get-nexthop $fec]"
  234. }
  235. set pathvec [split $pathvec "_"]
  236. if {[lsearch $pathvec [$node_ id]] > -1} {
  237. # loop detected
  238. set ldpagent [$module_ get-ldp-agent $src]
  239. $ldpagent new-msgid
  240. $ldpagent send-notification-msg "LoopDetected" -1           
  241. return
  242. }
  243. set nexthop [$module_ get-nexthop $fec]
  244. if {$src == $nexthop} {
  245. #  message from downstream node
  246. $self mapping-msg-from-downstream $msgid $src $fec $label 
  247. $pathvec $reqmsgid
  248. } else {
  249. #  message from upstream node
  250. $self mapping-msg-from-upstream $msgid $src $fec $label 
  251. $pathvec $reqmsgid
  252. }
  253. }
  254. Agent/LDP instproc mapping-msg-from-downstream {msgid src fec label 
  255. pathvec reqmsgid} {
  256. $self instvar node_ module_
  257. #  allocate label (upstream label allocation)
  258. $module_ out-label-install $fec -1 $src $label
  259. if { $reqmsgid > -1 } {
  260. # downstream-on-demand mode
  261. # 1. find a upstream-node who sent a request-msg in msgtbl
  262. #    & delete entry in msgtbl
  263. set prvsrc   [$self msgtbl-get-src      $reqmsgid]
  264. set prvmsgid [$self msgtbl-get-reqmsgid $reqmsgid]
  265. $self msgtbl-clear $reqmsgid
  266. if { $prvsrc == [$node_ id] || $prvsrc < 0} {
  267. return
  268. }
  269. if { [Classifier/Addr/MPLS ordered-control?] == 1 } {
  270. # ordered-control mode
  271. # 1. allocate incoming-label
  272. set inlabel [$module_ new-incoming-label]
  273. $module_ in-label-install $fec -1 $prvsrc $inlabel
  274. # 2. find a ldpagent for a upstream-node,
  275. #    send a mapping-msg forward a upstream-node
  276. set ldpagent [$module_ get-ldp-agent $prvsrc]
  277. $ldpagent new-msgid
  278. $ldpagent send-mapping-msg $fec $inlabel -1 $prvmsgid
  279. return
  280. }
  281. } else {
  282. #  trigger label distribution (control-driven-trigger)
  283. $module_ ldp-trigger-by-control $fec $pathvec
  284. return
  285. }
  286. }
  287. Agent/LDP instproc mapping-msg-from-upstream {msgid src fec label pathvec 
  288. reqmsgid} {
  289. $self instvar node_ module_
  290. # check whether or not myself is a next hop of src for a fec.
  291. set nexthop [$module_ lookup-nexthop $src $fec]
  292. if { $nexthop != [$node_ id] } {
  293. return
  294. }
  295. #  1. allocate label (upstream label allocation)
  296. set inlabel [$module_ get-incoming-label $fec -1]
  297. if { $inlabel == -1 } {
  298. if { [$module_ is-egress-lsr $fec] == 1 } {
  299. #  message from a penultimate hop
  300. #  so, send a null label to a penultimate hop
  301. if { $label != 0 } {
  302. set ldpagent [$module_ get-ldp-agent $src]
  303. $ldpagent new-msgid
  304. $ldpagent send-mapping-msg $fec 0 "*" $msgid
  305. }
  306. } else {
  307. $module_ in-label-install $fec -1 $src $label
  308. }
  309. } else {
  310. set ldpagent [$module_ get-ldp-agent $src]
  311. if { $reqmsgid < 0 } {
  312. $ldpagent new-msgid
  313. $ldpagent send-mapping-msg $fec $inlabel "*" $msgid
  314. }   
  315. }    
  316. #  2. trigger label distribution (data-driven-trigger)
  317. #     support on-demand mode only in data-driven-trigger
  318. if { $reqmsgid < 0 } {
  319. $module_ ldp-trigger-by-data -1 $src $fec $pathvec
  320. } else {   
  321. # if ($reqmsgid > -1) then delete a entry in msgid table
  322. $self msgtbl-clear $reqmsgid
  323. }    
  324. }
  325. Agent/LDP instproc get-notification-msg {src status lspid} {
  326. $self instvar node_ trace_ldp_ module_
  327. # Notification-msg (in case of Loop Detection, No Route)
  328. if { $trace_ldp_ } {
  329. puts "Notification($src->[$node_ id]): $status src=$src lspid=$lspid"
  330. }
  331. set msgid [$self msgtbl-get-msgid -1 $lspid -1]
  332. if {$msgid > -1} {
  333. set prvsrc   [$self msgtbl-get-src      $msgid]
  334. $self msgtbl-clear $msgid            
  335. if { $prvsrc < -1 || $prvsrc == [$node_ id] } {
  336. return
  337. }
  338. set ldpagent [$module_ get-ldp-agent $prvsrc]
  339. $ldpagent new-msgid
  340. $ldpagent send-notification-msg $status $lspid
  341. }
  342. }
  343. Agent/LDP instproc get-withdraw-msg {src fec lspid} {
  344. $self instvar module_
  345. # withdraw msg : downstream -> upstream
  346. set outiface  [$module_ get-outgoing-iface $fec $lspid]
  347. if {$src == $outiface} {
  348. $module_ out-label-clear $fec $lspid
  349. set inlabel [$module_ get-incoming-label $fec $lspid]
  350. if {$inlabel > -1} {
  351. $module_ ldp-trigger-by-withdraw $fec $lspid
  352. }
  353. }
  354. }
  355. Agent/LDP instproc get-release-msg {src fec lspid} {
  356. $self instvar module_
  357. # release msg : upstream --> downstream
  358. set iniface  [$module_ get-incoming-iface $fec $lspid]
  359. set outlabel [$module_ get-outgoing-label $fec $lspid]
  360. if {$iniface == $src} {
  361. $module_ in-label-clear $fec $lspid 
  362. if {$outlabel > -1} {
  363. $module_ ldp-trigger-by-release $fec $lspid
  364. }
  365. }
  366. Agent/LDP instproc trace-ldp-packet {src_addr src_port msgtype msgid fec 
  367. label pathvec lspid er rc reqmsgid status atime} {
  368. $self instvar node_
  369. puts "$atime [$node_ id]: $src_addr ($msgtype $msgid) $fec $label $pathvec  [$reqmsgid $status]  [$lspid $er $rc]"
  370. }
  371. Agent/LDP instproc send-notification-msg {status lspid} {
  372. $self set fid_ 101
  373. $self cmd notification-msg $status $lspid
  374. }
  375. Agent/LDP instproc send-request-msg {fec pathvec} {
  376. $self set fid_ 102
  377. $self request-msg $fec $pathvec
  378. }
  379. Agent/LDP instproc send-mapping-msg {fec label pathvec reqmsgid} {
  380. $self set fid_ 103
  381. $self cmd mapping-msg $fec $label $pathvec $reqmsgid
  382. }
  383. Agent/LDP instproc send-withdraw-msg {fec lspid} {
  384. $self set fid_ 104
  385. $self withdraw-msg $fec $lspid
  386. }
  387. Agent/LDP instproc send-release-msg {fec lspid} {
  388. $self set fid_ 105
  389. $self release-msg $fec $lspid
  390. }
  391. Agent/LDP instproc send-cr-request-msg {fec pathvec er lspid rc} {
  392. $self set fid_ 102
  393. $self cr-request-msg $fec $pathvec $er $lspid $rc
  394. }
  395. Agent/LDP instproc send-cr-mapping-msg {fec inlabel lspid prvmsgid} {
  396. $self set fid_ 103
  397. $self cr-mapping-msg $fec $inlabel $lspid $prvmsgid
  398. }