Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsalib.c @ 1a61882d

History | View | Annotate | Download (11.2 KB)

1 f45fd316 Ondrej Filip
/*
2
 *        BIRD -- OSPF
3
 *
4 6f3203fa Ondrej Filip
 *        (c) 1999--2004 Ondrej Filip <feela@network.cz>
5 f45fd316 Ondrej Filip
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9
#include "ospf.h"
10
11 c45f48fb Ondrej Filip
void
12 b224ca32 Ondrej Filip
flush_lsa(struct top_hash_entry *en, struct ospf_area *oa)
13 c45f48fb Ondrej Filip
{
14 2e10a170 Ondrej Filip
  struct proto *p = &oa->po->proto;
15
  OSPF_TRACE(D_EVENTS,
16
             "Going to remove node Type: %u, Id: %I, Rt: %I, Age: %u",
17
             en->lsa.type, en->lsa.id, en->lsa.rt, en->lsa.age);
18 b224ca32 Ondrej Filip
  s_rem_node(SNODE en);
19 2e10a170 Ondrej Filip
  if (en->lsa_body != NULL)
20
    mb_free(en->lsa_body);
21
  en->lsa_body = NULL;
22
  ospf_hash_delete(oa->gr, en);
23 c45f48fb Ondrej Filip
}
24
25 e9ab0b42 Ondrej Filip
/**
26
 * ospf_age
27
 * @oa: ospf area
28
 *
29 baa5dd6c Ondrej Filip
 * This function is periodicaly invoked from area_disp(). It computes the new
30
 * age of all LSAs and old (@age is higher than %LSA_MAXAGE) LSAs are flushed
31
 * whenever possible. If an LSA originated by the router itself is older
32
 * than %LSREFRESHTIME a new instance is originated.
33 e9ab0b42 Ondrej Filip
 *
34 baa5dd6c Ondrej Filip
 * The RFC says that a router should check the checksum of every LSA to detect
35
 * hardware problems. BIRD does not do this to minimalize CPU utilization.
36 25a3f3da Ondrej Filip
 *
37 baa5dd6c Ondrej Filip
 * If routing table calculation is scheduled, it also invalidates the old routing
38 25a3f3da Ondrej Filip
 * table calculation results.
39 e9ab0b42 Ondrej Filip
 */
