Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsalib.c @ 8e433d6a

History | View | Annotate | Download (13.3 KB)

1
/*
2
 *        BIRD -- OSPF
3
 *
4
 *        (c) 1999--2004 Ondrej Filip <feela@network.cz>
5
 *        (c) 2009--2015 Ondrej Zajicek <santiago@crfreenet.org>
6
 *        (c) 2009--2015 CZ.NIC z.s.p.o.
7
 *
8
 *        Can be freely distributed and used under the terms of the GNU GPL.
9
 */
10

    
11
#include "ospf.h"
12

    
13
#include "lib/fletcher16.h"
14

    
15
#ifndef CPU_BIG_ENDIAN
16
void
17
lsa_hton_hdr(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
18
{
19
  n->age = htons(h->age);
20
  n->type_raw = htons(h->type_raw);
21
  n->id = htonl(h->id);
22
  n->rt = htonl(h->rt);
23
  n->sn = htonl(h->sn);
24
  n->checksum = htons(h->checksum);
25
  n->length = htons(h->length);
26
}
27

    
28
void
29
lsa_ntoh_hdr(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
30
{
31
  h->age = ntohs(n->age);
32
  h->type_raw = ntohs(n->type_raw);
33
  h->id = ntohl(n->id);
34
  h->rt = ntohl(n->rt);
35
  h->sn = ntohl(n->sn);
36
  h->checksum = ntohs(n->checksum);
37
  h->length = ntohs(n->length);
38
}
39

    
40
void
41
lsa_hton_body(void *h, void *n, u16 len)
42
{
43
  u32 *hid = h;
44
  u32 *nid = n;
45
  uint i;
46

    
47
  for (i = 0; i < (len / sizeof(u32)); i++)
48
    nid[i] = htonl(hid[i]);
49
}
50

    
51
void
52
lsa_ntoh_body(void *n, void *h, u16 len)
53
{
54
  u32 *nid = n;
55
  u32 *hid = h;
56
  uint i;
57

    
58
  for (i = 0; i < (len / sizeof(u32)); i++)
59
    hid[i] = ntohl(nid[i]);
60
}
61
#endif /* little endian */
62

    
63

    
64

    
65
int
66
lsa_flooding_allowed(u32 type, u32 domain, struct ospf_iface *ifa)
67
{
68
  /* Handle inactive vlinks */
69
  if (ifa->state == OSPF_IS_DOWN)
70
    return 0;
71

    
72
  /* 4.5.2 (Case 2) */
73
  switch (LSA_SCOPE(type))
74
  {
75
  case LSA_SCOPE_LINK:
76
    return ifa->iface_id == domain;
77

    
78
  case LSA_SCOPE_AREA:
79
    return ifa->oa->areaid == domain;
80

    
81
  case LSA_SCOPE_AS:
82
    if (ifa->type == OSPF_IT_VLINK)
83
      return 0;
84
    if (!oa_is_ext(ifa->oa))
85
      return 0;
86
    return 1;
87

    
88
  default:
89
    log(L_ERR "OSPF: LSA with invalid scope");
90
    return 0;
91
  }
92
}
93

    
94

    
95
static int
96
unknown_lsa_type(u32 type)
97
{
98
  switch (type)
99
  {
100
  case LSA_T_RT:
101
  case LSA_T_NET:
102
  case LSA_T_SUM_NET:
103
  case LSA_T_SUM_RT:
104
  case LSA_T_EXT:
105
  case LSA_T_NSSA:
106
  case LSA_T_LINK:
107
  case LSA_T_PREFIX:
108
    return 0;
109

    
110
  default:
111
    return 1;
112
  }
113
}
114

    
115
#define LSA_V2_TMAX 8
116
static const u16 lsa_v2_types[LSA_V2_TMAX] =
117
  {0, LSA_T_RT, LSA_T_NET, LSA_T_SUM_NET, LSA_T_SUM_RT, LSA_T_EXT, 0, LSA_T_NSSA};
118

    
119
void
120
lsa_get_type_domain_(u32 itype, struct ospf_iface *ifa, u32 *otype, u32 *domain)
121
{
122
  if (ospf_is_v2(ifa->oa->po))
123
  {
124
    itype = itype & LSA_T_V2_MASK;
125
    itype = (itype < LSA_V2_TMAX) ? lsa_v2_types[itype] : 0;
126
  }
127
  else
128
  {
129
    /* For unkown LSAs without U-bit change scope to LSA_SCOPE_LINK */
130
    if (unknown_lsa_type(itype) && !(itype & LSA_UBIT))
131
      itype = itype & ~LSA_SCOPE_MASK;
132
  }
133

    
134
  *otype = itype;
135

    
136
  switch (LSA_SCOPE(itype))
137
  {
138
  case LSA_SCOPE_LINK:
139
    *domain = ifa->iface_id;
140
    return;
141

    
142
  case LSA_SCOPE_AREA:
143
    *domain = ifa->oa->areaid;
144
    return;
145

    
146
  case LSA_SCOPE_AS:
147
  default:
148
    *domain = 0;
149
    return;
150
  }
151
}
152

    
153

    
154
void
155
lsa_generate_checksum(struct ospf_lsa_header *lsa, const u8 *body)
156
{
157
  struct fletcher16_context ctx;
158
  struct ospf_lsa_header hdr;
159
  u16 len = lsa->length;
160

    
161
  /*
162
   * lsa and body are in the host order, we need to compute Fletcher-16 checksum
163
   * for data in the network order. We also skip the initial age field.
164
   */
165

    
166
  lsa_hton_hdr(lsa, &hdr);
167
  hdr.checksum = 0;
168

    
169
  fletcher16_init(&ctx);
170
  fletcher16_update(&ctx, (u8 *) &hdr + 2, sizeof(struct ospf_lsa_header) - 2);
171
  fletcher16_update_n32(&ctx, body, len - sizeof(struct ospf_lsa_header));
172
  lsa->checksum = fletcher16_final(&ctx, len, OFFSETOF(struct ospf_lsa_header, checksum));
173
}
174

    
175
u16
176
lsa_verify_checksum(const void *lsa_n, int lsa_len)
177
{
178
  struct fletcher16_context ctx;
179

    
180
  /* The whole LSA is at lsa_n in net order, we just skip initial age field */
181

    
182
  fletcher16_init(&ctx);
183
  fletcher16_update(&ctx, (u8 *) lsa_n + 2, lsa_len - 2);
184

    
185
  return fletcher16_compute(&ctx) == 0;
186
}
187

    
188

    
189
int
190
lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
191
                        /* Return codes from point of view of l1 */
192
{
193
  u32 sn1, sn2;
194

    
195
  sn1 = l1->sn - LSA_INITSEQNO + 1;
196
  sn2 = l2->sn - LSA_INITSEQNO + 1;
197

    
198
  if (sn1 > sn2)
199
    return CMP_NEWER;
200
  if (sn1 < sn2)
201
    return CMP_OLDER;
202

    
203
  if (l1->checksum != l2->checksum)
204
    return l1->checksum < l2->checksum ? CMP_OLDER : CMP_NEWER;
205

    
206
  if ((l1->age == LSA_MAXAGE) && (l2->age != LSA_MAXAGE))
207
    return CMP_NEWER;
208
  if ((l2->age == LSA_MAXAGE) && (l1->age != LSA_MAXAGE))
209
    return CMP_OLDER;
210

    
211
  if (ABS(l1->age - l2->age) > LSA_MAXAGEDIFF)
212
    return l1->age < l2->age ? CMP_NEWER : CMP_OLDER;
213

    
214
  return CMP_SAME;
215
}
216

    
217

    
218
static inline int
219
lsa_walk_rt2(struct ospf_lsa_rt_walk *rt)
220
{
221
  if (rt->buf >= rt->bufend)
222
    return 0;
223

    
224
  struct ospf_lsa_rt2_link *l = rt->buf;
225
  rt->buf += sizeof(struct ospf_lsa_rt2_link) + l->no_tos * sizeof(struct ospf_lsa_rt2_tos);
226

    
227
  rt->type = l->type;
228
  rt->metric = l->metric;
229
  rt->id = l->id;
230
  rt->data = l->data;
231
  return 1;
232
}
233

    
234
static inline int
235
lsa_walk_rt3(struct ospf_lsa_rt_walk *rt)
236
{
237
  while (rt->buf >= rt->bufend)
238
  {
239
    rt->en = ospf_hash_find_rt3_next(rt->en);
240
    if (!rt->en)
241
      return 0;
242

    
243
    rt->buf = rt->en->lsa_body;
244
    rt->bufend = rt->buf + rt->en->lsa.length - sizeof(struct ospf_lsa_header);
245
    rt->buf += sizeof(struct ospf_lsa_rt);
246
  }
247

    
248
  struct ospf_lsa_rt3_link *l = rt->buf;
249
  rt->buf += sizeof(struct ospf_lsa_rt3_link);
250

    
251
  rt->type = l->type;
252
  rt->metric = l->metric;
253
  rt->lif = l->lif;
254
  rt->nif = l->nif;
255
  rt->id = l->id;
256
  return 1;
257
}
258

    
259
void
260
lsa_walk_rt_init(struct ospf_proto *p, struct top_hash_entry *act, struct ospf_lsa_rt_walk *rt)
261
{
262
  rt->ospf2 = ospf_is_v2(p);
263
  rt->id = rt->data = rt->lif = rt->nif = 0;
264

    
265
  if (rt->ospf2)
266
    rt->en = act;
267
  else
268
    rt->en = ospf_hash_find_rt3_first(p->gr, act->domain, act->lsa.rt);
269

    
270
  rt->buf = rt->en->lsa_body;
271
  rt->bufend = rt->buf + rt->en->lsa.length - sizeof(struct ospf_lsa_header);
272
  rt->buf += sizeof(struct ospf_lsa_rt);
273
}
274

    
275
int
276
lsa_walk_rt(struct ospf_lsa_rt_walk *rt)
277
{
278
  return rt->ospf2 ? lsa_walk_rt2(rt) : lsa_walk_rt3(rt);
279
}
280

    
281

    
282
void
283
lsa_parse_sum_net(struct top_hash_entry *en, int ospf2, ip_addr *ip, int *pxlen, u8 *pxopts, u32 *metric)
284
{
285
  if (ospf2)
286
  {
287
    struct ospf_lsa_sum2 *ls = en->lsa_body;
288
    *ip = ipa_from_u32(en->lsa.id & ls->netmask);
289
    *pxlen = u32_masklen(ls->netmask);
290
    *pxopts = 0;
291
    *metric = ls->metric & LSA_METRIC_MASK;
292
  }
293
  else
294
  {
295
    struct ospf_lsa_sum3_net *ls = en->lsa_body;
296
    u16 rest;
297
    lsa_get_ipv6_prefix(ls->prefix, ip, pxlen, pxopts, &rest);
298
    *metric = ls->metric & LSA_METRIC_MASK;
299
  }
300
}
301

    
302
void
303
lsa_parse_sum_rt(struct top_hash_entry *en, int ospf2, u32 *drid, u32 *metric, u32 *options)
304
{
305
  if (ospf2)
306
  {
307
    struct ospf_lsa_sum2 *ls = en->lsa_body;
308
    *drid = en->lsa.id;
309
    *metric = ls->metric & LSA_METRIC_MASK;
310
    *options = 0;
311
  }
312
  else
313
  {
314
    struct ospf_lsa_sum3_rt *ls = en->lsa_body;
315
    *drid = ls->drid;
316
    *metric = ls->metric & LSA_METRIC_MASK;
317
    *options = ls->options & LSA_OPTIONS_MASK;
318
  }
319
}
320

    
321
void
322
lsa_parse_ext(struct top_hash_entry *en, int ospf2, struct ospf_lsa_ext_local *rt)
323
{
324
  if (ospf2)
325
  {
326
    struct ospf_lsa_ext2 *ext = en->lsa_body;
327
    rt->ip = ipa_from_u32(en->lsa.id & ext->netmask);
328
    rt->pxlen = u32_masklen(ext->netmask);
329
    rt->pxopts = 0;
330
    rt->metric = ext->metric & LSA_METRIC_MASK;
331
    rt->ebit = ext->metric & LSA_EXT2_EBIT;
332

    
333
    rt->fbit = ext->fwaddr;
334
    rt->fwaddr = ipa_from_u32(ext->fwaddr);
335

    
336
    rt->tag = ext->tag;
337
    rt->propagate = lsa_get_options(&en->lsa) & OPT_P;
338
  }
339
  else
340
  {
341
    struct ospf_lsa_ext3 *ext = en->lsa_body;
342
    u16 rest;
343
    u32 *buf = lsa_get_ipv6_prefix(ext->rest, &rt->ip, &rt->pxlen, &rt->pxopts, &rest);
344
    rt->metric = ext->metric & LSA_METRIC_MASK;
345
    rt->ebit = ext->metric & LSA_EXT3_EBIT;
346

    
347
    rt->fbit = ext->metric & LSA_EXT3_FBIT;
348
    if (rt->fbit)
349
      buf = lsa_get_ipv6_addr(buf, &rt->fwaddr);
350
    else
351
      rt->fwaddr = IPA_NONE;
352

    
353
    rt->tag = (ext->metric & LSA_EXT3_TBIT) ? *buf++ : 0;
354
    rt->propagate = rt->pxopts & OPT_PX_P;
355
  }
356
}
357

    
358
#define HDRLEN sizeof(struct ospf_lsa_header)
359

    
360
static int
361
lsa_validate_rt2(struct ospf_lsa_header *lsa, struct ospf_lsa_rt *body)
362
{
363
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_rt)))
364
    return 0;
