File: ns-mpls-ldpagent.tcl

package info (click to toggle)
ns2 2.35%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 78,120 kB
  • sloc: cpp: 172,923; tcl: 107,127; perl: 6,391; sh: 6,143; ansic: 5,846; makefile: 812; awk: 525; csh: 355
file content (460 lines) | stat: -rw-r--r-- 14,525 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# -*-	Mode:tcl; tcl-indent-level:8; tab-width:8; indent-tabs-mode:t -*-
#
# Time-stamp: <2000-09-11 14:54:38 haoboy>
# 
#  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.
# 
#  Original source contributed by Gaeil Ahn. See below.
#
#  $Header: /cvsroot/nsnam/ns-2/tcl/mpls/ns-mpls-ldpagent.tcl,v 1.3 2005/09/16 03:05:45 tomh Exp $

###########################################################################
# Copyright (c) 2000 by Gaeil Ahn                                	  #
# Everyone is permitted to copy and distribute this software.		  #
# Please send mail to fog1@ce.cnu.ac.kr when you modify or distribute     #
# this sources.								  #
###########################################################################

#############################################################
#                                                           #
#     File: File for LDP protocol                           #
#     Author: Gaeil Ahn (fog1@ce.cnu.ac.kr), Jan. 2000      #
#                                                           #
#############################################################

Agent/LDP instproc set-mpls-module { mod } {
	$self set module_ $mod
}

Agent/LDP instproc get-request-msg {msgid src fec pathvec} {
	$self instvar node_ module_

	set pathvec [split $pathvec "_"]
	if {[lsearch $pathvec [$node_ id]] > -1} {
		# loop detected
		set ldpagent [$module_ get-ldp-agent $src]
		$ldpagent new-msgid
		$ldpagent send-notification-msg "LoopDetected" -1           
		
		return
	}
	
	set nexthop [$module_ get-nexthop $fec]
	if {$src == $nexthop} {
		#  message from downstream node
		$self request-msg-from-downstream $msgid $src $fec $pathvec
	} else {
		#  message from upstream node
		$self request-msg-from-upstream $msgid $src $fec $pathvec
	}
}

Agent/LDP instproc request-msg-from-downstream {msgid src fec pathvec} {
	$self instvar module_

	#  1. allocate label (upstream label allocation)
	set outlabel [$module_ get-outgoing-label $fec -1]
	if { $outlabel < 0 } {
		if { $fec == $src } {
			# This is a penultimate hop
			set outlabel 0
		} else {
			set outlabel [$module_ new-outgoing-label]
		}     
		$module_ out-label-install $fec -1 $src $outlabel             
	} else {
		set outIface [$module_ get-outgoing-iface $fec -1]
		if { $src != $outIface} {
			# wrong LIB information, let's fix it up
			$module_ out-label-install $fec -1 $src $outlabel
		} 
	}
	
	#  2. reply a allocated label to $src
	set ldpagent [$module_ get-ldp-agent $src]
	$ldpagent new-msgid
	$ldpagent send-mapping-msg $fec $outlabel "*" $msgid

	#  3. trigger label distribution (control-driven-trigger)
	#     not support on-demand mode in control-driven-trigger
	$module_ ldp-trigger-by-control $fec $pathvec
}