40 c45f48fb Ondrej Filip
void
41 d1660fd3 Ondrej Filip
ospf_age(struct ospf_area *oa)
42 c45f48fb Ondrej Filip
{
43 2e10a170 Ondrej Filip
  struct proto *p = &oa->po->proto;
44
  struct proto_ospf *po = (struct proto_ospf *) p;
45
  struct top_hash_entry *en, *nxt;
46
  int flush = can_flush_lsa(oa);
47 e02652a7 Ondrej Filip
  int cleanup = (oa->rt && (oa->rt->dist != LSINFINITY));
48 d1660fd3 Ondrej Filip
49 025b0e85 Ondrej Filip
  OSPF_TRACE(D_EVENTS, "Running ospf_age");
50
51 2e10a170 Ondrej Filip
  WALK_SLIST_DELSAFE(en, nxt, oa->lsal)
52 c45f48fb Ondrej Filip
  {
53 e02652a7 Ondrej Filip
    if (cleanup)
54 25a3f3da Ondrej Filip
    {
55 2e10a170 Ondrej Filip
      en->color = OUTSPF;
56
      en->dist = LSINFINITY;
57
      en->nhi = NULL;
58
      en->nh = ipa_from_u32(0);
59 25a3f3da Ondrej Filip
      DBG("Infinitying Type: %u, Id: %I, Rt: %I\n", en->lsa.type, en->lsa.id,
60 2e10a170 Ondrej Filip
          en->lsa.rt);
61 25a3f3da Ondrej Filip
    }
62 2e10a170 Ondrej Filip
    if (en->lsa.age == LSA_MAXAGE)
63 d1660fd3 Ondrej Filip
    {
64 2e10a170 Ondrej Filip
      if (flush)
65
        flush_lsa(en, oa);
66 2eac33f7 Ondrej Filip
      continue;
67 d1660fd3 Ondrej Filip
    }
68 2e10a170 Ondrej Filip
    if ((en->lsa.rt == p->cf->global->router_id) &&(en->lsa.age >=
69
                                                    LSREFRESHTIME))
70 d1660fd3 Ondrej Filip
    {
71 2e10a170 Ondrej Filip
      OSPF_TRACE(D_EVENTS, "Refreshing my LSA: Type: %u, Id: %I, Rt: %I",
72
                 en->lsa.type, en->lsa.id, en->lsa.rt);
73
      en->lsa.sn++;
74
      en->lsa.age = 0;
75
      en->inst_t = now;
76
      en->ini_age = 0;
77 d5d9693c Ondrej Filip
      lsasum_calculate(&en->lsa, en->lsa_body);
78 2e10a170 Ondrej Filip
      ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, oa, 1);
79
      continue;
80 d1660fd3 Ondrej Filip
    }
81 2e10a170 Ondrej Filip
    if ((en->lsa.age = (en->ini_age + (now - en->inst_t))) >= LSA_MAXAGE)
82 d1660fd3 Ondrej Filip
    {
83 2e10a170 Ondrej Filip
      if (flush)
84 dab66519 Ondrej Filip
      {
85 2e10a170 Ondrej Filip
        flush_lsa(en, oa);
86 b8f17cf1 Ondrej Filip
        schedule_rtcalc(po);
87 dab66519 Ondrej Filip
      }
88 2e10a170 Ondrej Filip
      else
89
        en->lsa.age = LSA_MAXAGE;
90 d1660fd3 Ondrej Filip
    }
91 c45f48fb Ondrej Filip
  }