365

    
366
  uint i = 0;
367
  void *buf = body;
368
  void *bufend = buf + lsa->length - HDRLEN;
369
  buf += sizeof(struct ospf_lsa_rt);
370

    
371
  while (buf < bufend)
372
  {
373
    struct ospf_lsa_rt2_link *l = buf;
374
    buf += sizeof(struct ospf_lsa_rt2_link) + l->no_tos * sizeof(struct ospf_lsa_rt2_tos);
375
    i++;
376

    
377
    if (buf > bufend)
378
      return 0;
379

    
380
    if (!((l->type == LSART_PTP) ||
381
          (l->type == LSART_NET) ||
382
          (l->type == LSART_STUB) ||
383
          (l->type == LSART_VLNK)))
384
      return 0;
385
  }
386

    
387
  if ((body->options & LSA_RT2_LINKS) != i)
388
    return 0;
389

    
390
  return 1;
391
}
392

    
393

    
394
static int
395
lsa_validate_rt3(struct ospf_lsa_header *lsa, struct ospf_lsa_rt *body)
396
{
397
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_rt)))
398
    return 0;
399

    
400
  void *buf = body;
401
  void *bufend = buf + lsa->length - HDRLEN;
402
  buf += sizeof(struct ospf_lsa_rt);
403

    
404
  while (buf < bufend)
