Revision a7a7372a proto/ospf/topology.c

View differences:

proto/ospf/topology.c
40 40
 * new routing table calculation is necessary. This is described in 13.2 of RFC
41 41
 * 2328. This function is for received LSA only, locally originated LSAs are
42 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.
43 46
 */
44 47
struct top_hash_entry *
45 48
ospf_install_lsa(struct ospf_proto *p, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body)
46 49
{
47
  /* LSA can be temporary, but body must be mb_allocated. */
48 50
  struct top_hash_entry *en;
49 51
  int change = 0;
50 52

  
......
61 63
      memcmp(en->lsa_body, body, lsa->length - sizeof(struct ospf_lsa_header)))
62 64
    change = 1;
63 65

  
64
  DBG("Inst lsa: Id: %R, Rt: %R, Type: %u, Age: %u, Sum: %u, Sn: 0x%x\n",
65
      lsa->id, lsa->rt, lsa->type, lsa->age, lsa->checksum, lsa->sn);
66
  if ((en->lsa.age == LSA_MAXAGE) && (lsa->age == LSA_MAXAGE))
67
    change = 0;
66 68

  
67 69
  mb_free(en->lsa_body);
68 70
  en->lsa_body = body;
......
70 72
  en->init_age = en->lsa.age;
71 73
  en->inst_time = now;
72 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

  
73 85
  if (change)
74
    schedule_rtcalc(p);
86
    ospf_schedule_rtcalc(p);
75 87

  
76 88
  return en;
77 89
}
78 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
 */
79 108
void
80 109
ospf_advance_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body)
81 110
{
82
  // OSPF_TRACE(D_EVENTS, "Reflooding new self-originated LSA with newer sequence number");
111
  /* RFC 2328 13.4 */
83 112

  
84 113
  if (en && (en->lsa.age < LSA_MAXAGE))
85 114
  {
......
101 130
      en->init_age = 0;
102 131
      en->inst_time = now;
103 132
      lsasum_calculate(&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);
104 136
    }
105 137
    else
106 138
    {
......
129 161
      en->lsa.age = LSA_MAXAGE;
130 162
      en->init_age = lsa->age;
131 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);
132 169
    }
133 170
  }
134 171
  else
......
137 174
     * We do not have received LSA in the database. We have to flush the
138 175
     * received LSA. It has to be installed in the database to secure
139 176
     * retransmissions. Note that the received LSA may already be MaxAge.
177
     * Also note that en->next_lsa_* may be defined.
140 178
     */
141 179

  
142 180
    lsa->age = LSA_MAXAGE;
......
150 188
   * the neighbor we received it from), we cheat a bit here.
151 189
   */
152 190

  
153
  ospf_lsupd_flood(p, en, NULL);
191
  ospf_flood_lsa(p, en, NULL);
154 192
}
155 193

  
156 194

  
......
167 205
    /* Prepare to flush old LSA */
168 206
    if (en->lsa.age != LSA_MAXAGE)
169 207
    {
170
      OSPF_TRACE(D_EVENTS, "Resetting LSA: Type: %04x, Id: %R, Rt: %R",
171
		 en->lsa_type, en->lsa.id, en->lsa.rt);
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);
172 210

  
173 211
      en->lsa.age = LSA_MAXAGE;
174
      ospf_lsupd_flood(p, en, NULL);
212
      ospf_flood_lsa(p, en, NULL);
175 213
      return 0;
176 214
    }
177 215

  
......
183 221
    en->lsa.sn = LSA_ZEROSEQNO;
184 222
  }
185 223

  
186
  OSPF_TRACE(D_EVENTS, "Originating LSA: Type: %04x, Id: %R, Rt: %R",
187
	     en->lsa_type, en->lsa.id, en->lsa.rt);