92
}
93
94 f45fd316 Ondrej Filip
void
95
htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
96
{
97 2e10a170 Ondrej Filip
  n->age = htons(h->age);
98
  n->options = h->options;
99
  n->type = h->type;
100
  n->id = htonl(h->id);
101
  n->rt = htonl(h->rt);
102
  n->sn = htonl(h->sn);
103
  n->checksum = htons(h->checksum);
104
  n->length = htons(h->length);
105 f45fd316 Ondrej Filip
};
106
107
void
108
ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
109
{
110 2e10a170 Ondrej Filip
  h->age = ntohs(n->age);
111
  h->options = n->options;
112
  h->type = n->type;
113
  h->id = ntohl(n->id);
114
  h->rt = ntohl(n->rt);
115
  h->sn = ntohl(n->sn);
116
  h->checksum = ntohs(n->checksum);
117
  h->length = ntohs(n->length);
118 f45fd316 Ondrej Filip
};
119
120
void
121
htonlsab(void *h, void *n, u8 type, u16 len)
122
{
123
  unsigned int i;
124 2e10a170 Ondrej Filip
  switch (type)
125 f45fd316 Ondrej Filip
  {
126 2e10a170 Ondrej Filip
  case LSA_T_RT:
127 f45fd316 Ondrej Filip
    {
128
      struct ospf_lsa_rt *hrt, *nrt;
129 2e10a170 Ondrej Filip
      struct ospf_lsa_rt_link *hrtl, *nrtl;
130 499cb346 Ondrej Filip
      u16 links;
131 f45fd316 Ondrej Filip
132 2e10a170 Ondrej Filip
      nrt = n;
133
      hrt = h;
134
      links = hrt->links;
135 f45fd316 Ondrej Filip
136 2e10a170 Ondrej Filip
      nrt->veb.byte = hrt->veb.byte;
137
      nrt->padding = 0;
138
      nrt->links = htons(hrt->links);
139
      nrtl = (struct ospf_lsa_rt_link *) (nrt + 1);
140
      hrtl = (struct ospf_lsa_rt_link *) (hrt + 1);
141
      for (i = 0; i < links; i++)
142 f45fd316 Ondrej Filip
      {
143 2e10a170 Ondrej Filip
        (nrtl + i)->id = htonl((hrtl + i)->id);
144
        (nrtl + i)->data = htonl((hrtl + i)->data);
145
        (nrtl + i)->type = (hrtl + i)->type;
146
        (nrtl + i)->notos = (hrtl + i)->notos;
147
        (nrtl + i)->metric = htons((hrtl + i)->metric);
148 f45fd316 Ondrej Filip
      }
149
      break;
150
    }
151 2e10a170 Ondrej Filip
  case LSA_T_NET:
152 f45fd316 Ondrej Filip
    {
153 2e10a170 Ondrej Filip
      u32 *hid, *nid;
154 f45fd316 Ondrej Filip
155 2e10a170 Ondrej Filip
      nid = n;
156
      hid = h;
157 f45fd316 Ondrej Filip
158 2e10a170 Ondrej Filip
      for (i = 0; i < (len / sizeof(u32)); i++)
159 f45fd316 Ondrej Filip
      {
160 2e10a170 Ondrej Filip
        *(nid + i) = htonl(*(hid + i));
161 f45fd316 Ondrej Filip
      }
162
      break;
163
    }
164 2e10a170 Ondrej Filip
  case LSA_T_SUM_NET:
165
  case LSA_T_SUM_RT:
166 f45fd316 Ondrej Filip
    {
167
      struct ospf_lsa_summ *hs, *ns;
168
      struct ospf_lsa_summ_net *hn, *nn;
169
170 2e10a170 Ondrej Filip
      hs = h;
171
      ns = n;
172 f45fd316 Ondrej Filip
173 2e10a170 Ondrej Filip
      ns->netmask = hs->netmask;
174 2aa476a5 Ondrej Filip
      ipa_hton(ns->netmask);
175 f45fd316 Ondrej Filip
176 2e10a170 Ondrej Filip
      hn = (struct ospf_lsa_summ_net *) (hs + 1);
177
      nn = (struct ospf_lsa_summ_net *) (ns + 1);
178 f45fd316 Ondrej Filip
179 2e10a170 Ondrej Filip
      for (i = 0; i < ((len - sizeof(struct ospf_lsa_summ)) /
180
                       sizeof(struct ospf_lsa_summ_net)); i++)
181 f45fd316 Ondrej Filip
      {
182 2e10a170 Ondrej Filip
        (nn + i)->tos = (hn + i)->tos;
183
        (nn + i)->metric = htons((hn + i)->metric);
184
        (nn + i)->padding = 0;
185 f45fd316 Ondrej Filip
      }
186
      break;
187
    }
188 2e10a170 Ondrej Filip
  case LSA_T_EXT:
189 f45fd316 Ondrej Filip
    {
190
      struct ospf_lsa_ext *he, *ne;
191
      struct ospf_lsa_ext_tos *ht, *nt;
192
193 2e10a170 Ondrej Filip
      he = h;
194
      ne = n;
195 f45fd316 Ondrej Filip
196 2e10a170 Ondrej Filip
      ne->netmask = he->netmask;
197 2aa476a5 Ondrej Filip
      ipa_hton(ne->netmask);
198 f45fd316 Ondrej Filip
199 2e10a170 Ondrej Filip
      ht = (struct ospf_lsa_ext_tos *) (he + 1);
200
      nt = (struct ospf_lsa_ext_tos *) (ne + 1);
201 f45fd316 Ondrej Filip
202 2e10a170 Ondrej Filip
      for (i = 0; i < ((len - sizeof(struct ospf_lsa_ext)) /
203
                       sizeof(struct ospf_lsa_ext_tos)); i++)
204 f45fd316 Ondrej Filip
      {
205 2e10a170 Ondrej Filip
        (nt + i)->etos = (ht + i)->etos;
206
        (nt + i)->padding = 0;
207
        (nt + i)->metric = htons((ht + i)->metric);
208
        (nt + i)->fwaddr = (ht + i)->fwaddr;
209
        ipa_hton((nt + i)->fwaddr);
210
        (nt + i)->tag = htonl((ht + i)->tag);
211 f45fd316 Ondrej Filip
      }
212
      break;
213
    }
214 2e10a170 Ondrej Filip
  default:
215
    bug("(hton): Unknown LSA");
216 f45fd316 Ondrej Filip
  }
217
};
218
219
void
220
ntohlsab(void *n, void *h, u8 type, u16 len)
221
{
222
  unsigned int i;
223 2e10a170 Ondrej Filip
  switch (type)
224 f45fd316 Ondrej Filip
  {
225 2e10a170 Ondrej Filip
  case LSA_T_RT:
226 f45fd316 Ondrej Filip
    {
227
      struct ospf_lsa_rt *hrt, *nrt;
228 2e10a170 Ondrej Filip
      struct ospf_lsa_rt_link *hrtl, *nrtl;
229 499cb346 Ondrej Filip
      u16 links;
230 f45fd316 Ondrej Filip
231 2e10a170 Ondrej Filip
      nrt = n;
232
      hrt = h;
233 f45fd316 Ondrej Filip
234 2e10a170 Ondrej Filip
      hrt->veb.byte = nrt->veb.byte;
235
      hrt->padding = 0;
236
      links = hrt->links = ntohs(nrt->links);
237
      nrtl = (struct ospf_lsa_rt_link *) (nrt + 1);
238
      hrtl = (struct ospf_lsa_rt_link *) (hrt + 1);
239
      for (i = 0; i < links; i++)
240 f45fd316 Ondrej Filip
      {
241 2e10a170 Ondrej Filip
        (hrtl + i)->id = ntohl((nrtl + i)->id);
242
        (hrtl + i)->data = ntohl((nrtl + i)->data);
243
        (hrtl + i)->type = (nrtl + i)->type;
244
        (hrtl + i)->notos = (nrtl + i)->notos;
245
        (hrtl + i)->metric = ntohs((nrtl + i)->metric);
246 f45fd316 Ondrej Filip
      }
247
      break;
248
    }
249 2e10a170 Ondrej Filip
  case LSA_T_NET:
250 f45fd316 Ondrej Filip
    {
251 2e10a170 Ondrej Filip
      u32 *hid, *nid;
252 f45fd316 Ondrej Filip
253 2e10a170 Ondrej Filip
      hid = h;
254
      nid = n;
255 f45fd316 Ondrej Filip
256 2e10a170 Ondrej Filip
      for (i = 0; i < (len / sizeof(u32)); i++)
257 f45fd316 Ondrej Filip
      {
258 2e10a170 Ondrej Filip
        *(hid + i) = ntohl(*(nid + i));
259 f45fd316 Ondrej Filip
      }
260
      break;
261
    }
262 2e10a170 Ondrej Filip
  case LSA_T_SUM_NET:
263
  case LSA_T_SUM_RT:
264 f45fd316 Ondrej Filip
    {
265
      struct ospf_lsa_summ *hs, *ns;
266
      struct ospf_lsa_summ_net *hn, *nn;
267
268 2e10a170 Ondrej Filip
      hs = h;
269
      ns = n;
270 f45fd316 Ondrej Filip
271 2e10a170 Ondrej Filip
      hs->netmask = ns->netmask;
272 2aa476a5 Ondrej Filip
      ipa_ntoh(hs->netmask);
273 f45fd316 Ondrej Filip
274 2e10a170 Ondrej Filip
      hn = (struct ospf_lsa_summ_net *) (hs + 1);
275
      nn = (struct ospf_lsa_summ_net *) (ns + 1);
276 f45fd316 Ondrej Filip
277 2e10a170 Ondrej Filip
      for (i = 0; i < ((len - sizeof(struct ospf_lsa_summ)) /
278
                       sizeof(struct ospf_lsa_summ_net)); i++)
279 f45fd316 Ondrej Filip
      {
280 2e10a170 Ondrej Filip
        (hn + i)->tos = (nn + i)->tos;
281
        (hn + i)->metric = ntohs((nn + i)->metric);
282
        (hn + i)->padding = 0;
283 f45fd316 Ondrej Filip
      }
284
      break;
285
    }
286 2e10a170 Ondrej Filip
  case LSA_T_EXT:
287 f45fd316 Ondrej Filip
    {
288
      struct ospf_lsa_ext *he, *ne;
289
      struct ospf_lsa_ext_tos *ht, *nt;
290
291 2e10a170 Ondrej Filip
      he = h;
292
      ne = n;
293 f45fd316 Ondrej Filip
294 2e10a170 Ondrej Filip
      he->netmask = ne->netmask;
295 2aa476a5 Ondrej Filip
      ipa_ntoh(he->netmask);
296 f45fd316 Ondrej Filip
297 2e10a170 Ondrej Filip
      ht = (struct ospf_lsa_ext_tos *) (he + 1);
298
      nt = (struct ospf_lsa_ext_tos *) (ne + 1);
299 f45fd316 Ondrej Filip
300 2e10a170 Ondrej Filip
      for (i = 0; i < ((len - sizeof(struct ospf_lsa_ext)) /
301
                       sizeof(struct ospf_lsa_ext_tos)); i++)
302 f45fd316 Ondrej Filip
      {
303 2e10a170 Ondrej Filip
        (ht + i)->etos = (nt + i)->etos;
304
        (ht + i)->padding = 0;
305
        (ht + i)->metric = ntohs((nt + i)->metric);
306
        (ht + i)->fwaddr = (nt + i)->fwaddr;
307
        ipa_ntoh((ht + i)->fwaddr);
308
        (ht + i)->tag = ntohl((nt + i)->tag);
309 f45fd316 Ondrej Filip
      }
310
      break;
311
    }
312 2e10a170 Ondrej Filip
  default:
313
    bug("(ntoh): Unknown LSA");
314 f45fd316 Ondrej Filip
  }
315
};
316
317 499cb346 Ondrej Filip
#define MODX 4102                /* larges signed value without overflow */
318
319
/* Fletcher Checksum -- Refer to RFC1008. */
320
#define MODX                 4102
321
#define LSA_CHECKSUM_OFFSET    15
322
323
/* FIXME This is VERY uneficient, I have huge endianity problems */
324
void
325 d5d9693c Ondrej Filip
lsasum_calculate(struct ospf_lsa_header *h, void *body)
326 499cb346 Ondrej Filip
{
327 394acced Ondrej Filip
  u16 length;
328
329 2e10a170 Ondrej Filip
  length = h->length;
330
331
  htonlsah(h, h);
332
  htonlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
333 394acced Ondrej Filip
334 d5d9693c Ondrej Filip
  (void) lsasum_check(h, body);
335 2e10a170 Ondrej Filip
336
  ntohlsah(h, h);
337
  ntohlsab(body, body, h->type, length - sizeof(struct ospf_lsa_header));
338 394acced Ondrej Filip
}
339
340
/*
341
 * Note, that this function expects that LSA is in big endianity
342
 * It also returns value in big endian
343
 */
