ospfv2 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|