Annotation of embedaddon/bird2/proto/ospf/lsalib.c, revision 1.1.1.1

1.1       misho       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: #define HDRLEN sizeof(struct ospf_lsa_header)
                     16: 
                     17: 
                     18: #ifndef CPU_BIG_ENDIAN
                     19: void
                     20: lsa_hton_hdr(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
                     21: {
                     22:   n->age = htons(h->age);
                     23:   n->type_raw = htons(h->type_raw);
                     24:   n->id = htonl(h->id);
                     25:   n->rt = htonl(h->rt);
                     26:   n->sn = htonl(h->sn);
                     27:   n->checksum = htons(h->checksum);
                     28:   n->length = htons(h->length);
                     29: }
                     30: 
                     31: void
                     32: lsa_ntoh_hdr(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
                     33: {
                     34:   h->age = ntohs(n->age);
                     35:   h->type_raw = ntohs(n->type_raw);
                     36:   h->id = ntohl(n->id);
                     37:   h->rt = ntohl(n->rt);
                     38:   h->sn = ntohl(n->sn);
                     39:   h->checksum = ntohs(n->checksum);
                     40:   h->length = ntohs(n->length);
                     41: }
                     42: 
                     43: void
                     44: lsa_hton_body(void *h, void *n, u16 len)
                     45: {
                     46:   u32 *hid = h;
                     47:   u32 *nid = n;
                     48:   uint i;
                     49: 
                     50:   for (i = 0; i < (len / sizeof(u32)); i++)
                     51:     nid[i] = htonl(hid[i]);
                     52: }
                     53: 
                     54: void
                     55: lsa_ntoh_body(void *n, void *h, u16 len)
                     56: {
                     57:   u32 *nid = n;
                     58:   u32 *hid = h;
                     59:   uint i;
                     60: 
                     61:   for (i = 0; i < (len / sizeof(u32)); i++)
                     62:     hid[i] = ntohl(nid[i]);
                     63: }
                     64: #endif /* little endian */
                     65: 
                     66: 
                     67: int
                     68: lsa_flooding_allowed(u32 type, u32 domain, struct ospf_iface *ifa)
                     69: {
                     70:   /* Handle inactive vlinks */
                     71:   if (ifa->state == OSPF_IS_DOWN)
                     72:     return 0;
                     73: 
                     74:   /* 4.5.2 (Case 2) */
                     75:   switch (LSA_SCOPE(type))
                     76:   {
                     77:   case LSA_SCOPE_LINK:
                     78:     return ifa->iface_id == domain;
                     79: 
                     80:   case LSA_SCOPE_AREA:
                     81:     return ifa->oa->areaid == domain;
                     82: 
                     83:   case LSA_SCOPE_AS:
                     84:     if (ifa->type == OSPF_IT_VLINK)
                     85:       return 0;
                     86:     if (!oa_is_ext(ifa->oa))
                     87:       return 0;
                     88:     return 1;
                     89: 
                     90:   default:
                     91:     log(L_ERR "OSPF: LSA with invalid scope");
                     92:     return 0;
                     93:   }
                     94: }
                     95: 
                     96: int
                     97: lsa_is_acceptable(u32 type, struct ospf_neighbor *n, struct ospf_proto *p)
                     98: {
                     99:   if (ospf_is_v2(p))
                    100:   {
                    101:     /* Do not check NSSA-LSA here, as OPT_N is only in HELLO packets */
                    102: 
                    103:     if (lsa_is_opaque(type))
                    104:       return !!(n->options & OPT_O);
                    105: 
                    106:     return 1;
                    107:   }
                    108:   else
                    109:   {
                    110:     /*
                    111:      * There should be check whether receiving router understands that type
                    112:      * of LSA (for LSA types with U-bit == 0). But as we do not support any
                    113:      * optional LSA types, this is not needed yet.
                    114:      */
                    115: 
                    116:     return 1;
                    117:   }
                    118: }
                    119: 
                    120: static int
                    121: unknown_lsa_type(u32 type)
                    122: {
                    123:   switch (type)
                    124:   {
                    125:   case LSA_T_RT:
                    126:   case LSA_T_NET:
                    127:   case LSA_T_SUM_NET:
                    128:   case LSA_T_SUM_RT:
                    129:   case LSA_T_EXT:
                    130:   case LSA_T_NSSA:
                    131:   case LSA_T_LINK:
                    132:   case LSA_T_PREFIX:
                    133:   case LSA_T_RI_LINK:
                    134:   case LSA_T_RI_AREA:
                    135:   case LSA_T_RI_AS:
                    136:     return 0;
                    137: 
                    138:   default:
                    139:     return 1;
                    140:   }
                    141: }
                    142: 
                    143: /* Maps OSPFv2 types to OSPFv3 types */
                    144: static const u16 lsa_v2_types[] = {
                    145:   0, LSA_T_RT, LSA_T_NET, LSA_T_SUM_NET, LSA_T_SUM_RT, LSA_T_EXT, 0, LSA_T_NSSA,
                    146:   0, LSA_T_OPAQUE_LINK, LSA_T_OPAQUE_AREA, LSA_T_OPAQUE_AS
                    147: };
                    148: 
                    149: /* Maps OSPFv2 opaque types to OSPFv3 function codes */
                    150: static const u16 opaque_lsa_types[] = {
                    151:   [LSA_OT_GR] = LSA_T_GR,
                    152:   [LSA_OT_RI] = LSA_T_RI_,
                    153: };
                    154: 
                    155: /* Maps (subset of) OSPFv3 function codes to OSPFv2 opaque types */
                    156: static const u8 opaque_lsa_types_inv[] = {
                    157:   [LSA_T_GR] = LSA_OT_GR,
                    158:   [LSA_T_RI_] = LSA_OT_RI,
                    159: };
                    160: 
                    161: #define LOOKUP(a, i) ({ uint _i = (i); (_i < ARRAY_SIZE(a)) ? a[_i] : 0; })
                    162: 
                    163: void
                    164: lsa_get_type_domain_(u32 type, u32 id, struct ospf_iface *ifa, u32 *otype, u32 *domain)
                    165: {
                    166:   if (ospf_is_v2(ifa->oa->po))
                    167:   {
                    168:     type = type & LSA_T_V2_MASK;
                    169:     type = LOOKUP(lsa_v2_types, type);
                    170: 
                    171:     uint code;
                    172:     if (LSA_FUNCTION(type) == LSA_T_OPAQUE_)
                    173:       if (code = LOOKUP(opaque_lsa_types, id >> 24))
                    174:       {
                    175:        type = code | LSA_UBIT | LSA_SCOPE(type);
                    176: 
                    177:        /* Hack for Grace-LSA: It does not use U-bit for link-scoped LSAs */
                    178:        if (type == (LSA_T_GR | LSA_UBIT))
                    179:          type = LSA_T_GR;
                    180:       }
                    181:   }
                    182:   else
                    183:   {
                    184:     /* For unkown LSAs without U-bit change scope to LSA_SCOPE_LINK */
                    185:     if (unknown_lsa_type(type) && !(type & LSA_UBIT))
                    186:       type = type & ~LSA_SCOPE_MASK;
                    187:   }
                    188: 
                    189:   *otype = type;
                    190: 
                    191:   switch (LSA_SCOPE(type))
                    192:   {
                    193:   case LSA_SCOPE_LINK:
                    194:     *domain = ifa->iface_id;
                    195:     return;
                    196: 
                    197:   case LSA_SCOPE_AREA:
                    198:     *domain = ifa->oa->areaid;
                    199:     return;
                    200: 
                    201:   case LSA_SCOPE_AS:
                    202:   default:
                    203:     *domain = 0;
                    204:     return;
                    205:   }
                    206: }
                    207: 
                    208: int
                    209: lsa_is_opaque(u32 type)
                    210: {
                    211:   u32 fn = LSA_FUNCTION(type);
                    212:   return LOOKUP(opaque_lsa_types_inv, fn) || (fn == LSA_T_OPAQUE_);
                    213: }
                    214: 
                    215: u32
                    216: lsa_get_opaque_type(u32 type)
                    217: {
                    218:   return LOOKUP(opaque_lsa_types_inv, LSA_FUNCTION(type));
                    219: }
                    220: 
                    221: 
                    222: void
                    223: lsa_generate_checksum(struct ospf_lsa_header *lsa, const u8 *body)
                    224: {
                    225:   struct fletcher16_context ctx;
                    226:   struct ospf_lsa_header hdr;
                    227:   u16 len = lsa->length;
                    228: 
                    229:   /*
                    230:    * lsa and body are in the host order, we need to compute Fletcher-16 checksum
                    231:    * for data in the network order. We also skip the initial age field.
                    232:    */
                    233: 
                    234:   lsa_hton_hdr(lsa, &hdr);
                    235:   hdr.checksum = 0;
                    236: 
                    237:   fletcher16_init(&ctx);
                    238:   fletcher16_update(&ctx, (u8 *) &hdr + 2, sizeof(struct ospf_lsa_header) - 2);
                    239:   fletcher16_update_n32(&ctx, body, len - sizeof(struct ospf_lsa_header));
                    240:   lsa->checksum = fletcher16_final(&ctx, len, OFFSETOF(struct ospf_lsa_header, checksum));
                    241: }
                    242: 
                    243: u16
                    244: lsa_verify_checksum(const void *lsa_n, int lsa_len)
                    245: {
                    246:   struct fletcher16_context ctx;
                    247: 
                    248:   /* The whole LSA is at lsa_n in net order, we just skip initial age field */
                    249: 
                    250:   fletcher16_init(&ctx);
                    251:   fletcher16_update(&ctx, (u8 *) lsa_n + 2, lsa_len - 2);
                    252: 
                    253:   return fletcher16_compute(&ctx) == 0;
                    254: }
                    255: 
                    256: 
                    257: int
                    258: lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2)
                    259:                        /* Return codes from point of view of l1 */
                    260: {
                    261:   u32 sn1, sn2;
                    262: 
                    263:   sn1 = l1->sn - LSA_INITSEQNO + 1;
                    264:   sn2 = l2->sn - LSA_INITSEQNO + 1;
                    265: 
                    266:   if (sn1 > sn2)
                    267:     return CMP_NEWER;
                    268:   if (sn1 < sn2)
                    269:     return CMP_OLDER;
                    270: 
                    271:   if (l1->checksum != l2->checksum)
                    272:     return l1->checksum < l2->checksum ? CMP_OLDER : CMP_NEWER;
                    273: 
                    274:   if ((l1->age == LSA_MAXAGE) && (l2->age != LSA_MAXAGE))
                    275:     return CMP_NEWER;
                    276:   if ((l2->age == LSA_MAXAGE) && (l1->age != LSA_MAXAGE))
                    277:     return CMP_OLDER;
                    278: 
                    279:   if (ABS(l1->age - l2->age) > LSA_MAXAGEDIFF)
                    280:     return l1->age < l2->age ? CMP_NEWER : CMP_OLDER;
                    281: 
                    282:   return CMP_SAME;
                    283: }
                    284: 
                    285: 
                    286: #define LSA_TLV_LENGTH(tlv) \
                    287:   (sizeof(struct ospf_tlv) + BIRD_ALIGN((tlv)->length, 4))
                    288: 
                    289: #define LSA_NEXT_TLV(tlv) \
                    290:   ((struct ospf_tlv *) ((byte *) (tlv) + LSA_TLV_LENGTH(tlv)))
                    291: 
                    292: #define LSA_WALK_TLVS(tlv,buf,len)                                     \
                    293:   for(struct ospf_tlv *tlv = (void *) (buf);                           \
                    294:       (byte *) tlv < (byte *) (buf) + (len);                           \
                    295:       tlv = LSA_NEXT_TLV(tlv))
                    296: 
                    297: struct ospf_tlv *
                    298: lsa_get_tlv(struct top_hash_entry *en, uint type)
                    299: {
                    300:   LSA_WALK_TLVS(tlv, en->lsa_body, en->lsa.length - HDRLEN)
                    301:     if (tlv->type == type)
                    302:       return tlv;
                    303: 
                    304:   return NULL;
                    305: }
                    306: 
                    307: int
                    308: lsa_validate_tlvs(byte *buf, uint len)
                    309: {
                    310:   byte *pos = buf;
                    311:   byte *end = buf + len;
                    312: 
                    313:   while (pos < end)
                    314:   {
                    315:     if ((pos + sizeof(struct ospf_tlv)) > end)
                    316:       return 0;
                    317: 
                    318:     struct ospf_tlv *tlv = (void *) pos;
                    319:     uint len = LSA_TLV_LENGTH(tlv);
                    320: 
                    321:     if ((pos + len) > end)
                    322:       return 0;
                    323: 
                    324:     pos += len;
                    325:   }
                    326: 
                    327:   return 1;
                    328: }
                    329: 
                    330: 
                    331: static inline int
                    332: lsa_walk_rt2(struct ospf_lsa_rt_walk *rt)
                    333: {
                    334:   if (rt->buf >= rt->bufend)
                    335:     return 0;
                    336: 
                    337:   struct ospf_lsa_rt2_link *l = rt->buf;
                    338:   rt->buf += sizeof(struct ospf_lsa_rt2_link) + l->no_tos * sizeof(struct ospf_lsa_rt2_tos);
                    339: 
                    340:   rt->type = l->type;
                    341:   rt->metric = l->metric;
                    342:   rt->id = l->id;
                    343:   rt->data = l->data;
                    344:   return 1;
                    345: }
                    346: 
                    347: static inline int
                    348: lsa_walk_rt3(struct ospf_lsa_rt_walk *rt)
                    349: {
                    350:   while (rt->buf >= rt->bufend)
                    351:   {
                    352:     rt->en = ospf_hash_find_rt3_next(rt->en);
                    353:     if (!rt->en)
                    354:       return 0;
                    355: 
                    356:     rt->buf = rt->en->lsa_body;
                    357:     rt->bufend = rt->buf + rt->en->lsa.length - sizeof(struct ospf_lsa_header);
                    358:     rt->buf += sizeof(struct ospf_lsa_rt);
                    359:   }
                    360: 
                    361:   struct ospf_lsa_rt3_link *l = rt->buf;
                    362:   rt->buf += sizeof(struct ospf_lsa_rt3_link);
                    363: 
                    364:   rt->type = l->type;
                    365:   rt->metric = l->metric;
                    366:   rt->lif = l->lif;
                    367:   rt->nif = l->nif;
                    368:   rt->id = l->id;
                    369:   return 1;
                    370: }
                    371: 
                    372: void
                    373: lsa_walk_rt_init(struct ospf_proto *p, struct top_hash_entry *act, struct ospf_lsa_rt_walk *rt)
                    374: {
                    375:   rt->ospf2 = ospf_is_v2(p);
                    376:   rt->id = rt->data = rt->lif = rt->nif = 0;
                    377: 
                    378:   if (rt->ospf2)
                    379:     rt->en = act;
                    380:   else
                    381:     rt->en = ospf_hash_find_rt3_first(p->gr, act->domain, act->lsa.rt);
                    382: 
                    383:   rt->buf = rt->en->lsa_body;
                    384:   rt->bufend = rt->buf + rt->en->lsa.length - sizeof(struct ospf_lsa_header);
                    385:   rt->buf += sizeof(struct ospf_lsa_rt);
                    386: }
                    387: 
                    388: int
                    389: lsa_walk_rt(struct ospf_lsa_rt_walk *rt)
                    390: {
                    391:   return rt->ospf2 ? lsa_walk_rt2(rt) : lsa_walk_rt3(rt);
                    392: }
                    393: 
                    394: 
                    395: void
                    396: lsa_parse_sum_net(struct top_hash_entry *en, int ospf2, int af, net_addr *net, u8 *pxopts, u32 *metric)
                    397: {
                    398:   if (ospf2)
                    399:   {
                    400:     uint opts = lsa_get_options(&en->lsa);
                    401:     struct ospf_lsa_sum2 *ls = en->lsa_body;
                    402:     net_fill_ip4(net, ip4_from_u32(en->lsa.id & ls->netmask), u32_masklen(ls->netmask));
                    403:     *pxopts = (opts & OPT_DN) ? OPT_PX_DN : 0;
                    404:     *metric = ls->metric & LSA_METRIC_MASK;
                    405:   }
                    406:   else
                    407:   {
                    408:     struct ospf_lsa_sum3_net *ls = en->lsa_body;
                    409:     ospf3_get_prefix(ls->prefix, af, net, pxopts, NULL);
                    410:     *metric = ls->metric & LSA_METRIC_MASK;
                    411:   }
                    412: }
                    413: 
                    414: void
                    415: lsa_parse_sum_rt(struct top_hash_entry *en, int ospf2, u32 *drid, u32 *metric, u32 *options)
                    416: {
                    417:   if (ospf2)
                    418:   {
                    419:     struct ospf_lsa_sum2 *ls = en->lsa_body;
                    420:     *drid = en->lsa.id;
                    421:     *metric = ls->metric & LSA_METRIC_MASK;
                    422:     *options = 0;
                    423:   }
                    424:   else
                    425:   {
                    426:     struct ospf_lsa_sum3_rt *ls = en->lsa_body;
                    427:     *drid = ls->drid;
                    428:     *metric = ls->metric & LSA_METRIC_MASK;
                    429:     *options = ls->options & LSA_OPTIONS_MASK;
                    430:   }
                    431: }
                    432: 
                    433: void
                    434: lsa_parse_ext(struct top_hash_entry *en, int ospf2, int af, struct ospf_lsa_ext_local *rt)
                    435: {
                    436:   if (ospf2)
                    437:   {
                    438:     struct ospf_lsa_ext2 *ext = en->lsa_body;
                    439:     net_fill_ip4(&rt->net,
                    440:                 ip4_from_u32(en->lsa.id & ext->netmask),
                    441:                 u32_masklen(ext->netmask));
                    442:     rt->pxopts = 0;
                    443:     rt->metric = ext->metric & LSA_METRIC_MASK;
                    444:     rt->ebit = ext->metric & LSA_EXT2_EBIT;
                    445: 
                    446:     rt->fbit = ext->fwaddr;
                    447:     rt->fwaddr = ipa_from_u32(ext->fwaddr);
                    448: 
                    449:     rt->tag = ext->tag;
                    450:     rt->propagate = lsa_get_options(&en->lsa) & OPT_P;
                    451:     rt->downwards = lsa_get_options(&en->lsa) & OPT_DN;
                    452:   }
                    453:   else
                    454:   {
                    455:     struct ospf_lsa_ext3 *ext = en->lsa_body;
                    456:     u32 *buf = ospf3_get_prefix(ext->rest, af, &rt->net, &rt->pxopts, NULL);
                    457:     rt->metric = ext->metric & LSA_METRIC_MASK;
                    458:     rt->ebit = ext->metric & LSA_EXT3_EBIT;
                    459: 
                    460:     rt->fbit = ext->metric & LSA_EXT3_FBIT;
                    461:     if (rt->fbit)
                    462:       buf = ospf3_get_addr(buf, af, &rt->fwaddr);
                    463:     else
                    464:       rt->fwaddr = IPA_NONE;
                    465: 
                    466:     rt->tag = (ext->metric & LSA_EXT3_TBIT) ? *buf++ : 0;
                    467:     rt->propagate = rt->pxopts & OPT_PX_P;
                    468:     rt->downwards = rt->pxopts & OPT_PX_DN;
                    469:   }
                    470: }
                    471: 
                    472: 
                    473: static int
                    474: lsa_validate_rt2(struct ospf_lsa_header *lsa, struct ospf_lsa_rt *body)
                    475: {
                    476:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_rt)))
                    477:     return 0;
                    478: 
                    479:   uint i = 0;
                    480:   void *buf = body;
                    481:   void *bufend = buf + lsa->length - HDRLEN;
                    482:   buf += sizeof(struct ospf_lsa_rt);
                    483: 
                    484:   while (buf < bufend)
                    485:   {
                    486:     struct ospf_lsa_rt2_link *l = buf;
                    487:     buf += sizeof(struct ospf_lsa_rt2_link) + l->no_tos * sizeof(struct ospf_lsa_rt2_tos);
                    488:     i++;
                    489: 
                    490:     if (buf > bufend)
                    491:       return 0;
                    492: 
                    493:     if (!((l->type == LSART_PTP) ||
                    494:          (l->type == LSART_NET) ||
                    495:          (l->type == LSART_STUB) ||
                    496:          (l->type == LSART_VLNK)))
                    497:       return 0;
                    498:   }
                    499: 
                    500:   if ((body->options & LSA_RT2_LINKS) != i)
                    501:     return 0;
                    502: 
                    503:   return 1;
                    504: }
                    505: 
                    506: 
                    507: static int
                    508: lsa_validate_rt3(struct ospf_lsa_header *lsa, struct ospf_lsa_rt *body)
                    509: {
                    510:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_rt)))
                    511:     return 0;
                    512: 
                    513:   void *buf = body;
                    514:   void *bufend = buf + lsa->length - HDRLEN;
                    515:   buf += sizeof(struct ospf_lsa_rt);
                    516: 
                    517:   while (buf < bufend)
                    518:   {
                    519:     struct ospf_lsa_rt3_link *l = buf;
                    520:     buf += sizeof(struct ospf_lsa_rt3_link);
                    521: 
                    522:     if (buf > bufend)
                    523:       return 0;
                    524: 
                    525:     if (!((l->type == LSART_PTP) ||
                    526:          (l->type == LSART_NET) ||
                    527:          (l->type == LSART_VLNK)))
                    528:       return 0;
                    529:   }
                    530:   return 1;
                    531: }
                    532: 
                    533: static int
                    534: lsa_validate_net(struct ospf_lsa_header *lsa, struct ospf_lsa_net *body UNUSED)
                    535: {
                    536:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_net)))
                    537:     return 0;
                    538: 
                    539:   return 1;
                    540: }
                    541: 
                    542: static int
                    543: lsa_validate_sum2(struct ospf_lsa_header *lsa, struct ospf_lsa_sum2 *body)
                    544: {
                    545:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_sum2)))
                    546:     return 0;
                    547: 
                    548:   /* First field should have TOS = 0, we ignore other TOS fields */
                    549:   if ((body->metric & LSA_SUM2_TOS) != 0)
                    550:     return 0;
                    551: 
                    552:   return 1;
                    553: }
                    554: 
                    555: static inline int
                    556: pxlen(u32 *buf)
                    557: {
                    558:   return *buf >> 24;
                    559: }
                    560: 
                    561: static int
                    562: lsa_validate_sum3_net(struct ospf_lsa_header *lsa, struct ospf_lsa_sum3_net *body)
                    563: {
                    564:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_sum3_net) + 4))
                    565:     return 0;
                    566: 
                    567:   u8 pxl = pxlen(body->prefix);
                    568:   if (pxl > IP6_MAX_PREFIX_LENGTH)
                    569:     return 0;
                    570: 
                    571:   if (lsa->length != (HDRLEN + sizeof(struct ospf_lsa_sum3_net) +
                    572:                      IPV6_PREFIX_SPACE(pxl)))
                    573:     return 0;
                    574: 
                    575:   return 1;
                    576: }
                    577: 
                    578: static int
                    579: lsa_validate_sum3_rt(struct ospf_lsa_header *lsa, struct ospf_lsa_sum3_rt *body UNUSED)
                    580: {
                    581:   if (lsa->length != (HDRLEN + sizeof(struct ospf_lsa_sum3_rt)))
                    582:     return 0;
                    583: 
                    584:   return 1;
                    585: }
                    586: 
                    587: static int
                    588: lsa_validate_ext2(struct ospf_lsa_header *lsa, struct ospf_lsa_ext2 *body)
                    589: {
                    590:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_ext2)))
                    591:     return 0;
                    592: 
                    593:   /* First field should have TOS = 0, we ignore other TOS fields */
                    594:   if ((body->metric & LSA_EXT2_TOS) != 0)
                    595:     return 0;
                    596: 
                    597:   return 1;
                    598: }
                    599: 
                    600: static int
                    601: lsa_validate_ext3(struct ospf_lsa_header *lsa, struct ospf_lsa_ext3 *body)
                    602: {
                    603:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_ext3) + 4))
                    604:     return 0;
                    605: 
                    606:   u8 pxl = pxlen(body->rest);
                    607:   if (pxl > IP6_MAX_PREFIX_LENGTH)
                    608:     return 0;
                    609: 
                    610:   int len = IPV6_PREFIX_SPACE(pxl);
                    611:   if (body->metric & LSA_EXT3_FBIT) // forwarding address
                    612:     len += 16;
                    613:   if (body->metric & LSA_EXT3_TBIT) // route tag
                    614:     len += 4;
                    615:   if (*body->rest & 0xFFFF) // referenced LS type field
                    616:     len += 4;
                    617: 
                    618:   if (lsa->length != (HDRLEN + sizeof(struct ospf_lsa_ext3) + len))
                    619:     return 0;
                    620: 
                    621:   return 1;
                    622: }
                    623: 
                    624: static int
                    625: lsa_validate_pxlist(struct ospf_lsa_header *lsa, u32 pxcount, uint offset, u8 *pbuf)
                    626: {
                    627:   uint bound = lsa->length - HDRLEN - 4;
                    628:   u32 i;
                    629: 
                    630:   for (i = 0; i < pxcount; i++)
                    631:     {
                    632:       if (offset > bound)
                    633:        return 0;
                    634: 
                    635:       u8 pxl = pxlen((u32 *) (pbuf + offset));
                    636:       if (pxl > IP6_MAX_PREFIX_LENGTH)
                    637:        return 0;
                    638: 
                    639:       offset += IPV6_PREFIX_SPACE(pxl);
                    640:     }
                    641: 
                    642:   if (lsa->length != (HDRLEN + offset))
                    643:     return 0;
                    644: 
                    645:   return 1;
                    646: }
                    647: 
                    648: static int
                    649: lsa_validate_link(struct ospf_lsa_header *lsa, struct ospf_lsa_link *body)
                    650: {
                    651:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_link)))
                    652:     return 0;
                    653: 
                    654:   return lsa_validate_pxlist(lsa, body->pxcount, sizeof(struct ospf_lsa_link), (u8 *) body);
                    655: }
                    656: 
                    657: static int
                    658: lsa_validate_prefix(struct ospf_lsa_header *lsa, struct ospf_lsa_prefix *body)
                    659: {
                    660:   if (lsa->length < (HDRLEN + sizeof(struct ospf_lsa_prefix)))
                    661:     return 0;
                    662: 
                    663:   return lsa_validate_pxlist(lsa, body->pxcount, sizeof(struct ospf_lsa_prefix), (u8 *) body);
                    664: }
                    665: 
                    666: static int
                    667: lsa_validate_gr(struct ospf_lsa_header *lsa, void *body)
                    668: {
                    669:   return lsa_validate_tlvs(body, lsa->length - HDRLEN);
                    670: }
                    671: 
                    672: static int
                    673: lsa_validate_ri(struct ospf_lsa_header *lsa UNUSED, struct ospf_lsa_net *body UNUSED)
                    674: {
                    675:   /*
                    676:    * There should be proper validation. But we do not really process RI LSAs, so
                    677:    * we can just accept them like another unknown opaque LSAs.
                    678:    */
                    679: 
                    680:   return 1;
                    681: }
                    682: 
                    683: 
                    684: /**
                    685:  * lsa_validate - check whether given LSA is valid
                    686:  * @lsa: LSA header
                    687:  * @lsa_type: internal LSA type (%LSA_T_xxx)
                    688:  * @ospf2: %true for OSPFv2, %false for OSPFv3
                    689:  * @body: pointer to LSA body
                    690:  *
                    691:  * Checks internal structure of given LSA body (minimal length,
                    692:  * consistency). Returns true if valid.
                    693:  */
                    694: int
                    695: lsa_validate(struct ospf_lsa_header *lsa, u32 lsa_type, int ospf2, void *body)
                    696: {
                    697:   if (ospf2)
                    698:   {
                    699:     switch (lsa_type)
                    700:     {
                    701:     case LSA_T_RT:
                    702:       return lsa_validate_rt2(lsa, body);
                    703:     case LSA_T_NET:
                    704:       return lsa_validate_net(lsa, body);
                    705:     case LSA_T_SUM_NET:
                    706:       return lsa_validate_sum2(lsa, body);
                    707:     case LSA_T_SUM_RT:
                    708:       return lsa_validate_sum2(lsa, body);
                    709:     case LSA_T_EXT:
                    710:     case LSA_T_NSSA:
                    711:       return lsa_validate_ext2(lsa, body);
                    712:     case LSA_T_GR:
                    713:       return lsa_validate_gr(lsa, body);
                    714:     case LSA_T_RI_LINK:
                    715:     case LSA_T_RI_AREA:
                    716:     case LSA_T_RI_AS:
                    717:       return lsa_validate_ri(lsa, body);
                    718:     case LSA_T_OPAQUE_LINK:
                    719:     case LSA_T_OPAQUE_AREA:
                    720:     case LSA_T_OPAQUE_AS:
                    721:       return 1;        /* Unknown Opaque LSAs */
                    722:     default:
                    723:       return 0;        /* Should not happen, unknown LSAs are already rejected */
                    724:     }
                    725:   }
                    726:   else
                    727:   {
                    728:     switch (lsa_type)
                    729:     {
                    730:     case LSA_T_RT:
                    731:       return lsa_validate_rt3(lsa, body);
                    732:     case LSA_T_NET:
                    733:       return lsa_validate_net(lsa, body);
                    734:     case LSA_T_SUM_NET:
                    735:       return lsa_validate_sum3_net(lsa, body);
                    736:     case LSA_T_SUM_RT:
                    737:       return lsa_validate_sum3_rt(lsa, body);
                    738:     case LSA_T_EXT:
                    739:     case LSA_T_NSSA:
                    740:       return lsa_validate_ext3(lsa, body);
                    741:     case LSA_T_LINK:
                    742:       return lsa_validate_link(lsa, body);
                    743:     case LSA_T_PREFIX:
                    744:       return lsa_validate_prefix(lsa, body);
                    745:     case LSA_T_GR:
                    746:       return lsa_validate_gr(lsa, body);
                    747:     case LSA_T_RI_LINK:
                    748:     case LSA_T_RI_AREA:
                    749:     case LSA_T_RI_AS:
                    750:       return lsa_validate_ri(lsa, body);
                    751:     default:
                    752:       return 1;        /* Unknown LSAs are OK in OSPFv3 */
                    753:     }
                    754:   }
                    755: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>