Agent/LDP instproc request-msg-from-upstream {msgid src fec pathvec} {
	$self instvar module_

	#  ldp agent for src
	set ldpagent [$module_ get-ldp-agent $src]

	# This is a egress LSR
	if { [$module_ is-egress-lsr $fec] == 1 } {
                $ldpagent new-msgid
                $ldpagent send-mapping-msg $fec 0 "*" $msgid
                return
	}
	
	set inlabel  [$module_ get-incoming-label $fec -1]
	set outlabel [$module_ get-outgoing-label $fec -1]
	#
	# ordered-control mode
	#
	if { [Classifier/Addr/MPLS ordered-control?] == 1 } {
		if { $outlabel > -1 } {
			if { $inlabel < 0 } {
				set inlabel [$module_ new-incoming-label]
			}
			$ldpagent new-msgid
			$ldpagent send-mapping-msg $fec inlabel "*" $msgid
		} else {
			$module_ ldp-trigger-by-data $msgid $src $fec $pathvec
		}
		return
	}
	#
	#  independent-control mode
	#
	#  1. allocate label (upstream label allocation)
	if { $inlabel < 0 } {
		set inlabel [$module_ new-incoming-label]
		$module_ in-label-install $fec -1 $src $inlabel
	} else {
		set inIface [$module_ get-incoming-iface $fec -1]
		if { $src != $inIface} {
			set classifier [$module_ set classifier_]
			set dontcare [$classifier set dont_care_]
			$module_ in-label-install $fec -1 -1 $dontcare
		} 
	}
	#  2. reply a allocated label to $src
	$ldpagent new-msgid
	$ldpagent send-mapping-msg $fec $inlabel "*" $msgid
	#  3. trigger label distribution (data-driven-trigger)
	#     support on-demand mode in data-driven-trigger
	$module_ ldp-trigger-by-data $msgid $src $fec $pathvec
}

Agent/LDP instproc get-cr-request-msg {msgid src fec pathvec er lspid rc} {
	$self instvar node_ module_

	#
	#  CR-LDP:  used to setup explicit-LSP
	#
	set pathvec [split $pathvec "_"]
	if {[lsearch $pathvec [$node_ id]] > -1} {
		# loop detected
		set ldpagent [$module_ get-ldp-agent $src]
		$ldpagent new-msgid
		$ldpagent send-notification-msg "NoRoute" $lspid
		return
	}
	
	# reserve a required resources using $rc
	# if a reservation fails, send notificaiton-msg

	#  ldp agent for src
	set ldpagent [$module_ get-ldp-agent $src]

	#  if a outgoing label for the fec exists ingnore this request-msg and
	#  send cr-mapping-msg.
	set inlabel [$module_ get-incoming-label $fec $lspid]
	set outlabel [$module_ get-outgoing-label $fec $lspid]
	
	if { $outlabel > -1 } {
                if { $inlabel < 0 } {
			set inlabel [$module_ new-incoming-label]
			$module_ in-label-install $fec $lspid $src $inlabel
                }
                $ldpagent new-msgid
                $ldpagent send-cr-mapping-msg $fec $inlabel $lspid $msgid
                return
	}

	$module_ ldp-trigger-by-explicit-route $msgid $src $fec $pathvec $er \
			$lspid $rc
}

Agent/LDP instproc get-cr-mapping-msg {msgid src fec label lspid reqmsgid} {
	$self instvar node_ trace_ldp_ module_

	# select a upstream-node to receive a mapping-msg in msgtbl
	# and clear the msgtbl entry

	set prvsrc   [$self msgtbl-get-src       $reqmsgid]
	set prvmsgid [$self msgtbl-get-reqmsgid  $reqmsgid]
	set labelop  [$self msgtbl-get-labelop   $reqmsgid]
	if {$labelop == 2} {
		set tunnelid [$self msgtbl-get-erlspid   $reqmsgid]
	} else {
		set tunnelid -1
	}
	
	$self msgtbl-clear $reqmsgid

	if { $trace_ldp_ } {
		puts "$src -> [$node_ id] : prvsrc($prvsrc)"
	}
	
	# allocate outgoing-label
	if { $labelop == 2 } {
		# stack operation
		$module_ out-label-install $fec $lspid $src $label
		$module_ erlsp-stacking $lspid $tunnelid
	} elseif {$labelop == 1} {
		# only pass label
		set ldpagent [$module_ get-ldp-agent $prvsrc]
		$ldpagent new-msgid
		$ldpagent send-cr-mapping-msg $fec $label $lspid $prvmsgid
		return
	} else {
		# use the label
		$module_ out-label-install $fec $lspid  $src $label
	}
	
	if {$prvsrc == [$node_ id]} {
		return
	}

	# allocate incoming-label            
	set inlabel [$module_ new-incoming-label]
	$module_ in-label-install $fec $lspid $prvsrc $inlabel

	# find a ldpagent for a upstream-node, continually send a 
	# mapping-msg to the node
	set ldpagent [$module_ get-ldp-agent $prvsrc]
	$ldpagent new-msgid
	$ldpagent send-cr-mapping-msg $fec $inlabel $lspid $prvmsgid
}