188

  
189 224
  /*
190 225
   * lsa.type_raw is initialized by ospf_hash_get() to OSPFv3 LSA type.
191 226
   * lsa_set_options() implicitly converts it to OSPFv2 LSA type, assuming that
......
205 240
  en->inst_time = now;
206 241
  lsasum_calculate(&en->lsa, en->lsa_body);
207 242

  
208
  ospf_lsupd_flood(p, en, NULL);
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);
209 250

  
210 251
  return 1;
211 252
}
......
244 285
  {
245 286
    log(L_ERR "%s: LSA ID collision for %I/%d",
246 287
	p->p.name, lsa->nf->fn.prefix, lsa->nf->fn.pxlen);
288

  
289
    en = NULL;
247 290
    goto drop;
248 291
  }
249 292

  
250
  /* XXXX check for maxage or opts change */
293
  if (en->mode != lsa->mode)
294
    en->mode = lsa->mode;
251 295

  
252 296
  if (en->next_lsa_body)
253 297
  {
254 298
    /* Ignore the new LSA if it is the same as the scheduled one */
255
    if ((lsa_blen == en->next_lsa_blen) && !memcmp(lsa_body, en->next_lsa_body, lsa_blen))
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)))
256 302
      goto drop;
257 303

  
258 304
    /* Free scheduled LSA */
......
263 309
  }
264 310

  
265 311
  /* Ignore the the new LSA if is the same as the current one */
266
  if ((lsa_length == en->lsa.length) && !memcmp(lsa_body, en->lsa_body, lsa_blen))
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))))
267 316
    goto drop;
268 317

  
269 318
  lsa_body = lsab_flush(p);
270 319

  
271 320
  if (! ospf_do_originate_lsa(p, en, lsa_body, lsa_blen, lsa->opts))
272 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

  
273 325
    en->next_lsa_body = lsa_body;
274 326
    en->next_lsa_blen = lsa_blen;
275 327
    en->next_lsa_opts = lsa->opts;
......
293 345
  en->next_lsa_body = NULL;
294 346
  en->next_lsa_blen = 0;
295 347
  en->next_lsa_opts = 0;
296

  
297
  // XXXX:  schedule_rtcalc(p);
298 348
}
299 349

  
300 350
static void
......
309 359
   * switched lsa.age to LSA_MAXAGE.
310 360
   */
311 361

  
312
  OSPF_TRACE(D_EVENTS, "Refreshing LSA: Type: %04x, Id: %R, Rt: %R",
313
	     en->lsa_type, en->lsa.id, en->lsa.rt);
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);
314 364

  
315 365
  ASSERT(en->next_lsa_body == NULL);
316 366

  
......
324 374
    en->next_lsa_opts = ospf_is_v2(p) ? lsa_get_options(&en->lsa) : 0;
325 375

  
326 376
    en->lsa.age = LSA_MAXAGE;
327
    ospf_lsupd_flood(p, en, NULL);
377
    ospf_flood_lsa(p, en, NULL);
328 378
    return;
329 379
  }
330 380

  
......
333 383
  en->init_age = 0;
334 384
  en->inst_time = now;
335 385
  lsasum_calculate(&en->lsa, en->lsa_body);
336
  ospf_lsupd_flood(p, en, NULL);
386
  ospf_flood_lsa(p, en, NULL);
337 387
}
338 388

  
339 389
/**
......
349 399
 * immediately removed when being flushed, the caller may assume that @en still
350 400
 * exists after the call. The function is the opposite of ospf_originate_lsa()
351 401
 * and is supposed to do the right thing even in cases of postponed
352
 * origination. Note that this function do not schedule routing table
353
 * calculation, the caller is responsible to do it if necessary.
402
 * origination.
354 403
 */
