Annotation of embedaddon/bird/proto/ospf/topology.c, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD -- OSPF Topological Database
3: *
4: * (c) 1999 Martin Mares <mj@ucw.cz>
5: * (c) 1999--2004 Ondrej Filip <feela@network.cz>
6: * (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
7: * (c) 2009--2014 CZ.NIC z.s.p.o.
8: *
9: * Can be freely distributed and used under the terms of the GNU GPL.
10: */
11:
12: #include "nest/bird.h"
13: #include "lib/string.h"
14:
15: #include "ospf.h"
16:
17:
18: #define HASH_DEF_ORDER 6
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:
26: static inline void * lsab_flush(struct ospf_proto *p);
27: static inline void lsab_reset(struct ospf_proto *p);
28:
29:
30: /**
31: * ospf_install_lsa - install new LSA into database
32: * @p: OSPF protocol instance
33: * @lsa: LSA header
34: * @type: type of LSA
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().
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.
46: */
47: struct top_hash_entry *
48: ospf_install_lsa(struct ospf_proto *p, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body)
49: {
50: struct top_hash_entry *en;
51: int change = 0;
52:
53: en = ospf_hash_get(p->gr, domain, lsa->id, lsa->rt, type);
54:
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:
66: if ((en->lsa.age == LSA_MAXAGE) && (lsa->age == LSA_MAXAGE))
67: change = 0;
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:
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:
85: if (change)
86: ospf_schedule_rtcalc(p);
87:
88: return en;
89: }
90:
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
96: * @type: type of LSA
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: */
108: void
109: ospf_advance_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body)
110: {
111: /* RFC 2328 13.4 */
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;
132: lsa_generate_checksum(&en->lsa, en->lsa_body);
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);
136: }
137: else
138: {
139: /*
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;
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);
169: }
170: }
171: else
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.
177: * Also note that en->next_lsa_* may be defined.
178: */
179:
180: lsa->age = LSA_MAXAGE;
181: en = ospf_install_lsa(p, lsa, type, domain, body);
182: }
183:
184: /*
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
187: * regular received LSA (send the acknowledgement instead of the update to
188: * the neighbor we received it from), we cheat a bit here.
189: */
190:
191: ospf_flood_lsa(p, en, NULL);
192: }
193:
194:
195: static int
196: ospf_do_originate_lsa(struct ospf_proto *p, struct top_hash_entry *en, void *lsa_body, u16 lsa_blen, u16 lsa_opts)
197: {
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: {
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);
210:
211: en->lsa.age = LSA_MAXAGE;
212: ospf_flood_lsa(p, en, NULL);
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:
224: /*
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.
229: */
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;
241: lsa_generate_checksum(&en->lsa, en->lsa_body);
242:
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);
250:
251: return 1;
252: }
253:
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: */
268: struct top_hash_entry *
269: ospf_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;
275:
276: en = ospf_hash_get(p->gr, lsa->dom, lsa->id, p->router_id, lsa->type);
277:
278: if (!SNODE_VALID(en))
279: s_add_tail(&p->lsal, SNODE en);
280:
281: if (!en->nf || !en->lsa_body)
282: en->nf = lsa->nf;
283:
284: if (en->nf != lsa->nf)
285: {
286: log(L_ERR "%s: LSA ID collision for %I/%d",
287: p->p.name, lsa->nf->fn.prefix, lsa->nf->fn.pxlen);
288:
289: en = NULL;
290: goto drop;
291: }
292:
293: if (en->mode != lsa->mode)
294: en->mode = lsa->mode;
295:
296: if (en->next_lsa_body)
297: {
298: /* Ignore the new LSA if it is the same as the scheduled one */
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)))
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 */
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))))
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: {
322: OSPF_TRACE(D_EVENTS, "Postponing LSA: Type: %04x, Id: %R, Rt: %R",
323: en->lsa_type, en->lsa.id, en->lsa.rt);
324:
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:
337: static void
338: ospf_originate_next_lsa(struct ospf_proto *p, struct top_hash_entry *en)
339: {
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;
344:
345: en->next_lsa_body = NULL;
346: en->next_lsa_blen = 0;
347: en->next_lsa_opts = 0;
348: }
349:
350: static void
351: ospf_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:
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);
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;
377: ospf_flood_lsa(p, en, NULL);
378: return;
379: }
380:
381: en->lsa.sn++;
382: en->lsa.age = 0;
383: en->init_age = 0;
384: en->inst_time = now;
385: lsa_generate_checksum(&en->lsa, en->lsa_body);
386: ospf_flood_lsa(p, en, NULL);
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
402: * origination.
403: */
404: void
405: ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en)
406: {
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:
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:
421: en->lsa.age = LSA_MAXAGE;
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;
428: }
429:
430: static void
431: ospf_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.
436: * The log message is for 'remove' - we hide empty LSAs from users.
437: */
438:
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:
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:
449: static void
450: ospf_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: */
475: void
476: ospf_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)
507: {
508: ospf_flush_lsa(p, en);
509: continue;
510: }
511:
512: en->lsa.age = real_age;
513: }
514: }
515:
516:
517: static inline u32
518: ort_to_lsaid(struct ospf_proto *p UNUSED4 UNUSED6, 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
523: * prefix have to be mapped on itself. All received prefixes have to be
524: * mapped on different u32s.
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
545: * result in the input network, so we just use a hash-based unique ID of a
546: * routing table entry for a route that originated given LSA. For ext-LSA, it
547: * is an imported route in the nest's routing table (p->table). For summary-LSA,
548: * it is a 'source' route in the protocol internal routing table (p->rtf).
549: */
550:
551: if (ospf_is_v3(p))
552: return nf->fn.uid;
553:
554: u32 id = ipa_to_u32(nf->fn.prefix);
555: int pxlen = nf->fn.pxlen;
556:
557: if ((pxlen == 0) || (pxlen == 32))
558: return id;
559:
560: if (id & (1 << (32 - pxlen)))
561: return id;
562: else
563: return id | ~u32_mkmask(pxlen);
564: }
565:
566:
567: static void *
568: lsab_alloc(struct ospf_proto *p, uint size)
569: {
570: uint offset = p->lsab_used;
571: p->lsab_used += size;
572: if (p->lsab_used > p->lsab_size)
573: {
574: p->lsab_size = MAX(p->lsab_used, 2 * p->lsab_size);
575: p->lsab = p->lsab ? mb_realloc(p->lsab, p->lsab_size):
576: mb_alloc(p->p.pool, p->lsab_size);
577: }
578: return ((byte *) p->lsab) + offset;
579: }
580:
581: static inline void *
582: lsab_allocz(struct ospf_proto *p, uint size)
583: {
584: void *r = lsab_alloc(p, size);
585: bzero(r, size);
586: return r;
587: }
588:
589: static inline void *
590: lsab_flush(struct ospf_proto *p)
591: {
592: void *r = mb_alloc(p->p.pool, p->lsab_used);
593: memcpy(r, p->lsab, p->lsab_used);
594: p->lsab_used = 0;
595: return r;
596: }
597:
598: static inline void
599: lsab_reset(struct ospf_proto *p)
600: {
601: p->lsab_used = 0;
602: }
603:
604: static inline void *
605: lsab_offset(struct ospf_proto *p, uint offset)
606: {
607: return ((byte *) p->lsab) + offset;
608: }
609:
610: static inline void * UNUSED
611: lsab_end(struct ospf_proto *p)
612: {
613: return ((byte *) p->lsab) + p->lsab_used;
614: }
615:
616:
617: /*
618: * Router-LSA handling
619: * Type = LSA_T_RT
620: */
621:
622: static int
623: configured_stubnet(struct ospf_area *oa, struct ifa *a)
624: {
625: /* Does not work for IA_PEER addresses, but it is not called on these */
626: struct ospf_stubnet_config *sn;
627: WALK_LIST(sn, oa->ac->stubnet_list)
628: {
629: if (sn->summary)
630: {
631: if (ipa_in_net(a->prefix, sn->px.addr, sn->px.len) && (a->pxlen >= sn->px.len))
632: return 1;
633: }
634: else
635: {
636: if (ipa_equal(a->prefix, sn->px.addr) && (a->pxlen == sn->px.len))
637: return 1;
638: }
639: }
640:
641: return 0;
642: }
643:
644: static int
645: bcast_net_active(struct ospf_iface *ifa)
646: {
647: struct ospf_neighbor *neigh;
648:
649: if (ifa->state == OSPF_IS_WAITING)
650: return 0;
651:
652: WALK_LIST(neigh, ifa->neigh_list)
653: {
654: if (neigh->state == NEIGHBOR_FULL)
655: {
656: if (neigh->rid == ifa->drid)
657: return 1;
658:
659: if (ifa->state == OSPF_IS_DR)
660: return 1;
661: }
662: }
663:
664: return 0;
665: }
666:
667: static inline u32
668: get_rt_options(struct ospf_proto *p, struct ospf_area *oa, int bitv)
669: {
670: u32 opts = 0;
671:
672: if (p->areano > 1)
673: opts |= OPT_RT_B;
674:
675: if ((p->areano > 1) && oa_is_nssa(oa) && oa->ac->translator)
676: opts |= OPT_RT_NT;
677:
678: if (p->asbr && !oa_is_stub(oa))
679: opts |= OPT_RT_E;
680:
681: if (bitv)
682: opts |= OPT_RT_V;
683:
684: return opts;
685: }
686:
687: static inline void
688: add_rt2_lsa_link(struct ospf_proto *p, u8 type, u32 id, u32 data, u16 metric)
689: {
690: struct ospf_lsa_rt2_link *ln = lsab_alloc(p, sizeof(struct ospf_lsa_rt2_link));
691: ln->type = type;
692: ln->id = id;
693: ln->data = data;
694: ln->metric = metric;
695: ln->no_tos = 0;
696: }
697:
698: static void
699: prepare_rt2_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
700: {
701: struct ospf_iface *ifa;
702: int i = 0, bitv = 0;
703: struct ospf_neighbor *neigh;
704:
705: ASSERT(p->lsab_used == 0);
706: lsab_allocz(p, sizeof(struct ospf_lsa_rt));
707: /* ospf_lsa_rt header will be filled later */
708:
709: WALK_LIST(ifa, p->iface_list)
710: {
711: int net_lsa = 0;
712: u32 link_cost = p->stub_router ? 0xffff : ifa->cost;
713:
714: if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
715: (!EMPTY_LIST(ifa->neigh_list)))
716: {
717: neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
718: if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
719: bitv = 1;
720: }
721:
722: if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
723: continue;
724:
725: ifa->rt_pos_beg = i;
726:
727: /* RFC 2328 - 12.4.1.1-4 */
728: switch (ifa->type)
729: {
730: case OSPF_IT_PTP:
731: case OSPF_IT_PTMP:
732: WALK_LIST(neigh, ifa->neigh_list)
733: if (neigh->state == NEIGHBOR_FULL)
734: {
735: /*
736: * ln->data should be ifa->iface_id in case of no/ptp
737: * address (ifa->addr->flags & IA_PEER) on PTP link (see
738: * RFC 2328 12.4.1.1.), but the iface ID value has no use,
739: * while using IP address even in this case is here for
740: * compatibility with some broken implementations that use
741: * this address as a next-hop.
742: */
743: add_rt2_lsa_link(p, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost);
744: i++;
745: }
746: break;
747:
748: case OSPF_IT_BCAST:
749: case OSPF_IT_NBMA:
750: if (bcast_net_active(ifa))
751: {
752: add_rt2_lsa_link(p, LSART_NET, ipa_to_u32(ifa->drip), ipa_to_u32(ifa->addr->ip), link_cost);
753: i++;
754: net_lsa = 1;
755: }
756: break;
757:
758: case OSPF_IT_VLINK:
759: neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
760: if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
761: add_rt2_lsa_link(p, LSART_VLNK, neigh->rid, ipa_to_u32(ifa->addr->ip), link_cost), i++;
762: break;
763:
764: default:
765: log(L_BUG "OSPF: Unknown interface type");
766: break;
767: }
768:
769: ifa->rt_pos_end = i;
770:
771: /* Now we will originate stub area if there is no primary */
772: if (net_lsa ||
773: (ifa->type == OSPF_IT_VLINK) ||
774: ((ifa->addr->flags & IA_PEER) && ! ifa->cf->stub) ||
775: configured_stubnet(oa, ifa->addr))
776: continue;
777:
778: /* Host or network stub entry */
779: if ((ifa->addr->flags & IA_HOST) ||
780: (ifa->state == OSPF_IS_LOOP) ||
781: (ifa->type == OSPF_IT_PTMP))
782: add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(ifa->addr->ip), 0xffffffff, 0);
783: else
784: add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(ifa->addr->prefix), u32_mkmask(ifa->addr->pxlen), ifa->cost);
785: i++;
786:
787: ifa->rt_pos_end = i;
788: }
789:
790: struct ospf_stubnet_config *sn;
791: WALK_LIST(sn, oa->ac->stubnet_list)
792: if (!sn->hidden)
793: add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(sn->px.addr), u32_mkmask(sn->px.len), sn->cost), i++;
794:
795: struct ospf_lsa_rt *rt = p->lsab;
796: /* Store number of links in lower half of options */
797: rt->options = get_rt_options(p, oa, bitv) | (u16) i;
798: }
799:
800: static inline void
801: add_rt3_lsa_link(struct ospf_proto *p, u8 type, struct ospf_iface *ifa, u32 nif, u32 id)
802: {
803: struct ospf_lsa_rt3_link *ln = lsab_alloc(p, sizeof(struct ospf_lsa_rt3_link));
804: ln->type = type;
805: ln->padding = 0;
806: ln->metric = ifa->cost;
807: ln->lif = ifa->iface_id;
808: ln->nif = nif;
809: ln->id = id;
810: }
811:
812: static void
813: prepare_rt3_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
814: {
815: struct ospf_iface *ifa;
816: struct ospf_neighbor *neigh;
817: int bitv = 0;
818: int i = 0;
819:
820: ASSERT(p->lsab_used == 0);
821: lsab_allocz(p, sizeof(struct ospf_lsa_rt));
822: /* ospf_lsa_rt header will be filled later */
823:
824: WALK_LIST(ifa, p->iface_list)
825: {
826: if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
827: (!EMPTY_LIST(ifa->neigh_list)))
828: {
829: neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
830: if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
831: bitv = 1;
832: }
833:
834: if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
835: continue;
836:
837: ifa->rt_pos_beg = i;
838:
839: /* RFC 5340 - 4.4.3.2 */
840: switch (ifa->type)
841: {
842: case OSPF_IT_PTP:
843: case OSPF_IT_PTMP:
844: WALK_LIST(neigh, ifa->neigh_list)
845: if (neigh->state == NEIGHBOR_FULL)
846: add_rt3_lsa_link(p, LSART_PTP, ifa, neigh->iface_id, neigh->rid), i++;
847: break;
848:
849: case OSPF_IT_BCAST:
850: case OSPF_IT_NBMA:
851: if (bcast_net_active(ifa))
852: add_rt3_lsa_link(p, LSART_NET, ifa, ifa->dr_iface_id, ifa->drid), i++;
853: break;
854:
855: case OSPF_IT_VLINK:
856: neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
857: if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
858: add_rt3_lsa_link(p, LSART_VLNK, ifa, neigh->iface_id, neigh->rid), i++;
859: break;
860:
861: default:
862: log(L_BUG "OSPF: Unknown interface type");
863: break;
864: }
865:
866: ifa->rt_pos_end = i;
867: }
868:
869: struct ospf_lsa_rt *rt = p->lsab;
870: rt->options = get_rt_options(p, oa, bitv) | (oa->options & LSA_OPTIONS_MASK);
871: }
872:
873: static void
874: ospf_originate_rt_lsa(struct ospf_proto *p, struct ospf_area *oa)
875: {
876: struct ospf_new_lsa lsa = {
877: .type = LSA_T_RT,
878: .dom = oa->areaid,
879: .id = ospf_is_v2(p) ? p->router_id : 0,
880: .opts = oa->options
881: };
882:
883: OSPF_TRACE(D_EVENTS, "Updating router state for area %R", oa->areaid);
884:
885: if (ospf_is_v2(p))
886: prepare_rt2_lsa_body(p, oa);
887: else
888: prepare_rt3_lsa_body(p, oa);
889:
890: oa->rt = ospf_originate_lsa(p, &lsa);
891: }
892:
893:
894: /*
895: * Net-LSA handling
896: * Type = LSA_T_NET
897: */
898:
899: static void
900: prepare_net2_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
901: {
902: struct ospf_lsa_net *net;
903: struct ospf_neighbor *n;
904: int nodes = ifa->fadj + 1;
905: u16 i = 1;
906:
907: ASSERT(p->lsab_used == 0);
908: net = lsab_alloc(p, sizeof(struct ospf_lsa_net) + 4 * nodes);
909:
910: net->optx = u32_mkmask(ifa->addr->pxlen);
911: net->routers[0] = p->router_id;
912:
913: WALK_LIST(n, ifa->neigh_list)
914: {
915: if (n->state == NEIGHBOR_FULL)
916: {
917: net->routers[i] = n->rid;
918: i++;
919: }
920: }
921: ASSERT(i == nodes);
922: }
923:
924: static void
925: prepare_net3_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
926: {
927: struct ospf_lsa_net *net;
928: int nodes = ifa->fadj + 1;
929: u32 options = 0;
930: u16 i = 1;
931:
932: ASSERT(p->lsab_used == 0);
933: net = lsab_alloc(p, sizeof(struct ospf_lsa_net) + 4 * nodes);
934:
935: net->routers[0] = p->router_id;
936:
937: struct ospf_neighbor *n;
938: WALK_LIST(n, ifa->neigh_list)
939: {
940: if (n->state == NEIGHBOR_FULL)
941: {
942: /* In OSPFv3, we would like to merge options from Link LSAs of added neighbors */
943:
944: struct top_hash_entry *en =
945: ospf_hash_find(p->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK);
946:
947: if (en)
948: options |= ((struct ospf_lsa_link *) en->lsa_body)->options;
949:
950: net->routers[i] = n->rid;
951: i++;
952: }
953: }
954: ASSERT(i == nodes);
955:
956: net->optx = options & LSA_OPTIONS_MASK;
957: }
958:
959: static void
960: ospf_originate_net_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
961: {
962: struct ospf_new_lsa lsa = {
963: .type = LSA_T_NET,
964: .dom = ifa->oa->areaid,
965: .id = ospf_is_v2(p) ? ipa_to_u32(ifa->addr->ip) : ifa->iface_id,
966: .opts = ifa->oa->options,
967: .ifa = ifa
968: };
969:
970: OSPF_TRACE(D_EVENTS, "Updating network state for %s (Id: %R)", ifa->ifname, lsa.id);
971:
972: if (ospf_is_v2(p))
973: prepare_net2_lsa_body(p, ifa);
974: else
975: prepare_net3_lsa_body(p, ifa);
976:
977: ifa->net_lsa = ospf_originate_lsa(p, &lsa);
978: }
979:
980:
981: /*
982: * (Net|Rt)-summary-LSA handling
983: * (a.k.a. Inter-Area-(Prefix|Router)-LSA)
984: * Type = LSA_T_SUM_NET, LSA_T_SUM_RT
985: */
986:
987: static inline void
988: prepare_sum2_lsa_body(struct ospf_proto *p, uint pxlen, u32 metric)
989: {
990: struct ospf_lsa_sum2 *sum;
991:
992: sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum2));
993: sum->netmask = u32_mkmask(pxlen);
994: sum->metric = metric;
995: }
996:
997: static inline void
998: prepare_sum3_net_lsa_body(struct ospf_proto *p, ort *nf, u32 metric)
999: {
1000: struct ospf_lsa_sum3_net *sum;
1001:
1002: sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_net) + IPV6_PREFIX_SPACE(nf->fn.pxlen));
1003: sum->metric = metric;
1004: put_ipv6_prefix(sum->prefix, nf->fn.prefix, nf->fn.pxlen, 0, 0);
1005: }
1006:
1007: static inline void
1008: prepare_sum3_rt_lsa_body(struct ospf_proto *p, u32 drid, u32 metric, u32 options)
1009: {
1010: struct ospf_lsa_sum3_rt *sum;
1011:
1012: sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_rt));
1013: sum->options = options;
1014: sum->metric = metric;
1015: sum->drid = drid;
1016: }
1017:
1018: void
1019: ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric)
1020: {
1021: struct ospf_new_lsa lsa = {
1022: .type = LSA_T_SUM_NET,
1023: .mode = LSA_M_RTCALC,
1024: .dom = oa->areaid,
1025: .id = ort_to_lsaid(p, nf),
1026: .opts = oa->options,
1027: .nf = nf
1028: };
1029:
1030: if (ospf_is_v2(p))
1031: prepare_sum2_lsa_body(p, nf->fn.pxlen, metric);
1032: else
1033: prepare_sum3_net_lsa_body(p, nf, metric);
1034:
1035: ospf_originate_lsa(p, &lsa);
1036: }
1037:
1038: void
1039: ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric, u32 options)
1040: {
1041: struct ospf_new_lsa lsa = {
1042: .type = LSA_T_SUM_RT,
1043: .mode = LSA_M_RTCALC,
1044: .dom = oa->areaid,
1045: .id = ipa_to_rid(nf->fn.prefix), /* Router ID of ASBR, irrelevant for OSPFv3 */
1046: .opts = oa->options
1047: };
1048:
1049: if (ospf_is_v2(p))
1050: prepare_sum2_lsa_body(p, 0, metric);
1051: else
1052: prepare_sum3_rt_lsa_body(p, lsa.id, metric, options & LSA_OPTIONS_MASK);
1053:
1054: ospf_originate_lsa(p, &lsa);
1055: }
1056:
1057:
1058: /*
1059: * AS-external-LSA and NSSA-LSA handling
1060: * Type = LSA_T_EXT, LSA_T_NSSA
1061: */
1062:
1063: static inline void
1064: prepare_ext2_lsa_body(struct ospf_proto *p, uint pxlen,
1065: u32 metric, u32 ebit, ip_addr fwaddr, u32 tag)
1066: {
1067: struct ospf_lsa_ext2 *ext;
1068:
1069: ext = lsab_allocz(p, sizeof(struct ospf_lsa_ext2));
1070: ext->metric = metric & LSA_METRIC_MASK;
1071: ext->netmask = u32_mkmask(pxlen);
1072: ext->fwaddr = ipa_to_u32(fwaddr);
1073: ext->tag = tag;
1074:
1075: if (ebit)
1076: ext->metric |= LSA_EXT2_EBIT;
1077: }
1078:
1079: static inline void
1080: prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
1081: u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit)
1082: {
1083: struct ospf_lsa_ext3 *ext;
1084: int bsize = sizeof(struct ospf_lsa_ext3)
1085: + IPV6_PREFIX_SPACE(nf->fn.pxlen)
1086: + (ipa_nonzero(fwaddr) ? 16 : 0)
1087: + (tag ? 4 : 0);
1088:
1089: ext = lsab_allocz(p, bsize);
1090: ext->metric = metric & LSA_METRIC_MASK;
1091: u32 *buf = ext->rest;
1092:
1093: buf = put_ipv6_prefix(buf, nf->fn.prefix, nf->fn.pxlen, pbit ? OPT_PX_P : 0, 0);
1094:
1095: if (ebit)
1096: ext->metric |= LSA_EXT3_EBIT;
1097:
1098: if (ipa_nonzero(fwaddr))
1099: {
1100: ext->metric |= LSA_EXT3_FBIT;
1101: buf = put_ipv6_addr(buf, fwaddr);
1102: }
1103:
1104: if (tag)
1105: {
1106: ext->metric |= LSA_EXT3_TBIT;
1107: *buf++ = tag;
1108: }
1109: }
1110:
1111: /**
1112: * originate_ext_lsa - new route received from nest and filters
1113: * @p: OSPF protocol instance
1114: * @oa: ospf_area for which LSA is originated
1115: * @nf: network prefix and mask
1116: * @mode: the mode of the LSA (LSA_M_EXPORT or LSA_M_RTCALC)
1117: * @metric: the metric of a route
1118: * @ebit: E-bit for route metric (bool)
1119: * @fwaddr: the forwarding address
1120: * @tag: the route tag
1121: * @pbit: P-bit for NSSA LSAs (bool), ignored for external LSAs
1122: *
1123: * If I receive a message that new route is installed, I try to originate an
1124: * external LSA. If @oa is an NSSA area, NSSA-LSA is originated instead.
1125: * @oa should not be a stub area. @src does not specify whether the LSA
1126: * is external or NSSA, but it specifies the source of origination -
1127: * the export from ospf_rt_notify(), or the NSSA-EXT translation.
1128: */
1129: void
1130: ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode,
1131: u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit)
1132: {
1133: struct ospf_new_lsa lsa = {
1134: .type = oa ? LSA_T_NSSA : LSA_T_EXT,
1135: .mode = mode, /* LSA_M_EXPORT or LSA_M_RTCALC */
1136: .dom = oa ? oa->areaid : 0,
1137: .id = ort_to_lsaid(p, nf),
1138: .opts = oa ? (pbit ? OPT_P : 0) : OPT_E,
1139: .nf = nf
1140: };
1141:
1142: if (ospf_is_v2(p))
1143: prepare_ext2_lsa_body(p, nf->fn.pxlen, metric, ebit, fwaddr, tag);
1144: else
1145: prepare_ext3_lsa_body(p, nf, metric, ebit, fwaddr, tag, oa && pbit);
1146:
1147: ospf_originate_lsa(p, &lsa);
1148: }
1149:
1150: static struct top_hash_entry *
1151: ospf_hash_find_(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type);
1152:
1153: static void
1154: ospf_flush_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf)
1155: {
1156: struct top_hash_entry *en;
1157:
1158: u32 type = oa ? LSA_T_NSSA : LSA_T_EXT;
1159: u32 dom = oa ? oa->areaid : 0;
1160: u32 id = ort_to_lsaid(p, nf);
1161:
1162: en = ospf_hash_find_(p->gr, dom, id, p->router_id, type);
1163:
1164: if (!en || (en->nf != nf))
1165: return;
1166:
1167: ospf_flush_lsa(p, en);
1168: }
1169:
1170: static inline int
1171: use_gw_for_fwaddr(struct ospf_proto *p, ip_addr gw, struct iface *iface)
1172: {
1173: struct ospf_iface *ifa;
1174:
1175: if (ipa_zero(gw) || ipa_is_link_local(gw))
1176: return 0;
1177:
1178: WALK_LIST(ifa, p->iface_list)
1179: if ((ifa->iface == iface) &&
1180: (!ospf_is_v2(p) || ipa_in_net(gw, ifa->addr->prefix, ifa->addr->pxlen)))
1181: return 1;
1182:
1183: return 0;
1184: }
1185:
1186: static inline ip_addr
1187: find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
1188: {
1189: struct ospf_iface *ifa;
1190: struct ifa *a, *cur_addr = NULL;
1191: int np, cur_np = 0;
1192:
1193: /* RFC 3101 2.3 - surrogate forwarding address selection */
1194:
1195: WALK_LIST(ifa, p->iface_list)
1196: {
1197: if ((ifa->oa != oa) ||
1198: (ifa->type == OSPF_IT_VLINK))
1199: continue;
1200:
1201: if (ospf_is_v2(p))
1202: {
1203: a = ifa->addr;
1204: if (a->flags & IA_PEER)
1205: continue;
1206:
1207: np = (a->flags & IA_HOST) ? 3 : (ifa->stub ? 2 : 1);
1208: if (np > cur_np)
1209: {
1210: cur_addr = a;
1211: cur_np = np;
1212: }
1213: }
1214: else /* OSPFv3 */
1215: {
1216: WALK_LIST(a, ifa->iface->addrs)
1217: {
1218: if ((a->flags & IA_SECONDARY) ||
1219: (a->flags & IA_PEER) ||
1220: (a->scope <= SCOPE_LINK))
1221: continue;
1222:
1223: np = (a->flags & IA_HOST) ? 3 : (ifa->stub ? 2 : 1);
1224: if (np > cur_np)
1225: {
1226: cur_addr = a;
1227: cur_np = np;
1228: }
1229: }
1230: }
1231: }
1232:
1233: return cur_addr ? cur_addr->ip : IPA_NONE;
1234: }
1235:
1236: void
1237: ospf_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *ea)
1238: {
1239: struct ospf_proto *p = (struct ospf_proto *) P;
1240: struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */
1241: ort *nf;
1242:
1243: /*
1244: * There are several posibilities:
1245: * 1) router in regular area - originate external LSA with global scope
1246: * 2) router in NSSA area - originate area-specific NSSA-LSA
1247: * 3) router in stub area - cannot export routes
1248: * 4) area border router - same as (1), it is attached to backbone
1249: */
1250:
1251: if ((p->areano == 1) && oa_is_nssa(HEAD(p->area_list)))
1252: oa = HEAD(p->area_list);
1253:
1254: if (!new)
1255: {
1256: nf = (ort *) fib_find(&p->rtf, &n->n.prefix, n->n.pxlen);
1257:
1258: if (!nf || !nf->external_rte)
1259: return;
1260:
1261: ospf_flush_ext_lsa(p, oa, nf);
1262: nf->external_rte = 0;
1263:
1264: /* Old external route might blocked some NSSA translation */
1265: if ((p->areano > 1) && rt_is_nssa(nf) && nf->n.oa->translate)
1266: ospf_schedule_rtcalc(p);
1267:
1268: return;
1269: }
1270:
1271: ASSERT(p->asbr);
1272:
1273: /* Get route attributes */
1274: rta *a = new->attrs;
1275: u32 m1 = ea_get_int(ea, EA_OSPF_METRIC1, LSINFINITY);
1276: u32 m2 = ea_get_int(ea, EA_OSPF_METRIC2, 10000);
1277: int ebit = (m1 == LSINFINITY);
1278: u32 metric = ebit ? m2 : m1;
1279: u32 tag = ea_get_int(ea, EA_OSPF_TAG, 0);
1280: ip_addr fwd = IPA_NONE;
1281:
1282:
1283: if ((a->dest == RTD_ROUTER) && use_gw_for_fwaddr(p, a->gw, a->iface))
1284: fwd = a->gw;
1285:
1286: /* NSSA-LSA with P-bit set must have non-zero forwarding address */
1287: if (oa && ipa_zero(fwd))
1288: {
1289: fwd = find_surrogate_fwaddr(p, oa);
1290:
1291: if (ipa_zero(fwd))
1292: {
1293: log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %I/%d",
1294: p->p.name, n->n.prefix, n->n.pxlen);
1295: return;
1296: }
1297: }
1298:
1299: nf = (ort *) fib_get(&p->rtf, &n->n.prefix, n->n.pxlen);
1300: ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1);
1301: nf->external_rte = 1;
1302: }
1303:
1304:
1305: /*
1306: * Link-LSA handling (assume OSPFv3)
1307: * Type = LSA_T_LINK
1308: */
1309:
1310: static inline void
1311: lsab_put_prefix(struct ospf_proto *p, ip_addr prefix, u32 pxlen, u32 cost)
1312: {
1313: void *buf = lsab_alloc(p, IPV6_PREFIX_SPACE(pxlen));
1314: u8 flags = (pxlen < MAX_PREFIX_LENGTH) ? 0 : OPT_PX_LA;
1315: put_ipv6_prefix(buf, prefix, pxlen, flags, cost);
1316: }
1317:
1318: static void
1319: prepare_link_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
1320: {
1321: struct ospf_lsa_link *ll;
1322: int i = 0;
1323:
1324: ASSERT(p->lsab_used == 0);
1325: ll = lsab_allocz(p, sizeof(struct ospf_lsa_link));
1326: ll->options = ifa->oa->options | (ifa->priority << 24);
1327: ll->lladdr = ipa_to_ip6(ifa->addr->ip);
1328: ll = NULL; /* buffer might be reallocated later */
1329:
1330: struct ifa *a;
1331: WALK_LIST(a, ifa->iface->addrs)
1332: {
1333: if ((a->flags & IA_SECONDARY) ||
1334: (a->scope < SCOPE_SITE))
1335: continue;
1336:
1337: lsab_put_prefix(p, a->prefix, a->pxlen, 0);
1338: i++;
1339: }
1340:
1341: ll = p->lsab;
1342: ll->pxcount = i;
1343: }
1344:
1345: static void
1346: ospf_originate_link_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
1347: {
1348: if (ospf_is_v2(p))
1349: return;
1350:
1351: struct ospf_new_lsa lsa = {
1352: .type = LSA_T_LINK,
1353: .dom = ifa->iface_id,
1354: .id = ifa->iface_id,
1355: .ifa = ifa
1356: };
1357:
1358: OSPF_TRACE(D_EVENTS, "Updating link state for %s (Id: %R)", ifa->ifname, lsa.id);
1359:
1360: prepare_link_lsa_body(p, ifa);
1361:
1362: ifa->link_lsa = ospf_originate_lsa(p, &lsa);
1363: }
1364:
1365:
1366: /*
1367: * Prefix-Rt-LSA handling (assume OSPFv3)
1368: * Type = LSA_T_PREFIX, referred type = LSA_T_RT
1369: */
1370:
1371: static void
1372: prepare_prefix_rt_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
1373: {
1374: struct ospf_config *cf = (struct ospf_config *) (p->p.cf);
1375: struct ospf_iface *ifa;
1376: struct ospf_lsa_prefix *lp;
1377: int host_addr = 0;
1378: int net_lsa;
1379: int i = 0;
1380:
1381: ASSERT(p->lsab_used == 0);
1382: lp = lsab_allocz(p, sizeof(struct ospf_lsa_prefix));
1383: lp->ref_type = LSA_T_RT;
1384: lp->ref_id = 0;
1385: lp->ref_rt = p->router_id;
1386: lp = NULL; /* buffer might be reallocated later */
1387:
1388: WALK_LIST(ifa, p->iface_list)
1389: {
1390: if ((ifa->oa != oa) || (ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
1391: continue;
1392:
1393: ifa->px_pos_beg = i;
1394:
1395: if ((ifa->type == OSPF_IT_BCAST) ||
1396: (ifa->type == OSPF_IT_NBMA))
1397: net_lsa = bcast_net_active(ifa);
1398: else
1399: net_lsa = 0;
1400:
1401: struct ifa *a;
1402: WALK_LIST(a, ifa->iface->addrs)
1403: {
1404: if ((a->flags & IA_SECONDARY) ||
1405: (a->flags & IA_PEER) ||
1406: (a->scope <= SCOPE_LINK))
1407: continue;
1408:
1409: if (((a->pxlen < MAX_PREFIX_LENGTH) && net_lsa) ||
1410: configured_stubnet(oa, a))
1411: continue;
1412:
1413: if ((a->flags & IA_HOST) ||
1414: (ifa->state == OSPF_IS_LOOP) ||
1415: (ifa->type == OSPF_IT_PTMP))
1416: {
1417: lsab_put_prefix(p, a->ip, MAX_PREFIX_LENGTH, 0);
1418: host_addr = 1;
1419: }
1420: else
1421: lsab_put_prefix(p, a->prefix, a->pxlen, ifa->cost);
1422: i++;
1423: }
1424:
1425: ifa->px_pos_end = i;
1426: }
1427:
1428: struct ospf_stubnet_config *sn;
1429: WALK_LIST(sn, oa->ac->stubnet_list)
1430: if (!sn->hidden)
1431: {
1432: lsab_put_prefix(p, sn->px.addr, sn->px.len, sn->cost);
1433: if (sn->px.len == MAX_PREFIX_LENGTH)
1434: host_addr = 1;
1435: i++;
1436: }
1437:
1438: /* If there are some configured vlinks, find some global address
1439: (even from another area), which will be used as a vlink endpoint. */
1440: if (!EMPTY_LIST(cf->vlink_list) && !host_addr)
1441: {
1442: WALK_LIST(ifa, p->iface_list)
1443: {
1444: if ((ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
1445: continue;
1446:
1447: struct ifa *a;
1448: WALK_LIST(a, ifa->iface->addrs)
1449: {
1450: if ((a->flags & IA_SECONDARY) || (a->scope <= SCOPE_LINK))
1451: continue;
1452:
1453: /* Found some IP */
1454: lsab_put_prefix(p, a->ip, MAX_PREFIX_LENGTH, 0);
1455: i++;
1456: goto done;
1457: }
1458: }
1459: }
1460:
1461: done:
1462: lp = p->lsab;
1463: lp->pxcount = i;
1464: }
1465:
1466: static void
1467: ospf_originate_prefix_rt_lsa(struct ospf_proto *p, struct ospf_area *oa)
1468: {
1469: if (ospf_is_v2(p))
1470: return;
1471:
1472: struct ospf_new_lsa lsa = {
1473: .type = LSA_T_PREFIX,
1474: .dom = oa->areaid,
1475: .id = 0
1476: };
1477:
1478: prepare_prefix_rt_lsa_body(p, oa);
1479:
1480: ospf_originate_lsa(p, &lsa);
1481: }
1482:
1483:
1484: /*
1485: * Prefix-Net-LSA handling (assume OSPFv3)
1486: * Type = LSA_T_PREFIX, referred type = LSA_T_NET
1487: */
1488:
1489: static inline int
1490: prefix_space(u32 *buf)
1491: {
1492: int pxl = *buf >> 24;
1493: return IPV6_PREFIX_SPACE(pxl);
1494: }
1495:
1496: static inline int
1497: prefix_same(u32 *b1, u32 *b2)
1498: {
1499: int pxl1 = *b1 >> 24;
1500: int pxl2 = *b2 >> 24;
1501: int pxs, i;
1502:
1503: if (pxl1 != pxl2)
1504: return 0;
1505:
1506: pxs = IPV6_PREFIX_WORDS(pxl1);
1507: for (i = 1; i < pxs; i++)
1508: if (b1[i] != b2[i])
1509: return 0;
1510:
1511: return 1;
1512: }
1513:
1514: static inline u32 *
1515: prefix_advance(u32 *buf)
1516: {
1517: int pxl = *buf >> 24;
1518: return buf + IPV6_PREFIX_WORDS(pxl);
1519: }
1520:
1521: /* FIXME eliminate items with LA bit set? see 4.4.3.9 */
1522: static void
1523: add_prefix(struct ospf_proto *p, u32 *px, int offset, int *pxc)
1524: {
1525: u32 *pxl = lsab_offset(p, offset);
1526: int i;
1527: for (i = 0; i < *pxc; pxl = prefix_advance(pxl), i++)
1528: if (prefix_same(px, pxl))
1529: {
1530: /* Options should be logically OR'ed together */
1531: *pxl |= (*px & 0x00FF0000);
1532: return;
1533: }
1534:
1535: ASSERT(pxl == lsab_end(p));
1536:
1537: int pxspace = prefix_space(px);
1538: pxl = lsab_alloc(p, pxspace);
1539: memcpy(pxl, px, pxspace);
1540: *pxl &= 0xFFFF0000; /* Set metric to zero */
1541: (*pxc)++;
1542: }
1543:
1544: static void
1545: add_link_lsa(struct ospf_proto *p, struct ospf_lsa_link *ll, int offset, int *pxc)
1546: {
1547: u32 *pxb = ll->rest;
1548: uint j;
1549:
1550: for (j = 0; j < ll->pxcount; pxb = prefix_advance(pxb), j++)
1551: {
1552: u8 pxlen = (pxb[0] >> 24);
1553: u8 pxopts = (pxb[0] >> 16);
1554:
1555: /* Skip NU or LA prefixes */
1556: if (pxopts & (OPT_PX_NU | OPT_PX_LA))
1557: continue;
1558:
1559: /* Skip link-local prefixes */
1560: if ((pxlen >= 10) && ((pxb[1] & 0xffc00000) == 0xfe800000))
1561: continue;
1562:
1563: add_prefix(p, pxb, offset, pxc);
1564: }
1565: }
1566:
1567: static void
1568: prepare_prefix_net_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
1569: {
1570: struct ospf_lsa_prefix *lp;
1571: struct ospf_neighbor *n;
1572: struct top_hash_entry *en;
1573: int pxc, offset;
1574:
1575: ASSERT(p->lsab_used == 0);
1576: lp = lsab_allocz(p, sizeof(struct ospf_lsa_prefix));
1577: lp->ref_type = LSA_T_NET;
1578: lp->ref_id = ifa->net_lsa->lsa.id;
1579: lp->ref_rt = p->router_id;
1580: lp = NULL; /* buffer might be reallocated later */
1581:
1582: pxc = 0;
1583: offset = p->lsab_used;
1584:
1585: /* Find all Link LSAs associated with the link and merge their prefixes */
1586: if (en = ifa->link_lsa)
1587: add_link_lsa(p, en->next_lsa_body ?: en->lsa_body, offset, &pxc);
1588:
1589: WALK_LIST(n, ifa->neigh_list)
1590: if ((n->state == NEIGHBOR_FULL) &&
1591: (en = ospf_hash_find(p->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK)))
1592: add_link_lsa(p, en->lsa_body, offset, &pxc);
1593:
1594: lp = p->lsab;
1595: lp->pxcount = pxc;
1596: }
1597:
1598: static void
1599: ospf_originate_prefix_net_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
1600: {
1601: if (ospf_is_v2(p))
1602: return;
1603:
1604: struct ospf_new_lsa lsa = {
1605: .type = LSA_T_PREFIX,
1606: .dom = ifa->oa->areaid,
1607: .id = ifa->iface_id,
1608: .ifa = ifa
1609: };
1610:
1611: prepare_prefix_net_lsa_body(p, ifa);
1612:
1613: ifa->pxn_lsa = ospf_originate_lsa(p, &lsa);
1614: }
1615:
1616: static inline int breaks_minlsinterval(struct top_hash_entry *en)
1617: { return en && (en->lsa.age < LSA_MAXAGE) && ((en->inst_time + MINLSINTERVAL) > now); }
1618:
1619: void
1620: ospf_update_topology(struct ospf_proto *p)
1621: {
1622: struct ospf_area *oa;
1623: struct ospf_iface *ifa;
1624:
1625: WALK_LIST(oa, p->area_list)
1626: {
1627: if (oa->update_rt_lsa)
1628: {
1629: /*
1630: * Generally, MinLSInterval is enforced in ospf_do_originate_lsa(), but
1631: * origination of (prefix) router LSA is a special case. We do not want to
1632: * prepare a new router LSA body and then postpone it in en->next_lsa_body
1633: * for later origination, because there are side effects (updates of
1634: * rt_pos_* and px_pos_* in ospf_iface structures) during that, which may
1635: * confuse routing table calculation if executed after LSA body
1636: * preparation but before final LSA origination (as rtcalc would use
1637: * current rt_pos_* indexes but the old router LSA body).
1638: *
1639: * Here, we ensure that MinLSInterval is observed and we do not even try
1640: * to originate these LSAs if it is not. Therefore, origination, when
1641: * requested, will succeed unless there is also a seqnum wrapping, which
1642: * is not a problem because in that case rtcalc is blocked by MaxAge.
1643: */
1644:
1645: if (breaks_minlsinterval(oa->rt) || breaks_minlsinterval(oa->pxr_lsa))
1646: continue;
1647:
1648: ospf_originate_rt_lsa(p, oa);
1649: ospf_originate_prefix_rt_lsa(p, oa);
1650: oa->update_rt_lsa = 0;
1651: }
1652: }
1653:
1654: WALK_LIST(ifa, p->iface_list)
1655: {
1656: if (ifa->type == OSPF_IT_VLINK)
1657: continue;
1658:
1659: if (ifa->update_link_lsa)
1660: {
1661: if ((ifa->state > OSPF_IS_LOOP) && !ifa->link_lsa_suppression)
1662: ospf_originate_link_lsa(p, ifa);
1663: else
1664: ospf_flush2_lsa(p, &ifa->link_lsa);
1665:
1666: ifa->update_link_lsa = 0;
1667: }
1668:
1669: if (ifa->update_net_lsa)
1670: {
1671: if ((ifa->state == OSPF_IS_DR) && (ifa->fadj > 0))
1672: {
1673: ospf_originate_net_lsa(p, ifa);
1674: ospf_originate_prefix_net_lsa(p, ifa);
1675: }
1676: else
1677: {
1678: ospf_flush2_lsa(p, &ifa->net_lsa);
1679: ospf_flush2_lsa(p, &ifa->pxn_lsa);
1680: }
1681:
1682: ifa->update_net_lsa = 0;
1683: }
1684: }
1685: }
1686:
1687:
1688: static void
1689: ospf_top_ht_alloc(struct top_graph *f)
1690: {
1691: f->hash_size = 1 << f->hash_order;
1692: f->hash_mask = f->hash_size - 1;
1693: if (f->hash_order > HASH_HI_MAX - HASH_HI_STEP)
1694: f->hash_entries_max = ~0;
1695: else
1696: f->hash_entries_max = f->hash_size HASH_HI_MARK;
1697: if (f->hash_order < HASH_LO_MIN + HASH_LO_STEP)
1698: f->hash_entries_min = 0;
1699: else
1700: f->hash_entries_min = f->hash_size HASH_LO_MARK;
1701: DBG("Allocating OSPF hash of order %d: %d hash_entries, %d low, %d high\n",
1702: f->hash_order, f->hash_size, f->hash_entries_min, f->hash_entries_max);
1703: f->hash_table =
1704: mb_alloc(f->pool, f->hash_size * sizeof(struct top_hash_entry *));
1705: bzero(f->hash_table, f->hash_size * sizeof(struct top_hash_entry *));
1706: }
1707:
1708: static inline void
1709: ospf_top_ht_free(struct top_hash_entry **h)
1710: {
1711: mb_free(h);
1712: }
1713:
1714: static inline u32
1715: ospf_top_hash_u32(u32 a)
1716: {
1717: /* Shamelessly stolen from IP address hashing in ipv4.h */
1718: a ^= a >> 16;
1719: a ^= a << 10;
1720: return a;
1721: }
1722:
1723: static uint
1724: ospf_top_hash(struct top_graph *f, u32 domain, u32 lsaid, u32 rtrid, u32 type)
1725: {
1726: /* In OSPFv2, we don't know Router ID when looking for network LSAs.
1727: In OSPFv3, we don't know LSA ID when looking for router LSAs.
1728: In both cases, there is (usually) just one (or small number)
1729: appropriate LSA, so we just clear unknown part of key. */
1730:
1731: return (((f->ospf2 && (type == LSA_T_NET)) ? 0 : ospf_top_hash_u32(rtrid)) +
1732: ((!f->ospf2 && (type == LSA_T_RT)) ? 0 : ospf_top_hash_u32(lsaid)) +
1733: type + domain) & f->hash_mask;
1734:
1735: /*
1736: return (ospf_top_hash_u32(lsaid) + ospf_top_hash_u32(rtrid) +
1737: type + areaid) & f->hash_mask;
1738: */
1739: }
1740:
1741: /**
1742: * ospf_top_new - allocated new topology database
1743: * @p: OSPF protocol instance
1744: * @pool: pool for allocation
1745: *
1746: * This dynamically hashed structure is used for keeping LSAs. Mainly it is used
1747: * for the LSA database of the OSPF protocol, but also for LSA retransmission
1748: * and request lists of OSPF neighbors.
1749: */
1750: struct top_graph *
1751: ospf_top_new(struct ospf_proto *p UNUSED4 UNUSED6, pool *pool)
1752: {
1753: struct top_graph *f;
1754:
1755: f = mb_allocz(pool, sizeof(struct top_graph));
1756: f->pool = pool;
1757: f->hash_slab = sl_new(f->pool, sizeof(struct top_hash_entry));
1758: f->hash_order = HASH_DEF_ORDER;
1759: ospf_top_ht_alloc(f);
1760: f->hash_entries = 0;
1761: f->hash_entries_min = 0;
1762: f->ospf2 = ospf_is_v2(p);
1763: return f;
1764: }
1765:
1766: void
1767: ospf_top_free(struct top_graph *f)
1768: {
1769: rfree(f->hash_slab);
1770: ospf_top_ht_free(f->hash_table);
1771: mb_free(f);
1772: }
1773:
1774: static void
1775: ospf_top_rehash(struct top_graph *f, int step)
1776: {
1777: struct top_hash_entry **n, **oldt, **newt, *e, *x;
1778: uint oldn, oldh;
1779:
1780: oldn = f->hash_size;
1781: oldt = f->hash_table;
1782: DBG("re-hashing topology hash from order %d to %d\n", f->hash_order,
1783: f->hash_order + step);
1784: f->hash_order += step;
1785: ospf_top_ht_alloc(f);
1786: newt = f->hash_table;
1787:
1788: for (oldh = 0; oldh < oldn; oldh++)
1789: {
1790: e = oldt[oldh];
1791: while (e)
1792: {
1793: x = e->next;
1794: n = newt + ospf_top_hash(f, e->domain, e->lsa.id, e->lsa.rt, e->lsa_type);
1795: e->next = *n;
1796: *n = e;
1797: e = x;
1798: }
1799: }
1800: ospf_top_ht_free(oldt);
1801: }
1802:
1803: static struct top_hash_entry *
1804: ospf_hash_find_(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
1805: {
1806: struct top_hash_entry *e;
1807: e = f->hash_table[ospf_top_hash(f, domain, lsa, rtr, type)];
1808:
1809: while (e && (e->lsa.id != lsa || e->lsa.rt != rtr ||
1810: e->lsa_type != type || e->domain != domain))
1811: e = e->next;
1812:
1813: return e;
1814: }
1815:
1816: struct top_hash_entry *
1817: ospf_hash_find(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
1818: {
1819: struct top_hash_entry *e = ospf_hash_find_(f, domain, lsa, rtr, type);
1820:
1821: /* Hide hash entry with empty lsa_body */
1822: return (e && e->lsa_body) ? e : NULL;
1823: }
1824:
1825: /* In OSPFv2, lsa.id is the same as lsa.rt for router LSA. In OSPFv3, we don't know
1826: lsa.id when looking for router LSAs. We return matching LSA with smallest lsa.id. */
1827: struct top_hash_entry *
1828: ospf_hash_find_rt(struct top_graph *f, u32 domain, u32 rtr)
1829: {
1830: struct top_hash_entry *rv = NULL;
1831: struct top_hash_entry *e;
1832: /* We can put rtr for lsa.id to hash fn, it is ignored in OSPFv3 */
1833: e = f->hash_table[ospf_top_hash(f, domain, rtr, rtr, LSA_T_RT)];
1834:
1835: while (e)
1836: {
1837: if (e->lsa.rt == rtr && e->lsa_type == LSA_T_RT && e->domain == domain && e->lsa_body)
1838: {
1839: if (f->ospf2 && (e->lsa.id == rtr))
1840: return e;
1841: if (!f->ospf2 && (!rv || e->lsa.id < rv->lsa.id))
1842: rv = e;
1843: }
1844: e = e->next;
1845: }
1846:
1847: return rv;
1848: }
1849:
1850: /*
1851: * ospf_hash_find_rt3_first() and ospf_hash_find_rt3_next() are used exclusively
1852: * for lsa_walk_rt_init(), lsa_walk_rt(), therefore they skip MaxAge entries.
1853: */
1854: static inline struct top_hash_entry *
1855: find_matching_rt3(struct top_hash_entry *e, u32 domain, u32 rtr)
1856: {
1857: while (e && (e->lsa.rt != rtr || e->lsa_type != LSA_T_RT ||
1858: e->domain != domain || e->lsa.age == LSA_MAXAGE))
1859: e = e->next;
1860: return e;
1861: }
1862:
1863: struct top_hash_entry *
1864: ospf_hash_find_rt3_first(struct top_graph *f, u32 domain, u32 rtr)
1865: {
1866: struct top_hash_entry *e;
1867: e = f->hash_table[ospf_top_hash(f, domain, 0, rtr, LSA_T_RT)];
1868: return find_matching_rt3(e, domain, rtr);
1869: }
1870:
1871: struct top_hash_entry *
1872: ospf_hash_find_rt3_next(struct top_hash_entry *e)
1873: {
1874: return find_matching_rt3(e->next, e->domain, e->lsa.rt);
1875: }
1876:
1877: /* In OSPFv2, we don't know Router ID when looking for network LSAs.
1878: There should be just one, so we find any match. */
1879: struct top_hash_entry *
1880: ospf_hash_find_net2(struct top_graph *f, u32 domain, u32 id)
1881: {
1882: struct top_hash_entry *e;
1883: e = f->hash_table[ospf_top_hash(f, domain, id, 0, LSA_T_NET)];
1884:
1885: while (e && (e->lsa.id != id || e->lsa_type != LSA_T_NET ||
1886: e->domain != domain || e->lsa_body == NULL))
1887: e = e->next;
1888:
1889: return e;
1890: }
1891:
1892:
1893: struct top_hash_entry *
1894: ospf_hash_get(struct top_graph *f, u32 domain, u32 lsa, u32 rtr, u32 type)
1895: {
1896: struct top_hash_entry **ee;
1897: struct top_hash_entry *e;
1898:
1899: ee = f->hash_table + ospf_top_hash(f, domain, lsa, rtr, type);
1900: e = *ee;
1901:
1902: while (e && (e->lsa.id != lsa || e->lsa.rt != rtr ||
1903: e->lsa_type != type || e->domain != domain))
1904: e = e->next;
1905:
1906: if (e)
1907: return e;
1908:
1909: e = sl_alloc(f->hash_slab);
1910: bzero(e, sizeof(struct top_hash_entry));
1911:
1912: e->color = OUTSPF;
1913: e->dist = LSINFINITY;
1914: e->lsa.type_raw = type;
1915: e->lsa.id = lsa;
1916: e->lsa.rt = rtr;
1917: e->lsa.sn = LSA_ZEROSEQNO;
1918: e->lsa_type = type;
1919: e->domain = domain;
1920: e->next = *ee;
1921: *ee = e;
1922: if (f->hash_entries++ > f->hash_entries_max)
1923: ospf_top_rehash(f, HASH_HI_STEP);
1924: return e;
1925: }
1926:
1927: void
1928: ospf_hash_delete(struct top_graph *f, struct top_hash_entry *e)
1929: {
1930: struct top_hash_entry **ee = f->hash_table +
1931: ospf_top_hash(f, e->domain, e->lsa.id, e->lsa.rt, e->lsa_type);
1932:
1933: while (*ee)
1934: {
1935: if (*ee == e)
1936: {
1937: *ee = e->next;
1938: sl_free(f->hash_slab, e);
1939: if (f->hash_entries-- < f->hash_entries_min)
1940: ospf_top_rehash(f, -HASH_LO_STEP);
1941: return;
1942: }
1943: ee = &((*ee)->next);
1944: }
1945: bug("ospf_hash_delete() called for invalid node");
1946: }
1947:
1948: /*
1949: static void
1950: ospf_dump_lsa(struct top_hash_entry *he, struct proto *p)
1951: {
1952:
1953: struct ospf_lsa_rt *rt = NULL;
1954: struct ospf_lsa_rt_link *rr = NULL;
1955: struct ospf_lsa_net *ln = NULL;
1956: u32 *rts = NULL;
1957: u32 i, max;
1958:
1959: OSPF_TRACE(D_EVENTS, "- %1x %-1R %-1R %4u 0x%08x 0x%04x %-1R",
1960: he->lsa.type, he->lsa.id, he->lsa.rt, he->lsa.age, he->lsa.sn,
1961: he->lsa.checksum, he->domain);
1962:
1963:
1964: switch (he->lsa.type)
1965: {
1966: case LSA_T_RT:
1967: rt = he->lsa_body;
1968: rr = (struct ospf_lsa_rt_link *) (rt + 1);
1969:
1970: for (i = 0; i < lsa_rt_items(&he->lsa); i++)
1971: OSPF_TRACE(D_EVENTS, " - %1x %-1R %-1R %5u",
1972: rr[i].type, rr[i].id, rr[i].data, rr[i].metric);
1973: break;
1974:
1975: case LSA_T_NET:
1976: ln = he->lsa_body;
1977: rts = (u32 *) (ln + 1);
1978:
1979: for (i = 0; i < lsa_net_items(&he->lsa); i++)
1980: OSPF_TRACE(D_EVENTS, " - %-1R", rts[i]);
1981: break;
1982:
1983: default:
1984: break;
1985: }
1986: }
1987:
1988: void
1989: ospf_top_dump(struct top_graph *f, struct proto *p)
1990: {
1991: uint i;
1992: OSPF_TRACE(D_EVENTS, "Hash entries: %d", f->hash_entries);
1993:
1994: for (i = 0; i < f->hash_size; i++)
1995: {
1996: struct top_hash_entry *e;
1997: for (e = f->hash_table[i]; e != NULL; e = e->next)
1998: ospf_dump_lsa(e, p);
1999: }
2000: }
2001: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>