]> git.ipfire.org Git - thirdparty/bird.git/blame - proto/ospf/topology.c
Merged multipath and single-path data structures.
[thirdparty/bird.git] / proto / ospf / topology.c
CommitLineData
6ba36f06
MM
1/*
2 * BIRD -- OSPF Topological Database
3 *
98ac6176
OF
4 * (c) 1999 Martin Mares <mj@ucw.cz>
5 * (c) 1999--2004 Ondrej Filip <feela@network.cz>
70945cb6
OZ
6 * (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
7 * (c) 2009--2014 CZ.NIC z.s.p.o.
6ba36f06
MM
8 *
9 * Can be freely distributed and used under the terms of the GNU GPL.
10 */
11
6ba36f06 12#include "nest/bird.h"
221135d6 13#include "lib/string.h"
6ba36f06
MM
14
15#include "ospf.h"
16
70945cb6 17
8d56febe 18#define HASH_DEF_ORDER 6
6ba36f06
MM
19#define HASH_HI_MARK *4
20#define HASH_HI_STEP 2
21#define HASH_HI_MAX 16
22#define HASH_LO_MARK /5
23#define HASH_LO_STEP 2
24#define HASH_LO_MIN 8
25
70945cb6
OZ
26static inline void * lsab_flush(struct ospf_proto *p);
27static inline void lsab_reset(struct ospf_proto *p);
b49e6f5a 28
b49e6f5a 29
70945cb6
OZ
30/**
31 * ospf_install_lsa - install new LSA into database
32 * @p: OSPF protocol instance
33 * @lsa: LSA header
742029eb 34 * @type: type of LSA
70945cb6
OZ
35 * @domain: domain of LSA
36 * @body: pointer to LSA body
37 *
38 * This function ensures installing new LSA received in LS update into LSA
39 * database. Old instance is replaced. Several actions are taken to detect if
40 * new routing table calculation is necessary. This is described in 13.2 of RFC
41 * 2328. This function is for received LSA only, locally originated LSAs are
42 * installed by ospf_originate_lsa().
a7a7372a
OZ
43 *
44 * The LSA body in @body is expected to be mb_allocated by the caller and its
45 * ownership is transferred to the LSA entry structure.
70945cb6
OZ
46 */
47struct top_hash_entry *
48ospf_install_lsa(struct ospf_proto *p, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body)
49{
70945cb6
OZ
50 struct top_hash_entry *en;
51 int change = 0;
d82fc18d 52
70945cb6 53 en = ospf_hash_get(p->gr, domain, lsa->id, lsa->rt, type);
d82fc18d 54
70945cb6
OZ
55 if (!SNODE_VALID(en))
56 s_add_tail(&p->lsal, SNODE en);
57
58 if ((en->lsa_body == NULL) || /* No old LSA */
59 (en->lsa.length != lsa->length) ||
60 (en->lsa.type_raw != lsa->type_raw) || /* Check for OSPFv2 options */
61 (en->lsa.age == LSA_MAXAGE) ||
62 (lsa->age == LSA_MAXAGE) ||
63 memcmp(en->lsa_body, body, lsa->length - sizeof(struct ospf_lsa_header)))
64 change = 1;
65
a7a7372a
OZ
66 if ((en->lsa.age == LSA_MAXAGE) && (lsa->age == LSA_MAXAGE))
67 change = 0;
70945cb6
OZ
68
69 mb_free(en->lsa_body);
70 en->lsa_body = body;
71 en->lsa = *lsa;
72 en->init_age = en->lsa.age;
73 en->inst_time = now;
74
a7a7372a
OZ
75 /*
76 * We do not set en->mode. It is either default LSA_M_BASIC, or in a special
77 * case when en is local but flushed, there is postponed LSA, self-originated
78 * LSA is received and ospf_install_lsa() is called from ospf_advance_lse(),
79 * then we have en->mode from the postponed LSA origination.
80 */
81
82 OSPF_TRACE(D_EVENTS, "Installing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x, Age: %u",
83 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn, en->lsa.age);
84
70945cb6 85 if (change)
a7a7372a 86 ospf_schedule_rtcalc(p);
70945cb6
OZ
87
88 return en;
89}
90
a7a7372a
OZ
91/**
92 * ospf_advance_lsa - handle received unexpected self-originated LSA
93 * @p: OSPF protocol instance
94 * @en: current LSA entry or NULL
95 * @lsa: new LSA header
742029eb 96 * @type: type of LSA
a7a7372a
OZ
97 * @domain: domain of LSA
98 * @body: pointer to LSA body
99 *
100 * This function handles received unexpected self-originated LSA (@lsa, @body)
101 * by either advancing sequence number of the local LSA instance (@en) and
102 * propagating it, or installing the received LSA and immediately flushing it
103 * (if there is no local LSA; i.e., @en is NULL or MaxAge).
104 *
105 * The LSA body in @body is expected to be mb_allocated by the caller and its
106 * ownership is transferred to the LSA entry structure or it is freed.
107 */
70945cb6
OZ
108void
109ospf_advance_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body)
110{
a7a7372a 111 /* RFC 2328 13.4 */
70945cb6
OZ
112
113 if (en && (en->lsa.age < LSA_MAXAGE))
114 {
115 if (lsa->sn != LSA_MAXSEQNO)
116 {
117 /*
118 * We simply advance current LSA to have higher seqnum than received LSA.
119 * The received LSA is ignored and the advanced LSA is propagated instead.
120 *
121 * Although this is an origination of distinct LSA instance and therefore
122 * should be limited by MinLSInterval, we do not enforce it here. Fast
123 * reaction is needed and we are already limited by MinLSArrival.
124 */
125
126 mb_free(body);
127
128 en->lsa.sn = lsa->sn + 1;
129 en->lsa.age = 0;
130 en->init_age = 0;
131 en->inst_time = now;
77edab64 132 lsa_generate_checksum(&en->lsa, en->lsa_body);
a7a7372a
OZ
133
134 OSPF_TRACE(D_EVENTS, "Advancing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
135 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
70945cb6
OZ
136 }
137 else
138 {
742029eb 139 /*
70945cb6
OZ
140 * Received LSA has maximal sequence number, so we cannot simply override
141 * it. We have to install it to the database, immediately flush it to
142 * implement sequence number wrapping, and schedule our current LSA to be
143 * originated after the received instance is flushed.
144 */
145
146 if (en->next_lsa_body == NULL)
147 {
148 /* Schedule current LSA */
149 en->next_lsa_blen = en->lsa.length - sizeof(struct ospf_lsa_header);
150 en->next_lsa_body = en->lsa_body;
151 en->next_lsa_opts = ospf_is_v2(p) ? lsa_get_options(&en->lsa) : 0;
152 }
153 else
154 {
155 /* There is already scheduled LSA, so we just free current one */
156 mb_free(en->lsa_body);
157 }
158
159 en->lsa_body = body;
160 en->lsa = *lsa;
161 en->lsa.age = LSA_MAXAGE;
162 en->init_age = lsa->age;
163 en->inst_time = now;
a7a7372a
OZ
164
165 OSPF_TRACE(D_EVENTS, "Resetting LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
166 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
167 OSPF_TRACE(D_EVENTS, "Postponing LSA: Type: %04x, Id: %R, Rt: %R",
168 en->lsa_type, en->lsa.id, en->lsa.rt);
70945cb6
OZ
169 }
170 }
d82fc18d 171 else
70945cb6
OZ
172 {
173 /*
174 * We do not have received LSA in the database. We have to flush the
175 * received LSA. It has to be installed in the database to secure
176 * retransmissions. Note that the received LSA may already be MaxAge.
a7a7372a 177 * Also note that en->next_lsa_* may be defined.
70945cb6
OZ
178 */
179
180 lsa->age = LSA_MAXAGE;
181 en = ospf_install_lsa(p, lsa, type, domain, body);
182 }
183
742029eb 184 /*
70945cb6
OZ
185 * We flood the updated LSA. Although in some cases the to-be-flooded LSA is
186 * the same as the received LSA, and therefore we should propagate it as
742029eb 187 * regular received LSA (send the acknowledgement instead of the update to
70945cb6
OZ
188 * the neighbor we received it from), we cheat a bit here.
189 */
190
a7a7372a 191 ospf_flood_lsa(p, en, NULL);
d82fc18d
OZ
192}
193
d82fc18d 194
70945cb6
OZ
195static int
196ospf_do_originate_lsa(struct ospf_proto *p, struct top_hash_entry *en, void *lsa_body, u16 lsa_blen, u16 lsa_opts)
d82fc18d 197{
70945cb6
OZ
198 /* Enforce MinLSInterval */
199 if ((en->init_age == 0) && en->inst_time && ((en->inst_time + MINLSINTERVAL) > now))
200 return 0;
201
202 /* Handle wrapping sequence number */
203 if (en->lsa.sn == LSA_MAXSEQNO)
204 {
205 /* Prepare to flush old LSA */
206 if (en->lsa.age != LSA_MAXAGE)
207 {
a7a7372a
OZ
208 OSPF_TRACE(D_EVENTS, "Resetting LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
209 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
70945cb6
OZ
210
211 en->lsa.age = LSA_MAXAGE;
a7a7372a 212 ospf_flood_lsa(p, en, NULL);
70945cb6
OZ
213 return 0;
214 }
215
216 /* Already flushing */
217 if ((p->padj != 0) || (en->ret_count != 0))
218 return 0;
219
220 /* Flush done, just clean up seqnum, lsa_body is freed below */
221 en->lsa.sn = LSA_ZEROSEQNO;
222 }
223
6384c7d7 224 /*
70945cb6
OZ
225 * lsa.type_raw is initialized by ospf_hash_get() to OSPFv3 LSA type.
226 * lsa_set_options() implicitly converts it to OSPFv2 LSA type, assuming that
227 * old type is just new type masked by 0xff. That is not universally true,
228 * but it holds for all OSPFv2 types currently supported by BIRD.
6384c7d7 229 */
70945cb6
OZ
230
231 if (ospf_is_v2(p))
232 lsa_set_options(&en->lsa, lsa_opts);
233
234 mb_free(en->lsa_body);
235 en->lsa_body = lsa_body;
236 en->lsa.length = sizeof(struct ospf_lsa_header) + lsa_blen;
237 en->lsa.sn++;
238 en->lsa.age = 0;
239 en->init_age = 0;
240 en->inst_time = now;
77edab64 241 lsa_generate_checksum(&en->lsa, en->lsa_body);
70945cb6 242
a7a7372a
OZ
243 OSPF_TRACE(D_EVENTS, "Originating LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
244 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
245
246 ospf_flood_lsa(p, en, NULL);
247
248 if (en->mode == LSA_M_BASIC)
249 ospf_schedule_rtcalc(p);
70945cb6
OZ
250
251 return 1;
d82fc18d
OZ
252}
253
70945cb6
OZ
254/**
255 * ospf_originate_lsa - originate new LSA
256 * @p: OSPF protocol instance
257 * @lsa: New LSA specification
258 *
259 * This function prepares a new LSA, installs it into the LSA database and
260 * floods it. If the new LSA cannot be originated now (because the old instance
261 * was originated within MinLSInterval, or because the LSA seqnum is currently
262 * wrapping), the origination is instead scheduled for later. If the new LSA is
263 * equivalent to the current LSA, the origination is skipped. In all cases, the
264 * corresponding LSA entry is returned. The new LSA is based on the LSA
265 * specification (@lsa) and the LSA body from lsab buffer of @p, which is
266 * emptied after the call. The opposite of this function is ospf_flush_lsa().
267 */
268struct top_hash_entry *
269ospf_originate_lsa(struct ospf_proto *p, struct ospf_new_lsa *lsa)
270{
271 struct top_hash_entry *en;
272 void *lsa_body = p->lsab;
273 u16 lsa_blen = p->lsab_used;
274 u16 lsa_length = sizeof(struct ospf_lsa_header) + lsa_blen;
b49e6f5a 275
70945cb6 276 en = ospf_hash_get(p->gr, lsa->dom, lsa->id, p->router_id, lsa->type);
b49e6f5a 277
70945cb6
OZ
278 if (!SNODE_VALID(en))
279 s_add_tail(&p->lsal, SNODE en);
280
39a6b19d 281 if (!en->nf || !en->lsa_body)
70945cb6
OZ
282 en->nf = lsa->nf;
283
284 if (en->nf != lsa->nf)
285 {
fe9f1a6d
OZ
286 log(L_ERR "%s: LSA ID collision for %N",
287 p->p.name, lsa->nf->fn.addr);
a7a7372a
OZ
288
289 en = NULL;
70945cb6
OZ
290 goto drop;
291 }
292
a7a7372a
OZ
293 if (en->mode != lsa->mode)
294 en->mode = lsa->mode;
70945cb6
OZ
295
296 if (en->next_lsa_body)
297 {
298 /* Ignore the new LSA if it is the same as the scheduled one */
a7a7372a
OZ
299 if ((lsa_blen == en->next_lsa_blen) &&
300 !memcmp(lsa_body, en->next_lsa_body, lsa_blen) &&
301 (!ospf_is_v2(p) || (lsa->opts == en->next_lsa_opts)))
70945cb6
OZ
302 goto drop;
303
304 /* Free scheduled LSA */
305 mb_free(en->next_lsa_body);
306 en->next_lsa_body = NULL;
307 en->next_lsa_blen = 0;
308 en->next_lsa_opts = 0;
309 }
310
311 /* Ignore the the new LSA if is the same as the current one */
a7a7372a
OZ
312 if ((en->lsa.age < LSA_MAXAGE) &&
313 (lsa_length == en->lsa.length) &&
314 !memcmp(lsa_body, en->lsa_body, lsa_blen) &&
315 (!ospf_is_v2(p) || (lsa->opts == lsa_get_options(&en->lsa))))
70945cb6
OZ
316 goto drop;
317
318 lsa_body = lsab_flush(p);
319
320 if (! ospf_do_originate_lsa(p, en, lsa_body, lsa_blen, lsa->opts))
321 {
a7a7372a
OZ
322 OSPF_TRACE(D_EVENTS, "Postponing LSA: Type: %04x, Id: %R, Rt: %R",
323 en->lsa_type, en->lsa.id, en->lsa.rt);
324
70945cb6
OZ
325 en->next_lsa_body = lsa_body;
326 en->next_lsa_blen = lsa_blen;
327 en->next_lsa_opts = lsa->opts;
328 }
329
330 return en;
331
332 drop:
333 lsab_reset(p);
334 return en;
335}
336
337static void
338ospf_originate_next_lsa(struct ospf_proto *p, struct top_hash_entry *en)
3d15dcdb 339{
70945cb6
OZ
340 /* Called by ospf_update_lsadb() to handle scheduled origination */
341
342 if (! ospf_do_originate_lsa(p, en, en->next_lsa_body, en->next_lsa_blen, en->next_lsa_opts))
343 return;
742029eb 344
70945cb6
OZ
345 en->next_lsa_body = NULL;
346 en->next_lsa_blen = 0;
347 en->next_lsa_opts = 0;
70945cb6
OZ
348}
349
350static void
351ospf_refresh_lsa(struct ospf_proto *p, struct top_hash_entry *en)
352{
353 /*
354 * Called by ospf_update_lsadb() for periodic LSA refresh.
355 *
356 * We know that lsa.age < LSA_MAXAGE and lsa.rt is our router ID. We can also
357 * assume that there is no scheduled LSA, because inst_time is deep in past,
358 * therefore ospf_originate_next_lsa() called before would either succeed or
359 * switched lsa.age to LSA_MAXAGE.
360 */
361
a7a7372a
OZ
362 OSPF_TRACE(D_EVENTS, "Refreshing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
363 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
70945cb6
OZ
364
365 ASSERT(en->next_lsa_body == NULL);
366
367 /* Handle wrapping sequence number */
368 if (en->lsa.sn == LSA_MAXSEQNO)
369 {
370 /* Copy LSA body as next LSA to get automatic origination after flush is finished */
371 en->next_lsa_blen = en->lsa.length - sizeof(struct ospf_lsa_header);
372 en->next_lsa_body = mb_alloc(p->p.pool, en->next_lsa_blen);
373 memcpy(en->next_lsa_body, en->lsa_body, en->next_lsa_blen);
374 en->next_lsa_opts = ospf_is_v2(p) ? lsa_get_options(&en->lsa) : 0;
375
376 en->lsa.age = LSA_MAXAGE;
a7a7372a 377 ospf_flood_lsa(p, en, NULL);
70945cb6
OZ
378 return;
379 }
380
381 en->lsa.sn++;
382 en->lsa.age = 0;
383 en->init_age = 0;
384 en->inst_time = now;
77edab64 385 lsa_generate_checksum(&en->lsa, en->lsa_body);
a7a7372a 386 ospf_flood_lsa(p, en, NULL);
70945cb6
OZ
387}
388
389/**
390 * ospf_flush_lsa - flush LSA from OSPF domain
391 * @p: OSPF protocol instance
392 * @en: LSA entry to flush
393 *
394 * This function flushes @en from the OSPF domain by setting its age to
395 * %LSA_MAXAGE and flooding it. That also triggers subsequent events in LSA
396 * lifecycle leading to removal of the LSA from the LSA database (e.g. the LSA
397 * content is freed when flushing is acknowledged by neighbors). The function
398 * does nothing if the LSA is already being flushed. LSA entries are not
399 * immediately removed when being flushed, the caller may assume that @en still
400 * exists after the call. The function is the opposite of ospf_originate_lsa()
401 * and is supposed to do the right thing even in cases of postponed
a7a7372a 402 * origination.
70945cb6
OZ
403 */
404void
405ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en)
406{
70945cb6
OZ
407 if (en->next_lsa_body)
408 {
409 mb_free(en->next_lsa_body);
410 en->next_lsa_body = NULL;
411 en->next_lsa_blen = 0;
412 en->next_lsa_opts = 0;
413 }
414
415 if (en->lsa.age == LSA_MAXAGE)
416 return;
417
6f8bbaa1
OZ
418 OSPF_TRACE(D_EVENTS, "Flushing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
419 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
420
70945cb6 421 en->lsa.age = LSA_MAXAGE;
a7a7372a
OZ
422 ospf_flood_lsa(p, en, NULL);
423
424 if (en->mode == LSA_M_BASIC)
425 ospf_schedule_rtcalc(p);
426
427 en->mode = LSA_M_BASIC;
70945cb6
OZ
428}
429
430static void
431ospf_clear_lsa(struct ospf_proto *p, struct top_hash_entry *en)
432{
433 /*
434 * Called by ospf_update_lsadb() as part of LSA flushing process.
435 * Flushed LSA was acknowledged by neighbors and we can free its content.
6f8bbaa1 436 * The log message is for 'remove' - we hide empty LSAs from users.
70945cb6
OZ
437 */
438
6f8bbaa1
OZ
439 OSPF_TRACE(D_EVENTS, "Removing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
440 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
441
70945cb6
OZ
442 if (en->lsa.sn == LSA_MAXSEQNO)
443 en->lsa.sn = LSA_ZEROSEQNO;
444
445 mb_free(en->lsa_body);
446 en->lsa_body = NULL;
447}
448
449static void
450ospf_remove_lsa(struct ospf_proto *p, struct top_hash_entry *en)
451{
452 /*
453 * Called by ospf_update_lsadb() as part of LSA flushing process.
454 * Both lsa_body and next_lsa_body are NULL.
455 */
456
457 s_rem_node(SNODE en);
458 ospf_hash_delete(p->gr, en);
459}
460
461/**
462 * ospf_update_lsadb - update LSA database
463 * @p: OSPF protocol instance
464 *
465 * This function is periodicaly invoked from ospf_disp(). It does some periodic
466 * or postponed processing related to LSA entries. It originates postponed LSAs
467 * scheduled by ospf_originate_lsa(), It continues in flushing processes started
468 * by ospf_flush_lsa(). It also periodically refreshs locally originated LSAs --
469 * when the current instance is older %LSREFRESHTIME, a new instance is originated.
470 * Finally, it also ages stored LSAs and flushes ones that reached %LSA_MAXAGE.
471 *
472 * The RFC 2328 says that a router should periodically check checksums of all
473 * stored LSAs to detect hardware problems. This is not implemented.
474 */
475void
476ospf_update_lsadb(struct ospf_proto *p)
477{
478 struct top_hash_entry *en, *nxt;
479 bird_clock_t real_age;
480
481 WALK_SLIST_DELSAFE(en, nxt, p->lsal)
482 {
483 if (en->next_lsa_body)
484 ospf_originate_next_lsa(p, en);
485
486 real_age = en->init_age + (now - en->inst_time);
487
488 if (en->lsa.age == LSA_MAXAGE)
489 {
490 if (en->lsa_body && (p->padj == 0) && (en->ret_count == 0))
491 ospf_clear_lsa(p, en);
492
493 if ((en->lsa_body == NULL) && (en->next_lsa_body == NULL) &&
494 ((en->lsa.rt != p->router_id) || (real_age >= LSA_MAXAGE)))
495 ospf_remove_lsa(p, en);
496
497 continue;
498 }
499
500 if ((en->lsa.rt == p->router_id) && (real_age >= LSREFRESHTIME))
501 {
502 ospf_refresh_lsa(p, en);
503 continue;
504 }
505
506 if (real_age >= LSA_MAXAGE)
3d15dcdb 507 {
70945cb6 508 ospf_flush_lsa(p, en);
70945cb6 509 continue;
3d15dcdb 510 }
70945cb6
OZ
511
512 en->lsa.age = real_age;
513 }
514}
515
516
74c838a8 517static u32
70945cb6
OZ
518ort_to_lsaid(struct ospf_proto *p, ort *nf)
519{
520 /*
521 * In OSPFv2, We have to map IP prefixes to u32 in such manner that resulting
522 * u32 interpreted as IP address is a member of given prefix. Therefore, /32
fe9f1a6d
OZ
523 * prefix has to be mapped on itself. All received prefixes have to be mapped
524 * on different u32s.
70945cb6
OZ
525 *
526 * We have an assumption that if there is nontrivial (non-/32) network prefix,
527 * then there is not /32 prefix for the first and the last IP address of the
528 * network (these are usually reserved, therefore it is not an important
529 * restriction). The network prefix is mapped to the first or the last IP
530 * address in the manner that disallow collisions - we use the IP address that
531 * cannot be used by the parent prefix.
532 *
533 * For example:
534 * 192.168.0.0/24 maps to 192.168.0.255
535 * 192.168.1.0/24 maps to 192.168.1.0
536 * because 192.168.0.0 and 192.168.1.255 might be used by 192.168.0.0/23 .
537 *
538 * Appendig E of RFC 2328 suggests different algorithm, that tries to maximize
539 * both compatibility and subnetting. But as it is not possible to have both
540 * reliably and the suggested algorithm was unnecessary complicated and it
541 * does crazy things like changing LSA ID for a network because different
542 * network appeared, we choose a different way.
543 *
544 * In OSPFv3, it is simpler. There is not a requirement for membership of the
74c838a8
OZ
545 * result in the input network, so we just allocate a unique ID from ID map
546 * and store it in nf->lsa_id for further reference.
70945cb6
OZ
547 */
548
549 if (ospf_is_v3(p))
74c838a8
OZ
550 {
551 if (!nf->lsa_id)
552 nf->lsa_id = idm_alloc(&p->idm);
553
554 return nf->lsa_id;
555 }
70945cb6 556
fe9f1a6d
OZ
557 net_addr_ip4 *net = (void *) nf->fn.addr;
558 u32 id = ip4_to_u32(net->prefix);
559 int pxlen = net->pxlen;
70945cb6
OZ
560
561 if ((pxlen == 0) || (pxlen == 32))
562 return id;
563
564 if (id & (1 << (32 - pxlen)))
565 return id;
566 else
567 return id | ~u32_mkmask(pxlen);
568}
569
570
571static void *
a7a7372a 572lsab_alloc(struct ospf_proto *p, uint size)
70945cb6 573{
a7a7372a 574 uint offset = p->lsab_used;
70945cb6
OZ
575 p->lsab_used += size;
576 if (p->lsab_used > p->lsab_size)
577 {
578 p->lsab_size = MAX(p->lsab_used, 2 * p->lsab_size);
579 p->lsab = p->lsab ? mb_realloc(p->lsab, p->lsab_size):
580 mb_alloc(p->p.pool, p->lsab_size);
581 }
582 return ((byte *) p->lsab) + offset;
3d15dcdb
OZ
583}
584
585static inline void *
a7a7372a 586lsab_allocz(struct ospf_proto *p, uint size)
3d15dcdb 587{
70945cb6 588 void *r = lsab_alloc(p, size);
3d15dcdb
OZ
589 bzero(r, size);
590 return r;
591}
592
593static inline void *
70945cb6 594lsab_flush(struct ospf_proto *p)
3d15dcdb 595{
70945cb6
OZ
596 void *r = mb_alloc(p->p.pool, p->lsab_used);
597 memcpy(r, p->lsab, p->lsab_used);
598 p->lsab_used = 0;
3d15dcdb
OZ
599 return r;
600}
601
70945cb6
OZ
602static inline void
603lsab_reset(struct ospf_proto *p)
c3226991 604{
70945cb6 605 p->lsab_used = 0;
c3226991
OZ
606}
607
608static inline void *
a7a7372a 609lsab_offset(struct ospf_proto *p, uint offset)
c3226991 610{
70945cb6 611 return ((byte *) p->lsab) + offset;
c3226991
OZ
612}
613
3e236955 614static inline void * UNUSED
70945cb6 615lsab_end(struct ospf_proto *p)
52572e94 616{
70945cb6 617 return ((byte *) p->lsab) + p->lsab_used;
52572e94
OZ
618}
619
c3226991 620
70945cb6
OZ
621/*
622 * Router-LSA handling
623 * Type = LSA_T_RT
624 */
625
38675202
OZ
626static int
627configured_stubnet(struct ospf_area *oa, struct ifa *a)
628{
52a43ae3 629 /* Does not work for IA_PEER addresses, but it is not called on these */
38675202
OZ
630 struct ospf_stubnet_config *sn;
631 WALK_LIST(sn, oa->ac->stubnet_list)
70945cb6
OZ
632 {
633 if (sn->summary)
38675202 634 {
d44e686e 635 if (net_in_netX(&a->prefix, &sn->prefix))
70945cb6 636 return 1;
38675202 637 }
70945cb6
OZ
638 else
639 {
d44e686e 640 if (net_equal(&a->prefix, &sn->prefix))
70945cb6
OZ
641 return 1;
642 }
643 }
644
38675202
OZ
645 return 0;
646}
3d15dcdb 647
70945cb6 648static int
c3226991
OZ
649bcast_net_active(struct ospf_iface *ifa)
650{
651 struct ospf_neighbor *neigh;
652
653 if (ifa->state == OSPF_IS_WAITING)
654 return 0;
655
656 WALK_LIST(neigh, ifa->neigh_list)
70945cb6
OZ
657 {
658 if (neigh->state == NEIGHBOR_FULL)
c3226991 659 {
70945cb6
OZ
660 if (neigh->rid == ifa->drid)
661 return 1;
c3226991 662
70945cb6
OZ
663 if (ifa->state == OSPF_IS_DR)
664 return 1;
c3226991 665 }
70945cb6 666 }
c3226991
OZ
667
668 return 0;
669}
670
70945cb6
OZ
671static inline u32
672get_rt_options(struct ospf_proto *p, struct ospf_area *oa, int bitv)
673{
674 u32 opts = 0;
c3226991 675
70945cb6
OZ
676 if (p->areano > 1)
677 opts |= OPT_RT_B;
c3226991 678
70945cb6
OZ
679 if ((p->areano > 1) && oa_is_nssa(oa) && oa->ac->translator)
680 opts |= OPT_RT_NT;
ce17d4c1 681
70945cb6
OZ
682 if (p->asbr && !oa_is_stub(oa))
683 opts |= OPT_RT_E;
c3226991 684
70945cb6
OZ
685 if (bitv)
686 opts |= OPT_RT_V;
c3226991 687
70945cb6
OZ
688 return opts;
689}
c3226991 690
70945cb6
OZ
691static inline void
692add_rt2_lsa_link(struct ospf_proto *p, u8 type, u32 id, u32 data, u16 metric)
693{
694 struct ospf_lsa_rt2_link *ln = lsab_alloc(p, sizeof(struct ospf_lsa_rt2_link));
695 ln->type = type;
696 ln->id = id;
697 ln->data = data;
698 ln->metric = metric;
699 ln->no_tos = 0;
700}
4160a9dd 701
70945cb6
OZ
702static void
703prepare_rt2_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
704{
705 struct ospf_iface *ifa;
706 int i = 0, bitv = 0;
707 struct ospf_neighbor *neigh;
c3226991 708
70945cb6
OZ
709 ASSERT(p->lsab_used == 0);
710 lsab_allocz(p, sizeof(struct ospf_lsa_rt));
711 /* ospf_lsa_rt header will be filled later */
b9ed99f7 712
70945cb6 713 WALK_LIST(ifa, p->iface_list)
ce17d4c1 714 {
353729f5 715 int net_lsa = 0;
70945cb6 716 u32 link_cost = p->stub_router ? 0xffff : ifa->cost;
3d15dcdb
OZ
717
718 if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
719 (!EMPTY_LIST(ifa->neigh_list)))
5d3f5552
OF
720 {
721 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
722 if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
3d15dcdb 723 bitv = 1;
5d3f5552 724 }
3b16080c
OF
725
726 if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
b9ed99f7 727 continue;
3b580a23 728
e7b4948c
OZ
729 ifa->rt_pos_beg = i;
730
70945cb6 731 /* RFC 2328 - 12.4.1.1-4 */
3d15dcdb 732 switch (ifa->type)
70945cb6
OZ
733 {
734 case OSPF_IT_PTP:
735 case OSPF_IT_PTMP:
736 WALK_LIST(neigh, ifa->neigh_list)
737 if (neigh->state == NEIGHBOR_FULL)
98ac6176 738 {
70945cb6
OZ
739 /*
740 * ln->data should be ifa->iface_id in case of no/ptp
741 * address (ifa->addr->flags & IA_PEER) on PTP link (see
742 * RFC 2328 12.4.1.1.), but the iface ID value has no use,
743 * while using IP address even in this case is here for
744 * compatibility with some broken implementations that use
745 * this address as a next-hop.
746 */
747 add_rt2_lsa_link(p, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost);
3d15dcdb 748 i++;
70945cb6
OZ
749 }
750 break;
3d15dcdb 751
70945cb6
OZ
752 case OSPF_IT_BCAST:
753 case OSPF_IT_NBMA:
754 if (bcast_net_active(ifa))
755 {
756 add_rt2_lsa_link(p, LSART_NET, ipa_to_u32(ifa->drip), ipa_to_u32(ifa->addr->ip), link_cost);
757 i++;
758 net_lsa = 1;
ce17d4c1 759 }
70945cb6
OZ
760 break;
761
762 case OSPF_IT_VLINK:
763 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
764 if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
765 add_rt2_lsa_link(p, LSART_VLNK, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost), i++;
766 break;
767
768 default:
f8fefde3 769 log(L_BUG "OSPF: Unknown interface type");
70945cb6
OZ
770 break;
771 }
3d15dcdb 772
e7b4948c
OZ
773 ifa->rt_pos_end = i;
774
0aad2b92
OZ
775 /* Now we will originate stub area if there is no primary */
776 if (net_lsa ||
777 (ifa->type == OSPF_IT_VLINK) ||
a55a90fa 778 ((ifa->addr->flags & IA_PEER) && ! ifa->cf->stub) ||
0aad2b92
OZ
779 configured_stubnet(oa, ifa->addr))
780 continue;
3d15dcdb 781
70945cb6 782 /* Host or network stub entry */
52a43ae3
OZ
783 if ((ifa->addr->flags & IA_HOST) ||
784 (ifa->state == OSPF_IS_LOOP) ||
785 (ifa->type == OSPF_IT_PTMP))
70945cb6 786 add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(ifa->addr->ip), 0xffffffff, 0);
742029eb 787 else
d44e686e
OZ
788 add_rt2_lsa_link(p, LSART_STUB, ip4_to_u32(net4_prefix(&ifa->addr->prefix)),
789 u32_mkmask(net4_pxlen(&ifa->addr->prefix)), ifa->cost);
0aad2b92 790 i++;
e7b4948c
OZ
791
792 ifa->rt_pos_end = i;
ce17d4c1 793 }
3d15dcdb 794
38675202 795 struct ospf_stubnet_config *sn;
70945cb6
OZ
796 WALK_LIST(sn, oa->ac->stubnet_list)
797 if (!sn->hidden)
d44e686e
OZ
798 add_rt2_lsa_link(p, LSART_STUB, ip4_to_u32(net4_prefix(&sn->prefix)),
799 u32_mkmask(net4_pxlen(&sn->prefix)), sn->cost), i++;
c3226991 800
70945cb6 801 struct ospf_lsa_rt *rt = p->lsab;
742029eb 802 /* Store number of links in lower half of options */
70945cb6 803 rt->options = get_rt_options(p, oa, bitv) | (u16) i;
ce17d4c1 804}
c45f48fb 805
70945cb6
OZ
806static inline void
807add_rt3_lsa_link(struct ospf_proto *p, u8 type, struct ospf_iface *ifa, u32 nif, u32 id)
c3226991 808{
70945cb6 809 struct ospf_lsa_rt3_link *ln = lsab_alloc(p, sizeof(struct ospf_lsa_rt3_link));
c3226991
OZ
810 ln->type = type;
811 ln->padding = 0;
812 ln->metric = ifa->cost;
dd4da6f6 813 ln->lif = ifa->iface_id;
c3226991
OZ
814 ln->nif = nif;
815 ln->id = id;
816}
817
70945cb6
OZ
818static void
819prepare_rt3_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
c3226991 820{
c3226991 821 struct ospf_iface *ifa;
70945cb6 822 struct ospf_neighbor *neigh;
b49e6f5a 823 int bitv = 0;
e7b4948c 824 int i = 0;
4160a9dd 825
70945cb6
OZ
826 ASSERT(p->lsab_used == 0);
827 lsab_allocz(p, sizeof(struct ospf_lsa_rt));
828 /* ospf_lsa_rt header will be filled later */
c3226991 829
70945cb6 830 WALK_LIST(ifa, p->iface_list)
c3226991
OZ
831 {
832 if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
833 (!EMPTY_LIST(ifa->neigh_list)))
834 {
835 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
836 if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
837 bitv = 1;
838 }
839
840 if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
841 continue;
842
e7b4948c
OZ
843 ifa->rt_pos_beg = i;
844
70945cb6 845 /* RFC 5340 - 4.4.3.2 */
c3226991 846 switch (ifa->type)
70945cb6
OZ
847 {
848 case OSPF_IT_PTP:
849 case OSPF_IT_PTMP:
850 WALK_LIST(neigh, ifa->neigh_list)
851 if (neigh->state == NEIGHBOR_FULL)
852 add_rt3_lsa_link(p, LSART_PTP, ifa, neigh->iface_id, neigh->rid), i++;
853 break;
e7b4948c 854
70945cb6
OZ
855 case OSPF_IT_BCAST:
856 case OSPF_IT_NBMA:
857 if (bcast_net_active(ifa))
858 add_rt3_lsa_link(p, LSART_NET, ifa, ifa->dr_iface_id, ifa->drid), i++;
859 break;
c3226991 860
70945cb6
OZ
861 case OSPF_IT_VLINK:
862 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
863 if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
864 add_rt3_lsa_link(p, LSART_VLNK, ifa, neigh->iface_id, neigh->rid), i++;
865 break;
866
867 default:
f8fefde3 868 log(L_BUG "OSPF: Unknown interface type");
70945cb6 869 break;
c3226991
OZ
870 }
871
70945cb6
OZ
872 ifa->rt_pos_end = i;
873 }
c3226991 874
70945cb6
OZ
875 struct ospf_lsa_rt *rt = p->lsab;
876 rt->options = get_rt_options(p, oa, bitv) | (oa->options & LSA_OPTIONS_MASK);
877}
c3226991 878
70945cb6
OZ
879static void
880ospf_originate_rt_lsa(struct ospf_proto *p, struct ospf_area *oa)
d8852b36 881{
70945cb6
OZ
882 struct ospf_new_lsa lsa = {
883 .type = LSA_T_RT,
884 .dom = oa->areaid,
885 .id = ospf_is_v2(p) ? p->router_id : 0,
886 .opts = oa->options
887 };
d8852b36 888
a7a7372a
OZ
889 OSPF_TRACE(D_EVENTS, "Updating router state for area %R", oa->areaid);
890
70945cb6
OZ
891 if (ospf_is_v2(p))
892 prepare_rt2_lsa_body(p, oa);
893 else
894 prepare_rt3_lsa_body(p, oa);
b9ed99f7 895
70945cb6
OZ
896 oa->rt = ospf_originate_lsa(p, &lsa);
897}
cf31112f 898
c3226991 899
70945cb6
OZ
900/*
901 * Net-LSA handling
902 * Type = LSA_T_NET
903 */
b49e6f5a 904
70945cb6
OZ
905static void
906prepare_net2_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
b49e6f5a 907{
70945cb6
OZ
908 struct ospf_lsa_net *net;
909 struct ospf_neighbor *n;
910 int nodes = ifa->fadj + 1;
911 u16 i = 1;
b49e6f5a 912
70945cb6
OZ
913 ASSERT(p->lsab_used == 0);
914 net = lsab_alloc(p, sizeof(struct ospf_lsa_net) + 4 * nodes);
b49e6f5a 915
d44e686e 916 net->optx = u32_mkmask(ifa->addr->prefix.pxlen);
70945cb6 917 net->routers[0] = p->router_id;
b49e6f5a 918
70945cb6
OZ
919 WALK_LIST(n, ifa->neigh_list)
920 {
921 if (n->state == NEIGHBOR_FULL)
922 {
923 net->routers[i] = n->rid;
924 i++;
925 }
926 }
927 ASSERT(i == nodes);
ab56f6b1
OF
928}
929
70945cb6
OZ
930static void
931prepare_net3_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
0bf2f203 932{
d345cda5 933 struct ospf_lsa_net *net;
c3226991 934 int nodes = ifa->fadj + 1;
c3226991 935 u32 options = 0;
70945cb6
OZ
936 u16 i = 1;
937
938 ASSERT(p->lsab_used == 0);
939 net = lsab_alloc(p, sizeof(struct ospf_lsa_net) + 4 * nodes);
c3226991 940
70945cb6 941 net->routers[0] = p->router_id;
d345cda5 942
70945cb6 943 struct ospf_neighbor *n;
b9ed99f7 944 WALK_LIST(n, ifa->neigh_list)
0bf2f203 945 {
b9ed99f7 946 if (n->state == NEIGHBOR_FULL)
0bf2f203 947 {
70945cb6
OZ
948 /* In OSPFv3, we would like to merge options from Link LSAs of added neighbors */
949
950 struct top_hash_entry *en =
951 ospf_hash_find(p->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK);
952
c3226991
OZ
953 if (en)
954 options |= ((struct ospf_lsa_link *) en->lsa_body)->options;
c3226991
OZ
955
956 net->routers[i] = n->rid;
0bf2f203
OF
957 i++;
958 }
959 }
c3226991
OZ
960 ASSERT(i == nodes);
961
70945cb6 962 net->optx = options & LSA_OPTIONS_MASK;
0bf2f203
OF
963}
964
70945cb6
OZ
965static void
966ospf_originate_net_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
967{
968 struct ospf_new_lsa lsa = {
969 .type = LSA_T_NET,
970 .dom = ifa->oa->areaid,
971 .id = ospf_is_v2(p) ? ipa_to_u32(ifa->addr->ip) : ifa->iface_id,
972 .opts = ifa->oa->options,
973 .ifa = ifa
974 };
975
a7a7372a
OZ
976 OSPF_TRACE(D_EVENTS, "Updating network state for %s (Id: %R)", ifa->ifname, lsa.id);
977
70945cb6
OZ
978 if (ospf_is_v2(p))
979 prepare_net2_lsa_body(p, ifa);
b49e6f5a 980 else
70945cb6 981 prepare_net3_lsa_body(p, ifa);
9727681a 982
70945cb6 983 ifa->net_lsa = ospf_originate_lsa(p, &lsa);
9727681a
OZ
984}
985
7ff5803b 986
70945cb6
OZ
987/*
988 * (Net|Rt)-summary-LSA handling
989 * (a.k.a. Inter-Area-(Prefix|Router)-LSA)
990 * Type = LSA_T_SUM_NET, LSA_T_SUM_RT
991 */
0077aab4 992
70945cb6
OZ
993static inline void
994prepare_sum2_lsa_body(struct ospf_proto *p, uint pxlen, u32 metric)
0077aab4 995{
70945cb6 996 struct ospf_lsa_sum2 *sum;
c3226991 997
70945cb6
OZ
998 sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum2));
999 sum->netmask = u32_mkmask(pxlen);
c3226991 1000 sum->metric = metric;
c3226991
OZ
1001}
1002
70945cb6
OZ
1003static inline void
1004prepare_sum3_net_lsa_body(struct ospf_proto *p, ort *nf, u32 metric)
9727681a 1005{
70945cb6 1006 struct ospf_lsa_sum3_net *sum;
9727681a 1007
fe9f1a6d
OZ
1008 sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_net) +
1009 IPV6_PREFIX_SPACE(nf->fn.addr->pxlen));
70945cb6 1010 sum->metric = metric;
fe9f1a6d 1011 ospf_put_ipv6_prefix(sum->prefix, nf->fn.addr, 0, 0);
9727681a
OZ
1012}
1013
70945cb6
OZ
1014static inline void
1015prepare_sum3_rt_lsa_body(struct ospf_proto *p, u32 drid, u32 metric, u32 options)
c3226991 1016{
70945cb6 1017 struct ospf_lsa_sum3_rt *sum;
c3226991 1018
70945cb6 1019 sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_rt));
7ff5803b 1020 sum->options = options;
c3226991
OZ
1021 sum->metric = metric;
1022 sum->drid = drid;
7ff5803b
OZ
1023}
1024
98ac6176 1025void
70945cb6 1026ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric)
98ac6176 1027{
70945cb6
OZ
1028 struct ospf_new_lsa lsa = {
1029 .type = LSA_T_SUM_NET,
a7a7372a 1030 .mode = LSA_M_RTCALC,
70945cb6
OZ
1031 .dom = oa->areaid,
1032 .id = ort_to_lsaid(p, nf),
1033 .opts = oa->options,
1034 .nf = nf
1035 };
7ff5803b 1036
70945cb6 1037 if (ospf_is_v2(p))
fe9f1a6d 1038 prepare_sum2_lsa_body(p, nf->fn.addr->pxlen, metric);
70945cb6
OZ
1039 else
1040 prepare_sum3_net_lsa_body(p, nf, metric);
c3226991 1041
a7a7372a 1042 ospf_originate_lsa(p, &lsa);
9727681a 1043}
c3226991 1044
9727681a 1045void
fe9f1a6d 1046ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 drid, int metric, u32 options)
9727681a 1047{
70945cb6
OZ
1048 struct ospf_new_lsa lsa = {
1049 .type = LSA_T_SUM_RT,
a7a7372a 1050 .mode = LSA_M_RTCALC,
70945cb6 1051 .dom = oa->areaid,
fe9f1a6d 1052 .id = drid, /* Router ID of ASBR, irrelevant for OSPFv3 */
70945cb6
OZ
1053 .opts = oa->options
1054 };
98ac6176 1055
70945cb6
OZ
1056 if (ospf_is_v2(p))
1057 prepare_sum2_lsa_body(p, 0, metric);
c3226991 1058 else
fe9f1a6d 1059 prepare_sum3_rt_lsa_body(p, drid, metric, options & LSA_OPTIONS_MASK);
9727681a 1060
a7a7372a 1061 ospf_originate_lsa(p, &lsa);
98ac6176
OF
1062}
1063
c3226991 1064
7ff5803b 1065/*
70945cb6
OZ
1066 * AS-external-LSA and NSSA-LSA handling
1067 * Type = LSA_T_EXT, LSA_T_NSSA
7ff5803b 1068 */
c3226991 1069
70945cb6
OZ
1070static inline void
1071prepare_ext2_lsa_body(struct ospf_proto *p, uint pxlen,
1072 u32 metric, u32 ebit, ip_addr fwaddr, u32 tag)
7ff5803b 1073{
70945cb6 1074 struct ospf_lsa_ext2 *ext;
7ff5803b 1075
70945cb6
OZ
1076 ext = lsab_allocz(p, sizeof(struct ospf_lsa_ext2));
1077 ext->metric = metric & LSA_METRIC_MASK;
1078 ext->netmask = u32_mkmask(pxlen);
1079 ext->fwaddr = ipa_to_u32(fwaddr);
1080 ext->tag = tag;
7ff5803b 1081
70945cb6
OZ
1082 if (ebit)
1083 ext->metric |= LSA_EXT2_EBIT;
7ff5803b 1084}
c3226991 1085
70945cb6
OZ
1086static inline void
1087prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
1088 u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit)
7ff5803b 1089{
70945cb6
OZ
1090 struct ospf_lsa_ext3 *ext;
1091 int bsize = sizeof(struct ospf_lsa_ext3)
fe9f1a6d 1092 + IPV6_PREFIX_SPACE(nf->fn.addr->pxlen)
7ff5803b
OZ
1093 + (ipa_nonzero(fwaddr) ? 16 : 0)
1094 + (tag ? 4 : 0);
1095
70945cb6
OZ
1096 ext = lsab_allocz(p, bsize);
1097 ext->metric = metric & LSA_METRIC_MASK;
1098 u32 *buf = ext->rest;
7ff5803b 1099
fe9f1a6d 1100 buf = ospf_put_ipv6_prefix(buf, nf->fn.addr, pbit ? OPT_PX_P : 0, 0);
7ff5803b 1101
70945cb6
OZ
1102 if (ebit)
1103 ext->metric |= LSA_EXT3_EBIT;
c3226991 1104
7ff5803b
OZ
1105 if (ipa_nonzero(fwaddr))
1106 {
70945cb6 1107 ext->metric |= LSA_EXT3_FBIT;
fe9f1a6d 1108 buf = ospf_put_ipv6_addr(buf, fwaddr);
7ff5803b 1109 }
c3226991
OZ
1110
1111 if (tag)
7ff5803b 1112 {
70945cb6 1113 ext->metric |= LSA_EXT3_TBIT;
7ff5803b
OZ
1114 *buf++ = tag;
1115 }
c3226991
OZ
1116}
1117
70945cb6
OZ
1118/**
1119 * originate_ext_lsa - new route received from nest and filters
a7a7372a 1120 * @p: OSPF protocol instance
70945cb6
OZ
1121 * @oa: ospf_area for which LSA is originated
1122 * @nf: network prefix and mask
a7a7372a
OZ
1123 * @mode: the mode of the LSA (LSA_M_EXPORT or LSA_M_RTCALC)
1124 * @metric: the metric of a route
1125 * @ebit: E-bit for route metric (bool)
70945cb6
OZ
1126 * @fwaddr: the forwarding address
1127 * @tag: the route tag
a7a7372a 1128 * @pbit: P-bit for NSSA LSAs (bool), ignored for external LSAs
70945cb6
OZ
1129 *
1130 * If I receive a message that new route is installed, I try to originate an
1131 * external LSA. If @oa is an NSSA area, NSSA-LSA is originated instead.
1132 * @oa should not be a stub area. @src does not specify whether the LSA
742029eb 1133 * is external or NSSA, but it specifies the source of origination -
70945cb6
OZ
1134 * the export from ospf_rt_notify(), or the NSSA-EXT translation.
1135 */
1136void
a7a7372a 1137ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode,
70945cb6 1138 u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit)
7ff5803b 1139{
70945cb6
OZ
1140 struct ospf_new_lsa lsa = {
1141 .type = oa ? LSA_T_NSSA : LSA_T_EXT,
a7a7372a 1142 .mode = mode, /* LSA_M_EXPORT or LSA_M_RTCALC */
70945cb6
OZ
1143 .dom = oa ? oa->areaid : 0,
1144 .id = ort_to_lsaid(p, nf),
1145 .opts = oa ? (pbit ? OPT_P : 0) : OPT_E,
1146 .nf = nf
1147 };
7ff5803b 1148
70945cb6 1149 if (ospf_is_v2(p))
fe9f1a6d 1150 prepare_ext2_lsa_body(p, nf->fn.addr->pxlen, metric, ebit, fwaddr, tag);
70945cb6
OZ
1151 else
1152 prepare_ext3_lsa_body(p, nf, metric, ebit, fwaddr, tag, oa && pbit);
7ff5803b 1153
a7a7372a 1154 ospf_originate_lsa(p, &lsa);
70945cb6
OZ
1155}
1156
6f8bbaa1
OZ
1157static struct top_hash_entry *
1158ospf_hash_find_(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type);
1159
70945cb6
OZ
1160static void
1161ospf_flush_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf)
1162{
1163 struct top_hash_entry *en;
d395fe48 1164
70945cb6
OZ
1165 u32 type = oa ? LSA_T_NSSA : LSA_T_EXT;
1166 u32 dom = oa ? oa->areaid : 0;
1167 u32 id = ort_to_lsaid(p, nf);
7ff5803b 1168
6f8bbaa1 1169 en = ospf_hash_find_(p->gr, dom, id, p->router_id, type);
7ff5803b 1170
70945cb6
OZ
1171 if (!en || (en->nf != nf))
1172 return;
7ff5803b 1173
70945cb6 1174 ospf_flush_lsa(p, en);
7ff5803b
OZ
1175}
1176
70945cb6
OZ
1177static inline int
1178use_gw_for_fwaddr(struct ospf_proto *p, ip_addr gw, struct iface *iface)
1179{
1180 struct ospf_iface *ifa;
1181
1182 if (ipa_zero(gw) || ipa_is_link_local(gw))
1183 return 0;
7ff5803b 1184
70945cb6
OZ
1185 WALK_LIST(ifa, p->iface_list)
1186 if ((ifa->iface == iface) &&
d44e686e 1187 (!ospf_is_v2(p) || ipa_in_netX(gw, &ifa->addr->prefix)))
70945cb6
OZ
1188 return 1;
1189
1190 return 0;
1191}
7ff5803b 1192
2918e610 1193static inline ip_addr
70945cb6 1194find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
2918e610 1195{
2918e610
OZ
1196 struct ospf_iface *ifa;
1197 struct ifa *a, *cur_addr = NULL;
1198 int np, cur_np = 0;
1199
70945cb6
OZ
1200 /* RFC 3101 2.3 - surrogate forwarding address selection */
1201
1202 WALK_LIST(ifa, p->iface_list)
2918e610
OZ
1203 {
1204 if ((ifa->oa != oa) ||
2918e610
OZ
1205 (ifa->type == OSPF_IT_VLINK))
1206 continue;
1207
70945cb6 1208 if (ospf_is_v2(p))
2918e610 1209 {
70945cb6
OZ
1210 a = ifa->addr;
1211 if (a->flags & IA_PEER)
2918e610
OZ
1212 continue;
1213
70945cb6 1214 np = (a->flags & IA_HOST) ? 3 : (ifa->stub ? 2 : 1);
2918e610
OZ
1215 if (np > cur_np)
1216 {
1217 cur_addr = a;
1218 cur_np = np;
1219 }
1220 }
70945cb6
OZ
1221 else /* OSPFv3 */
1222 {
1223 WALK_LIST(a, ifa->iface->addrs)
1224 {
d44e686e
OZ
1225 if ((a->prefix.type != NET_IP6) ||
1226 (a->flags & IA_SECONDARY) ||
70945cb6
OZ
1227 (a->flags & IA_PEER) ||
1228 (a->scope <= SCOPE_LINK))
1229 continue;
1230
1231 np = (a->flags & IA_HOST) ? 3 : (ifa->stub ? 2 : 1);
1232 if (np > cur_np)
1233 {
1234 cur_addr = a;
1235 cur_np = np;
1236 }
1237 }
1238 }
2918e610
OZ
1239 }
1240
1241 return cur_addr ? cur_addr->ip : IPA_NONE;
1242}
1243
e8085aba 1244void
4bdf1881 1245ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *ea)
e8085aba 1246{
70945cb6
OZ
1247 struct ospf_proto *p = (struct ospf_proto *) P;
1248 struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */
1249 ort *nf;
41b612c3 1250
70945cb6
OZ
1251 /*
1252 * There are several posibilities:
1253 * 1) router in regular area - originate external LSA with global scope
1254 * 2) router in NSSA area - originate area-specific NSSA-LSA
1255 * 3) router in stub area - cannot export routes
1256 * 4) area border router - same as (1), it is attached to backbone
1257 */
b9ed99f7 1258
70945cb6
OZ
1259 if ((p->areano == 1) && oa_is_nssa(HEAD(p->area_list)))
1260 oa = HEAD(p->area_list);
273fd2c1 1261
70945cb6 1262 if (!new)
41b612c3 1263 {
fe9f1a6d 1264 nf = fib_find(&p->rtf, n->n.addr);
2918e610 1265
70945cb6 1266 if (!nf || !nf->external_rte)
2918e610 1267 return;
41b612c3 1268
70945cb6
OZ
1269 ospf_flush_ext_lsa(p, oa, nf);
1270 nf->external_rte = 0;
273fd2c1 1271
70945cb6
OZ
1272 /* Old external route might blocked some NSSA translation */
1273 if ((p->areano > 1) && rt_is_nssa(nf) && nf->n.oa->translate)
a7a7372a 1274 ospf_schedule_rtcalc(p);
7ff5803b 1275
70945cb6
OZ
1276 return;
1277 }
c3226991 1278
70945cb6 1279 ASSERT(p->asbr);
2918e610 1280
70945cb6
OZ
1281 /* Get route attributes */
1282 rta *a = new->attrs;
1283 u32 m1 = ea_get_int(ea, EA_OSPF_METRIC1, LSINFINITY);
1284 u32 m2 = ea_get_int(ea, EA_OSPF_METRIC2, 10000);
1285 int ebit = (m1 == LSINFINITY);
1286 u32 metric = ebit ? m2 : m1;
1287 u32 tag = ea_get_int(ea, EA_OSPF_TAG, 0);
1288 ip_addr fwd = IPA_NONE;
fdb19982 1289
e8085aba 1290
4e276a89
MM
1291 if ((a->dest == RTD_UNICAST) && use_gw_for_fwaddr(p, a->nh.gw, a->nh.iface))
1292 fwd = a->nh.gw;
be862406 1293
70945cb6
OZ
1294 /* NSSA-LSA with P-bit set must have non-zero forwarding address */
1295 if (oa && ipa_zero(fwd))
1296 {
1297 fwd = find_surrogate_fwaddr(p, oa);
c3226991 1298
70945cb6 1299 if (ipa_zero(fwd))
c3226991 1300 {
fe9f1a6d
OZ
1301 log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %N",
1302 p->p.name, n->n.addr);
70945cb6 1303 return;
c3226991 1304 }
70945cb6
OZ
1305 }
1306
fe9f1a6d 1307 nf = fib_get(&p->rtf, n->n.addr);
a7a7372a 1308 ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1);
70945cb6 1309 nf->external_rte = 1;
c3226991
OZ
1310}
1311
1312
70945cb6
OZ
1313/*
1314 * Link-LSA handling (assume OSPFv3)
1315 * Type = LSA_T_LINK
1316 */
c3226991 1317
70945cb6 1318static inline void
d44e686e 1319lsab_put_prefix(struct ospf_proto *p, net_addr *net, u32 cost)
70945cb6 1320{
d44e686e
OZ
1321 void *buf = lsab_alloc(p, IPV6_PREFIX_SPACE(net6_pxlen(net)));
1322 u8 flags = (net6_pxlen(net) < IP6_MAX_PREFIX_LENGTH) ? 0 : OPT_PX_LA;
1323 ospf_put_ipv6_prefix(buf, net, flags, cost);
70945cb6
OZ
1324}
1325
1326static void
1327prepare_link_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1328{
c3226991
OZ
1329 struct ospf_lsa_link *ll;
1330 int i = 0;
c3226991 1331
70945cb6
OZ
1332 ASSERT(p->lsab_used == 0);
1333 ll = lsab_allocz(p, sizeof(struct ospf_lsa_link));
c3226991 1334 ll->options = ifa->oa->options | (ifa->priority << 24);
88a183c6 1335 ll->lladdr = ipa_to_ip6(ifa->addr->ip);
c3226991
OZ
1336 ll = NULL; /* buffer might be reallocated later */
1337
1338 struct ifa *a;
1339 WALK_LIST(a, ifa->iface->addrs)
70945cb6 1340 {
d44e686e
OZ
1341 if ((a->prefix.type != NET_IP6) ||
1342 (a->flags & IA_SECONDARY) ||
1343 (a->scope <= SCOPE_LINK))
70945cb6 1344 continue;
c3226991 1345
d44e686e 1346 lsab_put_prefix(p, &a->prefix, 0);
70945cb6
OZ
1347 i++;
1348 }
c3226991 1349
70945cb6 1350 ll = p->lsab;
c3226991 1351 ll->pxcount = i;
c3226991
OZ
1352}
1353
70945cb6
OZ
1354static void
1355ospf_originate_link_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1356{
70945cb6 1357 if (ospf_is_v2(p))
48e5f32d
OZ
1358 return;
1359
70945cb6
OZ
1360 struct ospf_new_lsa lsa = {
1361 .type = LSA_T_LINK,
1362 .dom = ifa->iface_id,
1363 .id = ifa->iface_id,
1364 .ifa = ifa
1365 };
c3226991 1366
a7a7372a
OZ
1367 OSPF_TRACE(D_EVENTS, "Updating link state for %s (Id: %R)", ifa->ifname, lsa.id);
1368
70945cb6 1369 prepare_link_lsa_body(p, ifa);
be862406 1370
70945cb6 1371 ifa->link_lsa = ospf_originate_lsa(p, &lsa);
c3226991
OZ
1372}
1373
1374
70945cb6
OZ
1375/*
1376 * Prefix-Rt-LSA handling (assume OSPFv3)
1377 * Type = LSA_T_PREFIX, referred type = LSA_T_RT
1378 */
d9e7e1b1 1379
70945cb6
OZ
1380static void
1381prepare_prefix_rt_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
c3226991 1382{
70945cb6 1383 struct ospf_config *cf = (struct ospf_config *) (p->p.cf);
c3226991
OZ
1384 struct ospf_iface *ifa;
1385 struct ospf_lsa_prefix *lp;
3b89a232 1386 int host_addr = 0;
c3226991
OZ
1387 int net_lsa;
1388 int i = 0;
c3226991 1389
70945cb6
OZ
1390 ASSERT(p->lsab_used == 0);
1391 lp = lsab_allocz(p, sizeof(struct ospf_lsa_prefix));
c3226991
OZ
1392 lp->ref_type = LSA_T_RT;
1393 lp->ref_id = 0;
70945cb6 1394 lp->ref_rt = p->router_id;
c3226991
OZ
1395 lp = NULL; /* buffer might be reallocated later */
1396
70945cb6 1397 WALK_LIST(ifa, p->iface_list)
c3226991 1398 {
e4404cef 1399 if ((ifa->oa != oa) || (ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
c3226991
OZ
1400 continue;
1401
e7b4948c
OZ
1402 ifa->px_pos_beg = i;
1403
c3226991
OZ
1404 if ((ifa->type == OSPF_IT_BCAST) ||
1405 (ifa->type == OSPF_IT_NBMA))
1406 net_lsa = bcast_net_active(ifa);
1407 else
1408 net_lsa = 0;
1409
1410 struct ifa *a;
1411 WALK_LIST(a, ifa->iface->addrs)
70945cb6 1412 {
d44e686e
OZ
1413 if ((a->prefix.type != NET_IP6) ||
1414 (a->flags & IA_SECONDARY) ||
70945cb6
OZ
1415 (a->flags & IA_PEER) ||
1416 (a->scope <= SCOPE_LINK))
1417 continue;
3b89a232 1418
d44e686e 1419 if (((a->prefix.pxlen < IP6_MAX_PREFIX_LENGTH) && net_lsa) ||
70945cb6
OZ
1420 configured_stubnet(oa, a))
1421 continue;
c3226991 1422
70945cb6
OZ
1423 if ((a->flags & IA_HOST) ||
1424 (ifa->state == OSPF_IS_LOOP) ||
1425 (ifa->type == OSPF_IT_PTMP))
1426 {
d44e686e
OZ
1427 net_addr_ip6 net = NET_ADDR_IP6(a->ip, IP6_MAX_PREFIX_LENGTH);
1428 lsab_put_prefix(p, (net_addr *) &net, 0);
70945cb6 1429 host_addr = 1;
c3226991 1430 }
70945cb6 1431 else
d44e686e 1432 lsab_put_prefix(p, &a->prefix, ifa->cost);
70945cb6
OZ
1433 i++;
1434 }
e7b4948c
OZ
1435
1436 ifa->px_pos_end = i;
c3226991
OZ
1437 }
1438
c3226991 1439 struct ospf_stubnet_config *sn;
70945cb6
OZ
1440 WALK_LIST(sn, oa->ac->stubnet_list)
1441 if (!sn->hidden)
1442 {
d44e686e
OZ
1443 lsab_put_prefix(p, &sn->prefix, sn->cost);
1444 if (sn->prefix.pxlen == IP6_MAX_PREFIX_LENGTH)
70945cb6
OZ
1445 host_addr = 1;
1446 i++;
1447 }
e4404cef
OZ
1448
1449 /* If there are some configured vlinks, find some global address
1450 (even from another area), which will be used as a vlink endpoint. */
1451 if (!EMPTY_LIST(cf->vlink_list) && !host_addr)
1452 {
70945cb6 1453 WALK_LIST(ifa, p->iface_list)
e4404cef
OZ
1454 {
1455 if ((ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
1456 continue;
1457
1458 struct ifa *a;
1459 WALK_LIST(a, ifa->iface->addrs)
1460 {
d44e686e
OZ
1461 if ((a->prefix.type != NET_IP6) ||
1462 (a->flags & IA_SECONDARY) ||
1463 (a->scope <= SCOPE_LINK))
e4404cef
OZ
1464 continue;
1465
1466 /* Found some IP */
d44e686e
OZ
1467 net_addr_ip6 net = NET_ADDR_IP6(a->ip, IP6_MAX_PREFIX_LENGTH);
1468 lsab_put_prefix(p, (net_addr *) &net, 0);
c3226991 1469 i++;
e4404cef 1470 goto done;
c3226991 1471 }
e4404cef
OZ
1472 }
1473 }
c3226991 1474
e4404cef 1475 done:
70945cb6 1476 lp = p->lsab;
c3226991 1477 lp->pxcount = i;
c3226991
OZ
1478}
1479
70945cb6
OZ
1480static void
1481ospf_originate_prefix_rt_lsa(struct ospf_proto *p, struct ospf_area *oa)
c3226991 1482{
70945cb6
OZ
1483 if (ospf_is_v2(p))
1484 return;
c3226991 1485
70945cb6
OZ
1486 struct ospf_new_lsa lsa = {
1487 .type = LSA_T_PREFIX,
1488 .dom = oa->areaid,
1489 .id = 0
1490 };
be862406 1491
70945cb6 1492 prepare_prefix_rt_lsa_body(p, oa);
c3226991 1493
70945cb6 1494 ospf_originate_lsa(p, &lsa);
c3226991
OZ
1495}
1496
1497
70945cb6
OZ
1498/*
1499 * Prefix-Net-LSA handling (assume OSPFv3)
1500 * Type = LSA_T_PREFIX, referred type = LSA_T_NET
1501 */
1502
c3226991
OZ
1503static inline int
1504prefix_space(u32 *buf)
1505{
1506 int pxl = *buf >> 24;
1507 return IPV6_PREFIX_SPACE(pxl);
1508}
1509
1510static inline int
1511prefix_same(u32 *b1, u32 *b2)
1512{
1513 int pxl1 = *b1 >> 24;
1514 int pxl2 = *b2 >> 24;
1515 int pxs, i;
742029eb 1516
c3226991
OZ
1517 if (pxl1 != pxl2)
1518 return 0;
1519
1520 pxs = IPV6_PREFIX_WORDS(pxl1);
1521 for (i = 1; i < pxs; i++)
1522 if (b1[i] != b2[i])
1523 return 0;
1524
1525 return 1;
1526}
1527
1528static inline u32 *
1529prefix_advance(u32 *buf)
1530{
be862406
OZ
1531 int pxl = *buf >> 24;
1532 return buf + IPV6_PREFIX_WORDS(pxl);
c3226991
OZ
1533}
1534
2918e610 1535/* FIXME eliminate items with LA bit set? see 4.4.3.9 */
c3226991 1536static void
70945cb6 1537add_prefix(struct ospf_proto *p, u32 *px, int offset, int *pxc)
c3226991 1538{
70945cb6 1539 u32 *pxl = lsab_offset(p, offset);
c3226991 1540 int i;
e4404cef
OZ
1541 for (i = 0; i < *pxc; pxl = prefix_advance(pxl), i++)
1542 if (prefix_same(px, pxl))
c3226991 1543 {
e4404cef
OZ
1544 /* Options should be logically OR'ed together */
1545 *pxl |= (*px & 0x00FF0000);
1546 return;
c3226991
OZ
1547 }
1548
70945cb6 1549 ASSERT(pxl == lsab_end(p));
c3226991
OZ
1550
1551 int pxspace = prefix_space(px);
70945cb6 1552 pxl = lsab_alloc(p, pxspace);
c3226991 1553 memcpy(pxl, px, pxspace);
e4404cef 1554 *pxl &= 0xFFFF0000; /* Set metric to zero */
c3226991
OZ
1555 (*pxc)++;
1556}
1557
be862406 1558static void
70945cb6 1559add_link_lsa(struct ospf_proto *p, struct ospf_lsa_link *ll, int offset, int *pxc)
be862406 1560{
be862406 1561 u32 *pxb = ll->rest;
3e236955 1562 uint j;
be862406 1563
e4404cef
OZ
1564 for (j = 0; j < ll->pxcount; pxb = prefix_advance(pxb), j++)
1565 {
1566 u8 pxlen = (pxb[0] >> 24);
1567 u8 pxopts = (pxb[0] >> 16);
1568
1569 /* Skip NU or LA prefixes */
1570 if (pxopts & (OPT_PX_NU | OPT_PX_LA))
1571 continue;
1572
1573 /* Skip link-local prefixes */
1574 if ((pxlen >= 10) && ((pxb[1] & 0xffc00000) == 0xfe800000))
1575 continue;
1576
70945cb6 1577 add_prefix(p, pxb, offset, pxc);
e4404cef 1578 }
be862406
OZ
1579}
1580
70945cb6
OZ
1581static void
1582prepare_prefix_net_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1583{
c3226991 1584 struct ospf_lsa_prefix *lp;
c3226991
OZ
1585 struct ospf_neighbor *n;
1586 struct top_hash_entry *en;
be862406 1587 int pxc, offset;
c3226991 1588
70945cb6
OZ
1589 ASSERT(p->lsab_used == 0);
1590 lp = lsab_allocz(p, sizeof(struct ospf_lsa_prefix));
c3226991
OZ
1591 lp->ref_type = LSA_T_NET;
1592 lp->ref_id = ifa->net_lsa->lsa.id;
70945cb6 1593 lp->ref_rt = p->router_id;
c3226991
OZ
1594 lp = NULL; /* buffer might be reallocated later */
1595
be862406 1596 pxc = 0;
70945cb6 1597 offset = p->lsab_used;
c3226991 1598
be862406 1599 /* Find all Link LSAs associated with the link and merge their prefixes */
70945cb6
OZ
1600 if (en = ifa->link_lsa)
1601 add_link_lsa(p, en->next_lsa_body ?: en->lsa_body, offset, &pxc);
be862406 1602
c3226991
OZ
1603 WALK_LIST(n, ifa->neigh_list)
1604 if ((n->state == NEIGHBOR_FULL) &&
742029eb 1605 (en = ospf_hash_find(p->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK)))
70945cb6 1606 add_link_lsa(p, en->lsa_body, offset, &pxc);
c3226991 1607
70945cb6 1608 lp = p->lsab;
be862406 1609 lp->pxcount = pxc;
c3226991
OZ
1610}
1611
70945cb6
OZ
1612static void
1613ospf_originate_prefix_net_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1614{
70945cb6
OZ
1615 if (ospf_is_v2(p))
1616 return;
c3226991 1617
70945cb6
OZ
1618 struct ospf_new_lsa lsa = {
1619 .type = LSA_T_PREFIX,
1620 .dom = ifa->oa->areaid,
1621 .id = ifa->iface_id,
1622 .ifa = ifa
1623 };
be862406 1624
70945cb6 1625 prepare_prefix_net_lsa_body(p, ifa);
c3226991 1626
70945cb6 1627 ifa->pxn_lsa = ospf_originate_lsa(p, &lsa);
c3226991
OZ
1628}
1629
a7a7372a
OZ
1630static inline int breaks_minlsinterval(struct top_hash_entry *en)
1631{ return en && (en->lsa.age < LSA_MAXAGE) && ((en->inst_time + MINLSINTERVAL) > now); }
70945cb6 1632
061ab802 1633void
70945cb6 1634ospf_update_topology(struct ospf_proto *p)
061ab802 1635{
70945cb6
OZ
1636 struct ospf_area *oa;
1637 struct ospf_iface *ifa;
061ab802 1638
70945cb6
OZ
1639 WALK_LIST(oa, p->area_list)
1640 {
1641 if (oa->update_rt_lsa)
1642 {
a7a7372a
OZ
1643 /*
1644 * Generally, MinLSInterval is enforced in ospf_do_originate_lsa(), but
1645 * origination of (prefix) router LSA is a special case. We do not want to
1646 * prepare a new router LSA body and then postpone it in en->next_lsa_body
1647 * for later origination, because there are side effects (updates of
1648 * rt_pos_* and px_pos_* in ospf_iface structures) during that, which may
1649 * confuse routing table calculation if executed after LSA body
1650 * preparation but before final LSA origination (as rtcalc would use
1651 * current rt_pos_* indexes but the old router LSA body).
1652 *
1653 * Here, we ensure that MinLSInterval is observed and we do not even try
1654 * to originate these LSAs if it is not. Therefore, origination, when
1655 * requested, will succeed unless there is also a seqnum wrapping, which
1656 * is not a problem because in that case rtcalc is blocked by MaxAge.
1657 */
1658
1659 if (breaks_minlsinterval(oa->rt) || breaks_minlsinterval(oa->pxr_lsa))
1660 continue;
1661
70945cb6
OZ
1662 ospf_originate_rt_lsa(p, oa);
1663 ospf_originate_prefix_rt_lsa(p, oa);
1664 oa->update_rt_lsa = 0;
1665 }
1666 }
061ab802 1667
70945cb6
OZ
1668 WALK_LIST(ifa, p->iface_list)
1669 {
1670 if (ifa->type == OSPF_IT_VLINK)
1671 continue;
be862406 1672
70945cb6
OZ
1673 if (ifa->update_link_lsa)
1674 {
1675 if ((ifa->state > OSPF_IS_LOOP) && !ifa->link_lsa_suppression)
1676 ospf_originate_link_lsa(p, ifa);
1677 else
1678 ospf_flush2_lsa(p, &ifa->link_lsa);
061ab802 1679
70945cb6
OZ
1680 ifa->update_link_lsa = 0;
1681 }
061ab802 1682
70945cb6
OZ
1683 if (ifa->update_net_lsa)
1684 {
1685 if ((ifa->state == OSPF_IS_DR) && (ifa->fadj > 0))
1686 {
1687 ospf_originate_net_lsa(p, ifa);
1688 ospf_originate_prefix_net_lsa(p, ifa);
1689 }
1690 else
1691 {
1692 ospf_flush2_lsa(p, &ifa->net_lsa);
1693 ospf_flush2_lsa(p, &ifa->pxn_lsa);
1694 }
1695
1696 ifa->update_net_lsa = 0;
1697 }
1698 }
70945cb6 1699}
e8085aba 1700
b49e6f5a 1701
6ba36f06
MM
1702static void
1703ospf_top_ht_alloc(struct top_graph *f)
1704{
1705 f->hash_size = 1 << f->hash_order;
1706 f->hash_mask = f->hash_size - 1;
1707 if (f->hash_order > HASH_HI_MAX - HASH_HI_STEP)
1708 f->hash_entries_max = ~0;
1709 else
1710 f->hash_entries_max = f->hash_size HASH_HI_MARK;
1711 if (f->hash_order < HASH_LO_MIN + HASH_LO_STEP)
1712 f->hash_entries_min = 0;
1713 else
1714 f->hash_entries_min = f->hash_size HASH_LO_MARK;
1715 DBG("Allocating OSPF hash of order %d: %d hash_entries, %d low, %d high\n",
1716 f->hash_order, f->hash_size, f->hash_entries_min, f->hash_entries_max);
b9ed99f7
OF
1717 f->hash_table =
1718 mb_alloc(f->pool, f->hash_size * sizeof(struct top_hash_entry *));
6ba36f06
MM
1719 bzero(f->hash_table, f->hash_size * sizeof(struct top_hash_entry *));
1720}
1721
1722static inline void
1723ospf_top_ht_free(struct top_hash_entry **h)
1724{
1725 mb_free(h);
1726}
1727
1728static inline u32
1729ospf_top_hash_u32(u32 a)
1730{
1731 /* Shamelessly stolen from IP address hashing in ipv4.h */
1732 a ^= a >> 16;
1733 a ^= a << 10;
1734 return a;
1735}
1736
a7a7372a 1737static uint
c3226991
OZ
1738ospf_top_hash(struct top_graph *f, u32 domain, u32 lsaid, u32 rtrid, u32 type)
1739{
be862406 1740 /* In OSPFv2, we don't know Router ID when looking for network LSAs.
9f0ba7b1
OZ
1741 In OSPFv3, we don't know LSA ID when looking for router LSAs.
1742 In both cases, there is (usually) just one (or small number)
1743 appropriate LSA, so we just clear unknown part of key. */
c3226991 1744
70945cb6
OZ
1745 return (((f->ospf2 && (type == LSA_T_NET)) ? 0 : ospf_top_hash_u32(rtrid)) +
1746 ((!f->ospf2 && (type == LSA_T_RT)) ? 0 : ospf_top_hash_u32(lsaid)) +
9f0ba7b1 1747 type + domain) & f->hash_mask;
c3226991
OZ
1748
1749 /*
b9ed99f7 1750 return (ospf_top_hash_u32(lsaid) + ospf_top_hash_u32(rtrid) +
86c84d76 1751 type + areaid) & f->hash_mask;
c3226991 1752 */
6ba36f06
MM
1753}
1754
7ab3ff6a
OF
1755/**
1756 * ospf_top_new - allocated new topology database
70945cb6 1757 * @p: OSPF protocol instance
a7a7372a 1758 * @pool: pool for allocation
7ab3ff6a 1759 *
a7a7372a
OZ
1760 * This dynamically hashed structure is used for keeping LSAs. Mainly it is used
1761 * for the LSA database of the OSPF protocol, but also for LSA retransmission
1762 * and request lists of OSPF neighbors.
7ab3ff6a 1763 */
6ba36f06 1764struct top_graph *
a7a7372a 1765ospf_top_new(struct ospf_proto *p, pool *pool)
6ba36f06
MM
1766{
1767 struct top_graph *f;
1768
035f6acb
OF
1769 f = mb_allocz(pool, sizeof(struct top_graph));
1770 f->pool = pool;
6ba36f06
MM
1771 f->hash_slab = sl_new(f->pool, sizeof(struct top_hash_entry));
1772 f->hash_order = HASH_DEF_ORDER;
1773 ospf_top_ht_alloc(f);
1774 f->hash_entries = 0;
1775 f->hash_entries_min = 0;
a7a7372a 1776 f->ospf2 = ospf_is_v2(p);
6ba36f06
MM
1777 return f;
1778}
1779
1780void
1781ospf_top_free(struct top_graph *f)
1782{
1783 rfree(f->hash_slab);
1784 ospf_top_ht_free(f->hash_table);
1785 mb_free(f);
1786}
1787
1788static void
1789ospf_top_rehash(struct top_graph *f, int step)
1790{
6ba36f06 1791 struct top_hash_entry **n, **oldt, **newt, *e, *x;
a7a7372a 1792 uint oldn, oldh;
6ba36f06
MM
1793
1794 oldn = f->hash_size;
1795 oldt = f->hash_table;
b49e6f5a 1796 DBG("re-hashing topology hash from order %d to %d\n", f->hash_order,
b9ed99f7 1797 f->hash_order + step);
6ba36f06
MM
1798 f->hash_order += step;
1799 ospf_top_ht_alloc(f);
1800 newt = f->hash_table;
1801
b9ed99f7
OF
1802 for (oldh = 0; oldh < oldn; oldh++)
1803 {
1804 e = oldt[oldh];
1805 while (e)
6ba36f06 1806 {
b9ed99f7 1807 x = e->next;
70945cb6 1808 n = newt + ospf_top_hash(f, e->domain, e->lsa.id, e->lsa.rt, e->lsa_type);
b9ed99f7
OF
1809 e->next = *n;
1810 *n = e;
1811 e = x;
6ba36f06 1812 }
b9ed99f7 1813 }
6ba36f06
MM
1814 ospf_top_ht_free(oldt);
1815}
1816
6f8bbaa1
OZ
1817static struct top_hash_entry *
1818ospf_hash_find_(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
6ba36f06 1819{
86c84d76 1820 struct top_hash_entry *e;
c3226991 1821 e = f->hash_table[ospf_top_hash(f, domain, lsa, rtr, type)];
86c84d76 1822
70945cb6
OZ
1823 while (e && (e->lsa.id != lsa || e->lsa.rt != rtr ||
1824 e->lsa_type != type || e->domain != domain))
9f0ba7b1
OZ
1825 e = e->next;
1826
6f8bbaa1
OZ
1827 return e;
1828}
1829
1830struct top_hash_entry *
1831ospf_hash_find(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
1832{
1833 struct top_hash_entry *e = ospf_hash_find_(f, domain, lsa, rtr, type);
1834
70945cb6 1835 /* Hide hash entry with empty lsa_body */
a7a7372a 1836 return (e && e->lsa_body) ? e : NULL;
9f0ba7b1 1837}
86c84d76 1838
70945cb6
OZ
1839/* In OSPFv2, lsa.id is the same as lsa.rt for router LSA. In OSPFv3, we don't know
1840 lsa.id when looking for router LSAs. We return matching LSA with smallest lsa.id. */
9f0ba7b1
OZ
1841struct top_hash_entry *
1842ospf_hash_find_rt(struct top_graph *f, u32 domain, u32 rtr)
1843{
1844 struct top_hash_entry *rv = NULL;
1845 struct top_hash_entry *e;
70945cb6
OZ
1846 /* We can put rtr for lsa.id to hash fn, it is ignored in OSPFv3 */
1847 e = f->hash_table[ospf_top_hash(f, domain, rtr, rtr, LSA_T_RT)];
1848
9f0ba7b1 1849 while (e)
70945cb6
OZ
1850 {
1851 if (e->lsa.rt == rtr && e->lsa_type == LSA_T_RT && e->domain == domain && e->lsa_body)
9f0ba7b1 1852 {
70945cb6
OZ
1853 if (f->ospf2 && (e->lsa.id == rtr))
1854 return e;
1855 if (!f->ospf2 && (!rv || e->lsa.id < rv->lsa.id))
1856 rv = e;
9f0ba7b1 1857 }
70945cb6
OZ
1858 e = e->next;
1859 }
9f0ba7b1
OZ
1860
1861 return rv;
1862}
1863
a7a7372a
OZ
1864/*
1865 * ospf_hash_find_rt3_first() and ospf_hash_find_rt3_next() are used exclusively
1866 * for lsa_walk_rt_init(), lsa_walk_rt(), therefore they skip MaxAge entries.
1867 */
9f0ba7b1 1868static inline struct top_hash_entry *
70945cb6 1869find_matching_rt3(struct top_hash_entry *e, u32 domain, u32 rtr)
9f0ba7b1 1870{
70945cb6 1871 while (e && (e->lsa.rt != rtr || e->lsa_type != LSA_T_RT ||
a7a7372a 1872 e->domain != domain || e->lsa.age == LSA_MAXAGE))
9f0ba7b1 1873 e = e->next;
6ba36f06
MM
1874 return e;
1875}
1876
9f0ba7b1 1877struct top_hash_entry *
70945cb6 1878ospf_hash_find_rt3_first(struct top_graph *f, u32 domain, u32 rtr)
9f0ba7b1
OZ
1879{
1880 struct top_hash_entry *e;
1881 e = f->hash_table[ospf_top_hash(f, domain, 0, rtr, LSA_T_RT)];
70945cb6 1882 return find_matching_rt3(e, domain, rtr);
9f0ba7b1
OZ
1883}
1884
1885struct top_hash_entry *
70945cb6 1886ospf_hash_find_rt3_next(struct top_hash_entry *e)
9f0ba7b1 1887{
70945cb6 1888 return find_matching_rt3(e->next, e->domain, e->lsa.rt);
9f0ba7b1
OZ
1889}
1890
70945cb6
OZ
1891/* In OSPFv2, we don't know Router ID when looking for network LSAs.
1892 There should be just one, so we find any match. */
1893struct top_hash_entry *
1894ospf_hash_find_net2(struct top_graph *f, u32 domain, u32 id)
1895{
1896 struct top_hash_entry *e;
1897 e = f->hash_table[ospf_top_hash(f, domain, id, 0, LSA_T_NET)];
1898
1899 while (e && (e->lsa.id != id || e->lsa_type != LSA_T_NET ||
1900 e->domain != domain || e->lsa_body == NULL))
1901 e = e->next;
1902
1903 return e;
1904}
9f0ba7b1
OZ
1905
1906
6ba36f06 1907struct top_hash_entry *
b49e6f5a 1908ospf_hash_get(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
6ba36f06 1909{
86c84d76
OF
1910 struct top_hash_entry **ee;
1911 struct top_hash_entry *e;
86c84d76 1912
c3226991 1913 ee = f->hash_table + ospf_top_hash(f, domain, lsa, rtr, type);
86c84d76
OF
1914 e = *ee;
1915
742029eb 1916 while (e && (e->lsa.id != lsa || e->lsa.rt != rtr ||
70945cb6 1917 e->lsa_type != type || e->domain != domain))
c3226991 1918 e = e->next;
6ba36f06 1919
6ba36f06
MM
1920 if (e)
1921 return e;
933bfdde 1922
6ba36f06 1923 e = sl_alloc(f->hash_slab);
70945cb6
OZ
1924 bzero(e, sizeof(struct top_hash_entry));
1925
933bfdde
OF
1926 e->color = OUTSPF;
1927 e->dist = LSINFINITY;
70945cb6 1928 e->lsa.type_raw = type;
ce17d4c1
OF
1929 e->lsa.id = lsa;
1930 e->lsa.rt = rtr;
70945cb6
OZ
1931 e->lsa.sn = LSA_ZEROSEQNO;
1932 e->lsa_type = type;
c3226991 1933 e->domain = domain;
933bfdde 1934 e->next = *ee;
b9ed99f7 1935 *ee = e;
6ba36f06
MM
1936 if (f->hash_entries++ > f->hash_entries_max)
1937 ospf_top_rehash(f, HASH_HI_STEP);
1938 return e;
1939}
1940
1941void
1942ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e)
1943{
742029eb 1944 struct top_hash_entry **ee = f->hash_table +
70945cb6 1945 ospf_top_hash(f, e->domain, e->lsa.id, e->lsa.rt, e->lsa_type);
6ba36f06
MM
1946
1947 while (*ee)
b9ed99f7
OF
1948 {
1949 if (*ee == e)
6ba36f06 1950 {
b9ed99f7
OF
1951 *ee = e->next;
1952 sl_free(f->hash_slab, e);
1953 if (f->hash_entries-- < f->hash_entries_min)
1954 ospf_top_rehash(f, -HASH_LO_STEP);
1955 return;
6ba36f06 1956 }
b9ed99f7
OF
1957 ee = &((*ee)->next);
1958 }
6ba36f06
MM
1959 bug("ospf_hash_delete() called for invalid node");
1960}
1961
e81b440f 1962/*
226cb2bc
OF
1963static void
1964ospf_dump_lsa(struct top_hash_entry *he, struct proto *p)
1965{
e81b440f 1966
226cb2bc
OF
1967 struct ospf_lsa_rt *rt = NULL;
1968 struct ospf_lsa_rt_link *rr = NULL;
1969 struct ospf_lsa_net *ln = NULL;
1970 u32 *rts = NULL;
1971 u32 i, max;
1972
3aab39f5
OZ
1973 OSPF_TRACE(D_EVENTS, "- %1x %-1R %-1R %4u 0x%08x 0x%04x %-1R",
1974 he->lsa.type, he->lsa.id, he->lsa.rt, he->lsa.age, he->lsa.sn,
c3226991 1975 he->lsa.checksum, he->domain);
226cb2bc 1976
b49e6f5a 1977
226cb2bc
OF
1978 switch (he->lsa.type)
1979 {
1980 case LSA_T_RT:
1981 rt = he->lsa_body;
1982 rr = (struct ospf_lsa_rt_link *) (rt + 1);
1983
c3226991 1984 for (i = 0; i < lsa_rt_items(&he->lsa); i++)
742029eb 1985 OSPF_TRACE(D_EVENTS, " - %1x %-1R %-1R %5u",
3aab39f5 1986 rr[i].type, rr[i].id, rr[i].data, rr[i].metric);
226cb2bc
OF
1987 break;
1988
1989 case LSA_T_NET:
1990 ln = he->lsa_body;
1991 rts = (u32 *) (ln + 1);
226cb2bc 1992
c3226991 1993 for (i = 0; i < lsa_net_items(&he->lsa); i++)
742029eb 1994 OSPF_TRACE(D_EVENTS, " - %-1R", rts[i]);
226cb2bc
OF
1995 break;
1996
1997 default:
1998 break;
1999 }
2000}
2001
6ba36f06 2002void
992705f6 2003ospf_top_dump(struct top_graph *f, struct proto *p)
6ba36f06 2004{
a7a7372a 2005 uint i;
992705f6 2006 OSPF_TRACE(D_EVENTS, "Hash entries: %d", f->hash_entries);
6ba36f06 2007
b9ed99f7
OF
2008 for (i = 0; i < f->hash_size; i++)
2009 {
226cb2bc
OF
2010 struct top_hash_entry *e;
2011 for (e = f->hash_table[i]; e != NULL; e = e->next)
2012 ospf_dump_lsa(e, p);
b9ed99f7 2013 }
6ba36f06 2014}
e81b440f 2015*/