355 404
void
356 405
ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en)
357 406
{
358
  OSPF_TRACE(D_EVENTS, "Flushing LSA: Type: %04x, Id: %R, Rt: %R",
359
	     en->lsa_type, en->lsa.id, en->lsa.rt);
360

  
361
  en->rtcalc = 0;
407
  OSPF_TRACE(D_EVENTS, "Flushing LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
408
	     en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn);
362 409

  
363 410
  if (en->next_lsa_body)
364 411
  {
......
372 419
    return;
373 420

  
374 421
  en->lsa.age = LSA_MAXAGE;
375
  ospf_lsupd_flood(p, en, NULL);
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;
376 428
}
377 429

  
378 430
static void
......
450 502
    if (real_age >= LSA_MAXAGE)
451 503
    {
452 504
      ospf_flush_lsa(p, en);
453
      schedule_rtcalc(p);
454 505
      continue;
455 506
    }
456 507

  
......
510 561

  
511 562

  
512 563
static void *
513
lsab_alloc(struct ospf_proto *p, unsigned size)
564
lsab_alloc(struct ospf_proto *p, uint size)
514 565
{
515
  unsigned offset = p->lsab_used;
566
  uint offset = p->lsab_used;
516 567
  p->lsab_used += size;
517 568
  if (p->lsab_used > p->lsab_size)
518 569
  {
......
524 575
}
525 576

  
526 577
static inline void *
527
lsab_allocz(struct ospf_proto *p, unsigned size)
578
lsab_allocz(struct ospf_proto *p, uint size)
528 579
{
529 580
  void *r = lsab_alloc(p, size);
530 581
  bzero(r, size);
......
547 598
}
548 599

  
549 600
static inline void *
550
lsab_offset(struct ospf_proto *p, unsigned offset)
601
lsab_offset(struct ospf_proto *p, uint offset)
551 602
{
552 603
  return ((byte *) p->lsab) + offset;
553 604
}
......
815 866
  rt->options = get_rt_options(p, oa, bitv) | (oa->options & LSA_OPTIONS_MASK);
816 867
}
817 868

  
818
/**
819
 * ospf_originate_rt_lsa - build new instance of router LSA
820
 * @oa: ospf_area which is LSA built to
821
 *
822
 * It builds router LSA walking through all OSPF interfaces in
823
 * specified OSPF area. This function is mostly called from
824
 * area_disp(). Builds new LSA, increases sequence number (if old
825
 * instance exists) and sets age of LSA to zero.
826
 */
827 869
static void
828 870
ospf_originate_rt_lsa(struct ospf_proto *p, struct ospf_area *oa)
829 871
{
......
834 876
    .opts = oa->options
835 877
  };
836 878

  
879
  OSPF_TRACE(D_EVENTS, "Updating router state for area %R", oa->areaid);
880

  
837 881
  if (ospf_is_v2(p))
838 882
    prepare_rt2_lsa_body(p, oa);
839 883
  else
......
908 952
  net->optx = options & LSA_OPTIONS_MASK;
909 953
}
910 954

  
911
/**
912
 * ospf_originate_net_lsa - originates of deletes network LSA
913
 * @ifa: interface which is LSA originated for
914
 *
915
 * Interface counts number of adjacent neighbors. If this number is
916
 * lower than one or interface is not in state %OSPF_IS_DR it deletes
917
 * and premature ages instance of network LSA for specified interface.
918
 * In other case, new instance of network LSA is originated.
919
 */
920 955
static void
921 956
ospf_originate_net_lsa(struct ospf_proto *p, struct ospf_iface *ifa)
922 957
{
......
928 963
    .ifa  = ifa
929 964
  };
930 965

  
966
  OSPF_TRACE(D_EVENTS, "Updating network state for %s (Id: %R)", ifa->ifname, lsa.id);
967

  
931 968
  if (ospf_is_v2(p))
932 969
    prepare_net2_lsa_body(p, ifa);
933 970
  else
