]> git.ipfire.org Git - thirdparty/bird.git/blame - proto/ospf/topology.c
OSPF: Fix wrong LSA collisions detection
[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;
b32d557a 73 en->inst_time = current_time();
70945cb6 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;
b32d557a 131 en->inst_time = current_time();
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;
b32d557a 163 en->inst_time = current_time();
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 198 /* Enforce MinLSInterval */
b32d557a 199 if (!en->init_age && en->inst_time && (lsa_inst_age(en) < MINLSINTERVAL))
70945cb6
OZ
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;
b32d557a 240 en->inst_time = current_time();
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;
b32d557a 384 en->inst_time = current_time();
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{
cea2e25f
OZ
407 en->nf = NULL;
408
70945cb6
OZ
409 if (en->next_lsa_body)
410 {
411 mb_free(en->next_lsa_body);
412 en->next_lsa_body = NULL;
413 en->next_lsa_blen = 0;
414 en->next_lsa_opts = 0;
415 }
416
417 if (en->lsa.age == LSA_MAXAGE)
418 return;
419
6f8bbaa1
OZ
420 OSPF_TRACE(D_EVENTS, "Flushing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
421 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
422
70945cb6 423 en->lsa.age = LSA_MAXAGE;
a7a7372a
OZ
424 ospf_flood_lsa(p, en, NULL);
425
426 if (en->mode == LSA_M_BASIC)
427 ospf_schedule_rtcalc(p);
428
429 en->mode = LSA_M_BASIC;
70945cb6
OZ
430}
431
432static void
433ospf_clear_lsa(struct ospf_proto *p, struct top_hash_entry *en)
434{
435 /*
436 * Called by ospf_update_lsadb() as part of LSA flushing process.
437 * Flushed LSA was acknowledged by neighbors and we can free its content.
6f8bbaa1 438 * The log message is for 'remove' - we hide empty LSAs from users.
70945cb6
OZ
439 */
440
6f8bbaa1
OZ
441 OSPF_TRACE(D_EVENTS, "Removing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
442 en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
443
70945cb6
OZ
444 if (en->lsa.sn == LSA_MAXSEQNO)
445 en->lsa.sn = LSA_ZEROSEQNO;
446
447 mb_free(en->lsa_body);
448 en->lsa_body = NULL;
449}
450
451static void
452ospf_remove_lsa(struct ospf_proto *p, struct top_hash_entry *en)
453{
454 /*
455 * Called by ospf_update_lsadb() as part of LSA flushing process.
456 * Both lsa_body and next_lsa_body are NULL.
457 */
458
459 s_rem_node(SNODE en);
460 ospf_hash_delete(p->gr, en);
461}
462
463/**
464 * ospf_update_lsadb - update LSA database
465 * @p: OSPF protocol instance
466 *
467 * This function is periodicaly invoked from ospf_disp(). It does some periodic
468 * or postponed processing related to LSA entries. It originates postponed LSAs
469 * scheduled by ospf_originate_lsa(), It continues in flushing processes started
470 * by ospf_flush_lsa(). It also periodically refreshs locally originated LSAs --
471 * when the current instance is older %LSREFRESHTIME, a new instance is originated.
472 * Finally, it also ages stored LSAs and flushes ones that reached %LSA_MAXAGE.
473 *
474 * The RFC 2328 says that a router should periodically check checksums of all
475 * stored LSAs to detect hardware problems. This is not implemented.
476 */
477void
478ospf_update_lsadb(struct ospf_proto *p)
479{
480 struct top_hash_entry *en, *nxt;
b32d557a
OZ
481 btime now_ = current_time();
482 int real_age;
70945cb6
OZ
483
484 WALK_SLIST_DELSAFE(en, nxt, p->lsal)
485 {
486 if (en->next_lsa_body)
487 ospf_originate_next_lsa(p, en);
488
b32d557a 489 real_age = en->init_age + (now_ - en->inst_time) TO_S;
70945cb6
OZ
490
491 if (en->lsa.age == LSA_MAXAGE)
492 {
493 if (en->lsa_body && (p->padj == 0) && (en->ret_count == 0))
494 ospf_clear_lsa(p, en);
495
496 if ((en->lsa_body == NULL) && (en->next_lsa_body == NULL) &&
497 ((en->lsa.rt != p->router_id) || (real_age >= LSA_MAXAGE)))
498 ospf_remove_lsa(p, en);
499
500 continue;
501 }
502
503 if ((en->lsa.rt == p->router_id) && (real_age >= LSREFRESHTIME))
504 {
505 ospf_refresh_lsa(p, en);
506 continue;
507 }
508
509 if (real_age >= LSA_MAXAGE)
3d15dcdb 510 {
70945cb6 511 ospf_flush_lsa(p, en);
70945cb6 512 continue;
3d15dcdb 513 }
70945cb6
OZ
514
515 en->lsa.age = real_age;
516 }
517}
518
519
74c838a8 520static u32
70945cb6
OZ
521ort_to_lsaid(struct ospf_proto *p, ort *nf)
522{
523 /*
524 * In OSPFv2, We have to map IP prefixes to u32 in such manner that resulting
525 * u32 interpreted as IP address is a member of given prefix. Therefore, /32
fe9f1a6d
OZ
526 * prefix has to be mapped on itself. All received prefixes have to be mapped
527 * on different u32s.
70945cb6
OZ
528 *
529 * We have an assumption that if there is nontrivial (non-/32) network prefix,
530 * then there is not /32 prefix for the first and the last IP address of the
531 * network (these are usually reserved, therefore it is not an important
532 * restriction). The network prefix is mapped to the first or the last IP
533 * address in the manner that disallow collisions - we use the IP address that
534 * cannot be used by the parent prefix.
535 *
536 * For example:
537 * 192.168.0.0/24 maps to 192.168.0.255
538 * 192.168.1.0/24 maps to 192.168.1.0
539 * because 192.168.0.0 and 192.168.1.255 might be used by 192.168.0.0/23 .
540 *
541 * Appendig E of RFC 2328 suggests different algorithm, that tries to maximize
542 * both compatibility and subnetting. But as it is not possible to have both
543 * reliably and the suggested algorithm was unnecessary complicated and it
544 * does crazy things like changing LSA ID for a network because different
545 * network appeared, we choose a different way.
546 *
547 * In OSPFv3, it is simpler. There is not a requirement for membership of the
74c838a8
OZ
548 * result in the input network, so we just allocate a unique ID from ID map
549 * and store it in nf->lsa_id for further reference.
70945cb6
OZ
550 */
551
552 if (ospf_is_v3(p))
74c838a8
OZ
553 {
554 if (!nf->lsa_id)
555 nf->lsa_id = idm_alloc(&p->idm);
556
557 return nf->lsa_id;
558 }
70945cb6 559
fe9f1a6d
OZ
560 net_addr_ip4 *net = (void *) nf->fn.addr;
561 u32 id = ip4_to_u32(net->prefix);
562 int pxlen = net->pxlen;
70945cb6
OZ
563
564 if ((pxlen == 0) || (pxlen == 32))
565 return id;
566
567 if (id & (1 << (32 - pxlen)))
568 return id;
569 else
570 return id | ~u32_mkmask(pxlen);
571}
572
573
574static void *
a7a7372a 575lsab_alloc(struct ospf_proto *p, uint size)
70945cb6 576{
a7a7372a 577 uint offset = p->lsab_used;
70945cb6
OZ
578 p->lsab_used += size;
579 if (p->lsab_used > p->lsab_size)
580 {
581 p->lsab_size = MAX(p->lsab_used, 2 * p->lsab_size);
582 p->lsab = p->lsab ? mb_realloc(p->lsab, p->lsab_size):
583 mb_alloc(p->p.pool, p->lsab_size);
584 }
585 return ((byte *) p->lsab) + offset;
3d15dcdb
OZ
586}
587
588static inline void *
a7a7372a 589lsab_allocz(struct ospf_proto *p, uint size)
3d15dcdb 590{
70945cb6 591 void *r = lsab_alloc(p, size);
3d15dcdb
OZ
592 bzero(r, size);
593 return r;
594}
595
596static inline void *
70945cb6 597lsab_flush(struct ospf_proto *p)
3d15dcdb 598{
70945cb6
OZ
599 void *r = mb_alloc(p->p.pool, p->lsab_used);
600 memcpy(r, p->lsab, p->lsab_used);
601 p->lsab_used = 0;
3d15dcdb
OZ
602 return r;
603}
604
70945cb6
OZ
605static inline void
606lsab_reset(struct ospf_proto *p)
c3226991 607{
70945cb6 608 p->lsab_used = 0;
c3226991
OZ
609}
610
611static inline void *
a7a7372a 612lsab_offset(struct ospf_proto *p, uint offset)
c3226991 613{
70945cb6 614 return ((byte *) p->lsab) + offset;
c3226991
OZ
615}
616
3e236955 617static inline void * UNUSED
70945cb6 618lsab_end(struct ospf_proto *p)
52572e94 619{
70945cb6 620 return ((byte *) p->lsab) + p->lsab_used;
52572e94
OZ
621}
622
c3226991 623
70945cb6
OZ
624/*
625 * Router-LSA handling
626 * Type = LSA_T_RT
627 */
628
38675202
OZ
629static int
630configured_stubnet(struct ospf_area *oa, struct ifa *a)
631{
52a43ae3 632 /* Does not work for IA_PEER addresses, but it is not called on these */
38675202
OZ
633 struct ospf_stubnet_config *sn;
634 WALK_LIST(sn, oa->ac->stubnet_list)
70945cb6
OZ
635 {
636 if (sn->summary)
38675202 637 {
d44e686e 638 if (net_in_netX(&a->prefix, &sn->prefix))
70945cb6 639 return 1;
38675202 640 }
70945cb6
OZ
641 else
642 {
d44e686e 643 if (net_equal(&a->prefix, &sn->prefix))
70945cb6
OZ
644 return 1;
645 }
646 }
647
38675202
OZ
648 return 0;
649}
3d15dcdb 650
70945cb6 651static int
c3226991
OZ
652bcast_net_active(struct ospf_iface *ifa)
653{
654 struct ospf_neighbor *neigh;
655
656 if (ifa->state == OSPF_IS_WAITING)
657 return 0;
658
659 WALK_LIST(neigh, ifa->neigh_list)
70945cb6
OZ
660 {
661 if (neigh->state == NEIGHBOR_FULL)
c3226991 662 {
70945cb6
OZ
663 if (neigh->rid == ifa->drid)
664 return 1;
c3226991 665
70945cb6
OZ
666 if (ifa->state == OSPF_IS_DR)
667 return 1;
c3226991 668 }
70945cb6 669 }
c3226991
OZ
670
671 return 0;
672}
673
70945cb6
OZ
674static inline u32
675get_rt_options(struct ospf_proto *p, struct ospf_area *oa, int bitv)
676{
677 u32 opts = 0;
c3226991 678
70945cb6
OZ
679 if (p->areano > 1)
680 opts |= OPT_RT_B;
c3226991 681
70945cb6
OZ
682 if ((p->areano > 1) && oa_is_nssa(oa) && oa->ac->translator)
683 opts |= OPT_RT_NT;
ce17d4c1 684
70945cb6
OZ
685 if (p->asbr && !oa_is_stub(oa))
686 opts |= OPT_RT_E;
c3226991 687
70945cb6
OZ
688 if (bitv)
689 opts |= OPT_RT_V;
c3226991 690
70945cb6
OZ
691 return opts;
692}
c3226991 693
70945cb6
OZ
694static inline void
695add_rt2_lsa_link(struct ospf_proto *p, u8 type, u32 id, u32 data, u16 metric)
696{
697 struct ospf_lsa_rt2_link *ln = lsab_alloc(p, sizeof(struct ospf_lsa_rt2_link));
698 ln->type = type;
699 ln->id = id;
700 ln->data = data;
701 ln->metric = metric;
702 ln->no_tos = 0;
703}
4160a9dd 704
70945cb6
OZ
705static void
706prepare_rt2_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
707{
708 struct ospf_iface *ifa;
709 int i = 0, bitv = 0;
710 struct ospf_neighbor *neigh;
c3226991 711
70945cb6
OZ
712 ASSERT(p->lsab_used == 0);
713 lsab_allocz(p, sizeof(struct ospf_lsa_rt));
714 /* ospf_lsa_rt header will be filled later */
b9ed99f7 715
70945cb6 716 WALK_LIST(ifa, p->iface_list)
ce17d4c1 717 {
353729f5 718 int net_lsa = 0;
70945cb6 719 u32 link_cost = p->stub_router ? 0xffff : ifa->cost;
3d15dcdb
OZ
720
721 if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
722 (!EMPTY_LIST(ifa->neigh_list)))
5d3f5552
OF
723 {
724 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
725 if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
3d15dcdb 726 bitv = 1;
5d3f5552 727 }
3b16080c
OF
728
729 if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
b9ed99f7 730 continue;
3b580a23 731
e7b4948c
OZ
732 ifa->rt_pos_beg = i;
733
70945cb6 734 /* RFC 2328 - 12.4.1.1-4 */
3d15dcdb 735 switch (ifa->type)
70945cb6
OZ
736 {
737 case OSPF_IT_PTP:
738 case OSPF_IT_PTMP:
739 WALK_LIST(neigh, ifa->neigh_list)
740 if (neigh->state == NEIGHBOR_FULL)
98ac6176 741 {
70945cb6
OZ
742 /*
743 * ln->data should be ifa->iface_id in case of no/ptp
744 * address (ifa->addr->flags & IA_PEER) on PTP link (see
745 * RFC 2328 12.4.1.1.), but the iface ID value has no use,
746 * while using IP address even in this case is here for
747 * compatibility with some broken implementations that use
748 * this address as a next-hop.
749 */
750 add_rt2_lsa_link(p, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost);
3d15dcdb 751 i++;
70945cb6
OZ
752 }
753 break;
3d15dcdb 754
70945cb6
OZ
755 case OSPF_IT_BCAST:
756 case OSPF_IT_NBMA:
757 if (bcast_net_active(ifa))
758 {
759 add_rt2_lsa_link(p, LSART_NET, ipa_to_u32(ifa->drip), ipa_to_u32(ifa->addr->ip), link_cost);
760 i++;
761 net_lsa = 1;
ce17d4c1 762 }
70945cb6
OZ
763 break;
764
765 case OSPF_IT_VLINK:
766 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
767 if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
768 add_rt2_lsa_link(p, LSART_VLNK, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost), i++;
769 break;
770
771 default:
f8fefde3 772 log(L_BUG "OSPF: Unknown interface type");
70945cb6
OZ
773 break;
774 }
3d15dcdb 775
e7b4948c
OZ
776 ifa->rt_pos_end = i;
777
0aad2b92
OZ
778 /* Now we will originate stub area if there is no primary */
779 if (net_lsa ||
780 (ifa->type == OSPF_IT_VLINK) ||
a55a90fa 781 ((ifa->addr->flags & IA_PEER) && ! ifa->cf->stub) ||
0aad2b92
OZ
782 configured_stubnet(oa, ifa->addr))
783 continue;
3d15dcdb 784
70945cb6 785 /* Host or network stub entry */
52a43ae3
OZ
786 if ((ifa->addr->flags & IA_HOST) ||
787 (ifa->state == OSPF_IS_LOOP) ||
788 (ifa->type == OSPF_IT_PTMP))
70945cb6 789 add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(ifa->addr->ip), 0xffffffff, 0);
742029eb 790 else
d44e686e
OZ
791 add_rt2_lsa_link(p, LSART_STUB, ip4_to_u32(net4_prefix(&ifa->addr->prefix)),
792 u32_mkmask(net4_pxlen(&ifa->addr->prefix)), ifa->cost);
0aad2b92 793 i++;
e7b4948c
OZ
794
795 ifa->rt_pos_end = i;
ce17d4c1 796 }
3d15dcdb 797
38675202 798 struct ospf_stubnet_config *sn;
70945cb6
OZ
799 WALK_LIST(sn, oa->ac->stubnet_list)
800 if (!sn->hidden)
d44e686e
OZ
801 add_rt2_lsa_link(p, LSART_STUB, ip4_to_u32(net4_prefix(&sn->prefix)),
802 u32_mkmask(net4_pxlen(&sn->prefix)), sn->cost), i++;
c3226991 803
70945cb6 804 struct ospf_lsa_rt *rt = p->lsab;
742029eb 805 /* Store number of links in lower half of options */
70945cb6 806 rt->options = get_rt_options(p, oa, bitv) | (u16) i;
ce17d4c1 807}
c45f48fb 808
70945cb6
OZ
809static inline void
810add_rt3_lsa_link(struct ospf_proto *p, u8 type, struct ospf_iface *ifa, u32 nif, u32 id)
c3226991 811{
70945cb6 812 struct ospf_lsa_rt3_link *ln = lsab_alloc(p, sizeof(struct ospf_lsa_rt3_link));
c3226991
OZ
813 ln->type = type;
814 ln->padding = 0;
815 ln->metric = ifa->cost;
dd4da6f6 816 ln->lif = ifa->iface_id;
c3226991
OZ
817 ln->nif = nif;
818 ln->id = id;
819}
820
70945cb6
OZ
821static void
822prepare_rt3_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
c3226991 823{
c3226991 824 struct ospf_iface *ifa;
70945cb6 825 struct ospf_neighbor *neigh;
b49e6f5a 826 int bitv = 0;
e7b4948c 827 int i = 0;
4160a9dd 828
70945cb6
OZ
829 ASSERT(p->lsab_used == 0);
830 lsab_allocz(p, sizeof(struct ospf_lsa_rt));
831 /* ospf_lsa_rt header will be filled later */
c3226991 832
70945cb6 833 WALK_LIST(ifa, p->iface_list)
c3226991
OZ
834 {
835 if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
836 (!EMPTY_LIST(ifa->neigh_list)))
837 {
838 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
839 if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
840 bitv = 1;
841 }
842
843 if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
844 continue;
845
e7b4948c
OZ
846 ifa->rt_pos_beg = i;
847
70945cb6 848 /* RFC 5340 - 4.4.3.2 */
c3226991 849 switch (ifa->type)
70945cb6
OZ
850 {
851 case OSPF_IT_PTP:
852 case OSPF_IT_PTMP:
853 WALK_LIST(neigh, ifa->neigh_list)
854 if (neigh->state == NEIGHBOR_FULL)
855 add_rt3_lsa_link(p, LSART_PTP, ifa, neigh->iface_id, neigh->rid), i++;
856 break;
e7b4948c 857
70945cb6
OZ
858 case OSPF_IT_BCAST:
859 case OSPF_IT_NBMA:
860 if (bcast_net_active(ifa))
861 add_rt3_lsa_link(p, LSART_NET, ifa, ifa->dr_iface_id, ifa->drid), i++;
862 break;
c3226991 863
70945cb6
OZ
864 case OSPF_IT_VLINK:
865 neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
866 if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
867 add_rt3_lsa_link(p, LSART_VLNK, ifa, neigh->iface_id, neigh->rid), i++;
868 break;
869
870 default:
f8fefde3 871 log(L_BUG "OSPF: Unknown interface type");
70945cb6 872 break;
c3226991
OZ
873 }
874
70945cb6
OZ
875 ifa->rt_pos_end = i;
876 }
c3226991 877
70945cb6
OZ
878 struct ospf_lsa_rt *rt = p->lsab;
879 rt->options = get_rt_options(p, oa, bitv) | (oa->options & LSA_OPTIONS_MASK);
880}
c3226991 881
70945cb6
OZ
882static void
883ospf_originate_rt_lsa(struct ospf_proto *p, struct ospf_area *oa)
d8852b36 884{
70945cb6
OZ
885 struct ospf_new_lsa lsa = {
886 .type = LSA_T_RT,
887 .dom = oa->areaid,
888 .id = ospf_is_v2(p) ? p->router_id : 0,
889 .opts = oa->options
890 };
d8852b36 891
a7a7372a
OZ
892 OSPF_TRACE(D_EVENTS, "Updating router state for area %R", oa->areaid);
893
70945cb6
OZ
894 if (ospf_is_v2(p))
895 prepare_rt2_lsa_body(p, oa);
896 else
897 prepare_rt3_lsa_body(p, oa);
b9ed99f7 898
70945cb6
OZ
899 oa->rt = ospf_originate_lsa(p, &lsa);
900}
cf31112f 901
c3226991 902
70945cb6
OZ
903/*
904 * Net-LSA handling
905 * Type = LSA_T_NET
906 */
b49e6f5a 907
70945cb6
OZ
908static void
909prepare_net2_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
b49e6f5a 910{
70945cb6
OZ
911 struct ospf_lsa_net *net;
912 struct ospf_neighbor *n;
913 int nodes = ifa->fadj + 1;
914 u16 i = 1;
b49e6f5a 915
70945cb6
OZ
916 ASSERT(p->lsab_used == 0);
917 net = lsab_alloc(p, sizeof(struct ospf_lsa_net) + 4 * nodes);
b49e6f5a 918
d44e686e 919 net->optx = u32_mkmask(ifa->addr->prefix.pxlen);
70945cb6 920 net->routers[0] = p->router_id;
b49e6f5a 921
70945cb6
OZ
922 WALK_LIST(n, ifa->neigh_list)
923 {
924 if (n->state == NEIGHBOR_FULL)
925 {
926 net->routers[i] = n->rid;
927 i++;
928 }
929 }
930 ASSERT(i == nodes);
ab56f6b1
OF
931}
932
70945cb6
OZ
933static void
934prepare_net3_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
0bf2f203 935{
d345cda5 936 struct ospf_lsa_net *net;
c3226991 937 int nodes = ifa->fadj + 1;
c3226991 938 u32 options = 0;
70945cb6
OZ
939 u16 i = 1;
940
941 ASSERT(p->lsab_used == 0);
942 net = lsab_alloc(p, sizeof(struct ospf_lsa_net) + 4 * nodes);
c3226991 943
70945cb6 944 net->routers[0] = p->router_id;
d345cda5 945
70945cb6 946 struct ospf_neighbor *n;
b9ed99f7 947 WALK_LIST(n, ifa->neigh_list)
0bf2f203 948 {
b9ed99f7 949 if (n->state == NEIGHBOR_FULL)
0bf2f203 950 {
70945cb6
OZ
951 /* In OSPFv3, we would like to merge options from Link LSAs of added neighbors */
952
953 struct top_hash_entry *en =
954 ospf_hash_find(p->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK);
955
c3226991
OZ
956 if (en)
957 options |= ((struct ospf_lsa_link *) en->lsa_body)->options;
c3226991
OZ
958
959 net->routers[i] = n->rid;
0bf2f203
OF
960 i++;
961 }
962 }
c3226991
OZ
963 ASSERT(i == nodes);
964
70945cb6 965 net->optx = options & LSA_OPTIONS_MASK;
0bf2f203
OF
966}
967
70945cb6
OZ
968static void
969ospf_originate_net_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
970{
971 struct ospf_new_lsa lsa = {
972 .type = LSA_T_NET,
973 .dom = ifa->oa->areaid,
974 .id = ospf_is_v2(p) ? ipa_to_u32(ifa->addr->ip) : ifa->iface_id,
975 .opts = ifa->oa->options,
976 .ifa = ifa
977 };
978
a7a7372a
OZ
979 OSPF_TRACE(D_EVENTS, "Updating network state for %s (Id: %R)", ifa->ifname, lsa.id);
980
70945cb6
OZ
981 if (ospf_is_v2(p))
982 prepare_net2_lsa_body(p, ifa);
b49e6f5a 983 else
70945cb6 984 prepare_net3_lsa_body(p, ifa);
9727681a 985
70945cb6 986 ifa->net_lsa = ospf_originate_lsa(p, &lsa);
9727681a
OZ
987}
988
7ff5803b 989
70945cb6
OZ
990/*
991 * (Net|Rt)-summary-LSA handling
992 * (a.k.a. Inter-Area-(Prefix|Router)-LSA)
993 * Type = LSA_T_SUM_NET, LSA_T_SUM_RT
994 */
0077aab4 995
70945cb6
OZ
996static inline void
997prepare_sum2_lsa_body(struct ospf_proto *p, uint pxlen, u32 metric)
0077aab4 998{
70945cb6 999 struct ospf_lsa_sum2 *sum;
c3226991 1000
70945cb6
OZ
1001 sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum2));
1002 sum->netmask = u32_mkmask(pxlen);
c3226991 1003 sum->metric = metric;
c3226991
OZ
1004}
1005
70945cb6
OZ
1006static inline void
1007prepare_sum3_net_lsa_body(struct ospf_proto *p, ort *nf, u32 metric)
9727681a 1008{
70945cb6 1009 struct ospf_lsa_sum3_net *sum;
9727681a 1010
fe9f1a6d
OZ
1011 sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_net) +
1012 IPV6_PREFIX_SPACE(nf->fn.addr->pxlen));
70945cb6 1013 sum->metric = metric;
d3f4f92b 1014 ospf3_put_prefix(sum->prefix, nf->fn.addr, 0, 0);
9727681a
OZ
1015}
1016
70945cb6
OZ
1017static inline void
1018prepare_sum3_rt_lsa_body(struct ospf_proto *p, u32 drid, u32 metric, u32 options)
c3226991 1019{
70945cb6 1020 struct ospf_lsa_sum3_rt *sum;
c3226991 1021
70945cb6 1022 sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_rt));
7ff5803b 1023 sum->options = options;
c3226991
OZ
1024 sum->metric = metric;
1025 sum->drid = drid;
7ff5803b
OZ
1026}
1027
98ac6176 1028void
70945cb6 1029ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric)
98ac6176 1030{
70945cb6
OZ
1031 struct ospf_new_lsa lsa = {
1032 .type = LSA_T_SUM_NET,
a7a7372a 1033 .mode = LSA_M_RTCALC,
70945cb6
OZ
1034 .dom = oa->areaid,
1035 .id = ort_to_lsaid(p, nf),
1036 .opts = oa->options,
1037 .nf = nf
1038 };
7ff5803b 1039
70945cb6 1040 if (ospf_is_v2(p))
fe9f1a6d 1041 prepare_sum2_lsa_body(p, nf->fn.addr->pxlen, metric);
70945cb6
OZ
1042 else
1043 prepare_sum3_net_lsa_body(p, nf, metric);
c3226991 1044
a7a7372a 1045 ospf_originate_lsa(p, &lsa);
9727681a 1046}
c3226991 1047
9727681a 1048void
fe9f1a6d 1049ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 drid, int metric, u32 options)
9727681a 1050{
70945cb6
OZ
1051 struct ospf_new_lsa lsa = {
1052 .type = LSA_T_SUM_RT,
a7a7372a 1053 .mode = LSA_M_RTCALC,
70945cb6 1054 .dom = oa->areaid,
fe9f1a6d 1055 .id = drid, /* Router ID of ASBR, irrelevant for OSPFv3 */
70945cb6
OZ
1056 .opts = oa->options
1057 };
98ac6176 1058
70945cb6
OZ
1059 if (ospf_is_v2(p))
1060 prepare_sum2_lsa_body(p, 0, metric);
c3226991 1061 else
fe9f1a6d 1062 prepare_sum3_rt_lsa_body(p, drid, metric, options & LSA_OPTIONS_MASK);
9727681a 1063
a7a7372a 1064 ospf_originate_lsa(p, &lsa);
98ac6176
OF
1065}
1066
c3226991 1067
7ff5803b 1068/*
70945cb6
OZ
1069 * AS-external-LSA and NSSA-LSA handling
1070 * Type = LSA_T_EXT, LSA_T_NSSA
7ff5803b 1071 */
c3226991 1072
70945cb6
OZ
1073static inline void
1074prepare_ext2_lsa_body(struct ospf_proto *p, uint pxlen,
1075 u32 metric, u32 ebit, ip_addr fwaddr, u32 tag)
7ff5803b 1076{
70945cb6 1077 struct ospf_lsa_ext2 *ext;
7ff5803b 1078
70945cb6
OZ
1079 ext = lsab_allocz(p, sizeof(struct ospf_lsa_ext2));
1080 ext->metric = metric & LSA_METRIC_MASK;
1081 ext->netmask = u32_mkmask(pxlen);
1082 ext->fwaddr = ipa_to_u32(fwaddr);
1083 ext->tag = tag;
7ff5803b 1084
70945cb6
OZ
1085 if (ebit)
1086 ext->metric |= LSA_EXT2_EBIT;
7ff5803b 1087}
c3226991 1088
70945cb6
OZ
1089static inline void
1090prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
1091 u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit)
7ff5803b 1092{
70945cb6
OZ
1093 struct ospf_lsa_ext3 *ext;
1094 int bsize = sizeof(struct ospf_lsa_ext3)
fe9f1a6d 1095 + IPV6_PREFIX_SPACE(nf->fn.addr->pxlen)
7ff5803b
OZ
1096 + (ipa_nonzero(fwaddr) ? 16 : 0)
1097 + (tag ? 4 : 0);
1098
70945cb6
OZ
1099 ext = lsab_allocz(p, bsize);
1100 ext->metric = metric & LSA_METRIC_MASK;
1101 u32 *buf = ext->rest;
7ff5803b 1102
d3f4f92b 1103 buf = ospf3_put_prefix(buf, nf->fn.addr, pbit ? OPT_PX_P : 0, 0);
7ff5803b 1104
70945cb6
OZ
1105 if (ebit)
1106 ext->metric |= LSA_EXT3_EBIT;
c3226991 1107
7ff5803b
OZ
1108 if (ipa_nonzero(fwaddr))
1109 {
70945cb6 1110 ext->metric |= LSA_EXT3_FBIT;
d3f4f92b 1111 buf = ospf3_put_addr(buf, fwaddr);
7ff5803b 1112 }
c3226991
OZ
1113
1114 if (tag)
7ff5803b 1115 {
70945cb6 1116 ext->metric |= LSA_EXT3_TBIT;
7ff5803b
OZ
1117 *buf++ = tag;
1118 }
c3226991
OZ
1119}
1120
70945cb6
OZ
1121/**
1122 * originate_ext_lsa - new route received from nest and filters
a7a7372a 1123 * @p: OSPF protocol instance
70945cb6
OZ
1124 * @oa: ospf_area for which LSA is originated
1125 * @nf: network prefix and mask
a7a7372a
OZ
1126 * @mode: the mode of the LSA (LSA_M_EXPORT or LSA_M_RTCALC)
1127 * @metric: the metric of a route
1128 * @ebit: E-bit for route metric (bool)
70945cb6
OZ
1129 * @fwaddr: the forwarding address
1130 * @tag: the route tag
a7a7372a 1131 * @pbit: P-bit for NSSA LSAs (bool), ignored for external LSAs
70945cb6
OZ
1132 *
1133 * If I receive a message that new route is installed, I try to originate an
1134 * external LSA. If @oa is an NSSA area, NSSA-LSA is originated instead.
1135 * @oa should not be a stub area. @src does not specify whether the LSA
742029eb 1136 * is external or NSSA, but it specifies the source of origination -
70945cb6
OZ
1137 * the export from ospf_rt_notify(), or the NSSA-EXT translation.
1138 */
1139void
a7a7372a 1140ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode,
70945cb6 1141 u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit)
7ff5803b 1142{
70945cb6
OZ
1143 struct ospf_new_lsa lsa = {
1144 .type = oa ? LSA_T_NSSA : LSA_T_EXT,
a7a7372a 1145 .mode = mode, /* LSA_M_EXPORT or LSA_M_RTCALC */
70945cb6
OZ
1146 .dom = oa ? oa->areaid : 0,
1147 .id = ort_to_lsaid(p, nf),
1148 .opts = oa ? (pbit ? OPT_P : 0) : OPT_E,
1149 .nf = nf
1150 };
7ff5803b 1151
70945cb6 1152 if (ospf_is_v2(p))
fe9f1a6d 1153 prepare_ext2_lsa_body(p, nf->fn.addr->pxlen, metric, ebit, fwaddr, tag);
70945cb6
OZ
1154 else
1155 prepare_ext3_lsa_body(p, nf, metric, ebit, fwaddr, tag, oa && pbit);
7ff5803b 1156
a7a7372a 1157 ospf_originate_lsa(p, &lsa);
70945cb6
OZ
1158}
1159
6f8bbaa1
OZ
1160static struct top_hash_entry *
1161ospf_hash_find_(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type);
1162
70945cb6
OZ
1163static void
1164ospf_flush_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf)
1165{
1166 struct top_hash_entry *en;
d395fe48 1167
70945cb6
OZ
1168 u32 type = oa ? LSA_T_NSSA : LSA_T_EXT;
1169 u32 dom = oa ? oa->areaid : 0;
1170 u32 id = ort_to_lsaid(p, nf);
7ff5803b 1171
6f8bbaa1 1172 en = ospf_hash_find_(p->gr, dom, id, p->router_id, type);
7ff5803b 1173
70945cb6
OZ
1174 if (!en || (en->nf != nf))
1175 return;
7ff5803b 1176
70945cb6 1177 ospf_flush_lsa(p, en);
7ff5803b
OZ
1178}
1179
70945cb6
OZ
1180static inline int
1181use_gw_for_fwaddr(struct ospf_proto *p, ip_addr gw, struct iface *iface)
1182{
1183 struct ospf_iface *ifa;
1184
1185 if (ipa_zero(gw) || ipa_is_link_local(gw))
1186 return 0;
7ff5803b 1187
70945cb6
OZ
1188 WALK_LIST(ifa, p->iface_list)
1189 if ((ifa->iface == iface) &&
d44e686e 1190 (!ospf_is_v2(p) || ipa_in_netX(gw, &ifa->addr->prefix)))
70945cb6
OZ
1191 return 1;
1192
1193 return 0;
1194}
7ff5803b 1195
2918e610 1196static inline ip_addr
70945cb6 1197find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
2918e610 1198{
2918e610
OZ
1199 struct ospf_iface *ifa;
1200 struct ifa *a, *cur_addr = NULL;
1201 int np, cur_np = 0;
1202
70945cb6
OZ
1203 /* RFC 3101 2.3 - surrogate forwarding address selection */
1204
1205 WALK_LIST(ifa, p->iface_list)
2918e610
OZ
1206 {
1207 if ((ifa->oa != oa) ||
2918e610
OZ
1208 (ifa->type == OSPF_IT_VLINK))
1209 continue;
1210
70945cb6 1211 if (ospf_is_v2(p))
2918e610 1212 {
70945cb6
OZ
1213 a = ifa->addr;
1214 if (a->flags & IA_PEER)
2918e610
OZ
1215 continue;
1216
70945cb6 1217 np = (a->flags & IA_HOST) ? 3 : (ifa->stub ? 2 : 1);
2918e610
OZ
1218 if (np > cur_np)
1219 {
1220 cur_addr = a;
1221 cur_np = np;
1222 }
1223 }
70945cb6
OZ
1224 else /* OSPFv3 */
1225 {
1226 WALK_LIST(a, ifa->iface->addrs)
1227 {
d3f4f92b 1228 if ((a->prefix.type != ospf_get_af(p)) ||
d44e686e 1229 (a->flags & IA_SECONDARY) ||
70945cb6
OZ
1230 (a->flags & IA_PEER) ||
1231 (a->scope <= SCOPE_LINK))
1232 continue;
1233
1234 np = (a->flags & IA_HOST) ? 3 : (ifa->stub ? 2 : 1);
1235 if (np > cur_np)
1236 {
1237 cur_addr = a;
1238 cur_np = np;
1239 }
1240 }
1241 }
2918e610
OZ
1242 }
1243
1244 return cur_addr ? cur_addr->ip : IPA_NONE;
1245}
1246
e8085aba 1247void
13c0be19 1248ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED)
e8085aba 1249{
70945cb6
OZ
1250 struct ospf_proto *p = (struct ospf_proto *) P;
1251 struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */
1252 ort *nf;
41b612c3 1253
70945cb6
OZ
1254 /*
1255 * There are several posibilities:
1256 * 1) router in regular area - originate external LSA with global scope
1257 * 2) router in NSSA area - originate area-specific NSSA-LSA
1258 * 3) router in stub area - cannot export routes
1259 * 4) area border router - same as (1), it is attached to backbone
1260 */
b9ed99f7 1261
70945cb6
OZ
1262 if ((p->areano == 1) && oa_is_nssa(HEAD(p->area_list)))
1263 oa = HEAD(p->area_list);
273fd2c1 1264
70945cb6 1265 if (!new)
41b612c3 1266 {
fe9f1a6d 1267 nf = fib_find(&p->rtf, n->n.addr);
2918e610 1268
70945cb6 1269 if (!nf || !nf->external_rte)
2918e610 1270 return;
41b612c3 1271
70945cb6
OZ
1272 ospf_flush_ext_lsa(p, oa, nf);
1273 nf->external_rte = 0;
273fd2c1 1274
70945cb6
OZ
1275 /* Old external route might blocked some NSSA translation */
1276 if ((p->areano > 1) && rt_is_nssa(nf) && nf->n.oa->translate)
a7a7372a 1277 ospf_schedule_rtcalc(p);
7ff5803b 1278
70945cb6
OZ
1279 return;
1280 }
c3226991 1281
70945cb6 1282 ASSERT(p->asbr);
2918e610 1283
70945cb6
OZ
1284 /* Get route attributes */
1285 rta *a = new->attrs;
8bd718b3
OZ
1286 eattr *m1a = ea_find(a->eattrs, EA_OSPF_METRIC1);
1287 eattr *m2a = ea_find(a->eattrs, EA_OSPF_METRIC2);
feae132e
OZ
1288 uint m1 = m1a ? m1a->u.data : 0;
1289 uint m2 = m2a ? m2a->u.data : 10000;
fdb19982 1290
feae132e
OZ
1291 if (m1 > LSINFINITY)
1292 {
1293 log(L_WARN "%s: Invalid ospf_metric1 value %u for route %N",
1294 p->p.name, m1, n->n.addr);
1295 m1 = LSINFINITY;
1296 }
e8085aba 1297
feae132e
OZ
1298 if (m2 > LSINFINITY)
1299 {
1300 log(L_WARN "%s: Invalid ospf_metric2 value %u for route %N",
1301 p->p.name, m2, n->n.addr);
1302 m2 = LSINFINITY;
1303 }
1304
1305 /* Ensure monotonicity of metric if both m1 and m2 are used */
1306 if ((m1 > 0) && (m2 < LSINFINITY))
1307 m2++;
1308
1309 uint ebit = m2a || !m1a;
1310 uint metric = ebit ? m2 : m1;
8bd718b3 1311 uint tag = ea_get_int(a->eattrs, EA_OSPF_TAG, 0);
feae132e
OZ
1312
1313 ip_addr fwd = IPA_NONE;
4e276a89
JMM
1314 if ((a->dest == RTD_UNICAST) && use_gw_for_fwaddr(p, a->nh.gw, a->nh.iface))
1315 fwd = a->nh.gw;
be862406 1316
70945cb6
OZ
1317 /* NSSA-LSA with P-bit set must have non-zero forwarding address */
1318 if (oa && ipa_zero(fwd))
1319 {
1320 fwd = find_surrogate_fwaddr(p, oa);
c3226991 1321
70945cb6 1322 if (ipa_zero(fwd))
c3226991 1323 {
fe9f1a6d
OZ
1324 log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %N",
1325 p->p.name, n->n.addr);
70945cb6 1326 return;
c3226991 1327 }
70945cb6
OZ
1328 }
1329
fe9f1a6d 1330 nf = fib_get(&p->rtf, n->n.addr);
a7a7372a 1331 ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1);
70945cb6 1332 nf->external_rte = 1;
c3226991
OZ
1333}
1334
1335
70945cb6
OZ
1336/*
1337 * Link-LSA handling (assume OSPFv3)
1338 * Type = LSA_T_LINK
1339 */
c3226991 1340
70945cb6 1341static inline void
d3f4f92b 1342lsab_put_prefix(struct ospf_proto *p, net_addr *n, u32 cost)
70945cb6 1343{
d3f4f92b
OZ
1344 void *buf = lsab_alloc(p, IPV6_PREFIX_SPACE(net_pxlen(n)));
1345 uint max = (n->type == NET_IP4) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH;
1346 u8 flags = (net_pxlen(n) < max) ? 0 : OPT_PX_LA;
1347 ospf3_put_prefix(buf, n, flags, cost);
70945cb6
OZ
1348}
1349
1350static void
1351prepare_link_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1352{
d3f4f92b 1353 ip_addr nh = ospf_is_ip4(p) ? IPA_NONE : ifa->addr->ip;
c3226991 1354 int i = 0;
c3226991 1355
d3f4f92b 1356 /* Preallocating space for header */
70945cb6 1357 ASSERT(p->lsab_used == 0);
d3f4f92b 1358 lsab_allocz(p, sizeof(struct ospf_lsa_link));
c3226991
OZ
1359
1360 struct ifa *a;
1361 WALK_LIST(a, ifa->iface->addrs)
70945cb6 1362 {
d3f4f92b 1363 if ((a->prefix.type != ospf_get_af(p)) ||
d44e686e
OZ
1364 (a->flags & IA_SECONDARY) ||
1365 (a->scope <= SCOPE_LINK))
70945cb6 1366 continue;
c3226991 1367
d3f4f92b
OZ
1368 if (ospf_is_ip4(p) && ipa_zero(nh))
1369 nh = a->ip;
1370
d44e686e 1371 lsab_put_prefix(p, &a->prefix, 0);
70945cb6
OZ
1372 i++;
1373 }
c3226991 1374
d3f4f92b
OZ
1375 /* Filling the preallocated header */
1376 struct ospf_lsa_link *ll = p->lsab;
1377 ll->options = ifa->oa->options | (ifa->priority << 24);
1378 ll->lladdr = ospf_is_ip4(p) ? ospf3_4to6(ipa_to_ip4(nh)) : ipa_to_ip6(nh);
c3226991 1379 ll->pxcount = i;
d3f4f92b
OZ
1380
1381 if (ipa_zero(nh))
1382 log(L_ERR "%s: Cannot find next hop address for %s", p->p.name, ifa->ifname);
c3226991
OZ
1383}
1384
70945cb6
OZ
1385static void
1386ospf_originate_link_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1387{
70945cb6 1388 if (ospf_is_v2(p))
48e5f32d
OZ
1389 return;
1390
70945cb6
OZ
1391 struct ospf_new_lsa lsa = {
1392 .type = LSA_T_LINK,
1393 .dom = ifa->iface_id,
1394 .id = ifa->iface_id,
1395 .ifa = ifa
1396 };
c3226991 1397
a7a7372a
OZ
1398 OSPF_TRACE(D_EVENTS, "Updating link state for %s (Id: %R)", ifa->ifname, lsa.id);
1399
70945cb6 1400 prepare_link_lsa_body(p, ifa);
be862406 1401
70945cb6 1402 ifa->link_lsa = ospf_originate_lsa(p, &lsa);
c3226991
OZ
1403}
1404
1405
70945cb6
OZ
1406/*
1407 * Prefix-Rt-LSA handling (assume OSPFv3)
1408 * Type = LSA_T_PREFIX, referred type = LSA_T_RT
1409 */
d9e7e1b1 1410
70945cb6
OZ
1411static void
1412prepare_prefix_rt_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
c3226991 1413{
70945cb6 1414 struct ospf_config *cf = (struct ospf_config *) (p->p.cf);
c3226991
OZ
1415 struct ospf_iface *ifa;
1416 struct ospf_lsa_prefix *lp;
3b89a232 1417 int host_addr = 0;
c3226991
OZ
1418 int net_lsa;
1419 int i = 0;
c3226991 1420
70945cb6
OZ
1421 ASSERT(p->lsab_used == 0);
1422 lp = lsab_allocz(p, sizeof(struct ospf_lsa_prefix));
c3226991
OZ
1423 lp->ref_type = LSA_T_RT;
1424 lp->ref_id = 0;
70945cb6 1425 lp->ref_rt = p->router_id;
c3226991
OZ
1426 lp = NULL; /* buffer might be reallocated later */
1427
70945cb6 1428 WALK_LIST(ifa, p->iface_list)
c3226991 1429 {
e4404cef 1430 if ((ifa->oa != oa) || (ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
c3226991
OZ
1431 continue;
1432
e7b4948c
OZ
1433 ifa->px_pos_beg = i;
1434
c3226991
OZ
1435 if ((ifa->type == OSPF_IT_BCAST) ||
1436 (ifa->type == OSPF_IT_NBMA))
1437 net_lsa = bcast_net_active(ifa);
1438 else
1439 net_lsa = 0;
1440
1441 struct ifa *a;
1442 WALK_LIST(a, ifa->iface->addrs)
70945cb6 1443 {
d3f4f92b 1444 if ((a->prefix.type != ospf_get_af(p)) ||
d44e686e 1445 (a->flags & IA_SECONDARY) ||
70945cb6
OZ
1446 (a->flags & IA_PEER) ||
1447 (a->scope <= SCOPE_LINK))
1448 continue;
3b89a232 1449
d44e686e 1450 if (((a->prefix.pxlen < IP6_MAX_PREFIX_LENGTH) && net_lsa) ||
70945cb6
OZ
1451 configured_stubnet(oa, a))
1452 continue;
c3226991 1453
70945cb6
OZ
1454 if ((a->flags & IA_HOST) ||
1455 (ifa->state == OSPF_IS_LOOP) ||
1456 (ifa->type == OSPF_IT_PTMP))
1457 {
d44e686e
OZ
1458 net_addr_ip6 net = NET_ADDR_IP6(a->ip, IP6_MAX_PREFIX_LENGTH);
1459 lsab_put_prefix(p, (net_addr *) &net, 0);
70945cb6 1460 host_addr = 1;
c3226991 1461 }
70945cb6 1462 else
d44e686e 1463 lsab_put_prefix(p, &a->prefix, ifa->cost);
70945cb6
OZ
1464 i++;
1465 }
e7b4948c
OZ
1466
1467 ifa->px_pos_end = i;
c3226991
OZ
1468 }
1469
c3226991 1470 struct ospf_stubnet_config *sn;
70945cb6
OZ
1471 WALK_LIST(sn, oa->ac->stubnet_list)
1472 if (!sn->hidden)
1473 {
d44e686e
OZ
1474 lsab_put_prefix(p, &sn->prefix, sn->cost);
1475 if (sn->prefix.pxlen == IP6_MAX_PREFIX_LENGTH)
70945cb6
OZ
1476 host_addr = 1;
1477 i++;
1478 }
e4404cef
OZ
1479
1480 /* If there are some configured vlinks, find some global address
1481 (even from another area), which will be used as a vlink endpoint. */
d3f4f92b 1482 if (!EMPTY_LIST(cf->vlink_list) && !host_addr && ospf_is_ip6(p))
e4404cef 1483 {
70945cb6 1484 WALK_LIST(ifa, p->iface_list)
e4404cef
OZ
1485 {
1486 if ((ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
1487 continue;
1488
1489 struct ifa *a;
1490 WALK_LIST(a, ifa->iface->addrs)
1491 {
d44e686e
OZ
1492 if ((a->prefix.type != NET_IP6) ||
1493 (a->flags & IA_SECONDARY) ||
1494 (a->scope <= SCOPE_LINK))
e4404cef
OZ
1495 continue;
1496
1497 /* Found some IP */
d44e686e
OZ
1498 net_addr_ip6 net = NET_ADDR_IP6(a->ip, IP6_MAX_PREFIX_LENGTH);
1499 lsab_put_prefix(p, (net_addr *) &net, 0);
c3226991 1500 i++;
e4404cef 1501 goto done;
c3226991 1502 }
e4404cef
OZ
1503 }
1504 }
c3226991 1505
e4404cef 1506 done:
70945cb6 1507 lp = p->lsab;
c3226991 1508 lp->pxcount = i;
c3226991
OZ
1509}
1510
70945cb6
OZ
1511static void
1512ospf_originate_prefix_rt_lsa(struct ospf_proto *p, struct ospf_area *oa)
c3226991 1513{
70945cb6
OZ
1514 if (ospf_is_v2(p))
1515 return;
c3226991 1516
70945cb6
OZ
1517 struct ospf_new_lsa lsa = {
1518 .type = LSA_T_PREFIX,
1519 .dom = oa->areaid,
1520 .id = 0
1521 };
be862406 1522
70945cb6 1523 prepare_prefix_rt_lsa_body(p, oa);
c3226991 1524
70945cb6 1525 ospf_originate_lsa(p, &lsa);
c3226991
OZ
1526}
1527
1528
70945cb6
OZ
1529/*
1530 * Prefix-Net-LSA handling (assume OSPFv3)
1531 * Type = LSA_T_PREFIX, referred type = LSA_T_NET
1532 */
1533
c3226991
OZ
1534static inline int
1535prefix_space(u32 *buf)
1536{
1537 int pxl = *buf >> 24;
1538 return IPV6_PREFIX_SPACE(pxl);
1539}
1540
1541static inline int
1542prefix_same(u32 *b1, u32 *b2)
1543{
1544 int pxl1 = *b1 >> 24;
1545 int pxl2 = *b2 >> 24;
1546 int pxs, i;
742029eb 1547
c3226991
OZ
1548 if (pxl1 != pxl2)
1549 return 0;
1550
1551 pxs = IPV6_PREFIX_WORDS(pxl1);
1552 for (i = 1; i < pxs; i++)
1553 if (b1[i] != b2[i])
1554 return 0;
1555
1556 return 1;
1557}
1558
1559static inline u32 *
1560prefix_advance(u32 *buf)
1561{
be862406
OZ
1562 int pxl = *buf >> 24;
1563 return buf + IPV6_PREFIX_WORDS(pxl);
c3226991
OZ
1564}
1565
2918e610 1566/* FIXME eliminate items with LA bit set? see 4.4.3.9 */
c3226991 1567static void
70945cb6 1568add_prefix(struct ospf_proto *p, u32 *px, int offset, int *pxc)
c3226991 1569{
70945cb6 1570 u32 *pxl = lsab_offset(p, offset);
c3226991 1571 int i;
e4404cef
OZ
1572 for (i = 0; i < *pxc; pxl = prefix_advance(pxl), i++)
1573 if (prefix_same(px, pxl))
c3226991 1574 {
e4404cef
OZ
1575 /* Options should be logically OR'ed together */
1576 *pxl |= (*px & 0x00FF0000);
1577 return;
c3226991
OZ
1578 }
1579
70945cb6 1580 ASSERT(pxl == lsab_end(p));
c3226991
OZ
1581
1582 int pxspace = prefix_space(px);
70945cb6 1583 pxl = lsab_alloc(p, pxspace);
c3226991 1584 memcpy(pxl, px, pxspace);
e4404cef 1585 *pxl &= 0xFFFF0000; /* Set metric to zero */
c3226991
OZ
1586 (*pxc)++;
1587}
1588
be862406 1589static void
70945cb6 1590add_link_lsa(struct ospf_proto *p, struct ospf_lsa_link *ll, int offset, int *pxc)
be862406 1591{
be862406 1592 u32 *pxb = ll->rest;
3e236955 1593 uint j;
be862406 1594
e4404cef
OZ
1595 for (j = 0; j < ll->pxcount; pxb = prefix_advance(pxb), j++)
1596 {
1597 u8 pxlen = (pxb[0] >> 24);
1598 u8 pxopts = (pxb[0] >> 16);
1599
1600 /* Skip NU or LA prefixes */
1601 if (pxopts & (OPT_PX_NU | OPT_PX_LA))
1602 continue;
1603
1604 /* Skip link-local prefixes */
d3f4f92b 1605 if (ospf_is_ip6(p) && (pxlen >= 10) && ((pxb[1] & 0xffc00000) == 0xfe800000))
e4404cef
OZ
1606 continue;
1607
70945cb6 1608 add_prefix(p, pxb, offset, pxc);
e4404cef 1609 }
be862406
OZ
1610}
1611
70945cb6
OZ
1612static void
1613prepare_prefix_net_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1614{
c3226991 1615 struct ospf_lsa_prefix *lp;
c3226991
OZ
1616 struct ospf_neighbor *n;
1617 struct top_hash_entry *en;
be862406 1618 int pxc, offset;
c3226991 1619
70945cb6
OZ
1620 ASSERT(p->lsab_used == 0);
1621 lp = lsab_allocz(p, sizeof(struct ospf_lsa_prefix));
c3226991
OZ
1622 lp->ref_type = LSA_T_NET;
1623 lp->ref_id = ifa->net_lsa->lsa.id;
70945cb6 1624 lp->ref_rt = p->router_id;
c3226991
OZ
1625 lp = NULL; /* buffer might be reallocated later */
1626
be862406 1627 pxc = 0;
70945cb6 1628 offset = p->lsab_used;
c3226991 1629
be862406 1630 /* Find all Link LSAs associated with the link and merge their prefixes */
70945cb6
OZ
1631 if (en = ifa->link_lsa)
1632 add_link_lsa(p, en->next_lsa_body ?: en->lsa_body, offset, &pxc);
be862406 1633
c3226991
OZ
1634 WALK_LIST(n, ifa->neigh_list)
1635 if ((n->state == NEIGHBOR_FULL) &&
742029eb 1636 (en = ospf_hash_find(p->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK)))
70945cb6 1637 add_link_lsa(p, en->lsa_body, offset, &pxc);
c3226991 1638
70945cb6 1639 lp = p->lsab;
be862406 1640 lp->pxcount = pxc;
c3226991
OZ
1641}
1642
70945cb6
OZ
1643static void
1644ospf_originate_prefix_net_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
c3226991 1645{
70945cb6
OZ
1646 if (ospf_is_v2(p))
1647 return;
c3226991 1648
70945cb6
OZ
1649 struct ospf_new_lsa lsa = {
1650 .type = LSA_T_PREFIX,
1651 .dom = ifa->oa->areaid,
1652 .id = ifa->iface_id,
1653 .ifa = ifa
1654 };
be862406 1655
70945cb6 1656 prepare_prefix_net_lsa_body(p, ifa);
c3226991 1657
70945cb6 1658 ifa->pxn_lsa = ospf_originate_lsa(p, &lsa);
c3226991
OZ
1659}
1660
a7a7372a 1661static inline int breaks_minlsinterval(struct top_hash_entry *en)
b32d557a 1662{ return en && (en->lsa.age < LSA_MAXAGE) && (lsa_inst_age(en) < MINLSINTERVAL); }
70945cb6 1663
061ab802 1664void
70945cb6 1665ospf_update_topology(struct ospf_proto *p)
061ab802 1666{
70945cb6
OZ
1667 struct ospf_area *oa;
1668 struct ospf_iface *ifa;
061ab802 1669
70945cb6
OZ
1670 WALK_LIST(oa, p->area_list)
1671 {
1672 if (oa->update_rt_lsa)
1673 {
a7a7372a
OZ
1674 /*
1675 * Generally, MinLSInterval is enforced in ospf_do_originate_lsa(), but
1676 * origination of (prefix) router LSA is a special case. We do not want to
1677 * prepare a new router LSA body and then postpone it in en->next_lsa_body
1678 * for later origination, because there are side effects (updates of
1679 * rt_pos_* and px_pos_* in ospf_iface structures) during that, which may
1680 * confuse routing table calculation if executed after LSA body
1681 * preparation but before final LSA origination (as rtcalc would use
1682 * current rt_pos_* indexes but the old router LSA body).
1683 *
1684 * Here, we ensure that MinLSInterval is observed and we do not even try
1685 * to originate these LSAs if it is not. Therefore, origination, when
1686 * requested, will succeed unless there is also a seqnum wrapping, which
1687 * is not a problem because in that case rtcalc is blocked by MaxAge.
1688 */
1689
1690 if (breaks_minlsinterval(oa->rt) || breaks_minlsinterval(oa->pxr_lsa))
1691 continue;
1692
70945cb6
OZ
1693 ospf_originate_rt_lsa(p, oa);
1694 ospf_originate_prefix_rt_lsa(p, oa);
1695 oa->update_rt_lsa = 0;
1696 }
1697 }
061ab802 1698
70945cb6
OZ
1699 WALK_LIST(ifa, p->iface_list)
1700 {
1701 if (ifa->type == OSPF_IT_VLINK)
1702 continue;
be862406 1703
70945cb6
OZ
1704 if (ifa->update_link_lsa)
1705 {
1706 if ((ifa->state > OSPF_IS_LOOP) && !ifa->link_lsa_suppression)
1707 ospf_originate_link_lsa(p, ifa);
1708 else
1709 ospf_flush2_lsa(p, &ifa->link_lsa);
061ab802 1710
70945cb6
OZ
1711 ifa->update_link_lsa = 0;
1712 }
061ab802 1713
70945cb6
OZ
1714 if (ifa->update_net_lsa)
1715 {
1716 if ((ifa->state == OSPF_IS_DR) && (ifa->fadj > 0))
1717 {
1718 ospf_originate_net_lsa(p, ifa);
1719 ospf_originate_prefix_net_lsa(p, ifa);
1720 }
1721 else
1722 {
1723 ospf_flush2_lsa(p, &ifa->net_lsa);
1724 ospf_flush2_lsa(p, &ifa->pxn_lsa);
1725 }
1726
1727 ifa->update_net_lsa = 0;
1728 }
1729 }
70945cb6 1730}
e8085aba 1731
b49e6f5a 1732
6ba36f06
MM
1733static void
1734ospf_top_ht_alloc(struct top_graph *f)
1735{
1736 f->hash_size = 1 << f->hash_order;
1737 f->hash_mask = f->hash_size - 1;
1738 if (f->hash_order > HASH_HI_MAX - HASH_HI_STEP)
1739 f->hash_entries_max = ~0;
1740 else
1741 f->hash_entries_max = f->hash_size HASH_HI_MARK;
1742 if (f->hash_order < HASH_LO_MIN + HASH_LO_STEP)
1743 f->hash_entries_min = 0;
1744 else
1745 f->hash_entries_min = f->hash_size HASH_LO_MARK;
1746 DBG("Allocating OSPF hash of order %d: %d hash_entries, %d low, %d high\n",
1747 f->hash_order, f->hash_size, f->hash_entries_min, f->hash_entries_max);
b9ed99f7
OF
1748 f->hash_table =
1749 mb_alloc(f->pool, f->hash_size * sizeof(struct top_hash_entry *));
6ba36f06
MM
1750 bzero(f->hash_table, f->hash_size * sizeof(struct top_hash_entry *));
1751}
1752
1753static inline void
1754ospf_top_ht_free(struct top_hash_entry **h)
1755{
1756 mb_free(h);
1757}
1758
1759static inline u32
1760ospf_top_hash_u32(u32 a)
1761{
1762 /* Shamelessly stolen from IP address hashing in ipv4.h */
1763 a ^= a >> 16;
1764 a ^= a << 10;
1765 return a;
1766}
1767
a7a7372a 1768static uint
c3226991
OZ
1769ospf_top_hash(struct top_graph *f, u32 domain, u32 lsaid, u32 rtrid, u32 type)
1770{
be862406 1771 /* In OSPFv2, we don't know Router ID when looking for network LSAs.
9f0ba7b1
OZ
1772 In OSPFv3, we don't know LSA ID when looking for router LSAs.
1773 In both cases, there is (usually) just one (or small number)
1774 appropriate LSA, so we just clear unknown part of key. */
c3226991 1775
70945cb6
OZ
1776 return (((f->ospf2 && (type == LSA_T_NET)) ? 0 : ospf_top_hash_u32(rtrid)) +
1777 ((!f->ospf2 && (type == LSA_T_RT)) ? 0 : ospf_top_hash_u32(lsaid)) +
9f0ba7b1 1778 type + domain) & f->hash_mask;
c3226991
OZ
1779
1780 /*
b9ed99f7 1781 return (ospf_top_hash_u32(lsaid) + ospf_top_hash_u32(rtrid) +
86c84d76 1782 type + areaid) & f->hash_mask;
c3226991 1783 */
6ba36f06
MM
1784}
1785
7ab3ff6a
OF
1786/**
1787 * ospf_top_new - allocated new topology database
70945cb6 1788 * @p: OSPF protocol instance
a7a7372a 1789 * @pool: pool for allocation
7ab3ff6a 1790 *
a7a7372a
OZ
1791 * This dynamically hashed structure is used for keeping LSAs. Mainly it is used
1792 * for the LSA database of the OSPF protocol, but also for LSA retransmission
1793 * and request lists of OSPF neighbors.
7ab3ff6a 1794 */
6ba36f06 1795struct top_graph *
a7a7372a 1796ospf_top_new(struct ospf_proto *p, pool *pool)
6ba36f06
MM
1797{
1798 struct top_graph *f;
1799
035f6acb
OF
1800 f = mb_allocz(pool, sizeof(struct top_graph));
1801 f->pool = pool;
6ba36f06
MM
1802 f->hash_slab = sl_new(f->pool, sizeof(struct top_hash_entry));
1803 f->hash_order = HASH_DEF_ORDER;
1804 ospf_top_ht_alloc(f);
1805 f->hash_entries = 0;
1806 f->hash_entries_min = 0;
a7a7372a 1807 f->ospf2 = ospf_is_v2(p);
6ba36f06
MM
1808 return f;
1809}
1810
1811void
1812ospf_top_free(struct top_graph *f)
1813{
1814 rfree(f->hash_slab);
1815 ospf_top_ht_free(f->hash_table);
1816 mb_free(f);
1817}
1818
1819static void
1820ospf_top_rehash(struct top_graph *f, int step)
1821{
6ba36f06 1822 struct top_hash_entry **n, **oldt, **newt, *e, *x;
a7a7372a 1823 uint oldn, oldh;
6ba36f06
MM
1824
1825 oldn = f->hash_size;
1826 oldt = f->hash_table;
b49e6f5a 1827 DBG("re-hashing topology hash from order %d to %d\n", f->hash_order,
b9ed99f7 1828 f->hash_order + step);
6ba36f06
MM
1829 f->hash_order += step;
1830 ospf_top_ht_alloc(f);
1831 newt = f->hash_table;
1832
b9ed99f7
OF
1833 for (oldh = 0; oldh < oldn; oldh++)
1834 {
1835 e = oldt[oldh];
1836 while (e)
6ba36f06 1837 {
b9ed99f7 1838 x = e->next;
70945cb6 1839 n = newt + ospf_top_hash(f, e->domain, e->lsa.id, e->lsa.rt, e->lsa_type);
b9ed99f7
OF
1840 e->next = *n;
1841 *n = e;
1842 e = x;
6ba36f06 1843 }
b9ed99f7 1844 }
6ba36f06
MM
1845 ospf_top_ht_free(oldt);
1846}
1847
6f8bbaa1
OZ
1848static struct top_hash_entry *
1849ospf_hash_find_(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
6ba36f06 1850{
86c84d76 1851 struct top_hash_entry *e;
c3226991 1852 e = f->hash_table[ospf_top_hash(f, domain, lsa, rtr, type)];
86c84d76 1853
70945cb6
OZ
1854 while (e && (e->lsa.id != lsa || e->lsa.rt != rtr ||
1855 e->lsa_type != type || e->domain != domain))
9f0ba7b1
OZ
1856 e = e->next;
1857
6f8bbaa1
OZ
1858 return e;
1859}
1860
1861struct top_hash_entry *
1862ospf_hash_find(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
1863{
1864 struct top_hash_entry *e = ospf_hash_find_(f, domain, lsa, rtr, type);
1865
70945cb6 1866 /* Hide hash entry with empty lsa_body */
a7a7372a 1867 return (e && e->lsa_body) ? e : NULL;
9f0ba7b1 1868}
86c84d76 1869
70945cb6
OZ
1870/* In OSPFv2, lsa.id is the same as lsa.rt for router LSA. In OSPFv3, we don't know
1871 lsa.id when looking for router LSAs. We return matching LSA with smallest lsa.id. */
9f0ba7b1
OZ
1872struct top_hash_entry *
1873ospf_hash_find_rt(struct top_graph *f, u32 domain, u32 rtr)
1874{
1875 struct top_hash_entry *rv = NULL;
1876 struct top_hash_entry *e;
70945cb6
OZ
1877 /* We can put rtr for lsa.id to hash fn, it is ignored in OSPFv3 */
1878 e = f->hash_table[ospf_top_hash(f, domain, rtr, rtr, LSA_T_RT)];
1879
9f0ba7b1 1880 while (e)
70945cb6
OZ
1881 {
1882 if (e->lsa.rt == rtr && e->lsa_type == LSA_T_RT && e->domain == domain && e->lsa_body)
9f0ba7b1 1883 {
70945cb6
OZ
1884 if (f->ospf2 && (e->lsa.id == rtr))
1885 return e;
1886 if (!f->ospf2 && (!rv || e->lsa.id < rv->lsa.id))
1887 rv = e;
9f0ba7b1 1888 }
70945cb6
OZ
1889 e = e->next;
1890 }
9f0ba7b1
OZ
1891
1892 return rv;
1893}
1894
a7a7372a
OZ
1895/*
1896 * ospf_hash_find_rt3_first() and ospf_hash_find_rt3_next() are used exclusively
1897 * for lsa_walk_rt_init(), lsa_walk_rt(), therefore they skip MaxAge entries.
1898 */
9f0ba7b1 1899static inline struct top_hash_entry *
70945cb6 1900find_matching_rt3(struct top_hash_entry *e, u32 domain, u32 rtr)
9f0ba7b1 1901{
70945cb6 1902 while (e && (e->lsa.rt != rtr || e->lsa_type != LSA_T_RT ||
a7a7372a 1903 e->domain != domain || e->lsa.age == LSA_MAXAGE))
9f0ba7b1 1904 e = e->next;
6ba36f06
MM
1905 return e;
1906}
1907
9f0ba7b1 1908struct top_hash_entry *
70945cb6 1909ospf_hash_find_rt3_first(struct top_graph *f, u32 domain, u32 rtr)
9f0ba7b1
OZ
1910{
1911 struct top_hash_entry *e;
1912 e = f->hash_table[ospf_top_hash(f, domain, 0, rtr, LSA_T_RT)];
70945cb6 1913 return find_matching_rt3(e, domain, rtr);
9f0ba7b1
OZ
1914}
1915
1916struct top_hash_entry *
70945cb6 1917ospf_hash_find_rt3_next(struct top_hash_entry *e)
9f0ba7b1 1918{
70945cb6 1919 return find_matching_rt3(e->next, e->domain, e->lsa.rt);
9f0ba7b1
OZ
1920}
1921
70945cb6
OZ
1922/* In OSPFv2, we don't know Router ID when looking for network LSAs.
1923 There should be just one, so we find any match. */
1924struct top_hash_entry *
1925ospf_hash_find_net2(struct top_graph *f, u32 domain, u32 id)
1926{
1927 struct top_hash_entry *e;
1928 e = f->hash_table[ospf_top_hash(f, domain, id, 0, LSA_T_NET)];
1929
1930 while (e && (e->lsa.id != id || e->lsa_type != LSA_T_NET ||
1931 e->domain != domain || e->lsa_body == NULL))
1932 e = e->next;
1933
1934 return e;
1935}
9f0ba7b1
OZ
1936
1937
6ba36f06 1938struct top_hash_entry *
b49e6f5a 1939ospf_hash_get(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
6ba36f06 1940{
86c84d76
OF
1941 struct top_hash_entry **ee;
1942 struct top_hash_entry *e;
86c84d76 1943
c3226991 1944 ee = f->hash_table + ospf_top_hash(f, domain, lsa, rtr, type);
86c84d76
OF
1945 e = *ee;
1946
742029eb 1947 while (e && (e->lsa.id != lsa || e->lsa.rt != rtr ||
70945cb6 1948 e->lsa_type != type || e->domain != domain))
c3226991 1949 e = e->next;
6ba36f06 1950
6ba36f06
MM
1951 if (e)
1952 return e;
933bfdde 1953
6ba36f06 1954 e = sl_alloc(f->hash_slab);
70945cb6
OZ
1955 bzero(e, sizeof(struct top_hash_entry));
1956
933bfdde
OF
1957 e->color = OUTSPF;
1958 e->dist = LSINFINITY;
70945cb6 1959 e->lsa.type_raw = type;
ce17d4c1
OF
1960 e->lsa.id = lsa;
1961 e->lsa.rt = rtr;
70945cb6
OZ
1962 e->lsa.sn = LSA_ZEROSEQNO;
1963 e->lsa_type = type;
c3226991 1964 e->domain = domain;
933bfdde 1965 e->next = *ee;
b9ed99f7 1966 *ee = e;
6ba36f06
MM
1967 if (f->hash_entries++ > f->hash_entries_max)
1968 ospf_top_rehash(f, HASH_HI_STEP);
1969 return e;
1970}
1971
1972void
1973ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e)
1974{
742029eb 1975 struct top_hash_entry **ee = f->hash_table +
70945cb6 1976 ospf_top_hash(f, e->domain, e->lsa.id, e->lsa.rt, e->lsa_type);
6ba36f06
MM
1977
1978 while (*ee)
b9ed99f7
OF
1979 {
1980 if (*ee == e)
6ba36f06 1981 {
b9ed99f7
OF
1982 *ee = e->next;
1983 sl_free(f->hash_slab, e);
1984 if (f->hash_entries-- < f->hash_entries_min)
1985 ospf_top_rehash(f, -HASH_LO_STEP);
1986 return;
6ba36f06 1987 }
b9ed99f7
OF
1988 ee = &((*ee)->next);
1989 }
6ba36f06
MM
1990 bug("ospf_hash_delete() called for invalid node");
1991}
1992
e81b440f 1993/*
226cb2bc
OF
1994static void
1995ospf_dump_lsa(struct top_hash_entry *he, struct proto *p)
1996{
e81b440f 1997
226cb2bc
OF
1998 struct ospf_lsa_rt *rt = NULL;
1999 struct ospf_lsa_rt_link *rr = NULL;
2000 struct ospf_lsa_net *ln = NULL;
2001 u32 *rts = NULL;
2002 u32 i, max;
2003
3aab39f5
OZ
2004 OSPF_TRACE(D_EVENTS, "- %1x %-1R %-1R %4u 0x%08x 0x%04x %-1R",
2005 he->lsa.type, he->lsa.id, he->lsa.rt, he->lsa.age, he->lsa.sn,
c3226991 2006 he->lsa.checksum, he->domain);
226cb2bc 2007
b49e6f5a 2008
226cb2bc
OF
2009 switch (he->lsa.type)
2010 {
2011 case LSA_T_RT:
2012 rt = he->lsa_body;
2013 rr = (struct ospf_lsa_rt_link *) (rt + 1);
2014
c3226991 2015 for (i = 0; i < lsa_rt_items(&he->lsa); i++)
742029eb 2016 OSPF_TRACE(D_EVENTS, " - %1x %-1R %-1R %5u",
3aab39f5 2017 rr[i].type, rr[i].id, rr[i].data, rr[i].metric);
226cb2bc
OF
2018 break;
2019
2020 case LSA_T_NET:
2021 ln = he->lsa_body;
2022 rts = (u32 *) (ln + 1);
226cb2bc 2023
c3226991 2024 for (i = 0; i < lsa_net_items(&he->lsa); i++)
742029eb 2025 OSPF_TRACE(D_EVENTS, " - %-1R", rts[i]);
226cb2bc
OF
2026 break;
2027
2028 default:
2029 break;
2030 }
2031}
2032
6ba36f06 2033void
992705f6 2034ospf_top_dump(struct top_graph *f, struct proto *p)
6ba36f06 2035{
a7a7372a 2036 uint i;
992705f6 2037 OSPF_TRACE(D_EVENTS, "Hash entries: %d", f->hash_entries);
6ba36f06 2038
b9ed99f7
OF
2039 for (i = 0; i < f->hash_size; i++)
2040 {
226cb2bc
OF
2041 struct top_hash_entry *e;
2042 for (e = f->hash_table[i]; e != NULL; e = e->next)
2043 ospf_dump_lsa(e, p);
b9ed99f7 2044 }
6ba36f06 2045}
e81b440f 2046*/