405
  {
406
    struct ospf_lsa_rt3_link *l = buf;
407
    buf += sizeof(struct ospf_lsa_rt3_link);
408

    
409
    if (buf > bufend)
410
      return 0;
411

    
412
    if (!((l->type == LSART_PTP) ||
413
          (l->type == LSART_NET) ||
414
          (l->type == LSART_VLNK)))
415
      return 0;
416
  }
417
  return 1;
418
}
419

    
420
static int
421
lsa_validate_net(struct ospf_lsa_header *lsa, struct ospf_lsa_net *body UNUSED)
422
{
423
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_net)))
424
    return 0;
425

    
426
  return 1;
427
}
428

    
429
static int
430
lsa_validate_sum2(struct ospf_lsa_header *lsa, struct ospf_lsa_sum2 *body)
431
{
432
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_sum2)))
433
    return 0;
434

    
435
  /* First field should have TOS = 0, we ignore other TOS fields */
436
  if ((body->metric & LSA_SUM2_TOS) != 0)
437
    return 0;
438

    
439
  return 1;
440
}
441

    
442
static inline int
443
pxlen(u32 *buf)
444
{
445
  return *buf >> 24;
446
}
447

    
448
static int
449
lsa_validate_sum3_net(struct ospf_lsa_header *lsa, struct ospf_lsa_sum3_net *body)
450
{
451
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_sum3_net) + 4))
452
    return 0;