344
u16
345 d5d9693c Ondrej Filip
lsasum_check(struct ospf_lsa_header *h, void *body)
346 394acced Ondrej Filip
{
347 499cb346 Ondrej Filip
  u8 *sp, *ep, *p, *q, *b;
348
  int c0 = 0, c1 = 0;
349
  int x, y;
350 c11007bc Ondrej Filip
  u16 length;
351 499cb346 Ondrej Filip
352 c11007bc Ondrej Filip
  b = body;
353 499cb346 Ondrej Filip
  sp = (char *) &h->options;
354 2e10a170 Ondrej Filip
  length = ntohs(h->length) - 2;
355 394acced Ondrej Filip
  h->checksum = 0;
356 499cb346 Ondrej Filip
357
  for (ep = sp + length; sp < ep; sp = q)
358 2e10a170 Ondrej Filip
  {                                /* Actually MODX is very large, do we need the for-cyclus? */
359 394acced Ondrej Filip
    q = sp + MODX;
360 2e10a170 Ondrej Filip
    if (q > ep)
361
      q = ep;
362 394acced Ondrej Filip
    for (p = sp; p < q; p++)
363 499cb346 Ondrej Filip
    {
364 394acced Ondrej Filip
      /* 
365
       * I count with bytes from header and than from body
366
       * but if there is no body, it's appended to header
367
       * (probably checksum in update receiving) and I go on
368
       * after header
369
       */
370 2e10a170 Ondrej Filip
      if ((b == NULL) || (p < (u8 *) (h + 1)))
371 394acced Ondrej Filip
      {
372 2e10a170 Ondrej Filip
        c0 += *p;
373 394acced Ondrej Filip
      }
374
      else
375
      {
376 2e10a170 Ondrej Filip
        c0 += *(b + (p - sp) - sizeof(struct ospf_lsa_header) + 2);
377 394acced Ondrej Filip
      }
378
379
      c1 += c0;
380 499cb346 Ondrej Filip
    }
381 394acced Ondrej Filip
    c0 %= 255;
382
    c1 %= 255;
383
  }
384 499cb346 Ondrej Filip
385
  x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
386 2e10a170 Ondrej Filip
  if (x <= 0)
387
    x += 255;
388 499cb346 Ondrej Filip
  y = 510 - c0 - x;
389 2e10a170 Ondrej Filip
  if (y > 255)
390
    y -= 255;
391 499cb346 Ondrej Filip
392 2e10a170 Ondrej Filip
  ((u8 *) & h->checksum)[0] = x;
393
  ((u8 *) & h->checksum)[1] = y;
394 c11007bc Ondrej Filip
  return h->checksum;
395 499cb346 Ondrej Filip
}
396
397 db9fb727 Ondrej Filip
int
398
lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
399 394acced Ondrej Filip
                        /* Return codes from point of view of l1 */