......
977 1014
void
978 1015
ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric)
979 1016
{
980
  struct top_hash_entry *en;
981

  
982 1017
  struct ospf_new_lsa lsa = {
983 1018
    .type = LSA_T_SUM_NET,
1019
    .mode = LSA_M_RTCALC,
984 1020
    .dom  = oa->areaid,
985 1021
    .id   = ort_to_lsaid(p, nf),
986 1022
    .opts = oa->options,
......
992 1028
  else
993 1029
    prepare_sum3_net_lsa_body(p, nf, metric);
994 1030

  
995
  en = ospf_originate_lsa(p, &lsa);
996
  en->rtcalc = LSA_RTCALC;
1031
  ospf_originate_lsa(p, &lsa);
997 1032
}
998 1033

  
999 1034
void
1000 1035
ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric, u32 options)
1001 1036
{
1002
  struct top_hash_entry *en;
1003
  u32 rid = ipa_to_rid(nf->fn.prefix);
1004

  
1005
  /* In OSPFv3, LSA ID is meaningless, but we still use Router ID of ASBR */
1006

  
1007 1037
  struct ospf_new_lsa lsa = {
1008 1038
    .type = LSA_T_SUM_RT,
1039
    .mode = LSA_M_RTCALC,
1009 1040
    .dom  = oa->areaid,
1010
    .id   = rid,
1041
    .id   = ipa_to_rid(nf->fn.prefix),	/* Router ID of ASBR, irrelevant for OSPFv3 */
1011 1042
    .opts = oa->options
1012 1043
  };
1013 1044

  
1014 1045
  if (ospf_is_v2(p))
1015 1046
    prepare_sum2_lsa_body(p, 0, metric);
1016 1047
  else
1017
    prepare_sum3_rt_lsa_body(p, rid, metric, options & LSA_OPTIONS_MASK);
1048
    prepare_sum3_rt_lsa_body(p, lsa.id, metric, options & LSA_OPTIONS_MASK);
1018 1049

  
1019
  en = ospf_originate_lsa(p, &lsa);
1020
  en->rtcalc = LSA_RTCALC;
1050
  ospf_originate_lsa(p, &lsa);
1021 1051
}
1022 1052

  
1023 1053

  
......
1076 1106

  
1077 1107
/**
1078 1108
 * originate_ext_lsa - new route received from nest and filters
1109
 * @p: OSPF protocol instance
1079 1110
 * @oa: ospf_area for which LSA is originated
1080 1111
 * @nf: network prefix and mask
1081
 * @src: the source of origination of the LSA (EXT_EXPORT/EXT_NSSA)
1082
 * @metric: the metric of a route (possibly with appropriate E-bit)
1112
 * @mode: the mode of the LSA (LSA_M_EXPORT or LSA_M_RTCALC)
1113
 * @metric: the metric of a route
1114
 * @ebit: E-bit for route metric (bool)
1083 1115
 * @fwaddr: the forwarding address
1084 1116
 * @tag: the route tag
1085
 * @pbit: P-bit for NSSA LSAs, ignored for external LSAs
1117
 * @pbit: P-bit for NSSA LSAs (bool), ignored for external LSAs
1086 1118
 *
1087 1119
 * If I receive a message that new route is installed, I try to originate an
1088 1120
 * external LSA. If @oa is an NSSA area, NSSA-LSA is originated instead.
......
1091 1123
 * the export from ospf_rt_notify(), or the NSSA-EXT translation.
1092 1124
 */
1093 1125
void
1094
ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 rtcalc,
1126
ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode,
1095 1127
		       u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit)
1096 1128
{
1097
  struct top_hash_entry *en;
1098

  
1099 1129
  struct ospf_new_lsa lsa = {
1100 1130
    .type = oa ? LSA_T_NSSA : LSA_T_EXT,
1131
    .mode = mode, /* LSA_M_EXPORT or LSA_M_RTCALC */
1101 1132
    .dom  = oa ? oa->areaid : 0,
1102 1133
    .id   = ort_to_lsaid(p, nf),
1103 1134
    .opts = oa ? (pbit ? OPT_P : 0) : OPT_E,
......
1109 1140
  else
1110 1141
    prepare_ext3_lsa_body(p, nf, metric, ebit, fwaddr, tag, oa && pbit);
1111 1142

  
1112
  en = ospf_originate_lsa(p, &lsa);
1113
  en->rtcalc = rtcalc;
1143
  ospf_originate_lsa(p, &lsa);
1114 1144
}
1115 1145

  
1116 1146
static void
......
1228 1258

  
1229 1259
    /* Old external route might blocked some NSSA translation */
1230 1260
    if ((p->areano > 1) && rt_is_nssa(nf) && nf->n.oa->translate)
1231
      schedule_rtcalc(p);
1261
      ospf_schedule_rtcalc(p);
1232 1262

  
1233 1263
    return;
1234 1264
  }
