Revision a7a7372a proto/ospf/lsupd.c

View differences:

proto/ospf/lsupd.c
115 115
    s_add_tail(&n->lsrtl, SNODE ret);
116 116
  }
117 117

  
118
  memcpy(&ret->lsa, &en->lsa, sizeof(struct ospf_lsa_header));
118
  ret->lsa = en->lsa;
119
  ret->lsa_body = LSA_BODY_DUMMY;
119 120
}
120 121

  
121 122
static inline int
......
134 135
  return 0;
135 136
}
136 137

  
138
void
139
ospf_add_flushed_to_lsrt(struct ospf_proto *p, struct ospf_neighbor *n)
140
{
141
  struct top_hash_entry *en;
142

  
143
  WALK_SLIST(en, p->lsal)
144
    if ((en->lsa.age == LSA_MAXAGE) && (en->lsa_body != NULL) &&
145
	lsa_flooding_allowed(en->lsa_type, en->domain, n->ifa))
146
      ospf_lsa_lsrt_up(en, n);
147
}
148

  
137 149

  
138
static void ospf_lsupd_flood_ifa(struct ospf_proto *p, struct ospf_iface *ifa, struct top_hash_entry *en);
150
static void ospf_send_lsupd_to_ifa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa);
139 151

  
140 152

  
141 153
/**
142
 * ospf_lsupd_flood - send received or generated LSA to the neighbors
143
 * @p: OSPF protocol
154
 * ospf_flood_lsa - send LSA to the neighbors
155
 * @p: OSPF protocol instance
144 156
 * @en: LSA entry
145 157
 * @from: neighbor than sent this LSA (or NULL if LSA is local)
146 158
 *
147 159
 * return value - was the LSA flooded back?
148 160
 */
149

  
150 161
int
151
ospf_lsupd_flood(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from)
162
ospf_flood_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from)
152 163
{
153 164
  struct ospf_iface *ifa;
154 165
  struct ospf_neighbor *n;
155 166

  
167
  /* RFC 2328 13.3 */
168

  
156 169
  int back = 0;
157 170
  WALK_LIST(ifa, p->iface_list)
158 171
  {
......
185 198
	  {
186 199
	    s_rem_node(SNODE req);
187 200
	    ospf_hash_delete(n->lsrqh, req);
201
	    n->want_lsreq = 1;
202

  
188 203
	    if ((EMPTY_SLIST(n->lsrql)) && (n->state == NEIGHBOR_LOADING))
189 204
	      ospf_neigh_sm(n, INM_LOADDONE);
190 205
	  }
......
227 242
    }
228 243

  
229 244
    /* 13.3 (5) - finally flood the packet */
230
    ospf_lsupd_flood_ifa(p, ifa, en);
245
    ospf_send_lsupd_to_ifa(p, en, ifa);
231 246
  }
232 247

  
233 248
  return back;