# msgid    : the msgid of a mapping message sent by dstination
# reqmsgid : the msgid of a request message sent by me before
Agent/LDP instproc get-mapping-msg {msgid src fec label pathvec reqmsgid} {
	$self instvar node_ trace_ldp_ module_

	if { $trace_ldp_ } {
		puts "[[Simulator instance] now]: <mapping-msg> $src ->\
[$node_ id] : fec($fec), label($label) [$module_ get-nexthop $fec]"
	}
	
	set pathvec [split $pathvec "_"]
	if {[lsearch $pathvec [$node_ id]] > -1} {
		# loop detected
		set ldpagent [$module_ get-ldp-agent $src]
		$ldpagent new-msgid
		$ldpagent send-notification-msg "LoopDetected" -1           
		return
	}

	set nexthop [$module_ get-nexthop $fec]
	if {$src == $nexthop} {
		#  message from downstream node
		$self mapping-msg-from-downstream $msgid $src $fec $label \
				$pathvec $reqmsgid
	} else {
		#  message from upstream node
		$self mapping-msg-from-upstream $msgid $src $fec $label \
				$pathvec $reqmsgid
	}
}

Agent/LDP instproc mapping-msg-from-downstream {msgid src fec label \
		pathvec reqmsgid} {
	$self instvar node_ module_

	#  allocate label (upstream label allocation)
	$module_ out-label-install $fec -1 $src $label
	if { $reqmsgid > -1 } {
		# downstream-on-demand mode
		
		# 1. find a upstream-node who sent a request-msg in msgtbl
		#    & delete entry in msgtbl
		set prvsrc   [$self msgtbl-get-src      $reqmsgid]
		set prvmsgid [$self msgtbl-get-reqmsgid $reqmsgid]
		$self msgtbl-clear $reqmsgid
		if { $prvsrc == [$node_ id] || $prvsrc < 0} {
			return
		}
		if { [Classifier/Addr/MPLS ordered-control?] == 1 } {
			# ordered-control mode

			# 1. allocate incoming-label
			set inlabel [$module_ new-incoming-label]
			$module_ in-label-install $fec -1 $prvsrc $inlabel
			# 2. find a ldpagent for a upstream-node,
			#    send a mapping-msg forward a upstream-node
			set ldpagent [$module_ get-ldp-agent $prvsrc]
			$ldpagent new-msgid
			$ldpagent send-mapping-msg $fec $inlabel -1 $prvmsgid
			return
		}
	} else {
		#  trigger label distribution (control-driven-trigger)
		$module_ ldp-trigger-by-control $fec $pathvec
		return
	}
}

Agent/LDP instproc mapping-msg-from-upstream {msgid src fec label pathvec \
		reqmsgid} {
	$self instvar node_ module_

	# check whether or not myself is a next hop of src for a fec.
	set nexthop [$module_ lookup-nexthop $src $fec]
	if { $nexthop != [$node_ id] } {
		return
	}

	#  1. allocate label (upstream label allocation)
	set inlabel [$module_ get-incoming-label $fec -1]
	if { $inlabel == -1 } {
		if { [$module_ is-egress-lsr $fec] == 1 } {
			#  message from a penultimate hop
			#  so, send a null label to a penultimate hop
			if { $label != 0 } {
				set ldpagent [$module_ get-ldp-agent $src]
				$ldpagent new-msgid
				$ldpagent send-mapping-msg $fec 0 "*" $msgid
			}
		} else {
			$module_ in-label-install $fec -1 $src $label
		}
	} else {
		set ldpagent [$module_ get-ldp-agent $src]
		if { $reqmsgid < 0 } {
			$ldpagent new-msgid
			$ldpagent send-mapping-msg $fec $inlabel "*" $msgid
		}   
	}    
	#  2. trigger label distribution (data-driven-trigger)
	#     support on-demand mode only in data-driven-trigger
	if { $reqmsgid < 0 } {
		$module_ ldp-trigger-by-data -1 $src $fec $pathvec
	} else {   
		# if ($reqmsgid > -1) then delete a entry in msgid table
		$self msgtbl-clear $reqmsgid
	}    
}