......
1262 1292
  }
1263 1293

  
1264 1294
  nf = (ort *) fib_get(&p->rtf, &n->n.prefix, n->n.pxlen);
1265
  ospf_originate_ext_lsa(p, oa, nf, 0, metric, ebit, fwd, tag, 1);
1295
  ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1);
1266 1296
  nf->external_rte = 1;
1267 1297
}
1268 1298

  
......
1320 1350
    .ifa  = ifa
1321 1351
  };
1322 1352

  
1353
  OSPF_TRACE(D_EVENTS, "Updating link state for %s (Id: %R)", ifa->ifname, lsa.id);
1354

  
1323 1355
  prepare_link_lsa_body(p, ifa);
1324 1356

  
1325 1357
  ifa->link_lsa = ospf_originate_lsa(p, &lsa);
......
1576 1608
  ifa->pxn_lsa = ospf_originate_lsa(p, &lsa);
1577 1609
}
1578 1610

  
1611
static inline int breaks_minlsinterval(struct top_hash_entry *en)
1612
{ return en && (en->lsa.age < LSA_MAXAGE) && ((en->inst_time + MINLSINTERVAL) > now); }
1579 1613

  
1580 1614
void
1581 1615
ospf_update_topology(struct ospf_proto *p)
......
1587 1621
  {
1588 1622
    if (oa->update_rt_lsa)
1589 1623
    {
1624
      /*
1625
       * Generally, MinLSInterval is enforced in ospf_do_originate_lsa(), but
1626
       * origination of (prefix) router LSA is a special case. We do not want to
1627
       * prepare a new router LSA body and then postpone it in en->next_lsa_body
1628
       * for later origination, because there are side effects (updates of
1629
       * rt_pos_* and px_pos_* in ospf_iface structures) during that, which may
1630
       * confuse routing table calculation if executed after LSA body
1631
       * preparation but before final LSA origination (as rtcalc would use
1632
       * current rt_pos_* indexes but the old router LSA body).
1633
       *
1634
       * Here, we ensure that MinLSInterval is observed and we do not even try
1635
       * to originate these LSAs if it is not. Therefore, origination, when
1636
       * requested, will succeed unless there is also a seqnum wrapping, which
1637
       * is not a problem because in that case rtcalc is blocked by MaxAge.
1638
       */
1639

  
1640
      if (breaks_minlsinterval(oa->rt) || breaks_minlsinterval(oa->pxr_lsa))
1641
	continue;
1642

  
1590 1643
      ospf_originate_rt_lsa(p, oa);
1591 1644
      ospf_originate_prefix_rt_lsa(p, oa);
1592 1645
      oa->update_rt_lsa = 0;
......
1624 1677
      ifa->update_net_lsa = 0;
1625 1678
    }
1626 1679
  }
1627

  
1628
  // XXXX schedule_rtcalc(p);
1629 1680
}
1630 1681

  
1631 1682

  
......
1664 1715
  return a;