......
288 303

  
289 304

  
290 305
static void
291
ospf_lsupd_flood_ifa(struct ospf_proto *p, struct ospf_iface *ifa, struct top_hash_entry *en)
306
ospf_send_lsupd_to_ifa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa)
292 307
{
293 308
  uint c = ospf_prepare_lsupd(p, ifa, &en, 1);
294 309

  
......
384 399

  
385 400
  /* RFC 2328 13. */
386 401

  
387
  int sendreq = 1;	  /* XXXX: review sendreq */
402
  int skip_lsreq = 0;
403
  n->want_lsreq = 0;
388 404

  
389 405
  uint plen = ntohs(pkt->length);
390 406
  if (plen < (ospf_lsupd_hdrlen(p) + sizeof(struct ospf_lsa_header)))
......
436 452
    u16 chsum = lsa_n->checksum;
437 453
    if (chsum != lsasum_check(lsa_n, NULL))
438 454
    {
439
      log(L_WARN "%s: Received LSA from %I with bad checskum: %x %x",
455
      log(L_WARN "%s: Received LSA from %I with bad checksum: %x %x",
440 456
	  p->p.name, n->ip, chsum, lsa_n->checksum);
441 457
      continue;
442 458
    }
......
501 517
      if (en && ((now - en->inst_time) < MINLSARRIVAL))
502 518
      {
503 519
	OSPF_TRACE(D_EVENTS, "Skipping LSA received in less that MinLSArrival");
504
	sendreq = 0;
520
	skip_lsreq = 1;
505 521
	continue;
506 522
      }
507 523

  
......
514 530
      {
515 531
	log(L_WARN "%s: Received invalid LSA from %I", p->p.name, n->ip);
516 532
	mb_free(body);
517
	sendreq = 0;
518 533
	continue;
519 534
      }
520 535

  
......
528 543
      }
529 544

  
530 545
      /* 13. (5c) - remove old LSA from all retransmission lists */
531
      /* Must be done before (5b), otherwise it also removes the new entries from (5b) */
532

  
546
      /*
547
       * We only need to remove it from the retransmission list of the neighbor
548
       * that send us the new LSA. The old LSA is automatically replaced in
549
       * retransmission lists by the new LSA.
550
       */
533 551
      if (en)
534 552
	ospf_lsa_lsrt_down(en, n);
535 553

  
554
#if 0
536 555
      /*
537
      {
538
	struct ospf_iface *ifi;
539
	struct ospf_neighbor *ni;
540

  
541
	WALK_LIST(ifi, p->iface_list)
542
	  WALK_LIST(ni, ifi->neigh_list)
543
	    if (ni->state > NEIGHBOR_EXSTART)
544
	      ospf_lsa_lsrt_down(en, ni);
545
      }
546
      */
556
       * Old code for removing LSA from all retransmission lists. Must be done
557
       * before (5b), otherwise it also removes the new entries from (5b).
558
       */
559
      struct ospf_iface *ifi;
560
      struct ospf_neighbor *ni;
561

  
562
      WALK_LIST(ifi, p->iface_list)
563
	WALK_LIST(ni, ifi->neigh_list)
564
	if (ni->state > NEIGHBOR_EXSTART)
565
	  ospf_lsa_lsrt_down(en, ni);
566
#endif
547 567

  
548 568
      /* 13. (5d) - install new LSA into database */
549 569
      en = ospf_install_lsa(p, &lsa, lsa_type, lsa_domain, body);
......
553 573
	ospf_notify_net_lsa(ifa);
554 574

  
555 575
      /* 13. (5b) - flood new LSA */
556
      int flood_back = ospf_lsupd_flood(p, en, n);
576
      int flood_back = ospf_flood_lsa(p, en, n);
557 577

  
558 578
      /* 13.5. - schedule ACKs (tbl 19, cases 1+2) */ 
559 579
      if (! flood_back)
......
582 602
      else
583 603
	ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
584 604

  
585
      sendreq = 0;
605
      skip_lsreq = 1;
586 606
      continue;
587 607
    }
588 608

  
......
598 618
    }
599 619
  }
600 620

  
601
  /* Send direct LSAs */
602
  ospf_lsack_send(n, ACKL_DIRECT);
603

  
604
  /* If loading, ask for another part of neighbor's database */
605
  if (sendreq && (n->state == NEIGHBOR_LOADING))
621
  /* Send direct LSACKs */
622
  ospf_send_lsack(p, n, ACKL_DIRECT);
623

  
624
  /*
625
   * In loading state, we should ask for another batch of LSAs. This is only
626
   * vaguely mentioned in RFC 2328. We send a new LSREQ only if the current
627
   * LSUPD actually removed some entries from LSA request list (want_lsreq) and
628
   * did not contain duplicate or early LSAs (skip_lsreq). The first condition
629
   * prevents endless floods, the second condition helps with flow control.
630
   */
631
  if ((n->state == NEIGHBOR_LOADING) && n->want_lsreq && !skip_lsreq)
606 632
    ospf_send_lsreq(p, n);
607 633
}
608 634

  

Also available in: Unified diff