Revision a7a7372a proto/ospf/lsupd.c
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