1665 1716
}
1666 1717

  
1667
static unsigned
1718
static uint
1668 1719
ospf_top_hash(struct top_graph *f, u32 domain, u32 lsaid, u32 rtrid, u32 type)
1669 1720
{
1670 1721
  /* In OSPFv2, we don't know Router ID when looking for network LSAs.
......
1685 1736
/**
1686 1737
 * ospf_top_new - allocated new topology database
1687 1738
 * @p: OSPF protocol instance
1739
 * @pool: pool for allocation
1688 1740
 *
1689
 * this dynamically hashed structure is often used for keeping lsas. mainly
1690
 * its used in @ospf_area structure.
1741
 * This dynamically hashed structure is used for keeping LSAs. Mainly it is used
1742
 * for the LSA database of the OSPF protocol, but also for LSA retransmission
1743
 * and request lists of OSPF neighbors.
1691 1744
 */
1692 1745
struct top_graph *
1693
ospf_top_new(pool *pool)
1746
ospf_top_new(struct ospf_proto *p, pool *pool)
1694 1747
{
1695 1748
  struct top_graph *f;
1696 1749

  
......
1701 1754
  ospf_top_ht_alloc(f);
1702 1755
  f->hash_entries = 0;
1703 1756
  f->hash_entries_min = 0;
1757
  f->ospf2 = ospf_is_v2(p);
1704 1758
  return f;
1705 1759
}
1706 1760

  
......
1715 1769
static void
1716 1770
ospf_top_rehash(struct top_graph *f, int step)
1717 1771
{
1718
  unsigned int oldn, oldh;
1719 1772
  struct top_hash_entry **n, **oldt, **newt, *e, *x;
1773
  uint oldn, oldh;
1720 1774

  
1721 1775
  oldn = f->hash_size;
1722 1776
  oldt = f->hash_table;
......
1752 1806
    e = e->next;
1753 1807

  
1754 1808
  /* Hide hash entry with empty lsa_body */
1755
  return e->lsa_body ? e : NULL;
1809
  return (e && e->lsa_body) ? e : NULL;
1756 1810
}
1757 1811

  
1758 1812
/* In OSPFv2, lsa.id is the same as lsa.rt for router LSA. In OSPFv3, we don't know
......
1780 1834
  return rv;
1781 1835
}
1782 1836

  
1837
/*
1838
 * ospf_hash_find_rt3_first() and ospf_hash_find_rt3_next() are used exclusively
1839
 * for lsa_walk_rt_init(), lsa_walk_rt(), therefore they skip MaxAge entries.
1840
 */
1783 1841
static inline struct top_hash_entry *
1784 1842
find_matching_rt3(struct top_hash_entry *e, u32 domain, u32 rtr)
1785 1843
{
1786 1844
  while (e && (e->lsa.rt != rtr || e->lsa_type != LSA_T_RT ||
1787
	       e->domain != domain || e->lsa_body == NULL))
1845
	       e->domain != domain || e->lsa.age == LSA_MAXAGE))
1788 1846
    e = e->next;
1789 1847
  return e;
1790 1848
}
......
1917 1975
void
1918 1976
ospf_top_dump(struct top_graph *f, struct proto *p)
1919 1977
{
1920
  unsigned int i;
1978
  uint i;
1921 1979
  OSPF_TRACE(D_EVENTS, "Hash entries: %d", f->hash_entries);
1922 1980

  
1923 1981
  for (i = 0; i < f->hash_size; i++)
......
1928 1986
  }