400 db9fb727 Ondrej Filip
{
401 2e10a170 Ondrej Filip
  u32 sn1, sn2;
402 37282678 Ondrej Filip
403 2e10a170 Ondrej Filip
  sn1 = l1->sn - LSA_INITSEQNO + 1;
404
  sn2 = l2->sn - LSA_INITSEQNO + 1;
405 37282678 Ondrej Filip
406 2e10a170 Ondrej Filip
  if (sn1 > sn2)
407
    return CMP_NEWER;
408
  if (sn1 < sn2)
409
    return CMP_OLDER;
410 ef6f26b4 Ondrej Filip
411 2e10a170 Ondrej Filip
  if (l1->checksum != l2->checksum)
412
    return l1->checksum < l2->checksum ? CMP_OLDER : CMP_NEWER;
413 ef6f26b4 Ondrej Filip
414 2e10a170 Ondrej Filip
  if ((l1->age == LSA_MAXAGE) && (l2->age != LSA_MAXAGE))
415
    return CMP_NEWER;
416
  if ((l2->age == LSA_MAXAGE) && (l1->age != LSA_MAXAGE))
417
    return CMP_OLDER;
418 ef6f26b4 Ondrej Filip
419 2e10a170 Ondrej Filip
  if (ABS(l1->age - l2->age) > LSA_MAXAGEDIFF)
420
    return l1->age < l2->age ? CMP_NEWER : CMP_OLDER;
421 ef6f26b4 Ondrej Filip
422
  return CMP_SAME;
423 db9fb727 Ondrej Filip
}
424
425 e9ab0b42 Ondrej Filip
/**
426
 * lsa_install_new - install new LSA into database
427
 * @lsa: LSA header
428 6567e6cf Martin Mares
 * @body: pointer to LSA body
429 e9ab0b42 Ondrej Filip
 * @oa: current ospf_area
430
 *
431
 * This function ensures installing new LSA into LSA database. Old instance is
432 4ca0d084 Ondrej Filip
 * replaced. Several actions are taken to detect if new routing table
433 e9ab0b42 Ondrej Filip
 * calculation is necessary. This is described in 13.2 of RFC 2328.
434
 */