453

    
454
  u8 pxl = pxlen(body->prefix);
455
  if (pxl > MAX_PREFIX_LENGTH)
456
    return 0;
457

    
458
  if (lsa->length != (HDRLEN + sizeof(struct ospf_lsa_sum3_net) +
459
                      IPV6_PREFIX_SPACE(pxl)))
460
    return 0;
461

    
462
  return 1;
463
}
464

    
465
static int
466
lsa_validate_sum3_rt(struct ospf_lsa_header *lsa, struct ospf_lsa_sum3_rt *body)
467
{
468
  if (lsa->length != (HDRLEN + sizeof(struct ospf_lsa_sum3_rt)))
469
    return 0;
470

    
471
  return 1;
472
}
473

    
474
static int
475
lsa_validate_ext2(struct ospf_lsa_header *lsa, struct ospf_lsa_ext2 *body)
476
{
477
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_ext2)))
478
    return 0;
479

    
480
  /* First field should have TOS = 0, we ignore other TOS fields */
481
  if ((body->metric & LSA_EXT2_TOS) != 0)
482
    return 0;
483

    
484
  return 1;
485
}
486

    
487
static int
488
lsa_validate_ext3(struct ospf_lsa_header *lsa, struct ospf_lsa_ext3 *body)
489
{
490
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_ext3) + 4))
491
    return 0;
