File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / proto / ospf / lsupd.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Aug 22 12:33:54 2017 UTC (6 years, 10 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, v1_6_3p0, v1_6_3, HEAD
bird 1.6.3

    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);
  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:       ospf_lsa_lsrt_up(en, n);
  176: 
  177:   /* If we found any flushed LSA, we send them ASAP */
  178:   if (tm_active(n->lsrt_timer))
  179:     tm_start(n->lsrt_timer, 0);
  180: }
  181: 
  182: 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);
  183: 
  184: static void
  185: ospf_enqueue_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa)
  186: {
  187:   if (ifa->flood_queue_used == ifa->flood_queue_size)
  188:   {
  189:     /* If we already have full queue, we send some packets */
  190:     uint sent = ospf_flood_lsupd(p, ifa->flood_queue, ifa->flood_queue_used, ifa->flood_queue_used / 2, ifa);
  191:     uint i;
  192: 
  193:     for (i = 0; i < sent; i++)
  194:       ifa->flood_queue[i]->ret_count--;
  195: 
  196:     ifa->flood_queue_used -= sent;
  197:     memmove(ifa->flood_queue, ifa->flood_queue + sent, ifa->flood_queue_used * sizeof(void *));
  198:     bzero(ifa->flood_queue + ifa->flood_queue_used, sent * sizeof(void *));
  199:   }
  200: 
  201:   en->ret_count++;
  202:   ifa->flood_queue[ifa->flood_queue_used] = en;
  203:   ifa->flood_queue_used++;
  204: 
  205:   if (!ev_active(p->flood_event))
  206:     ev_schedule(p->flood_event);
  207: }
  208: 
  209: void
  210: ospf_flood_event(void *ptr)
  211: {
  212:   struct ospf_proto *p = ptr;
  213:   struct ospf_iface *ifa;
  214:   int i, count;
  215: 
  216:   WALK_LIST(ifa, p->iface_list)
  217:   {
  218:     if (ifa->flood_queue_used == 0)
  219:       continue;
  220: 
  221:     count = ifa->flood_queue_used;
  222:     ospf_flood_lsupd(p, ifa->flood_queue, count, count, ifa);
  223: 
  224:     for (i = 0; i < count; i++)
  225:       ifa->flood_queue[i]->ret_count--;
  226: 
  227:     ifa->flood_queue_used = 0;
  228:     bzero(ifa->flood_queue, count * sizeof(void *));
  229:   }
  230: }
  231: 
  232: 
  233: /**
  234:  * ospf_flood_lsa - send LSA to the neighbors
  235:  * @p: OSPF protocol instance
  236:  * @en: LSA entry
  237:  * @from: neighbor than sent this LSA (or NULL if LSA is local)
  238:  *
  239:  * return value - was the LSA flooded back?
  240:  */
  241: int
  242: ospf_flood_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from)
  243: {
  244:   struct ospf_iface *ifa;
  245:   struct ospf_neighbor *n;
  246: 
  247:   /* RFC 2328 13.3 */
  248: 
  249:   int back = 0;
  250:   WALK_LIST(ifa, p->iface_list)
  251:   {
  252:     if (ifa->stub)
  253:       continue;
  254: 
  255:     if (! lsa_flooding_allowed(en->lsa_type, en->domain, ifa))
  256:       continue;
  257: 
  258:     DBG("Wanted to flood LSA: Type: %u, ID: %R, RT: %R, SN: 0x%x, Age %u\n",
  259: 	hh->type, hh->id, hh->rt, hh->sn, hh->age);
  260: 
  261:     int used = 0;
  262:     WALK_LIST(n, ifa->neigh_list)
  263:     {
  264:       /* 13.3 (1a) */
  265:       if (n->state < NEIGHBOR_EXCHANGE)
  266: 	continue;
  267: 
  268:       /* 13.3 (1b) */
  269:       if (n->state < NEIGHBOR_FULL)
  270:       {
  271: 	struct top_hash_entry *req = ospf_hash_find_entry(n->lsrqh, en);
  272: 	if (req != NULL)
  273: 	{
  274: 	  int cmp = lsa_comp(&en->lsa, &req->lsa);
  275: 
  276: 	  /* If same or newer, remove LSA from the link state request list */
  277: 	  if (cmp > CMP_OLDER)
  278: 	    ospf_lsa_lsrq_down(req, n);
  279: 
  280: 	  /* If older or same, skip processing of this neighbor */
  281: 	  if (cmp < CMP_NEWER)
  282: 	    continue;
  283: 	}
  284:       }
  285: 
  286:       /* 13.3 (1c) */
  287:       if (n == from)
  288: 	continue;
  289: 
  290:       /* In OSPFv3, there should be check whether receiving router understand
  291: 	 that type of LSA (for LSA types with U-bit == 0). But as we do not support
  292: 	 any optional LSA types, this is not needed yet */
  293: 
  294:       /* 13.3 (1d) - add LSA to the link state retransmission list */
  295:       ospf_lsa_lsrt_up(en, n);
  296: 
  297:       used = 1;
  298:     }
  299: 
  300:     /* 13.3 (2) */
  301:     if (!used)
  302:       continue;
  303: 
  304:     if (from && (from->ifa == ifa))
  305:     {
  306:       /* 13.3 (3) */
  307:       if ((from->rid == ifa->drid) || (from->rid == ifa->bdrid))
  308: 	continue;
  309: 
  310:       /* 13.3 (4) */
  311:       if (ifa->state == OSPF_IS_BACKUP)
  312: 	continue;
  313: 
  314:       back = 1;
  315:     }
  316: 
  317:     /* 13.3 (5) - finally flood the packet */
  318:     ospf_enqueue_lsa(p, en, ifa);
  319:   }
  320: 
  321:   return back;
  322: }
  323: 
  324: static uint
  325: ospf_prepare_lsupd(struct ospf_proto *p, struct ospf_iface *ifa,
  326: 		   struct top_hash_entry **lsa_list, uint lsa_count)
  327: {
  328:   struct ospf_packet *pkt;
  329:   uint hlen, pos, i, maxsize;
  330: 
  331:   pkt = ospf_tx_buffer(ifa);
  332:   hlen = ospf_lsupd_hdrlen(p);
  333:   maxsize = ospf_pkt_maxsize(ifa);
  334: 
  335:   ospf_pkt_fill_hdr(ifa, pkt, LSUPD_P);
  336:   pos = hlen;
  337: 
  338:   for (i = 0; i < lsa_count; i++)
  339:   {
  340:     struct top_hash_entry *en = lsa_list[i];
  341:     uint len = en->lsa.length;
  342: 
  343:     if ((pos + len) > maxsize)
  344:     {
  345:       /* The packet if full, stop adding LSAs and sent it */
  346:       if (i > 0)
  347: 	break;
  348: 
  349:       /* LSA is larger than MTU, check buffer size */
  350:       if (ospf_iface_assure_bufsize(ifa, pos + len) < 0)
  351:       {
  352: 	/* Cannot fit in a tx buffer, skip that */
  353: 	log(L_ERR "%s: LSA too large to send on %s (Type: %04x, Id: %R, Rt: %R)",
  354: 	    p->p.name, ifa->ifname, en->lsa_type, en->lsa.id, en->lsa.rt);
  355: 	break;
  356:       }
  357: 
  358:       /* TX buffer could be reallocated */
  359:       pkt = ospf_tx_buffer(ifa);
  360:     }
  361: 
  362:     struct ospf_lsa_header *buf = ((void *) pkt) + pos;
  363:     lsa_hton_hdr(&en->lsa, buf);
  364:     lsa_hton_body(en->lsa_body, ((void *) buf) + sizeof(struct ospf_lsa_header),
  365: 		  len - sizeof(struct ospf_lsa_header));
  366:     buf->age = htons(MIN(en->lsa.age + ifa->inftransdelay, LSA_MAXAGE));
  367: 
  368:     pos += len;
  369:   }
  370: 
  371:   ospf_lsupd_set_lsa_count(pkt, hlen, i);
  372:   pkt->length = htons(pos);
  373: 
  374:   return i;
  375: }
  376: 
  377: 
  378: static int
  379: ospf_flood_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, uint lsa_min_count, struct ospf_iface *ifa)
  380: {
  381:   uint i, c;
  382: 
  383:   for (i = 0; i < lsa_min_count; i += c)
  384:   {
  385:     c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i);
  386: 
  387:     if (!c)	/* Too large LSA */
  388:       { i++; continue; }
  389: 
  390:     OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa),
  391: 		"LSUPD packet flooded via %s", ifa->ifname);
  392: 
  393:     if (ifa->type == OSPF_IT_BCAST)
  394:     {
  395:       if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
  396: 	ospf_send_to_all(ifa);
  397:       else
  398: 	ospf_send_to_des(ifa);
  399:     }
  400:     else
  401:       ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
  402:   }
  403: 
  404:   return i;
  405: }
  406: 
  407: int
  408: ospf_send_lsupd(struct ospf_proto *p, struct top_hash_entry **lsa_list, uint lsa_count, struct ospf_neighbor *n)
  409: {
  410:   struct ospf_iface *ifa = n->ifa;
  411:   uint i, c;
  412: 
  413:   for (i = 0; i < lsa_count; i += c)
  414:   {
  415:     c = ospf_prepare_lsupd(p, ifa, lsa_list + i, lsa_count - i);
  416: 
  417:     if (!c)	/* Too large LSA */
  418:       { i++; continue; }
  419: 
  420:     OSPF_PACKET(ospf_dump_lsupd, ospf_tx_buffer(ifa),
  421: 		"LSUPD packet sent to nbr %R on %s", n->rid, ifa->ifname);
  422: 
  423:     ospf_send_to(ifa, n->ip);
  424:   }
  425: 
  426:   return i;
  427: }
  428: 
  429: void
  430: ospf_rxmt_lsupd(struct ospf_proto *p, struct ospf_neighbor *n)
  431: {
  432:   uint max = 2 * n->ifa->flood_queue_size;
  433:   struct top_hash_entry *entries[max];
  434:   struct top_hash_entry *ret, *nxt, *en;
  435:   uint i = 0;
  436: 
  437:   /* ASSERT((n->state >= NEIGHBOR_EXCHANGE) && !EMPTY_SLIST(n->lsrtl)); */
  438: 
  439:   WALK_SLIST_DELSAFE(ret, nxt, n->lsrtl)
  440:   {
  441:     if (i == max)
  442:       break;
  443: 
  444:     en = ospf_hash_find_entry(p->gr, ret);
  445:     if (!en)
  446:     {
  447:       /* Probably flushed LSA, this should not happen */
  448:       log(L_WARN "%s: LSA disappeared (Type: %04x, Id: %R, Rt: %R)",
  449: 	  p->p.name, ret->lsa_type, ret->lsa.id, ret->lsa.rt);
  450: 
  451:       s_rem_node(SNODE ret);
  452:       ospf_hash_delete(n->lsrth, ret);
  453: 
  454:       continue;
  455:     }
  456: 
  457:     entries[i] = en;
  458:     i++;
  459:   }
  460: 
  461:   ospf_send_lsupd(p, entries, i, n);
  462: }
  463: 
  464: 
  465: static inline int
  466: ospf_addr_is_local(struct ospf_proto *p, struct ospf_area *oa, ip_addr ip)
  467: {
  468:   struct ospf_iface *ifa;
  469:   WALK_LIST(ifa, p->iface_list)
  470:     if ((ifa->oa == oa) && ifa->addr && ipa_equal(ifa->addr->ip, ip))
  471:       return 1;
  472: 
  473:   return 0;
  474: }
  475: 
  476: void
  477: ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
  478: 		   struct ospf_neighbor *n)
  479: {
  480:   struct ospf_proto *p = ifa->oa->po;
  481:   const char *err_dsc = NULL;
  482:   uint plen, err_val = 0;
  483: 
  484:   /* RFC 2328 13. */
  485: 
  486:   plen = ntohs(pkt->length);
  487:   if (plen < ospf_lsupd_hdrlen(p))
  488:   {
  489:     LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)", n->rid, ifa->ifname, "too short", plen);
  490:     return;
  491:   }
  492: 
  493:   OSPF_PACKET(ospf_dump_lsupd, pkt, "LSUPD packet received from nbr %R on %s", n->rid, ifa->ifname);
  494: 
  495:   if (n->state < NEIGHBOR_EXCHANGE)
  496:   {
  497:     OSPF_TRACE(D_PACKETS, "LSUPD packet ignored - lesser state than Exchange");
  498:     return;
  499:   }
  500: 
  501:   ospf_neigh_sm(n, INM_HELLOREC);	/* Questionable */
  502: 
  503:   uint offset, i, lsa_count;
  504:   ospf_lsupd_body(p, pkt, &offset, &lsa_count);
  505: 
  506:   for (i = 0; i < lsa_count; i++)
  507:   {
  508:     struct ospf_lsa_header lsa, *lsa_n;
  509:     struct top_hash_entry *en;
  510:     u32 lsa_len, lsa_type, lsa_domain;
  511: 
  512:     if ((offset + sizeof(struct ospf_lsa_header)) > plen)
  513:       DROP("too short", plen);
  514: 
  515:     /* LSA header in network order */
  516:     lsa_n = ((void *) pkt) + offset;
  517:     lsa_len = ntohs(lsa_n->length);
  518:     offset += lsa_len;
  519: 
  520:     if (offset > plen)
  521:       DROP("too short", plen);
  522: 
  523:     if (((lsa_len % 4) != 0) || (lsa_len <= sizeof(struct ospf_lsa_header)))
  524:       DROP("invalid LSA length", lsa_len);
  525: 
  526:     /* LSA header in host order */
  527:     lsa_ntoh_hdr(lsa_n, &lsa);
  528:     lsa_get_type_domain(&lsa, ifa, &lsa_type, &lsa_domain);
  529: 
  530:     DBG("Update Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n",
  531: 	lsa_type, lsa.id, lsa.rt, lsa.sn, lsa.age, lsa.checksum);
  532: 
  533:     /* RFC 2328 13. (1) - verify LSA checksum */
  534:     if ((lsa_n->checksum == 0) || !lsa_verify_checksum(lsa_n, lsa_len))
  535:       SKIP("invalid checksum");
  536: 
  537:     /* RFC 2328 13. (2) */
  538:     if (!lsa_type)
  539:       SKIP("unknown type");
  540: 
  541:     /* RFC 5340 4.5.1 (2) and RFC 2328 13. (3) */
  542:     if (!oa_is_ext(ifa->oa) && (LSA_SCOPE(lsa_type) == LSA_SCOPE_AS))
  543:       SKIP("AS scope in stub area");
  544: 
  545:     /* Errata 3746 to RFC 2328 - rt-summary-LSAs forbidden in stub areas */
  546:     if (!oa_is_ext(ifa->oa) && (lsa_type == LSA_T_SUM_RT))
  547:       SKIP("rt-summary-LSA in stub area");
  548: 
  549:     /* RFC 5340 4.5.1 (3) */
  550:     if (LSA_SCOPE(lsa_type) == LSA_SCOPE_RES)
  551:       SKIP("invalid scope");
  552: 
  553:     /* Find local copy of LSA in link state database */
  554:     en = ospf_hash_find(p->gr, lsa_domain, lsa.id, lsa.rt, lsa_type);
  555: 
  556: #ifdef LOCAL_DEBUG
  557:     if (en)
  558:       DBG("I have Type: %04x, Id: %R, Rt: %R, Sn: 0x%08x, Age: %u, Sum: %u\n",
  559: 	  en->lsa_type, en->lsa.id, en->lsa.rt, en->lsa.sn, en->lsa.age, en->lsa.checksum);
  560: #endif
  561: 
  562:     /* 13. (4) - ignore maxage LSA if i have no local copy */
  563:     if ((lsa.age == LSA_MAXAGE) && !en && (p->padj == 0))
  564:     {
  565:       /* 13.5. - schedule ACKs (tbl 19, case 5) */
  566:       ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
  567:       continue;
  568:     }
  569: 
  570:     /* 13. (5) - received LSA is newer (or no local copy) */
  571:     if (!en || (lsa_comp(&lsa, &en->lsa) == CMP_NEWER))
  572:     {
  573:       /* 13. (5a) - enforce minimum time between updates for received LSAs */
  574:       /* We also use this to ratelimit reactions to received self-originated LSAs */
  575:       if (en && ((now - en->inst_time) < MINLSARRIVAL))
  576:       {
  577: 	OSPF_TRACE(D_EVENTS, "Skipping LSA received in less that MinLSArrival");
  578: 	continue;
  579:       }
  580: 
  581:       /* Copy and validate LSA body */
  582:       int blen = lsa.length - sizeof(struct ospf_lsa_header);
  583:       void *body = mb_alloc(p->p.pool, blen);
  584:       lsa_ntoh_body(lsa_n + 1, body, blen);
  585: 
  586:       if (lsa_validate(&lsa, lsa_type, ospf_is_v2(p), body) == 0)
  587:       {
  588: 	mb_free(body);
  589: 	SKIP("invalid body");
  590:       }
  591: 
  592:       /* 13. (5f) - handle self-originated LSAs, see also 13.4. */
  593:       if ((lsa.rt == p->router_id) ||
  594: 	  (ospf_is_v2(p) && (lsa_type == LSA_T_NET) && ospf_addr_is_local(p, ifa->oa, ipa_from_u32(lsa.id))))
  595:       {
  596: 	OSPF_TRACE(D_EVENTS, "Received unexpected self-originated LSA");
  597: 	ospf_advance_lsa(p, en, &lsa, lsa_type, lsa_domain, body);
  598: 	continue;
  599:       }
  600: 
  601:       /* 13. (5c) - remove old LSA from all retransmission lists
  602:        *
  603:        * We only need to remove it from the retransmission list of the neighbor
  604:        * that send us the new LSA. The old LSA is automatically replaced in
  605:        * retransmission lists by the new LSA.
  606:        */
  607:       if (en)
  608: 	ospf_lsa_lsrt_down(en, n);
  609: 
  610: #if 0
  611:       /*
  612:        * Old code for removing LSA from all retransmission lists. Must be done
  613:        * before (5b), otherwise it also removes the new entries from (5b).
  614:        */
  615:       struct ospf_iface *ifi;
  616:       struct ospf_neighbor *ni;
  617: 
  618:       WALK_LIST(ifi, p->iface_list)
  619: 	WALK_LIST(ni, ifi->neigh_list)
  620: 	  if (ni->state > NEIGHBOR_EXSTART)
  621: 	    ospf_lsa_lsrt_down(en, ni);
  622: #endif
  623: 
  624:       /* 13. (5d) - install new LSA into database */
  625:       en = ospf_install_lsa(p, &lsa, lsa_type, lsa_domain, body);
  626: 
  627:       /* RFC 5340 4.4.3 Events 6+7 - new Link LSA received */
  628:       if (lsa_type == LSA_T_LINK)
  629: 	ospf_notify_net_lsa(ifa);
  630: 
  631:       /* 13. (5b) - flood new LSA */
  632:       int flood_back = ospf_flood_lsa(p, en, n);
  633: 
  634:       /* 13.5. - schedule ACKs (tbl 19, cases 1+2) */
  635:       if (! flood_back)
  636: 	if ((ifa->state != OSPF_IS_BACKUP) || (n->rid == ifa->drid))
  637: 	  ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY);
  638: 
  639:       /* FIXME: remove LSA entry if it is LSA_MAXAGE and it is possible? */
  640: 
  641:       continue;
  642:     }
  643: 
  644:     /* 13. (6) - received LSA is in Link state request list (but not newer) */
  645:     if (ospf_hash_find_entry(n->lsrqh, en) != NULL)
  646:       DROP1("error in LSA database exchange");
  647: 
  648:     /* 13. (7) - received LSA is same */
  649:     if (lsa_comp(&lsa, &en->lsa) == CMP_SAME)
  650:     {
  651:       /* Duplicate LSA, treat as implicit ACK */
  652:       int implicit_ack = ospf_lsa_lsrt_down(en, n);
  653: 
  654:       /* 13.5. - schedule ACKs (tbl 19, cases 3+4) */
  655:       if (implicit_ack)
  656:       {
  657: 	if ((ifa->state == OSPF_IS_BACKUP) && (n->rid == ifa->drid))
  658: 	  ospf_enqueue_lsack(n, lsa_n, ACKL_DELAY);
  659:       }
  660:       else
  661: 	ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
  662: 
  663:       continue;
  664:     }
  665: 
  666:     /* 13. (8) - received LSA is older */
  667:     {
  668:       /* Seqnum is wrapping, wait until it is flushed */
  669:       if ((en->lsa.age == LSA_MAXAGE) && (en->lsa.sn == LSA_MAXSEQNO))
  670: 	continue;
  671: 
  672:       /* Send newer local copy back to neighbor */
  673:       /* FIXME - check for MinLSArrival ? */
  674:       ospf_send_lsupd(p, &en, 1, n);
  675: 
  676:       continue;
  677:     }
  678: 
  679:   skip:
  680:     LOG_LSA1("Bad LSA (Type: %04x, Id: %R, Rt: %R) in LSUPD", lsa_type, lsa.id, lsa.rt);
  681:     LOG_LSA2("  received from nbr %R on %s - %s", n->rid, ifa->ifname, err_dsc);
  682:   }
  683: 
  684:   /* Send direct LSACKs */
  685:   ospf_send_lsack(p, n, ACKL_DIRECT);
  686: 
  687:   /* Send enqueued LSAs immediately, do not wait for flood_event */
  688:   if (ev_active(p->flood_event))
  689:   {
  690:     ev_postpone(p->flood_event);
  691:     ospf_flood_event(p);
  692:   }
  693: 
  694:   /*
  695:    * During loading, we should ask for another batch of LSAs. This is only
  696:    * vaguely mentioned in RFC 2328. We send a new LSREQ if all requests sent in
  697:    * the last packet were already answered and/or removed from the LS request
  698:    * list and therefore lsrqi is pointing to the first node of the list.
  699:    */
  700:   if (!EMPTY_SLIST(n->lsrql) && (n->lsrqi == SHEAD(n->lsrql)))
  701:   {
  702:     ospf_send_lsreq(p, n);
  703:     tm_start(n->lsrq_timer, n->ifa->rxmtint);
  704:   }
  705: 
  706:   return;
  707: 
  708: drop:
  709:   LOG_PKT("Bad LSUPD packet from nbr %R on %s - %s (%u)",
  710: 	  n->rid, ifa->ifname, err_dsc, err_val);
  711: 
  712:   /* Malformed LSUPD - there is no defined error event, we abuse BadLSReq */
  713:   ospf_neigh_sm(n, INM_BADLSREQ);
  714:   return;
  715: }

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