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

1.1       misho       1: /*
                      2:  *     BIRD -- OSPF
                      3:  *
                      4:  *     (c) 2000--2004 Ondrej Filip <feela@network.cz>
                      5:  *     (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
                      6:  *     (c) 2009--2014 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: 
                     14: /*
                     15: struct ospf_lsupd_packet
                     16: {
                     17:   struct ospf_packet hdr;
                     18:   // union ospf_auth auth;
                     19: 
                     20:   u32 lsa_count;
                     21:   void lsas[];
                     22: };
                     23: */
                     24: 
                     25: 
                     26: void
                     27: ospf_dump_lsahdr(struct ospf_proto *p, struct ospf_lsa_header *lsa_n)
                     28: {
                     29:   struct ospf_lsa_header lsa;
                     30:   u32 lsa_etype;
                     31: 
                     32:   lsa_ntoh_hdr(lsa_n, &lsa);
                     33:   lsa_etype = lsa_get_etype(&lsa, p);
                     34: 
                     35:   log(L_TRACE "%s:     LSA      Type: %04x, Id: %R, Rt: %R, Seq: %08x, Age: %u, Sum: %04x",
                     36:       p->p.name, lsa_etype, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum);
                     37: }
                     38: 
                     39: void
                     40: ospf_dump_common(struct ospf_proto *p, struct ospf_packet *pkt)
                     41: {
                     42:   log(L_TRACE "%s:     length   %d", p->p.name, ntohs(pkt->length));
                     43:   log(L_TRACE "%s:     router   %R", p->p.name, ntohl(pkt->routerid));
                     44: }
                     45: 
                     46: static inline uint
                     47: ospf_lsupd_hdrlen(struct ospf_proto *p)
                     48: {
                     49:   return ospf_pkt_hdrlen(p) + 4; /* + u32 lsa count field */
                     50: }
                     51: 
                     52: static inline u32
                     53: ospf_lsupd_get_lsa_count(struct ospf_packet *pkt, uint hdrlen)
                     54: {
                     55:   u32 *c = ((void *) pkt) + hdrlen - 4;
                     56:   return ntohl(*c);
                     57: }
                     58: 
                     59: static inline void
                     60: ospf_lsupd_set_lsa_count(struct ospf_packet *pkt, uint hdrlen, u32 val)
                     61: {
                     62:   u32 *c = ((void *) pkt) + hdrlen - 4;
                     63:   *c = htonl(val);
                     64: }
                     65: 
                     66: static inline void
                     67: ospf_lsupd_body(struct ospf_proto *p, struct ospf_packet *pkt,
                     68:                uint *offset, uint *lsa_count)
                     69: {
                     70:   uint hlen = ospf_lsupd_hdrlen(p);
                     71:   *offset = hlen;
                     72:   *lsa_count = ospf_lsupd_get_lsa_count(pkt, hlen);
                     73: }
                     74: 
                     75: static void
                     76: ospf_dump_lsupd(struct ospf_proto *p, struct ospf_packet *pkt)
                     77: {
                     78:   uint offset, plen, i, lsa_count, lsa_len;
                     79: 
                     80:   ASSERT(pkt->type == LSUPD_P);
                     81:   ospf_dump_common(p, pkt);
                     82: 
                     83:   plen = ntohs(pkt->length);
                     84:   ospf_lsupd_body(p, pkt, &offset, &lsa_count);
                     85:   for (i = 0; i < lsa_count; i++)
                     86:   {
                     87:     if ((offset + sizeof(struct ospf_lsa_header)) > plen)
                     88:       goto invalid;
                     89: 
                     90:     struct ospf_lsa_header *lsa = ((void *) pkt) + offset;
                     91:     lsa_len = ntohs(lsa->length);
                     92: 
                     93:     if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header)))
                     94:       goto invalid;
                     95: 
                     96:     ospf_dump_lsahdr(p, lsa);
                     97:     offset += lsa_len;
                     98:   }
                     99:   return;
                    100: 
                    101: invalid:
                    102:   log(L_TRACE "%s:     LSA      invalid", p->p.name);
                    103:   return;
                    104: }
                    105: 
                    106: 
                    107: static inline void
                    108: ospf_lsa_lsrq_down(struct top_hash_entry *req, struct ospf_neighbor *n)
                    109: {
                    110:   if (req == n->lsrqi)
                    111:     n->lsrqi = SNODE_NEXT(req);
                    112: 
                    113:   s_rem_node(SNODE req);
                    114:   ospf_hash_delete(n->lsrqh, req);
                    115: 
                    116:   if (EMPTY_SLIST(n->lsrql))
                    117:   {
                    118:     tm_stop(n->lsrq_timer);
                    119: 
                    120:     if (n->state == NEIGHBOR_LOADING)
                    121:       ospf_neigh_sm(n, INM_LOADDONE);
                    122:   }
                    123: }
                    124: 
                    125: static inline void
                    126: ospf_lsa_lsrt_up(struct top_hash_entry *en, struct ospf_neighbor *n)
                    127: {
                    128:   struct top_hash_entry *ret = ospf_hash_get_entry(n->lsrth, en);
                    129: 
                    130:   if (!SNODE_VALID(ret))
                    131:   {
                    132:     en->ret_count++;
                    133:     s_add_tail(&n->lsrtl, SNODE ret);
                    134:   }
                    135: 
                    136:   ret->lsa = en->lsa;
                    137:   ret->lsa_body = LSA_BODY_DUMMY;
                    138: 
                    139:   if (!tm_active(n->lsrt_timer))
                    140:     tm_start(n->lsrt_timer, n->ifa->rxmtint S);
                    141: }
                    142: 
                    143: void
                    144: ospf_lsa_lsrt_down_(struct top_hash_entry *en, struct ospf_neighbor *n, struct top_hash_entry *ret)
                    145: {
                    146:   if (en)
                    147:     en->ret_count--;
                    148: 
                    149:   s_rem_node(SNODE ret);
                    150:   ospf_hash_delete(n->lsrth, ret);
                    151: 
                    152:   if (EMPTY_SLIST(n->lsrtl))
                    153:     tm_stop(n->lsrt_timer);
                    154: }
                    155: 
                    156: static inline int
                    157: ospf_lsa_lsrt_down(struct top_hash_entry *en, struct ospf_neighbor *n)
                    158: {
                    159:   struct top_hash_entry *ret = ospf_hash_find_entry(n->lsrth, en);
                    160: 
                    161:   if (ret)
                    162:     ospf_lsa_lsrt_down_(en, n, ret);
                    163: 
                    164:   return ret != NULL;
                    165: }
                    166: 
                    167: void
                    168: ospf_add_flushed_to_lsrt(struct ospf_proto *p, struct ospf_neighbor *n)
                    169: {
                    170:   struct top_hash_entry *en;
                    171: 
                    172:   WALK_SLIST(en, p->lsal)
                    173:     if ((en->lsa.age == LSA_MAXAGE) && (en->lsa_body != NULL) &&
                    174:        lsa_flooding_allowed(en->lsa_type, en->domain, n->ifa) &&
                    175:         lsa_is_acceptable(en->lsa_type, n, p))
                    176:       ospf_lsa_lsrt_up(en, n);
                    177: 
                    178:   /* If we found any flushed LSA, we send them ASAP */
                    179:   if (tm_active(n->lsrt_timer))
                    180:     tm_start(n->lsrt_timer, 0);
                    181: }
                    182: 
                    183: static int ospf_flood_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, uint lsa_min_count, struct ospf_iface *ifa);
                    184: 
                    185: static void
                    186: ospf_enqueue_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa)
                    187: {
                    188:   /* Exception for local Grace-LSA, they are flooded synchronously */
                    189:   if ((en->lsa_type == LSA_T_GR) && (en->lsa.rt == p->router_id))
                    190:   {
                    191:     ospf_flood_lsupd(p, &en, 1, 1, ifa);
                    192:     return;
                    193:   }
                    194: 
                    195:   if (ifa->flood_queue_used == ifa->flood_queue_size)
                    196:   {
                    197:     /* If we already have full queue, we send some packets */
                    198:     uint sent = ospf_flood_lsupd(p, ifa->flood_queue, ifa->flood_queue_used, ifa->flood_queue_used / 2, ifa);
                    199:     uint i;
                    200: 
                    201:     for (i = 0; i < sent; i++)
                    202:       ifa->flood_queue[i]->ret_count--;
                    203: 
                    204:     ifa->flood_queue_used -= sent;
                    205:     memmove(ifa->flood_queue, ifa->flood_queue + sent, ifa->flood_queue_used * sizeof(void *));
                    206:     bzero(ifa->flood_queue + ifa->flood_queue_used, sent * sizeof(void *));
                    207:   }
                    208: 
                    209:   en->ret_count++;
                    210:   ifa->flood_queue[ifa->flood_queue_used] = en;
                    211:   ifa->flood_queue_used++;
                    212: 
                    213:   if (!ev_active(p->flood_event))
                    214:     ev_schedule(p->flood_event);
                    215: }
                    216: 
                    217: void
                    218: ospf_flood_event(void *ptr)
                    219: {
                    220:   struct ospf_proto *p = ptr;
                    221:   struct ospf_iface *ifa;
                    222:   int i, count;
                    223: 
                    224:   WALK_LIST(ifa, p->iface_list)
                    225:   {
                    226:     if (ifa->flood_queue_used == 0)
                    227:       continue;
                    228: 
                    229:     count = ifa->flood_queue_used;
                    230:     ospf_flood_lsupd(p, ifa->flood_queue, count, count, ifa);
                    231: 
                    232:     for (i = 0; i < count; i++)
                    233:       ifa->flood_queue[i]->ret_count--;
                    234: 
                    235:     ifa->flood_queue_used = 0;
                    236:     bzero(ifa->flood_queue, count * sizeof(void *));
                    237:   }
                    238: }
                    239: 
                    240: 
                    241: /**
                    242:  * ospf_flood_lsa - send LSA to the neighbors
                    243:  * @p: OSPF protocol instance
                    244:  * @en: LSA entry
                    245:  * @from: neighbor than sent this LSA (or NULL if LSA is local)
                    246:  *
                    247:  * return value - was the LSA flooded back?
                    248:  */
                    249: int
                    250: ospf_flood_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from)
                    251: {
                    252:   struct ospf_iface *ifa;
                    253:   struct ospf_neighbor *n;
                    254: 
                    255:   /* RFC 2328 13.3 */
                    256: 
                    257:   int back = 0;
                    258:   WALK_LIST(ifa, p->iface_list)
                    259:   {
                    260:     if (ifa->stub)
                    261:       continue;
                    262: 
                    263:     if (! lsa_flooding_allowed(en->lsa_type, en->domain, ifa))
                    264:       continue;
                    265: 
                    266:     DBG("Wanted to flood LSA: Type: %u, ID: %R, RT: %R, SN: 0x%x, Age %u\n",
                    267:        hh->type, hh->id, hh->rt, hh->sn, hh->age);
                    268: 
                    269:     int used = 0;
                    270:     WALK_LIST(n, ifa->neigh_list)
                    271:     {
                    272:       /* 13.3 (1a) */
                    273:       if (n->state < NEIGHBOR_EXCHANGE)
                    274:        continue;
                    275: 
                    276:       /* 13.3 (1b) */
                    277:       if (n->state < NEIGHBOR_FULL)
                    278:       {
                    279:        struct top_hash_entry *req = ospf_hash_find_entry(n->lsrqh, en);
                    280:        if (req != NULL)
                    281:        {
                    282:          int cmp = lsa_comp(&en->lsa, &req->lsa);
                    283: 
                    284:          /* If same or newer, remove LSA from the link state request list */
                    285:          if (cmp > CMP_OLDER)
                    286:            ospf_lsa_lsrq_down(req, n);
                    287: 
                    288:          /* If older or same, skip processing of this neighbor */
                    289:          if (cmp < CMP_NEWER)
                    290:            continue;
                    291:        }
                    292:       }
                    293: 
                    294:       /* 13.3 (1c) */
                    295:       if (n == from)
                    296:        continue;
                    297: 
                    298:       /* Check whether optional LSAs are supported by neighbor */
                    299:       if (!lsa_is_acceptable(en->lsa_type, n, p))
                    300:        continue;
                    301: 
                    302:       /* 13.3 (1d) - add LSA to the link state retransmission list */
                    303:       ospf_lsa_lsrt_up(en, n);
                    304: 
                    305:       used = 1;
                    306:     }
                    307: 
                    308:     /* 13.3 (2) */
                    309:     if (!used)
                    310:       continue;
                    311: 
                    312:     if (from && (from->ifa == ifa))
                    313:     {
                    314:       /* 13.3 (3) */
                    315:       if ((from->rid == ifa->drid) || (from->rid == ifa->bdrid))
                    316:        continue;
                    317: 
                    318:       /* 13.3 (4) */
                    319:       if (ifa->state == OSPF_IS_BACKUP)
                    320:        continue;
                    321: 
                    322:       back = 1;
                    323:     }
                    324: 
                    325:     /* 13.3 (5) - finally flood the packet */
                    326:     ospf_enqueue_lsa(p, en, ifa);
                    327:   }
                    328: 
                    329:   return back;
                    330: }
                    331: 
                    332: static uint
                    333: ospf_prepare_lsupd(struct ospf_proto *p, struct ospf_iface *ifa,
                    334:                   struct top_hash_entry **lsa_list, uint lsa_count)
                    335: {
                    336:   struct ospf_packet *pkt;
                    337:   uint hlen, pos, i, maxsize;
                    338: 
                    339:   pkt = ospf_tx_buffer(ifa);
                    340:   hlen = ospf_lsupd_hdrlen(p);
                    341:   maxsize = ospf_pkt_maxsize(ifa);
                    342: 
                    343:   ospf_pkt_fill_hdr(ifa, pkt, LSUPD_P);
                    344:   pos = hlen;
                    345: 
                    346:   for (i = 0; i < lsa_count; i++)
                    347:   {
                    348:     struct top_hash_entry *en = lsa_list[i];
                    349:     uint len = en->lsa.length;
                    350: 
                    351:     if ((pos + len) > maxsize)
                    352:     {
                    353:       /* The packet if full, stop adding LSAs and sent it */
                    354:       if (i > 0)
                    355:        break;
                    356: 
                    357:       /* LSA is larger than MTU, check buffer size */
                    358:       if (ospf_iface_assure_bufsize(ifa, pos + len) < 0)
                    359:       {
                    360:        /* Cannot fit in a tx buffer, skip that */
                    361:        log(L_ERR "%s: LSA too large to send on %s (Type: %04x, Id: %R, Rt: %R)",
                    362:            p->p.name, ifa->ifname, en->lsa_type, en->lsa.id, en->lsa.rt);
                    363:        break;
                    364:       }
                    365: 
                    366:       /* TX buffer could be reallocated */
                    367:       pkt = ospf_tx_buffer(ifa);
                    368:     }
                    369: 
                    370:     struct ospf_lsa_header *buf = ((void *) pkt) + pos;
                    371:     lsa_hton_hdr(&en->lsa, buf);
                    372:     lsa_hton_body(en->lsa_body, ((void *) buf) + sizeof(struct ospf_lsa_header),
                    373:                  len - sizeof(struct ospf_lsa_header));
                    374:     buf->age = htons(MIN(en->lsa.age + ifa->inftransdelay, LSA_MAXAGE));
                    375: 
                    376:     pos += len;
                    377:   }
                    378: 
                    379:   ospf_lsupd_set_lsa_count(pkt, hlen, i);
                    380:   pkt->length = htons(pos);
                    381: 
                    382:   return i;
                    383: }
                    384: 
                    385: 
                    386: static int
                    387: ospf_flood_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, uint lsa_min_count, struct ospf_iface *ifa)
                    388: {
                    389:   uint i, c;
                    390: 
                    391:   for (i = 0; i < lsa_min_count; i += c)
                    392:   {
                    393:     c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i);
                    394: 
                    395:     if (!c)    /* Too large LSA */
                    396:       { i++; continue; }
                    397: 
                    398:     OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa),
                    399:                "LSUPD packet flooded via %s", ifa->ifname);
                    400: 
                    401:     if (ifa->type == OSPF_IT_BCAST)
                    402:     {
                    403:       if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
                    404:        ospf_send_to_all(ifa);
                    405:       else
                    406:        ospf_send_to_des(ifa);
                    407:     }
                    408:     else
                    409:       ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
                    410:   }
                    411: 
                    412:   return i;
                    413: }
                    414: 
                    415: int
                    416: ospf_send_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, struct ospf_neighbor *n)
                    417: {
                    418:   struct ospf_iface *ifa = n->ifa;
                    419:   uint i, c;
                    420: 
                    421:   for (i = 0; i < lsa_count; i += c)
                    422:   {
                    423:     c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i);
                    424: 
                    425:     if (!c)    /* Too large LSA */
                    426:       { i++; continue; }
                    427: 
                    428:     OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa),
                    429:                "LSUPD packet sent to nbr %R on %s", n->rid, ifa->ifname);
                    430: 
                    431:     ospf_send_to(ifa, n->ip);
                    432:   }
                    433: 
                    434:   return i;
                    435: }
                    436: 
                    437: void
                    438: ospf_rxmt_lsupd(struct ospf_proto *p, struct ospf_neighbor *n)
                    439: {
                    440:   uint max = 2 * n->ifa->flood_queue_size;
                    441:   struct top_hash_entry *entries[max];
                    442:   struct top_hash_entry *ret, *nxt, *en;
                    443:   uint i = 0;
                    444: 
                    445:   /* ASSERT((n->state >= NEIGHBOR_EXCHANGE) && !EMPTY_SLIST(n->lsrtl)); */
                    446: 
                    447:   WALK_SLIST_DELSAFE(ret, nxt, n->lsrtl)
                    448:   {
                    449:     if (i == max)
                    450:       break;
                    451: 
                    452:     en = ospf_hash_find_entry(p->gr, ret);
                    453:     if (!en)
                    454:     {
                    455:       /* Probably flushed LSA, this should not happen */
                    456:       log(L_WARN "%s: LSA disappeared (Type: %04x, Id: %R, Rt: %R)",
                    457:          p->p.name, ret->lsa_type, ret->lsa.id, ret->lsa.rt);
                    458: 
                    459:       s_rem_node(SNODE ret);
                    460:       ospf_hash_delete(n->lsrth, ret);
                    461: 
                    462:       continue;
                    463:     }
                    464: 
                    465:     entries[i] = en;
                    466:     i++;
                    467:   }
                    468: 
                    469:   ospf_send_lsupd(p, entries, i, n);
                    470: }
                    471: 
                    472: 
                    473: static inline int
                    474: ospf_addr_is_local(struct ospf_proto *p, struct ospf_area *oa, ip_addr ip)
                    475: {
                    476:   struct ospf_iface *ifa;
                    477:   WALK_LIST(ifa, p->iface_list)
                    478:     if ((ifa->oa == oa) && ifa->addr && ipa_equal(ifa->addr->ip, ip))
                    479:       return 1;
                    480: 
                    481:   return 0;
                    482: }
                    483: 
                    484: void
                    485: ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
                    486:                   struct ospf_neighbor *n)
                    487: {
                    488:   struct ospf_proto *p = ifa->oa->po;
                    489:   const char *err_dsc = NULL;
                    490:   uint plen, err_val = 0;
                    491: 
                    492:   /* RFC 2328 13. */
                    493: 
                    494:   plen = ntohs(pkt->length);
                    495:   if (plen < ospf_lsupd_hdrlen(p))
                    496:   {
                    497:     LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)", n->rid, ifa->ifname, "too short", plen);
                    498:     return;
                    499:   }
                    500: 
                    501:   OSPF_PACKET(ospf_dump_lsupd, pkt, "LSUPD packet received from nbr %R on %s", n->rid, ifa->ifname);
                    502: 
                    503:   if (n->state < NEIGHBOR_EXCHANGE)
                    504:   {
                    505:     OSPF_TRACE(D_PACKETS, "LSUPD packet ignored - lesser state than Exchange");
                    506:     return;
                    507:   }
                    508: 
                    509:   ospf_neigh_sm(n, INM_HELLOREC);      /* Questionable */
                    510: 
                    511:   uint offset, i, lsa_count;
                    512:   ospf_lsupd_body(p, pkt, &offset, &lsa_count);
                    513: 
                    514:   for (i = 0; i < lsa_count; i++)
                    515:   {
                    516:     struct ospf_lsa_header lsa, *lsa_n;
                    517:     struct top_hash_entry *en;
                    518:     u32 lsa_len, lsa_type, lsa_domain;
                    519: 
                    520:     if ((offset + sizeof(struct ospf_lsa_header)) > plen)
                    521:       DROP("too short", plen);
                    522: 
                    523:     /* LSA header in network order */
                    524:     lsa_n = ((void *) pkt) + offset;
                    525:     lsa_len = ntohs(lsa_n->length);
                    526:     offset += lsa_len;
                    527: 
                    528:     if (offset > plen)
                    529:       DROP("too short", plen);
                    530: 
                    531:     if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header)))
                    532:       DROP("invalid LSA length", lsa_len);
                    533: 
                    534:     /* LSA header in host order */
                    535:     lsa_ntoh_hdr(lsa_n, &lsa);
                    536:     lsa_get_type_domain(&lsa, ifa, &lsa_type, &lsa_domain);
                    537: 
                    538:     DBG("Update Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n",
                    539:        lsa_type, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum);
                    540: 
                    541:     /* RFC 2328 13. (1) - verify LSA checksum */
                    542:     if ((lsa_n->checksum == 0) || !lsa_verify_checksum(lsa_n, lsa_len))
                    543:       SKIP("invalid checksum");
                    544: 
                    545:     /* RFC 2328 13. (2) */
                    546:     if (!lsa_type)
                    547:       SKIP("unknown type");
                    548: 
                    549:     /* RFC 5340 4.5.1 (2) and RFC 2328 13. (3) */
                    550:     if (!oa_is_ext(ifa->oa) && (LSA_SCOPE(lsa_type) == LSA_SCOPE_AS))
                    551:       SKIP("AS scope in stub area");
                    552: 
                    553:     /* Errata 3746 to RFC 2328 - rt-summary-LSAs forbidden in stub areas */
                    554:     if (!oa_is_ext(ifa->oa) && (lsa_type == LSA_T_SUM_RT))
                    555:       SKIP("rt-summary-LSA in stub area");
                    556: 
                    557:     /* RFC 5340 4.5.1 (3) */
                    558:     if (LSA_SCOPE(lsa_type) == LSA_SCOPE_RES)
                    559:       SKIP("invalid scope");
                    560: 
                    561:     /* Find local copy of LSA in link state database */
                    562:     en = ospf_hash_find(p->gr, lsa_domain, lsa.id, lsa.rt, lsa_type);
                    563: 
                    564: #ifdef LOCAL_DEBUG
                    565:     if (en)
                    566:       DBG("I have Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n",
                    567:          en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn, en->lsa.age, en->lsa.checksum);
                    568: #endif
                    569: 
                    570:     /* 13. (4) - ignore maxage LSA if i have no local copy */
                    571:     if ((lsa.age == LSA_MAXAGE) && !en && (p->padj == 0))
                    572:     {
                    573:       /* 13.5. - schedule ACKs (tbl 19, case 5) */
                    574:       ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
                    575:       continue;
                    576:     }
                    577: 
                    578:     /* 13. (5) - received LSA is newer (or no local copy) */
                    579:     if (!en || (lsa_comp(&lsa, &en->lsa) == CMP_NEWER))
                    580:     {
                    581:       /* 13. (5a) - enforce minimum time between updates for received LSAs */
                    582:       /* We also use this to ratelimit reactions to received self-originated LSAs */
                    583:       if (en && (lsa_inst_age(en) < MINLSARRIVAL))
                    584:       {
                    585:        OSPF_TRACE(D_EVENTS, "Skipping LSA received in less that MinLSArrival");
                    586:        continue;
                    587:       }
                    588: 
                    589:       /* Copy and validate LSA body */
                    590:       int blen = lsa.length - sizeof(struct ospf_lsa_header);
                    591:       void *body = mb_alloc(p->p.pool, blen);
                    592:       lsa_ntoh_body(lsa_n + 1, body, blen);
                    593: 
                    594:       if (lsa_validate(&lsa, lsa_type, ospf_is_v2(p), body) == 0)
                    595:       {
                    596:        mb_free(body);
                    597:        SKIP("invalid body");
                    598:       }
                    599: 
                    600:       /* 13. (5f) - handle self-originated LSAs, see also 13.4. */
                    601:       if (!p->gr_recovery &&
                    602:          ((lsa.rt == p->router_id) ||
                    603:           (ospf_is_v2(p) && (lsa_type == LSA_T_NET) && ospf_addr_is_local(p, ifa->oa, ipa_from_u32(lsa.id)))))
                    604:       {
                    605:        OSPF_TRACE(D_EVENTS, "Received unexpected self-originated LSA");
                    606:        ospf_advance_lsa(p, en, &lsa, lsa_type, lsa_domain, body);
                    607:        continue;
                    608:       }
                    609: 
                    610:       /* 13. (5c) - remove old LSA from all retransmission lists
                    611:        *
                    612:        * We only need to remove it from the retransmission list of the neighbor
                    613:        * that send us the new LSA. The old LSA is automatically replaced in
                    614:        * retransmission lists by the new LSA.
                    615:        */
                    616:       if (en)
                    617:        ospf_lsa_lsrt_down(en, n);
                    618: 
                    619: #if 0
                    620:       /*
                    621:        * Old code for removing LSA from all retransmission lists. Must be done
                    622:        * before (5b), otherwise it also removes the new entries from (5b).
                    623:        */
                    624:       struct ospf_iface *ifi;
                    625:       struct ospf_neighbor *ni;
                    626: 
                    627:       WALK_LIST(ifi, p->iface_list)
                    628:        WALK_LIST(ni, ifi->neigh_list)
                    629:          if (ni->state > NEIGHBOR_EXSTART)
                    630:            ospf_lsa_lsrt_down(en, ni);
                    631: #endif
                    632: 
                    633:       /* 13. (5d) - install new LSA into database */
                    634:       en = ospf_install_lsa(p, &lsa, lsa_type, lsa_domain, body);
                    635: 
                    636:       /* RFC 5340 4.4.3 Events 6+7 - new Link LSA received */
                    637:       if (lsa_type == LSA_T_LINK)
                    638:        ospf_notify_net_lsa(ifa);
                    639: 
                    640:       /* RFC 3623 3.1 - entering graceful restart helper mode */
                    641:       if (lsa_type == LSA_T_GR)
                    642:        ospf_neigh_notify_grace_lsa(n, en);
                    643: 
                    644:       /* Link received pre-restart router LSA */
                    645:       if (p->gr_recovery && (lsa_type == LSA_T_RT) && (lsa.rt == p->router_id))
                    646:        ifa->oa->rt = en;
                    647: 
                    648:       /* 13. (5b) - flood new LSA */
                    649:       int flood_back = ospf_flood_lsa(p, en, n);
                    650: 
                    651:       /* 13.5. - schedule ACKs (tbl 19, cases 1+2) */
                    652:       if (! flood_back)
                    653:        if ((ifa->state != OSPF_IS_BACKUP) || (n->rid == ifa->drid))
                    654:          ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY);
                    655: 
                    656:       /* FIXME: remove LSA entry if it is LSA_MAXAGE and it is possible? */
                    657: 
                    658:       continue;
                    659:     }
                    660: 
                    661:     /* 13. (6) - received LSA is in Link state request list (but not newer) */
                    662:     if (ospf_hash_find_entry(n->lsrqh, en) != NULL)
                    663:       DROP1("error in LSA database exchange");
                    664: 
                    665:     /* 13. (7) - received LSA is same */
                    666:     if (lsa_comp(&lsa, &en->lsa) == CMP_SAME)
                    667:     {
                    668:       /* Duplicate LSA, treat as implicit ACK */
                    669:       int implicit_ack = ospf_lsa_lsrt_down(en, n);
                    670: 
                    671:       /* 13.5. - schedule ACKs (tbl 19, cases 3+4) */
                    672:       if (implicit_ack)
                    673:       {
                    674:        if ((ifa->state == OSPF_IS_BACKUP) && (n->rid == ifa->drid))
                    675:          ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY);
                    676:       }
                    677:       else
                    678:        ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
                    679: 
                    680:       continue;
                    681:     }
                    682: 
                    683:     /* 13. (8) - received LSA is older */
                    684:     {
                    685:       /* Seqnum is wrapping, wait until it is flushed */
                    686:       if ((en->lsa.age == LSA_MAXAGE) && (en->lsa.sn == LSA_MAXSEQNO))
                    687:        continue;
                    688: 
                    689:       /* Send newer local copy back to neighbor */
                    690:       /* FIXME - check for MinLSArrival ? */
                    691:       ospf_send_lsupd(p, &en, 1, n);
                    692: 
                    693:       continue;
                    694:     }
                    695: 
                    696:   skip:
                    697:     LOG_LSA1("Bad LSA (Type: %04x, Id: %R, Rt: %R) in LSUPD", lsa_type, lsa.id, lsa.rt);
                    698:     LOG_LSA2("  received from nbr %R on %s - %s", n->rid, ifa->ifname, err_dsc);
                    699:   }
                    700: 
                    701:   /* Send direct LSACKs */
                    702:   ospf_send_lsack(p, n, ACKL_DIRECT);
                    703: 
                    704:   /* Send enqueued LSAs immediately, do not wait for flood_event */
                    705:   if (ev_active(p->flood_event))
                    706:   {
                    707:     ev_postpone(p->flood_event);
                    708:     ospf_flood_event(p);
                    709:   }
                    710: 
                    711:   /*
                    712:    * During loading, we should ask for another batch of LSAs. This is only
                    713:    * vaguely mentioned in RFC 2328. We send a new LSREQ if all requests sent in
                    714:    * the last packet were already answered and/or removed from the LS request
                    715:    * list and therefore lsrqi is pointing to the first node of the list.
                    716:    */
                    717:   if (!EMPTY_SLIST(n->lsrql) && (n->lsrqi == SHEAD(n->lsrql)))
                    718:   {
                    719:     ospf_send_lsreq(p, n);
                    720:     tm_start(n->lsrq_timer, n->ifa->rxmtint S);
                    721:   }
                    722: 
                    723:   return;
                    724: 
                    725: drop:
                    726:   LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)",
                    727:          n->rid, ifa->ifname, err_dsc, err_val);
                    728: 
                    729:   /* Malformed LSUPD - there is no defined error event, we abuse BadLSReq */
                    730:   ospf_neigh_sm(n, INM_BADLSREQ);
                    731:   return;
                    732: }

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