1929 1987
}
1930 1988
*/
1931

  
1932

  
1933

  
1934
#if 0
1935

  
1936
void
1937
update_rt_lsa(struct ospf_area *oa)
1938
{
1939
  struct ospf_proto *po = oa->po;
1940

  
1941
  if ((oa->rt) && ((oa->rt->inst_t + MINLSINTERVAL)) > now)
1942
    return;
1943

  
1944
  originate_rt_lsa(oa);
1945
  if (ospf_is_v3(p))
1946
    originate_prefix_rt_lsa(oa);
1947

  
1948
  schedule_rtcalc(p);
1949
  oa->origrt = 0;
1950
}
1951

  
1952

  
1953

  
1954

  
1955
static inline int
1956
check_sum2_net_lsa(struct top_hash_entry *en, struct fib_node *fn, u32 metric)
1957
{
1958
  struct ospf_lsa_sum2 *sum = en->lsa_body;
1959

  
1960
  if (fn->pxlen != ip4_masklen(sum->netmask))
1961
    return -1;
1962

  
1963
  return (en->lsa.sn != LSA_MAXSEQNO) && (sum->metric == metric);
1964
}
1965

  
1966
static inline int
1967
check_sum3_net_lsa(struct top_hash_entry *en, struct fib_node *fn, u32 metric)
1968
{
1969
  struct ospf_lsa_sum3_net *sum = en->lsa_body;
1970
  ip6_addr prefix;
1971
  int pxlen;
1972
  u8 pxopts;
1973
  u16 rest;
1974
  lsa_get_ipv6_prefix(sum->prefix, &prefix, &pxlen, &pxopts, &rest);
1975

  
1976

  
1977
  if ((fn->pxlen != pxlen) || !ip6_equal(fn->prefix, prefix))
1978
    return -1;
1979

  
1980
  return (en->lsa.sn != LSA_MAXSEQNO) && (sum->metric == metric);
1981
}
1982

  
1983

  
1984
static int
1985
check_sum_net_lsa(struct ospf_proto *po, struct top_hash_entry *en, struct fib_node *fn, u32 metric)
1986
{
1987
  int rv = ospf_is_v2(po) ?
1988
    check_sum2_net_lsa(en, fn, metric) :
1989
    check_sum3_net_lsa(en, fn, metric);
1990

  
1991
  if (rv < 0)
1992
    log(L_ERR "%s: LSAID collision for %I/%d", p->p.name, fn->prefix, fn->pxlen);
1993

  
1994
  return rv;
1995
}
1996

  
1997
static int
1998
check_sum_rt_lsa(struct ospf_proto *po, struct top_hash_entry *en, u32 drid, u32 metric, u32 options)
1999
{
2000
  if (en->lsa.sn == LSA_MAXSEQNO)
2001
    return 0;
2002

  
2003
  if (ospf_is_v2(po))
2004
  {
2005
    struct ospf_lsa_sum2 *sum = en->lsa_body;
2006
    return (sum->metric == metric);
2007
  }
2008
  else
2009
  {
2010
    struct ospf_lsa_sum3_rt *sum = en->lsa_body;
2011
    return (sum->options == options) && (sum->metric == metric) && (sum->drid == drid);
2012
  }
2013
}
2014

  
2015

  
2016

  
2017

  
2018

  
2019

  
2020

  
2021
  OSPF_TRACE(D_EVENTS, "Originating router-LSA for area %R", oa->areaid);
2022
  OSPF_TRACE(D_EVENTS, "Originating network-LSA for iface %s", ifa->ifname);
2023
  OSPF_TRACE(D_EVENTS, "Originating net-summary-LSA for %I/%d (metric %d)", fn->prefix, fn->pxlen, metric);
2024
  OSPF_TRACE(D_EVENTS, "Originating rt-summary-LSA for %R (metric %d)", rid, metric);
2025
  OSPF_TRACE(D_EVENTS, "Originating %s-LSA for %I/%d",
2026
	     nssa ? "NSSA" : "AS-external", fn->prefix, fn->pxlen);
2027
  OSPF_TRACE(D_EVENTS, "Originating link-LSA for iface %s", ifa->ifname);
2028
  OSPF_TRACE(D_EVENTS, "Originating router prefix-LSA for area %R", oa->areaid);
2029
  OSPF_TRACE(D_EVENTS, "Originating network prefix-LSA for iface %s", ifa->ifname);
2030

  
2031

  
2032
  en = ospf_hash_find(po->gr, lsa.dom, lsa.id, po->router_id, lsa.type);
2033
  if (en && check_ext_lsa(po, en, fn, metric, fwaddr, tag))
2034
    return;
2035

  
2036
  *length = sizeof(struct ospf_lsa_header) + po->lsab_used;
2037
  return lsab_flush(po);
2038

  
2039
  *length = po->lsab_used + sizeof(struct ospf_lsa_header);
2040
  return lsab_flush(po);
2041

  
2042
#endif

Also available in: Unified diff