492

    
493
  u8 pxl = pxlen(body->rest);
494
  if (pxl > MAX_PREFIX_LENGTH)
495
    return 0;
496

    
497
  int len = IPV6_PREFIX_SPACE(pxl);
498
  if (body->metric & LSA_EXT3_FBIT) // forwardinf address
499
    len += 16;
500
  if (body->metric & LSA_EXT3_TBIT) // route tag
501
    len += 4;
502
  if (*body->rest & 0xFFFF) // referenced LS type field
503
    len += 4;
504

    
505
  if (lsa->length != (HDRLEN + sizeof(struct ospf_lsa_ext3) + len))
506
    return 0;
507

    
508
  return 1;
509
}
510

    
511
static int
512
lsa_validate_pxlist(struct ospf_lsa_header *lsa, u32 pxcount, uint offset, u8 *pbuf)
513
{
514
  uint bound = lsa->length - HDRLEN - 4;
515
  u32 i;
516

    
517
  for (i = 0; i < pxcount; i++)
518
    {
519
      if (offset > bound)
520
        return 0;
521

    
522
      u8 pxl = pxlen((u32 *) (pbuf + offset));
523
      if (pxl > MAX_PREFIX_LENGTH)
524
        return 0;
525

    
526
      offset += IPV6_PREFIX_SPACE(pxl);
527
    }
528

    
529
  if (lsa->length != (HDRLEN + offset))
530
    return 0;
531

    
532
  return 1;
533
}
534

    
535
static int
536
lsa_validate_link(struct ospf_lsa_header *lsa, struct ospf_lsa_link *body)
537
{
538
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_link)))
539
    return 0;
540

    
541
  return lsa_validate_pxlist(lsa, body->pxcount, sizeof(struct ospf_lsa_link), (u8 *) body);
542
}
543

    
544
static int
545
lsa_validate_prefix(struct ospf_lsa_header *lsa, struct ospf_lsa_prefix *body)
546
{
547
  if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_prefix)))
548
    return 0;
549

    
550
  return lsa_validate_pxlist(lsa, body->pxcount, sizeof(struct ospf_lsa_prefix), (u8 *) body);
551
}
552

    
553

    
554
/**
555
 * lsa_validate - check whether given LSA is valid
556
 * @lsa: LSA header
557
 * @lsa_type: one of %LSA_T_xxx
558
 * @ospf2: %true means OSPF version 2, %false means OSPF version 3
559
 * @body: pointer to LSA body
560
 *
561
 * Checks internal structure of given LSA body (minimal length,
562
 * consistency). Returns true if valid.
563
 */
564
int
565
lsa_validate(struct ospf_lsa_header *lsa, u32 lsa_type, int ospf2, void *body)
566
{
567
  if (ospf2)
568
  {
569
    switch (lsa_type)
570
    {
571
    case LSA_T_RT:
572
      return lsa_validate_rt2(lsa, body);
573
    case LSA_T_NET:
574
      return lsa_validate_net(lsa, body);
575
    case LSA_T_SUM_NET:
576
      return lsa_validate_sum2(lsa, body);
577
    case LSA_T_SUM_RT:
578
      return lsa_validate_sum2(lsa, body);
579
    case LSA_T_EXT:
580
    case LSA_T_NSSA:
581
      return lsa_validate_ext2(lsa, body);
582
    default:
583
      return 0;        /* Should not happen, unknown LSAs are already rejected */
584
    }
585
  }
586
  else
587
  {
588
    switch (lsa_type)
589
    {
590
    case LSA_T_RT:
591
      return lsa_validate_rt3(lsa, body);
592
    case LSA_T_NET:
593
      return lsa_validate_net(lsa, body);
594
    case LSA_T_SUM_NET:
595
      return lsa_validate_sum3_net(lsa, body);
596
    case LSA_T_SUM_RT:
597
      return lsa_validate_sum3_rt(lsa, body);
598
    case LSA_T_EXT:
599
    case LSA_T_NSSA:
600
      return lsa_validate_ext3(lsa, body);
601
    case LSA_T_LINK:
602
      return lsa_validate_link(lsa, body);
603
    case LSA_T_PREFIX:
604
      return lsa_validate_prefix(lsa, body);
605
    default:
606
      return 1;        /* Unknown LSAs are OK in OSPFv3 */
607
    }
608
  }
609
}