435 d8852b36 Ondrej Filip
struct top_hash_entry *
436 e9ab0b42 Ondrej Filip
lsa_install_new(struct ospf_lsa_header *lsa, void *body, struct ospf_area *oa)
437 d8852b36 Ondrej Filip
{
438 39e517d4 Ondrej Filip
  /* LSA can be temporarrily, but body must be mb_allocated. */
439 2e10a170 Ondrej Filip
  int change = 0;
440 85195f1a Ondrej Filip
  unsigned i;
441 d8852b36 Ondrej Filip
  struct top_hash_entry *en;
442 b8f17cf1 Ondrej Filip
  struct proto_ospf *po = oa->po;
443 d8852b36 Ondrej Filip
444 2e10a170 Ondrej Filip
  if ((en = ospf_hash_find_header(oa->gr, lsa)) == NULL)
445 d8852b36 Ondrej Filip
  {
446 2e10a170 Ondrej Filip
    en = ospf_hash_get_header(oa->gr, lsa);
447
    change = 1;
448 d8852b36 Ondrej Filip
  }
449
  else
450
  {
451 2e10a170 Ondrej Filip
    if ((en->lsa.length != lsa->length) || (en->lsa.options != lsa->options)
452
        || ((en->lsa.age == LSA_MAXAGE) || (lsa->age == LSA_MAXAGE)))
453
      change = 1;
454 d8852b36 Ondrej Filip
    else
455
    {
456 2e10a170 Ondrej Filip
      u8 *k = en->lsa_body, *l = body;
457
      for (i = 0; i < (lsa->length - sizeof(struct ospf_lsa_header)); i++)
458 d8852b36 Ondrej Filip
      {
459 2e10a170 Ondrej Filip
        if (*(k + i) != *(l + i))
460 d8852b36 Ondrej Filip
        {
461 2e10a170 Ondrej Filip
          change = 1;
462 d8852b36 Ondrej Filip
          break;
463
        }
464
      }
465 85195f1a Ondrej Filip
    }
466 273fd2c1 Ondrej Filip
    s_rem_node(SNODE en);
467 85195f1a Ondrej Filip
  }
468
469 273fd2c1 Ondrej Filip
  DBG("Inst lsa: Id: %I, Rt: %I, Type: %u, Age: %u, Sum: %u, Sn: 0x%x\n",
470 2e10a170 Ondrej Filip
      lsa->id, lsa->rt, lsa->type, lsa->age, lsa->checksum, lsa->sn);
471 273fd2c1 Ondrej Filip
472 dab66519 Ondrej Filip
  s_add_tail(&oa->lsal, SNODE en);
473 2e10a170 Ondrej Filip
  en->inst_t = now;
474
  if (en->lsa_body != NULL)
475
    mb_free(en->lsa_body);
476
  en->lsa_body = body;
477
  memcpy(&en->lsa, lsa, sizeof(struct ospf_lsa_header));
478
  en->ini_age = en->lsa.age;
479
480
  if (change)
481 85195f1a Ondrej Filip
  {
482 b8f17cf1 Ondrej Filip
    schedule_rtcalc(po);
483 d8852b36 Ondrej Filip
  }
484 2e10a170 Ondrej Filip
485 d8852b36 Ondrej Filip
  return en;
486
}