Agent/LDP instproc get-notification-msg {src status lspid} {
	$self instvar node_ trace_ldp_ module_

	# Notification-msg (in case of Loop Detection, No Route)
	if { $trace_ldp_ } {
		puts "Notification($src->[$node_ id]): $status src=$src lspid=$lspid"
	}
	set msgid [$self msgtbl-get-msgid -1 $lspid -1]
	if {$msgid > -1} {
		set prvsrc   [$self msgtbl-get-src      $msgid]
		$self msgtbl-clear $msgid            
		if { $prvsrc < -1 || $prvsrc == [$node_ id] } {
			return
		}
		set ldpagent [$module_ get-ldp-agent $prvsrc]
		$ldpagent new-msgid
		$ldpagent send-notification-msg $status $lspid
	}
}

Agent/LDP instproc get-withdraw-msg {src fec lspid} {
	$self instvar module_

	# withdraw msg : downstream -> upstream
	set outiface  [$module_ get-outgoing-iface $fec $lspid]
	if {$src == $outiface} {
		$module_ out-label-clear $fec $lspid
		set inlabel [$module_ get-incoming-label $fec $lspid]
		if {$inlabel > -1} {
			$module_ ldp-trigger-by-withdraw $fec $lspid
		}
	}
}

Agent/LDP instproc get-release-msg {src fec lspid} {
	$self instvar module_
	
	# release msg : upstream --> downstream
	set iniface  [$module_ get-incoming-iface $fec $lspid]
	set outlabel [$module_ get-outgoing-label $fec $lspid]
	if {$iniface == $src} {
		$module_ in-label-clear $fec $lspid 
		if {$outlabel > -1} {
			$module_ ldp-trigger-by-release $fec $lspid
		}
	} 
}

Agent/LDP instproc trace-ldp-packet {src_addr src_port msgtype msgid fec \
		label pathvec lspid er rc reqmsgid status atime} {
	$self instvar node_
	puts "$atime [$node_ id]: $src_addr ($msgtype $msgid) $fec $label $pathvec  \[$reqmsgid $status\]  \[$lspid $er $rc\]"
}

Agent/LDP instproc send-notification-msg {status lspid} {
	$self set fid_ 101
	$self cmd notification-msg $status $lspid
}

Agent/LDP instproc send-request-msg {fec pathvec} {
	$self set fid_ 102
	$self request-msg $fec $pathvec
}

Agent/LDP instproc send-mapping-msg {fec label pathvec reqmsgid} {
	$self set fid_ 103
	$self cmd mapping-msg $fec $label $pathvec $reqmsgid
}

Agent/LDP instproc send-withdraw-msg {fec lspid} {
	$self set fid_ 104
	$self withdraw-msg $fec $lspid
}

Agent/LDP instproc send-release-msg {fec lspid} {
	$self set fid_ 105
	$self release-msg $fec $lspid
}

Agent/LDP instproc send-cr-request-msg {fec pathvec er lspid rc} {
	$self set fid_ 102
	$self cr-request-msg $fec $pathvec $er $lspid $rc
}

Agent/LDP instproc send-cr-mapping-msg {fec inlabel lspid prvmsgid} {
	$self set fid_ 103
	$self cr-mapping-msg $fec $inlabel $lspid $prvmsgid
}