ospfv2 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/ospfv2 +136 -0
- data/lib/ie/au_type.rb +79 -0
- data/lib/ie/external_route.rb +181 -0
- data/lib/ie/id.rb +97 -0
- data/lib/ie/interface_mtu.rb +64 -0
- data/lib/ie/ls_age.rb +89 -0
- data/lib/ie/ls_type.rb +148 -0
- data/lib/ie/metric.rb +63 -0
- data/lib/ie/mt_metric.rb +119 -0
- data/lib/ie/options.rb +356 -0
- data/lib/ie/ospf_version.rb +67 -0
- data/lib/ie/packet_type.rb +65 -0
- data/lib/ie/router_link.rb +167 -0
- data/lib/ie/router_link_factory.rb +53 -0
- data/lib/ie/router_link_type.rb +86 -0
- data/lib/ie/sequence_number.rb +144 -0
- data/lib/ie/tos_metric.rb +102 -0
- data/lib/infra/ospf_common.rb +291 -0
- data/lib/infra/ospf_constants.rb +73 -0
- data/lib/infra/ospf_io.rb +133 -0
- data/lib/infra/ospf_socket.rb +126 -0
- data/lib/infra/parse_options.rb +135 -0
- data/lib/infra/timer.rb +104 -0
- data/lib/infra/to_s.rb +38 -0
- data/lib/ls_db/advertised_routers.rb +78 -0
- data/lib/ls_db/common.rb +31 -0
- data/lib/ls_db/link_state_database.rb +376 -0
- data/lib/ls_db/link_state_database_build.rb +181 -0
- data/lib/ls_db/link_state_database_links.rb +178 -0
- data/lib/ls_db/links.rb +160 -0
- data/lib/lsa/external.rb +347 -0
- data/lib/lsa/lsa.rb +438 -0
- data/lib/lsa/lsa_factory.rb +59 -0
- data/lib/lsa/network.rb +166 -0
- data/lib/lsa/router.rb +336 -0
- data/lib/lsa/summary.rb +393 -0
- data/lib/neighbor/neighbor.rb +298 -0
- data/lib/neighbor/neighbor_event_handler.rb +61 -0
- data/lib/neighbor/recv_database_description.rb +153 -0
- data/lib/neighbor/recv_hello.rb +53 -0
- data/lib/neighbor/recv_ospf_packet.rb +68 -0
- data/lib/neighbor_sm/attempt_state.rb +44 -0
- data/lib/neighbor_sm/down_state.rb +46 -0
- data/lib/neighbor_sm/exchange_state.rb +32 -0
- data/lib/neighbor_sm/exstart_state.rb +69 -0
- data/lib/neighbor_sm/full_state.rb +36 -0
- data/lib/neighbor_sm/init_state.rb +43 -0
- data/lib/neighbor_sm/loading_state.rb +33 -0
- data/lib/neighbor_sm/neighbor_state.rb +87 -0
- data/lib/packet/database_description.rb +300 -0
- data/lib/packet/hello.rb +327 -0
- data/lib/packet/link_state_ack.rb +144 -0
- data/lib/packet/link_state_request.rb +153 -0
- data/lib/packet/link_state_update.rb +189 -0
- data/lib/packet/ospf_packet.rb +306 -0
- metadata +116 -0
@@ -0,0 +1,376 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of OSPFv2.
|
8
|
+
#
|
9
|
+
# OSPFv2 is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# OSPFv2 is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
=begin rdoc
|
26
|
+
|
27
|
+
12.2. The link state database
|
28
|
+
|
29
|
+
A router has a separate link state database for every area to
|
30
|
+
which it belongs. All routers belonging to the same area have
|
31
|
+
identical link state databases for the area.
|
32
|
+
|
33
|
+
The databases for each individual area are always dealt with
|
34
|
+
separately. The shortest path calculation is performed
|
35
|
+
separately for each area (see Section 16). Components of the
|
36
|
+
area link-state database are flooded throughout the area only.
|
37
|
+
Finally, when an adjacency (belonging to Area A) is being
|
38
|
+
brought up, only the database for Area A is synchronized between
|
39
|
+
the two routers.
|
40
|
+
|
41
|
+
The area database is composed of router-LSAs, network-LSAs and
|
42
|
+
summary-LSAs (all listed in the area data structure). In
|
43
|
+
addition, external routes (AS-external-LSAs) are included in all
|
44
|
+
non-stub area databases (see Section 3.6).
|
45
|
+
|
46
|
+
An implementation of OSPF must be able to access individual
|
47
|
+
pieces of an area database. This lookup function is based on an
|
48
|
+
LSA's LS type, Link State ID and Advertising Router.[14] There
|
49
|
+
will be a single instance (the most up-to-date) of each LSA in
|
50
|
+
the database. The database lookup function is invoked during
|
51
|
+
the LSA flooding procedure (Section 13) and the routing table
|
52
|
+
calculation (Section 16). In addition, using this lookup
|
53
|
+
function the router can determine whether it has itself ever
|
54
|
+
originated a particular LSA, and if so, with what LS sequence
|
55
|
+
number.
|
56
|
+
|
57
|
+
An LSA is added to a router's database when either a) it is
|
58
|
+
received during the flooding process (Section 13) or b) it is
|
59
|
+
originated by the router itself (Section 12.4). An LSA is
|
60
|
+
deleted from a router's database when either a) it has been
|
61
|
+
overwritten by a newer instance during the flooding process
|
62
|
+
(Section 13) or b) the router originates a newer instance of one
|
63
|
+
of its self-originated LSAs (Section 12.4) or c) the LSA ages
|
64
|
+
out and is flushed from the routing domain (Section 14).
|
65
|
+
Whenever an LSA is deleted from the database it must also be
|
66
|
+
removed from all neighbors' Link state retransmission lists (see
|
67
|
+
Section 10).
|
68
|
+
|
69
|
+
=end
|
70
|
+
|
71
|
+
require 'set'
|
72
|
+
require 'ie/id'
|
73
|
+
require 'lsa/lsa_factory'
|
74
|
+
require 'ls_db/common'
|
75
|
+
require 'ls_db/advertised_routers'
|
76
|
+
|
77
|
+
require 'infra/to_s'
|
78
|
+
|
79
|
+
module OSPFv2
|
80
|
+
|
81
|
+
module LSDB
|
82
|
+
|
83
|
+
class LinkStateDatabase
|
84
|
+
include OSPFv2
|
85
|
+
include OSPFv2::Common
|
86
|
+
include TO_S
|
87
|
+
|
88
|
+
AreaId = Class.new(OSPFv2::Id)
|
89
|
+
|
90
|
+
attr_reader :area_id
|
91
|
+
attr_writer_delegate :area_id
|
92
|
+
|
93
|
+
attr_reader :advertised_routers
|
94
|
+
attr_accessor :offset, :ls_refresh_interval
|
95
|
+
|
96
|
+
def initialize(arg={})
|
97
|
+
@ls_db = Hash.new
|
98
|
+
@area_id = nil
|
99
|
+
@advertised_routers= AdvertisedRouters.new
|
100
|
+
@ls_refresh_interval=180
|
101
|
+
@offset=0
|
102
|
+
set arg
|
103
|
+
end
|
104
|
+
|
105
|
+
def ls_refresh_time
|
106
|
+
@ls_refresh_time ||= LSRefreshTime
|
107
|
+
end
|
108
|
+
|
109
|
+
def ls_refresh_time=(val)
|
110
|
+
@ls_refresh_time=val
|
111
|
+
end
|
112
|
+
|
113
|
+
def proxied?(router_id)
|
114
|
+
advertised_routers.has?(router_id)
|
115
|
+
end
|
116
|
+
|
117
|
+
def all
|
118
|
+
@ls_db.values
|
119
|
+
end
|
120
|
+
alias :lsas :all
|
121
|
+
|
122
|
+
#TODO: add opaque and external type 7
|
123
|
+
LsType.all.each do |type|
|
124
|
+
define_method("all_#{type}") do
|
125
|
+
@ls_db.find_all { |k,v| k[0]== LsType.to_i(type) }.collect { |k,v| v }.sort_by { |l| l.advertising_router.to_i }
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def all_proxied
|
130
|
+
@ls_db.values.find_all { |lsa| advertised_routers.has? lsa.advertising_router }
|
131
|
+
end
|
132
|
+
|
133
|
+
def each
|
134
|
+
@ls_db.values.each do |lsa|
|
135
|
+
yield lsa
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def ls_db=(arg)
|
140
|
+
[arg].flatten.each { |l| self << l }
|
141
|
+
end
|
142
|
+
|
143
|
+
def keys
|
144
|
+
@ls_db.keys
|
145
|
+
end
|
146
|
+
|
147
|
+
def <<(lsa)
|
148
|
+
lsa = OSPFv2::Lsa.factory(lsa) unless lsa.is_a?(Lsa)
|
149
|
+
@ls_db.store(lsa.key,lsa)
|
150
|
+
lsa
|
151
|
+
end
|
152
|
+
|
153
|
+
def ls_ack(lsa)
|
154
|
+
|
155
|
+
lsa = lookup(lsa)
|
156
|
+
if lsa
|
157
|
+
if lsa.maxaged?
|
158
|
+
@ls_db.delete(lsa.key)
|
159
|
+
else
|
160
|
+
@ls_db[lsa.key].ack
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
def to_hash
|
167
|
+
h= { :area=> @area_id.to_ip }
|
168
|
+
h.store :ls_db, @ls_db.sort.collect {|p| p[1].to_hash }
|
169
|
+
h.store :advertised_routers, advertised_routers.routers
|
170
|
+
h.store :ls_refresh_time, ls_refresh_time
|
171
|
+
h.store :ls_refresh_interval, ls_refresh_interval
|
172
|
+
|
173
|
+
# h.store(:retransmit,@retransmit)
|
174
|
+
# h.store(:ls_rxmt_interval,@ls_rxmt_interval)
|
175
|
+
# h.store(:aging,self.aging)
|
176
|
+
h
|
177
|
+
end
|
178
|
+
|
179
|
+
def find_router_lsa(router_id)
|
180
|
+
lookup(1,router_id)
|
181
|
+
end
|
182
|
+
def find_asbr_sum(advertising_router)
|
183
|
+
lookup(4,advertising_router)
|
184
|
+
end
|
185
|
+
|
186
|
+
def lookup(*args)
|
187
|
+
if args.size==1
|
188
|
+
if args[0].is_a?(Array) and args[0].size==3
|
189
|
+
if args[0][0].is_a?(Symbol)
|
190
|
+
args[0][0] = LsType.to_i(args[0][0])
|
191
|
+
end
|
192
|
+
args[0][1] = id2i(args[0][1])
|
193
|
+
args[0][2] = id2i(args[0][2])
|
194
|
+
# lsdb.lookup([type,lsid,advr])
|
195
|
+
# self[args[0]]
|
196
|
+
@ls_db[args[0]]
|
197
|
+
elsif args[0].is_a?(Lsa)
|
198
|
+
# ls_db.lookup(lsa)
|
199
|
+
@ls_db[args[0].key]
|
200
|
+
else
|
201
|
+
raise ArgumentError, "Invalid argument, #{args.inspect}"
|
202
|
+
end
|
203
|
+
elsif args.size==3
|
204
|
+
# lsdb.lookup(type, lsid, advr)
|
205
|
+
lookup(args)
|
206
|
+
elsif args.size==2
|
207
|
+
# lsdb.lookup(type, lsid, lsid)
|
208
|
+
lookup([args[0],args[1],args[1]])
|
209
|
+
else
|
210
|
+
raise ArgumentError, "*** Invalid argument, #{args.inspect}"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
def refresh
|
216
|
+
all.find_all {|l| l.refresh(ls_refresh_time) }
|
217
|
+
end
|
218
|
+
|
219
|
+
def reset
|
220
|
+
each {|lsa| lsa.ack }
|
221
|
+
@offset=0
|
222
|
+
end
|
223
|
+
|
224
|
+
def to_s_default
|
225
|
+
s = []
|
226
|
+
s << " OSPF link state database, Area #{area_id.to_ip}"
|
227
|
+
s << "Age Options Type Link-State ID Advr Router Sequence Checksum Length"
|
228
|
+
LsType.all.each do |type|
|
229
|
+
s << (__send__ "all_#{type}").collect { |l| l.to_s }
|
230
|
+
end
|
231
|
+
s.join("\n")
|
232
|
+
end
|
233
|
+
|
234
|
+
def to_s_junos(verbose=false)
|
235
|
+
lsas = []
|
236
|
+
lsas << " OSPF link state database, Area #{area_id.to_ip}"
|
237
|
+
lsas << " Type ID Adv Rtr Seq Age Opt Cksum Len "
|
238
|
+
LsType.all.each do |type|
|
239
|
+
lsas << " OSPF AS SCOPE link state database" if type == :external
|
240
|
+
lsas << (__send__ "all_#{type}").collect { |l|
|
241
|
+
if verbose
|
242
|
+
l.to_s_junos_verbose
|
243
|
+
else
|
244
|
+
l.to_s_junos
|
245
|
+
end
|
246
|
+
}
|
247
|
+
end
|
248
|
+
lsas.join("\n")
|
249
|
+
end
|
250
|
+
alias :to_j :to_s_junos
|
251
|
+
|
252
|
+
def [](*key)
|
253
|
+
lookup(*key)
|
254
|
+
end
|
255
|
+
|
256
|
+
def size
|
257
|
+
@ls_db.size
|
258
|
+
end
|
259
|
+
|
260
|
+
def all_not_acked
|
261
|
+
all.find_all { |l| ! l.ack? }
|
262
|
+
end
|
263
|
+
|
264
|
+
def method_missing(method, *args, &block)
|
265
|
+
super
|
266
|
+
end
|
267
|
+
|
268
|
+
def refresh
|
269
|
+
all.find_all {|l| l.refresh(advertised_routers, ls_refresh_time) }
|
270
|
+
end
|
271
|
+
|
272
|
+
def ls_refresh?(ls)
|
273
|
+
rt = ls_refresh_time
|
274
|
+
ls.instance_eval { refresh?(rt) }
|
275
|
+
end
|
276
|
+
|
277
|
+
def recv_link_state_update(link_state_update)
|
278
|
+
link_state_update.each do |lsa|
|
279
|
+
if advertised_routers.has?(lsa.advertising_router)
|
280
|
+
if @ls_db.key? lsa.key
|
281
|
+
@ls_db[lsa.key].force_refresh(lsa.sequence_number)
|
282
|
+
else
|
283
|
+
@ls_db.store(lsa.key,lsa)
|
284
|
+
lsa.maxage
|
285
|
+
end
|
286
|
+
else
|
287
|
+
if lsa.maxaged?
|
288
|
+
@ls_db.delete lsa.key
|
289
|
+
else
|
290
|
+
@ls_db.store(lsa.key,lsa)
|
291
|
+
# TBD: remove lsa from lsr_list
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def has?(obj)
|
298
|
+
lookup(obj)
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
def recv_dd(dd, ls_req_list)
|
303
|
+
raise ArgumentError, "lss nil" unless ls_req_list
|
304
|
+
dd.each { |dd_lsa|
|
305
|
+
if advertised_routers.has?(dd_lsa.advertising_router)
|
306
|
+
our_lsa = lookup(dd_lsa)
|
307
|
+
if our_lsa and (our_lsa <=> dd_lsa)
|
308
|
+
our_lsa.force_refresh(dd_lsa.sequence_number)
|
309
|
+
end
|
310
|
+
else
|
311
|
+
ls_req_list.store(dd_lsa.key,0)
|
312
|
+
end
|
313
|
+
}
|
314
|
+
nil
|
315
|
+
end
|
316
|
+
|
317
|
+
private
|
318
|
+
|
319
|
+
def lsa_types
|
320
|
+
[:router, :network, :summary, :asbr_summary, :as_external]
|
321
|
+
end
|
322
|
+
|
323
|
+
def id2i(id)
|
324
|
+
return id if id.is_a?(Integer)
|
325
|
+
IPAddr.new(id).to_i
|
326
|
+
end
|
327
|
+
def id2ip(id)
|
328
|
+
return id if id.is_a?(String)
|
329
|
+
IPAddr.create(id).to_s
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
334
|
+
#
|
335
|
+
# @ls_db = []
|
336
|
+
# @ls_db << {
|
337
|
+
# :sequence_number=>2147483650,
|
338
|
+
# :advertising_router=>"1.2.0.0",
|
339
|
+
# :ls_id=>"0.0.4.5",
|
340
|
+
# :nwveb=>1,
|
341
|
+
# :ls_type=>:router_lsa,
|
342
|
+
# :options=> 0x21,
|
343
|
+
# :ls_age=>10,
|
344
|
+
# :links=>[
|
345
|
+
# {
|
346
|
+
# :link_id=>"1.1.1.1",
|
347
|
+
# :link_data=>"255.255.255.255",
|
348
|
+
# :router_link_type=>:point_to_point,
|
349
|
+
# :metric=>11,
|
350
|
+
# :mt_metrics=>[ {:id=>1, :metric=>11}, {:id=>2, :metric=>22} ]
|
351
|
+
# },
|
352
|
+
# {
|
353
|
+
# :link_id=>"1.1.1.2",
|
354
|
+
# :link_data=>"255.255.255.255",
|
355
|
+
# :router_link_type=>:point_to_point,
|
356
|
+
# :metric=>12,
|
357
|
+
# :mt_metrics=>[]
|
358
|
+
# }
|
359
|
+
# ],
|
360
|
+
# }
|
361
|
+
#
|
362
|
+
#
|
363
|
+
# ls_db = LinkStateDatabase.new :area_id=> 1, :ls_db => @ls_db
|
364
|
+
# puts ""
|
365
|
+
# puts ls_db.to_s_junos
|
366
|
+
#
|
367
|
+
|
368
|
+
|
369
|
+
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
require 'ls_db/link_state_database_build'
|
374
|
+
|
375
|
+
load "../../../test/ospfv2/ls_db/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|
376
|
+
|
@@ -0,0 +1,181 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2010 Jean-Michel Esnault.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# This file is part of OSPFv2.
|
8
|
+
#
|
9
|
+
# OSPFv2 is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 3 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
#
|
14
|
+
# OSPFv2 is distributed in the hope that it will be useful,
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
+
# GNU General Public License for more details.
|
18
|
+
#
|
19
|
+
# You should have received a copy of the GNU General Public License
|
20
|
+
# along with OSPFv2. If not, see <http://www.gnu.org/licenses/>.
|
21
|
+
#++
|
22
|
+
|
23
|
+
|
24
|
+
require 'set'
|
25
|
+
require 'ie/id'
|
26
|
+
require 'ls_db/links'
|
27
|
+
|
28
|
+
require 'ls_db/link_state_database'
|
29
|
+
|
30
|
+
module OSPFv2::LSDB
|
31
|
+
class LinkStateDatabase
|
32
|
+
include OSPFv2
|
33
|
+
include OSPFv2::Common
|
34
|
+
|
35
|
+
|
36
|
+
def add_adjacency(*arg)
|
37
|
+
|
38
|
+
if arg.size==1 and arg[0].is_a?(Hash)
|
39
|
+
arg = arg[0]
|
40
|
+
router_id = arg[:router_id]
|
41
|
+
neighbor_id = arg[:neighbor_router_id]
|
42
|
+
prefix = arg[:prefix]
|
43
|
+
metric = arg[:metric] ||= 1
|
44
|
+
link = arg[:link] if arg[:link] and arg[:link].is_a?(Link)
|
45
|
+
elsif arg.size>2
|
46
|
+
router_id, neighbor_id, prefix, metric = arg
|
47
|
+
metric ||=1
|
48
|
+
else
|
49
|
+
raise ArgumentError
|
50
|
+
end
|
51
|
+
|
52
|
+
raise ArgumentError, "missing prefix" unless prefix
|
53
|
+
raise ArgumentError, "missing neighbor router id" unless neighbor_id
|
54
|
+
|
55
|
+
_, addr, plen, network, netmask = IPAddr.to_ary(prefix)
|
56
|
+
|
57
|
+
# if not set assume router id is the interface address given to us in :prefix
|
58
|
+
router_id ||= addr
|
59
|
+
|
60
|
+
|
61
|
+
# router_id to list of advertised routers
|
62
|
+
advertised_routers + router_id
|
63
|
+
|
64
|
+
rlsa = find_router_lsa router_id
|
65
|
+
|
66
|
+
if ! rlsa
|
67
|
+
|
68
|
+
# We need to build a router lsa
|
69
|
+
rlsa = OSPFv2::Lsa.factory \
|
70
|
+
:advertising_router=> router_id,
|
71
|
+
:ls_id=> router_id,
|
72
|
+
:ls_type=>:router_lsa,
|
73
|
+
:options=> 0x22
|
74
|
+
|
75
|
+
advertised_routers + router_id
|
76
|
+
|
77
|
+
# add to lsdb
|
78
|
+
self << rlsa
|
79
|
+
|
80
|
+
else
|
81
|
+
|
82
|
+
# delete any exisiting p2p and stub network
|
83
|
+
rlsa.delete(1,neighbor_id)
|
84
|
+
rlsa.delete(3,network)
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
# Add a new router-link and stub network that describes the adjacency
|
89
|
+
rlsa << { :link_id=>neighbor_id, :link_data=>addr, :router_link_type=>:point_to_point, :metric=>metric, }
|
90
|
+
rlsa << { :link_id=>network, :link_data=>netmask, :router_link_type=>:stub_network, :metric=>metric }
|
91
|
+
|
92
|
+
rlsa
|
93
|
+
|
94
|
+
end
|
95
|
+
alias :add_p2p_adjacency :add_adjacency
|
96
|
+
|
97
|
+
|
98
|
+
def remove_adjacency(rid, neighbor_id, prefix)
|
99
|
+
if (rlsa = lookup(:router_lsa, rid))
|
100
|
+
addr, source_address, plen, network, netmask = IPAddr.to_ary(prefix)
|
101
|
+
rlsa.delete(:point_to_point,id2ip(neighbor_id))
|
102
|
+
rlsa.delete(3,network)
|
103
|
+
end
|
104
|
+
rlsa
|
105
|
+
end
|
106
|
+
|
107
|
+
# :router_id=> 1, :link_id=> '192.168.0.1', :link_data => '255.255.255.255'
|
108
|
+
# :router_id=> 1, :network=> '192.168.0.1/24', :metric => 10
|
109
|
+
def add_link_to_stub_network(arg={})
|
110
|
+
|
111
|
+
router_id = arg[:router_id]
|
112
|
+
link_id = arg[:link_id]
|
113
|
+
link_data = arg[:link_data]
|
114
|
+
|
115
|
+
if arg[:network]
|
116
|
+
addr = IPAddr.new arg[:network]
|
117
|
+
link_id = addr.to_s
|
118
|
+
link_data = addr.netmask
|
119
|
+
end
|
120
|
+
|
121
|
+
raise ArgumentError, "missing neighbor router id" unless router_id
|
122
|
+
raise ArgumentError, "missing neighbor link_id" unless link_id
|
123
|
+
raise ArgumentError, "missing neighbor link_data" unless link_data
|
124
|
+
|
125
|
+
metric = arg[:metric] ||=0
|
126
|
+
|
127
|
+
# link = arg[:link] if arg[:link] and arg[:link].is_a?(RouterLink)
|
128
|
+
|
129
|
+
rlsa = find_router_lsa(router_id)
|
130
|
+
|
131
|
+
link = {:router_link_type=>:stub_network, :metric=>metric, :link_id=>link_id, :link_data=>link_data}
|
132
|
+
if ! rlsa
|
133
|
+
|
134
|
+
# build a router lsa with a stub network
|
135
|
+
rlsa = OSPFv2::Lsa.factory \
|
136
|
+
:advertising_router=> router_id,
|
137
|
+
:ls_id=> router_id,
|
138
|
+
:nwveb=>2,
|
139
|
+
:ls_type=>:router_lsa,
|
140
|
+
:options=> 0x22
|
141
|
+
|
142
|
+
advertised_routers + router_id
|
143
|
+
|
144
|
+
# add to lsdb
|
145
|
+
self << rlsa
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
# replace or add new stub router link
|
150
|
+
rlsa = find_router_lsa(router_id)
|
151
|
+
rlsa.delete(3,link_id)
|
152
|
+
rlsa << link
|
153
|
+
rlsa
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# Router ID: 13.11.13.11
|
158
|
+
#
|
159
|
+
# Router *13.11.13.11 13.11.13.11 0x80000022 458 0x22 0x58e9 36
|
160
|
+
# bits 0x0, link count 1
|
161
|
+
# id 192.168.1.200, data 192.168.1.200, Type Transit (2)
|
162
|
+
# Topology count: 0, Default metric: 10
|
163
|
+
#
|
164
|
+
def add_router_id(router_id)
|
165
|
+
add_link_to_stub_network :router_id => router_id, :link_id=> router_id, :link_data=> router_id
|
166
|
+
end
|
167
|
+
|
168
|
+
# Router *13.11.13.11 13.11.13.11 0x80000032 16 0x22 0xf55e 48
|
169
|
+
# bits 0x0, link count 1
|
170
|
+
# id 99.99.1.1, data 255.255.255.255, Type Stub (3)
|
171
|
+
# Topology count: 0, Default metric: 0
|
172
|
+
#
|
173
|
+
def add_loopback(arg={})
|
174
|
+
add_link_to_stub_network :router_id => arg[:router_id], :link_id=> arg[:address], :link_data=> '255.255.255.255', :metric=> arg[:metric]
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
load "../../../test/ospfv2/ls_db/#{ File.basename($0.gsub(/.rb/,'_test.rb'))}" if __FILE__ == $0
|