Revision a7a7372a
nest/locks.c | ||
---|---|---|
22 | 22 |
* or some other non-shareable resource, it asks the core to lock it and it doesn't |
23 | 23 |
* use the resource until it's notified that it has acquired the lock. |
24 | 24 |
* |
25 |
* Object locks are represented by &object_lock structures which are in turn a kind of
|
|
26 |
* resource. Lockable resources are uniquely determined by resource type |
|
25 |
* Object locks are represented by &object_lock structures which are in turn a |
|
26 |
* kind of resource. Lockable resources are uniquely determined by resource type
|
|
27 | 27 |
* (%OBJLOCK_UDP for a UDP port etc.), IP address (usually a broadcast or |
28 |
* multicast address the port is bound to), port number and interface. |
|
28 |
* multicast address the port is bound to), port number, interface and optional |
|
29 |
* instance ID. |
|
29 | 30 |
*/ |
30 | 31 |
|
31 | 32 |
#undef LOCAL_DEBUG |
... | ... | |
45 | 46 |
x->type == y->type && |
46 | 47 |
x->iface == y->iface && |
47 | 48 |
x->port == y->port && |
49 |
x->inst == y->inst && |
|
48 | 50 |
ipa_equal(x->addr, y->addr); |
49 | 51 |
} |
50 | 52 |
|
... | ... | |
88 | 90 |
struct object_lock *l = (struct object_lock *) r; |
89 | 91 |
static char *olock_states[] = { "free", "locked", "waiting", "event" }; |
90 | 92 |
|
91 |
debug("(%d:%s:%I:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->port, olock_states[l->state]);
|
|
93 |
debug("(%d:%s:%I:%d:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->port, l->inst, olock_states[l->state]);
|
|
92 | 94 |
if (!EMPTY_LIST(l->waiters)) |
93 | 95 |
debug(" [wanted]\n"); |
94 | 96 |
} |
nest/locks.h | ||
---|---|---|
26 | 26 |
struct object_lock { |
27 | 27 |
resource r; |
28 | 28 |
ip_addr addr; /* Identification of a object: IP address */ |
29 |
unsigned int type; /* ... object type (OBJLOCK_xxx) */ |
|
29 |
uint type; /* ... object type (OBJLOCK_xxx) */ |
|
30 |
uint port; /* ... port number */ |
|
31 |
uint inst; /* ... instance ID */ |
|
30 | 32 |
struct iface *iface; /* ... interface */ |
31 |
unsigned int port; /* ... port number */ |
|
32 | 33 |
void (*hook)(struct object_lock *); /* Called when the lock succeeds */ |
33 | 34 |
void *data; /* User data */ |
34 | 35 |
/* ... internal to lock manager, don't touch ... */ |
proto/ospf/dbdes.c | ||
---|---|---|
200 | 200 |
* of the buffer. |
201 | 201 |
*/ |
202 | 202 |
void |
203 |
ospf_send_dbdes(struct ospf_neighbor *n, int next) |
|
203 |
ospf_send_dbdes(struct ospf_proto *p, struct ospf_neighbor *n, int next)
|
|
204 | 204 |
{ |
205 |
struct ospf_iface *ifa = n->ifa; |
|
206 |
struct ospf_area *oa = ifa->oa; |
|
207 |
struct ospf_proto *p = oa->po; |
|
208 |
|
|
209 | 205 |
/* RFC 2328 10.8 */ |
210 | 206 |
|
211 |
if (oa->rt == NULL) |
|
207 |
if (n->ifa->oa->rt == NULL)
|
|
212 | 208 |
return; |
213 | 209 |
|
214 | 210 |
switch (n->state) |
... | ... | |
312 | 308 |
s_add_tail(&n->lsrql, SNODE req); |
313 | 309 |
|
314 | 310 |
req->lsa = lsa; |
311 |
req->lsa_body = LSA_BODY_DUMMY; |
|
315 | 312 |
} |
316 | 313 |
} |
317 | 314 |
|
... | ... | |
394 | 391 |
n->imms = rcv_imms; |
395 | 392 |
OSPF_TRACE(D_PACKETS, "I'm slave to %I", n->ip); |
396 | 393 |
ospf_neigh_sm(n, INM_NEGDONE); |
397 |
ospf_send_dbdes(n, 1); |
|
394 |
ospf_send_dbdes(p, n, 1);
|
|
398 | 395 |
break; |
399 | 396 |
} |
400 | 397 |
|
... | ... | |
426 | 423 |
if (!(n->myimms & DBDES_MS)) |
427 | 424 |
{ |
428 | 425 |
/* Slave should retransmit dbdes packet */ |
429 |
ospf_send_dbdes(n, 0); |
|
426 |
ospf_send_dbdes(p, n, 0);
|
|
430 | 427 |
} |
431 | 428 |
return; |
432 | 429 |
} |
... | ... | |
472 | 469 |
if (!(n->myimms & DBDES_M) && !(n->imms & DBDES_M)) |
473 | 470 |
ospf_neigh_sm(n, INM_EXDONE); |
474 | 471 |
else |
475 |
ospf_send_dbdes(n, 1); |
|
472 |
ospf_send_dbdes(p, n, 1);
|
|
476 | 473 |
} |
477 | 474 |
else |
478 | 475 |
{ |
... | ... | |
489 | 486 |
if (ospf_process_dbdes(p, pkt, n) < 0) |
490 | 487 |
return; |
491 | 488 |
|
492 |
ospf_send_dbdes(n, 1); |
|
489 |
ospf_send_dbdes(p, n, 1);
|
|
493 | 490 |
} |
494 | 491 |
break; |
495 | 492 |
|
... | ... | |
504 | 501 |
if (!(n->myimms & DBDES_MS)) |
505 | 502 |
{ |
506 | 503 |
/* Slave should retransmit dbdes packet */ |
507 |
ospf_send_dbdes(n, 0); |
|
504 |
ospf_send_dbdes(p, n, 0);
|
|
508 | 505 |
} |
509 | 506 |
return; |
510 | 507 |
} |
proto/ospf/hello.c | ||
---|---|---|
275 | 275 |
/* Check consistency of existing neighbor entry */ |
276 | 276 |
if (n) |
277 | 277 |
{ |
278 |
unsigned t = ifa->type;
|
|
278 |
uint t = ifa->type;
|
|
279 | 279 |
if (ospf_is_v2(p) && ((t == OSPF_IT_BCAST) || (t == OSPF_IT_NBMA) || (t == OSPF_IT_PTMP))) |
280 | 280 |
{ |
281 | 281 |
/* Neighbor identified by IP address; Router ID may change */ |
proto/ospf/iface.c | ||
---|---|---|
620 | 620 |
|
621 | 621 |
add_tail(&oa->po->iface_list, NODE ifa); |
622 | 622 |
|
623 |
/* |
|
624 |
* In some cases we allow more ospf_ifaces on one physical iface. |
|
625 |
* In OSPFv2, if they use different IP address prefix. |
|
626 |
* In OSPFv3, if they use different instance_id. |
|
627 |
* Therefore, we store such info to lock->addr field. |
|
628 |
*/ |
|
629 |
|
|
630 |
// XXXX review |
|
631 | 623 |
struct object_lock *lock = olock_new(pool); |
632 |
lock->addr = ospf_is_v2(p) ? ifa->addr->prefix : _MI6(0,0,0,ifa->instance_id);
|
|
624 |
lock->addr = ospf_is_v2(p) ? ifa->addr->prefix : IPA_NONE;
|
|
633 | 625 |
lock->type = OBJLOCK_IP; |
634 | 626 |
lock->port = OSPF_PROTO; |
627 |
lock->inst = ifa->instance_id; |
|
635 | 628 |
lock->iface = iface; |
636 | 629 |
lock->data = ifa; |
637 | 630 |
lock->hook = ospf_iface_add; |
... | ... | |
997 | 990 |
BIT32_SET(s->ignore, id); |
998 | 991 |
|
999 | 992 |
/* If we already found it in previous areas, ignore it and add warning */ |
1000 |
if (!BIT32_TEST(s->active, id))
|
|
993 |
if (BIT32_TEST(s->active, id)) |
|
1001 | 994 |
{ s->warn = 1; continue; } |
1002 | 995 |
|
1003 | 996 |
BIT32_SET(s->active, id); |
... | ... | |
1046 | 1039 |
{ |
1047 | 1040 |
struct ospf_mip_walk s = { .iface = a->iface, .a = a }; |
1048 | 1041 |
while (ospf_walk_matching_iface_patts(p, &s)) |
1049 |
ospf_iface_new(s.oa, s.a, s.ip);
|
|
1042 |
ospf_iface_new(s.oa, a, s.ip); |
|
1050 | 1043 |
} |
1051 | 1044 |
|
1052 | 1045 |
if (flags & IF_CHANGE_DOWN) |
... | ... | |
1078 | 1071 |
{ |
1079 | 1072 |
struct ospf_mip_walk s = { .iface = a->iface }; |
1080 | 1073 |
while (ospf_walk_matching_iface_patts(p, &s)) |
1081 |
ospf_iface_new(s.oa, s.a, s.ip);
|
|
1074 |
ospf_iface_new(s.oa, a, s.ip); |
|
1082 | 1075 |
} |
1083 | 1076 |
|
1084 | 1077 |
if (flags & IF_CHANGE_DOWN) |
proto/ospf/lsack.c | ||
---|---|---|
79 | 79 |
} |
80 | 80 |
|
81 | 81 |
static inline void |
82 |
ospf_send_lsack(struct ospf_neighbor *n, int queue)
|
|
82 |
ospf_send_lsack_(struct ospf_proto *p, struct ospf_neighbor *n, int queue)
|
|
83 | 83 |
{ |
84 | 84 |
struct ospf_iface *ifa = n->ifa; |
85 |
struct ospf_proto *p = ifa->oa->po; |
|
86 | 85 |
struct ospf_lsa_header *lsas; |
87 | 86 |
struct ospf_packet *pkt; |
88 | 87 |
struct lsa_node *no; |
... | ... | |
121 | 120 |
} |
122 | 121 |
|
123 | 122 |
void |
124 |
ospf_lsack_send(struct ospf_neighbor *n, int queue)
|
|
123 |
ospf_send_lsack(struct ospf_proto *p, struct ospf_neighbor *n, int queue)
|
|
125 | 124 |
{ |
126 | 125 |
while (!EMPTY_LIST(n->ackl[queue])) |
127 |
ospf_send_lsack(n, queue);
|
|
126 |
ospf_send_lsack_(p, n, queue);
|
|
128 | 127 |
} |
129 | 128 |
|
130 | 129 |
void |
... | ... | |
160 | 159 |
|
161 | 160 |
if (lsa_comp(&lsa, &ret->lsa) != CMP_SAME) |
162 | 161 |
{ |
163 |
if ((lsa.sn == LSA_MAXSEQNO) && (lsa.age == LSA_MAXAGE)) |
|
164 |
continue; |
|
165 |
|
|
166 | 162 |
OSPF_TRACE(D_PACKETS, "Strange LSACK from %I", n->ip); |
167 | 163 |
OSPF_TRACE(D_PACKETS, "Type: %04x, Id: %R, Rt: %R", |
168 | 164 |
lsa_type, lsa.id, lsa.rt); |
proto/ospf/lsreq.c | ||
---|---|---|
71 | 71 |
ospf_pkt_fill_hdr(ifa, pkt, LSREQ_P); |
72 | 72 |
ospf_lsreq_body(p, pkt, &lsrs, &lsr_max); |
73 | 73 |
|
74 |
// for (i = 0; i < lsr_max; i++) |
|
74 |
/* We send smaller LSREQ to prevent multiple LSACKs as answer */ |
|
75 |
lsr_max = lsr_max / 4; |
|
75 | 76 |
|
76 | 77 |
i = 0; |
77 | 78 |
WALK_SLIST(en, n->lsrql) |
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 |
|
proto/ospf/neighbor.c | ||
---|---|---|
33 | 33 |
static void ackd_timer_hook(timer * t); |
34 | 34 |
|
35 | 35 |
static void |
36 |
init_lists(struct ospf_neighbor *n) |
|
36 |
init_lists(struct ospf_proto *p, struct ospf_neighbor *n)
|
|
37 | 37 |
{ |
38 | 38 |
s_init_list(&(n->lsrql)); |
39 |
n->lsrqh = ospf_top_new(n->pool); |
|
39 |
n->lsrqh = ospf_top_new(p, n->pool);
|
|
40 | 40 |
|
41 | 41 |
s_init_list(&(n->lsrtl)); |
42 |
n->lsrth = ospf_top_new(n->pool); |
|
42 |
n->lsrth = ospf_top_new(p, n->pool); |
|
43 |
} |
|
44 |
|
|
45 |
static void |
|
46 |
release_lsrtl(struct ospf_proto *p, struct ospf_neighbor *n) |
|
47 |
{ |
|
48 |
struct top_hash_entry *ret, *en; |
|
49 |
|
|
50 |
WALK_SLIST(ret, n->lsrtl) |
|
51 |
{ |
|
52 |
en = ospf_hash_find_entry(p->gr, ret); |
|
53 |
if (en) |
|
54 |
en->ret_count--; |
|
55 |
} |
|
43 | 56 |
} |
44 | 57 |
|
45 | 58 |
/* Resets LSA request and retransmit lists. |
... | ... | |
47 | 60 |
* it is reset during entering EXCHANGE state. |
48 | 61 |
*/ |
49 | 62 |
static void |
50 |
reset_lists(struct ospf_neighbor *n) |
|
63 |
reset_lists(struct ospf_proto *p, struct ospf_neighbor *n)
|
|
51 | 64 |
{ |
65 |
release_lsrtl(p,n); |
|
52 | 66 |
ospf_top_free(n->lsrqh); |
53 | 67 |
ospf_top_free(n->lsrth); |
54 |
init_lists(n); |
|
68 |
init_lists(p, n);
|
|
55 | 69 |
} |
56 | 70 |
|
57 | 71 |
struct ospf_neighbor * |
... | ... | |
68 | 82 |
n->csn = 0; |
69 | 83 |
n->state = NEIGHBOR_DOWN; |
70 | 84 |
|
71 |
init_lists(n); |
|
85 |
init_lists(p, n);
|
|
72 | 86 |
s_init(&(n->dbsi), &(p->lsal)); |
73 | 87 |
|
74 | 88 |
n->inactim = tm_new(pool); |
... | ... | |
360 | 374 |
s_get(&(n->dbsi)); |
361 | 375 |
s_init(&(n->dbsi), &p->lsal); |
362 | 376 |
|
377 |
/* Add MaxAge LSA entries to retransmission list */ |
|
378 |
ospf_add_flushed_to_lsrt(p, n); |
|
379 |
|
|
380 |
/* FIXME: Why is this here ? */ |
|
363 | 381 |
ospf_reset_lsack_queue(n); |
364 | 382 |
} |
365 | 383 |
else |
... | ... | |
388 | 406 |
if (n->state >= NEIGHBOR_EXSTART) |
389 | 407 |
if (!can_do_adj(n)) |
390 | 408 |
{ |
391 |
reset_lists(n); |
|
409 |
reset_lists(p,n);
|
|
392 | 410 |
neigh_chstate(n, NEIGHBOR_2WAY); |
393 | 411 |
} |
394 | 412 |
break; |
... | ... | |
399 | 417 |
case INM_BADLSREQ: |
400 | 418 |
if (n->state >= NEIGHBOR_EXCHANGE) |
401 | 419 |
{ |
402 |
reset_lists(n); |
|
420 |
reset_lists(p, n);
|
|
403 | 421 |
neigh_chstate(n, NEIGHBOR_EXSTART); |
404 | 422 |
} |
405 | 423 |
break; |
... | ... | |
407 | 425 |
case INM_KILLNBR: |
408 | 426 |
case INM_LLDOWN: |
409 | 427 |
case INM_INACTTIM: |
410 |
reset_lists(n); |
|
428 |
reset_lists(p, n);
|
|
411 | 429 |
neigh_chstate(n, NEIGHBOR_DOWN); |
412 | 430 |
break; |
413 | 431 |
|
414 | 432 |
case INM_1WAYREC: |
415 |
reset_lists(n); |
|
433 |
reset_lists(p, n);
|
|
416 | 434 |
neigh_chstate(n, NEIGHBOR_INIT); |
417 | 435 |
break; |
418 | 436 |
|
... | ... | |
552 | 570 |
nn->found = 0; |
553 | 571 |
} |
554 | 572 |
|
555 |
s_get(&(n->dbsi)); |
|
556 | 573 |
neigh_chstate(n, NEIGHBOR_DOWN); |
574 |
|
|
575 |
s_get(&(n->dbsi)); |
|
576 |
release_lsrtl(p, n); |
|
557 | 577 |
rem_node(NODE n); |
558 | 578 |
rfree(n->pool); |
559 | 579 |
OSPF_TRACE(D_EVENTS, "Deleting neigbor %R", n->rid); |
... | ... | |
620 | 640 |
} |
621 | 641 |
|
622 | 642 |
static void |
623 |
rxmt_timer_hook(timer * timer)
|
|
643 |
rxmt_timer_hook(timer *t)
|
|
624 | 644 |
{ |
625 |
struct ospf_neighbor *n = (struct ospf_neighbor *) timer->data;
|
|
645 |
struct ospf_neighbor *n = t->data;
|
|
626 | 646 |
struct ospf_proto *p = n->ifa->oa->po; |
627 | 647 |
|
628 | 648 |
DBG("%s: RXMT timer fired on interface %s for neigh %I\n", |
... | ... | |
631 | 651 |
switch (n->state) |
632 | 652 |
{ |
633 | 653 |
case NEIGHBOR_EXSTART: |
634 |
ospf_send_dbdes(n, 1); |
|
654 |
ospf_send_dbdes(p, n, 1);
|
|
635 | 655 |
return; |
636 | 656 |
|
637 | 657 |
case NEIGHBOR_EXCHANGE: |
638 | 658 |
if (n->myimms & DBDES_MS) |
639 |
ospf_send_dbdes(n, 0); |
|
659 |
ospf_send_dbdes(p, n, 0);
|
|
640 | 660 |
case NEIGHBOR_LOADING: |
641 | 661 |
ospf_send_lsreq(p, n); |
642 | 662 |
return; |
... | ... | |
653 | 673 |
} |
654 | 674 |
|
655 | 675 |
static void |
656 |
ackd_timer_hook(timer * t)
|
|
676 |
ackd_timer_hook(timer *t) |
|
657 | 677 |
{ |
658 | 678 |
struct ospf_neighbor *n = t->data; |
659 |
ospf_lsack_send(n, ACKL_DELAY); |
|
679 |
struct ospf_proto *p = n->ifa->oa->po; |
|
680 |
|
|
681 |
DBG("%s: ACKD timer fired on interface %s for neigh %I\n", |
|
682 |
p->p.name, n->ifa->ifname, n->ip); |
|
683 |
|
|
684 |
ospf_send_lsack(p, n, ACKL_DELAY); |
|
660 | 685 |
} |
proto/ospf/ospf.c | ||
---|---|---|
11 | 11 |
/** |
12 | 12 |
* DOC: Open Shortest Path First (OSPF) |
13 | 13 |
* |
14 |
* The OSPF protocol is quite complicated and its complex implemenation is |
|
15 |
* split to many files. In |ospf.c|, you will find mainly the interface |
|
16 |
* for communication with the core (e.g., reconfiguration hooks, shutdown |
|
17 |
* and initialisation and so on). In |packet.c|, you will find various |
|
18 |
* functions for sending and receiving generic OSPF packets. There are |
|
19 |
* also routines for authentication and checksumming. File |iface.c| contains |
|
20 |
* the interface state machine and functions for allocation and deallocation of OSPF's |
|
21 |
* interface data structures. Source |neighbor.c| includes the neighbor state |
|
22 |
* machine and functions for election of Designated Router and Backup |
|
23 |
* Designated router. In |hello.c|, there are routines for sending |
|
24 |
* and receiving of hello packets as well as functions for maintaining |
|
25 |
* wait times and the inactivity timer. Files |lsreq.c|, |lsack.c|, |dbdes.c| |
|
26 |
* contain functions for sending and receiving of link-state requests, |
|
27 |
* link-state acknowledgements and database descriptions respectively. |
|
28 |
* In |lsupd.c|, there are functions for sending and receiving |
|
29 |
* of link-state updates and also the flooding algorithm. Source |topology.c| is |
|
30 |
* a place where routines for searching LSAs in the link-state database, |
|
31 |
* adding and deleting them reside, there also are functions for originating |
|
32 |
* of various types of LSAs (router LSA, net LSA, external LSA). File |rt.c| |
|
33 |
* contains routines for calculating the routing table. |lsalib.c| is a set |
|
34 |
* of various functions for working with the LSAs (endianity conversions, |
|
35 |
* calculation of checksum etc.). |
|
14 |
* The OSPF protocol is quite complicated and its complex implemenation is split |
|
15 |
* to many files. In |ospf.c|, you will find mainly the interface for |
|
16 |
* communication with the core (e.g., reconfiguration hooks, shutdown and |
|
17 |
* initialisation and so on). File |iface.c| contains the interface state |
|
18 |
* machine and functions for allocation and deallocation of OSPF's interface |
|
19 |
* data structures. Source |neighbor.c| includes the neighbor state machine and |
|
20 |
* functions for election of Designated Router and Backup Designated router. In |
|
21 |
* |packet.c|, you will find various functions for sending and receiving generic |
|
22 |
* OSPF packets. There are also routines for authentication and checksumming. |
|
23 |
* In |hello.c|, there are routines for sending and receiving of hello packets |
|
24 |
* as well as functions for maintaining wait times and the inactivity timer. |
|
25 |
* Files |lsreq.c|, |lsack.c|, |dbdes.c| contain functions for sending and |
|
26 |
* receiving of link-state requests, link-state acknowledgements and database |
|
27 |
* descriptions respectively. In |lsupd.c|, there are functions for sending and |
|
28 |
* receiving of link-state updates and also the flooding algorithm. Source |
|
29 |
* |topology.c| is a place where routines for searching LSAs in the link-state |
|
30 |
* database, adding and deleting them reside, there also are functions for |
|
31 |
* originating of various types of LSAs (router LSA, net LSA, external LSA). |
|
32 |
* File |rt.c| contains routines for calculating the routing table. |lsalib.c| |
|
33 |
* is a set of various functions for working with the LSAs (endianity |
|
34 |
* conversions, calculation of checksum etc.). |
|
36 | 35 |
* |
37 |
* One instance of the protocol is able to hold LSA databases for |
|
38 |
* multiple OSPF areas, to exchange routing information between |
|
39 |
* multiple neighbors and to calculate the routing tables. The core |
|
40 |
* structure is &ospf_proto to which multiple &ospf_area and |
|
41 |
* &ospf_iface structures are connected. &ospf_area is also connected to |
|
42 |
* &top_hash_graph which is a dynamic hashing structure that |
|
43 |
* describes the link-state database. It allows fast search, addition |
|
44 |
* and deletion. Each LSA is kept in two pieces: header and body. Both of them are |
|
36 |
* One instance of the protocol is able to hold LSA databases for multiple OSPF |
|
37 |
* areas, to exchange routing information between multiple neighbors and to |
|
38 |
* calculate the routing tables. The core structure is &ospf_proto to which |
|
39 |
* multiple &ospf_area and &ospf_iface structures are connected. &ospf_proto is |
|
40 |
* also connected to &top_hash_graph which is a dynamic hashing structure that |
|
41 |
* describes the link-state database. It allows fast search, addition and |
|
42 |
* deletion. Each LSA is kept in two pieces: header and body. Both of them are |
|
45 | 43 |
* kept in the endianity of the CPU. |
46 | 44 |
* |
47 |
* In OSPFv2 specification, it is implied that there is one IP prefix |
|
48 |
* for each physical network/interface (unless it is an ptp link). But |
|
49 |
* in modern systems, there might be more independent IP prefixes |
|
50 |
* associated with an interface. To handle this situation, we have |
|
51 |
* one &ospf_iface for each active IP prefix (instead for each active |
|
52 |
* iface); This behaves like virtual interface for the purpose of OSPF. |
|
53 |
* If we receive packet, we associate it with a proper virtual interface |
|
54 |
* mainly according to its source address. |
|
45 |
* In OSPFv2 specification, it is implied that there is one IP prefix for each |
|
46 |
* physical network/interface (unless it is an ptp link). But in modern systems, |
|
47 |
* there might be more independent IP prefixes associated with an interface. To |
|
48 |
* handle this situation, we have one &ospf_iface for each active IP prefix |
|
49 |
* (instead for each active iface); This behaves like virtual interface for the |
|
50 |
* purpose of OSPF. If we receive packet, we associate it with a proper virtual |
|
51 |
* interface mainly according to its source address. |
|
55 | 52 |
* |
56 |
* OSPF keeps one socket per &ospf_iface. This allows us (compared to |
|
57 |
* one socket approach) to evade problems with a limit of multicast |
|
58 |
* groups per socket and with sending multicast packets to appropriate |
|
59 |
* interface in a portable way. The socket is associated with |
|
60 |
* underlying physical iface and should not receive packets received |
|
61 |
* on other ifaces (unfortunately, this is not true on |
|
62 |
* BSD). Generally, one packet can be received by more sockets (for |
|
63 |
* example, if there are more &ospf_iface on one physical iface), |
|
64 |
* therefore we explicitly filter received packets according to |
|
65 |
* src/dst IP address and received iface. |
|
53 |
* OSPF keeps one socket per &ospf_iface. This allows us (compared to one socket |
|
54 |
* approach) to evade problems with a limit of multicast groups per socket and |
|
55 |
* with sending multicast packets to appropriate interface in a portable way. |
|
56 |
* The socket is associated with underlying physical iface and should not |
|
57 |
* receive packets received on other ifaces (unfortunately, this is not true on |
|
58 |
* BSD). Generally, one packet can be received by more sockets (for example, if |
|
59 |
* there are more &ospf_iface on one physical iface), therefore we explicitly |
|
60 |
* filter received packets according to src/dst IP address and received iface. |
|
66 | 61 |
* |
67 |
* Vlinks are implemented using particularly degenerate form of |
|
68 |
* &ospf_iface, which has several exceptions: it does not have its |
|
69 |
* iface or socket (it copies these from 'parent' &ospf_iface) and it |
|
70 |
* is present in iface list even when down (it is not freed in |
|
71 |
* ospf_iface_down()). |
|
62 |
* Vlinks are implemented using particularly degenerate form of &ospf_iface, |
|
63 |
* which has several exceptions: it does not have its iface or socket (it copies |
|
64 |
* these from 'parent' &ospf_iface) and it is present in iface list even when |
|
65 |
* down (it is not freed in ospf_iface_down()). |
|
72 | 66 |
* |
73 | 67 |
* The heart beat of ospf is ospf_disp(). It is called at regular intervals |
74 |
* (&ospf_proto->tick). It is responsible for aging and flushing of LSAs in |
|
75 |
* the database, for routing table calculaction and it call area_disp() of every
|
|
76 |
* ospf_area.
|
|
68 |
* (&ospf_proto->tick). It is responsible for aging and flushing of LSAs in the
|
|
69 |
* database, updating topology information in LSAs and for routing table
|
|
70 |
* calculation.
|
|
77 | 71 |
* |
78 |
* The function area_disp() is |
|
79 |
* responsible for late originating of router LSA and network LSA |
|
80 |
* and for cleanup before routing table calculation process in |
|
81 |
* the area. |
|
82 |
* To every &ospf_iface, we connect one or more |
|
83 |
* &ospf_neighbor's -- a structure containing many timers and queues |
|
84 |
* for building adjacency and for exchange of routing messages. |
|
72 |
* To every &ospf_iface, we connect one or more &ospf_neighbor's -- a structure |
|
73 |
* containing many timers and queues for building adjacency and for exchange of |
|
74 |
* routing messages. |
|
85 | 75 |
* |
86 |
* BIRD's OSPF implementation respects RFC2328 in every detail, but |
|
87 |
* some of internal algorithms do differ. The RFC recommends making a snapshot |
|
88 |
* of the link-state database when a new adjacency is forming and sending |
|
89 |
* the database description packets based on the information in this |
|
90 |
* snapshot. The database can be quite large in some networks, so |
|
91 |
* rather we walk through a &slist structure which allows us to |
|
92 |
* continue even if the actual LSA we were working with is deleted. New |
|
93 |
* LSAs are added at the tail of this &slist. |
|
76 |
* BIRD's OSPF implementation respects RFC2328 in every detail, but some of |
|
77 |
* internal algorithms do differ. The RFC recommends making a snapshot of the |
|
78 |
* link-state database when a new adjacency is forming and sending the database |
|
79 |
* description packets based on the information in this snapshot. The database |
|
80 |
* can be quite large in some networks, so rather we walk through a &slist |
|
81 |
* structure which allows us to continue even if the actual LSA we were working |
|
82 |
* with is deleted. New LSAs are added at the tail of this &slist. |
|
94 | 83 |
* |
95 |
* We also don't keep a separate OSPF routing table, because the core |
|
96 |
* helps us by being able to recognize when a route is updated |
|
97 |
* to an identical one and it suppresses the update automatically. |
|
98 |
* Due to this, we can flush all the routes we've recalculated and |
|
99 |
* also those we've deleted to the core's routing table and the |
|
100 |
* core will take care of the rest. This simplifies the process |
|
84 |
* We also do not keep a separate OSPF routing table, because the core helps us |
|
85 |
* by being able to recognize when a route is updated to an identical one and it |
|
86 |
* suppresses the update automatically. Due to this, we can flush all the routes |
|
87 |
* we have recalculated and also those we have deleted to the core's routing |
|
88 |
* table and the core will take care of the rest. This simplifies the process |
|
101 | 89 |
* and conserves memory. |
102 | 90 |
*/ |
103 | 91 |
|
... | ... | |
145 | 133 |
} |
146 | 134 |
|
147 | 135 |
static void |
148 |
ospf_area_add(struct ospf_proto *p, struct ospf_area_config *ac, int reconf)
|
|
136 |
ospf_area_add(struct ospf_proto *p, struct ospf_area_config *ac) |
|
149 | 137 |
{ |
150 | 138 |
struct ospf_area *oa; |
151 | 139 |
|
... | ... | |
169 | 157 |
oa->options = ac->type; |
170 | 158 |
else |
171 | 159 |
oa->options = ac->type | OPT_V6 | (p->stub_router ? 0 : OPT_R); |
160 |
|
|
161 |
ospf_notify_rt_lsa(oa); |
|
172 | 162 |
} |
173 | 163 |
|
174 | 164 |
static void |
... | ... | |
252 | 242 |
init_list(&(p->area_list)); |
253 | 243 |
fib_init(&p->rtf, P->pool, sizeof(ort), 0, ospf_rt_initort); |
254 | 244 |
p->areano = 0; |
255 |
p->gr = ospf_top_new(P->pool); |
|
245 |
p->gr = ospf_top_new(p, P->pool);
|
|
256 | 246 |
s_init_list(&(p->lsal)); |
257 | 247 |
|
258 | 248 |
WALK_LIST(ac, c->area_list) |
259 |
ospf_area_add(p, ac, 0);
|
|
249 |
ospf_area_add(p, ac); |
|
260 | 250 |
|
261 | 251 |
if (c->abr) |
262 | 252 |
ospf_open_vlink_sk(p); |
... | ... | |
382 | 372 |
|
383 | 373 |
|
384 | 374 |
void |
385 |
schedule_rtcalc(struct ospf_proto *p) |
|
375 |
ospf_schedule_rtcalc(struct ospf_proto *p)
|
|
386 | 376 |
{ |
387 | 377 |
if (p->calcrt) |
388 | 378 |
return; |
... | ... | |
418 | 408 |
/* Originate or flush local topology LSAs */ |
419 | 409 |
ospf_update_topology(p); |
420 | 410 |
|
421 |
/* Age LSA DB */
|
|
411 |
/* Process LSA DB */
|
|
422 | 412 |
ospf_update_lsadb(p); |
423 | 413 |
|
424 | 414 |
/* Calculate routing table */ |
... | ... | |
429 | 419 |
|
430 | 420 |
/** |
431 | 421 |
* ospf_import_control - accept or reject new route from nest's routing table |
432 |
* @p: current instance of protocol
|
|
422 |
* @P: OSPF protocol instance
|
|
433 | 423 |
* @new: the new route |
434 | 424 |
* @attrs: list of attributes |
435 | 425 |
* @pool: pool for allocation of attributes |
... | ... | |
475 | 465 |
|
476 | 466 |
/** |
477 | 467 |
* ospf_shutdown - Finish of OSPF instance |
478 |
* @p: current instance of protocol
|
|
468 |
* @P: OSPF protocol instance
|
|
479 | 469 |
* |
480 | 470 |
* RFC does not define any action that should be taken before router |
481 | 471 |
* shutdown. To make my neighbors react as fast as possible, I send |
... | ... | |
619 | 609 |
|
620 | 610 |
/** |
621 | 611 |
* ospf_reconfigure - reconfiguration hook |
622 |
* @p: current instance of protocol (with old configuration)
|
|
612 |
* @P: current instance of protocol (with old configuration)
|
|
623 | 613 |
* @c: new configuration requested by user |
624 | 614 |
* |
625 | 615 |
* This hook tries to be a little bit intelligent. Instance of OSPF |
... | ... | |
669 | 659 |
if (oa) |
670 | 660 |
ospf_area_reconfigure(oa, nac); |
671 | 661 |
else |
672 |
ospf_area_add(p, nac, 1);
|
|
662 |
ospf_area_add(p, nac); |
|
673 | 663 |
} |
674 | 664 |
|
675 | 665 |
/* Add and update interfaces */ |
... | ... | |
697 | 687 |
if (oa->marked) |
698 | 688 |
ospf_area_remove(oa); |
699 | 689 |
|
700 |
schedule_rtcalc(p); |
|
690 |
ospf_schedule_rtcalc(p);
|
|
701 | 691 |
|
702 | 692 |
return 1; |
703 | 693 |
} |
... | ... | |
1009 | 999 |
/* In OSPFv2, we try to find network-LSA to get prefix/pxlen */ |
1010 | 1000 |
struct top_hash_entry *net_he = ospf_hash_find_net2(p->gr, he->domain, rtl.id); |
1011 | 1001 |
|
1012 |
if (net_he) |
|
1002 |
if (net_he && (net_he->lsa.age < LSA_MAXAGE))
|
|
1013 | 1003 |
{ |
1014 | 1004 |
struct ospf_lsa_header *net_lsa = &(net_he->lsa); |
1015 | 1005 |
struct ospf_lsa_net *net_ln = net_he->lsa_body; |
... | ... | |
1367 | 1357 |
ospf_sh_lsadb(struct lsadb_show_data *ld) |
1368 | 1358 |
{ |
1369 | 1359 |
struct ospf_proto *p = (struct ospf_proto *) proto_get_named(ld->name, &proto_ospf); |
1370 |
int num = p->gr->hash_entries; |
|
1371 |
unsigned int i, j;
|
|
1360 |
uint num = p->gr->hash_entries;
|
|
1361 |
uint i, j; |
|
1372 | 1362 |
int last_dscope = -1; |
1373 | 1363 |
u32 last_domain = 0; |
1374 | 1364 |
u16 type_mask = ospf_is_v2(p) ? 0x00ff : 0xffff; /* see lsa_etype() */ |
proto/ospf/ospf.h | ||
---|---|---|
102 | 102 |
struct ospf_config |
103 | 103 |
{ |
104 | 104 |
struct proto_config c; |
105 |
unsigned tick;
|
|
105 |
uint tick;
|
|
106 | 106 |
byte ospf2; |
107 | 107 |
byte rfc1583; |
108 | 108 |
byte stub_router; |
... | ... | |
110 | 110 |
byte abr; |
111 | 111 |
byte asbr; |
112 | 112 |
int ecmp; |
113 |
list area_list; /* list of struct ospf_area_config */
|
|
114 |
list vlink_list; /* list of struct ospf_iface_patt */
|
|
113 |
list area_list; /* list of area configs (struct ospf_area_config) */
|
|
114 |
list vlink_list; /* list of configured vlinks (struct ospf_iface_patt) */
|
|
115 | 115 |
}; |
116 | 116 |
|
117 |
struct nbma_node
|
|
117 |
struct ospf_area_config
|
|
118 | 118 |
{ |
119 | 119 |
node n; |
120 |
ip_addr ip; |
|
121 |
byte eligible; |
|
122 |
byte found; |
|
120 |
u32 areaid; |
|
121 |
u32 default_cost; /* Cost of default route for stub areas |
|
122 |
(With possible LSA_EXT3_EBIT for NSSA areas) */ |
|
123 |
u8 type; /* Area type (standard, stub, NSSA), represented |
|
124 |
by option flags (OPT_E, OPT_N) */ |
|
125 |
u8 summary; /* Import summaries to this stub/NSSA area, valid for ABR */ |
|
126 |
u8 default_nssa; /* Generate default NSSA route for NSSA+summary area */ |
|
127 |
u8 translator; /* Translator role, for NSSA ABR */ |
|
128 |
u32 transint; /* Translator stability interval */ |
|
129 |
list patt_list; /* List of iface configs (struct ospf_iface_patt) */ |
|
130 |
list net_list; /* List of aggregate networks for that area */ |
|
131 |
list enet_list; /* List of aggregate external (NSSA) networks */ |
|
132 |
list stubnet_list; /* List of stub networks added to Router LSA */ |
|
123 | 133 |
}; |
124 | 134 |
|
125 | 135 |
struct area_net_config |
... | ... | |
148 | 158 |
u8 summary; |
149 | 159 |
}; |
150 | 160 |
|
151 |
struct ospf_area_config
|
|
161 |
struct nbma_node
|
|
152 | 162 |
{ |
153 | 163 |
node n; |
154 |
u32 areaid; |
|
155 |
u32 default_cost; /* Cost of default route for stub areas |
|
156 |
(With possible LSA_EXT3_EBIT for NSSA areas) */ |
|
157 |
u8 type; /* Area type (standard, stub, NSSA), represented |
|
158 |
by option flags (OPT_E, OPT_N) */ |
|
159 |
u8 summary; /* Import summaries to this stub/NSSA area, valid for ABR */ |
|
160 |
u8 default_nssa; /* Generate default NSSA route for NSSA+summary area */ |
|
161 |
u8 translator; /* Translator role, for NSSA ABR */ |
|
162 |
u32 transint; /* Translator stability interval */ |
|
163 |
list patt_list; |
|
164 |
list net_list; /* List of aggregate networks for that area */ |
|
165 |
list enet_list; /* List of aggregate external (NSSA) networks */ |
|
166 |
list stubnet_list; /* List of stub networks added to Router LSA */ |
|
164 |
ip_addr ip; |
|
165 |
byte eligible; |
|
166 |
byte found; |
|
167 | 167 |
}; |
168 | 168 |
|
169 |
struct ospf_iface_patt |
|
170 |
{ |
|
171 |
struct iface_patt i; |
|
172 |
u32 type; |
|
173 |
u32 stub; |
|
174 |
u32 cost; |
|
175 |
u32 helloint; |
|
176 |
u32 rxmtint; |
|
177 |
u32 pollint; |
|
178 |
u32 waitint; |
|
179 |
u32 deadc; |
|
180 |
u32 deadint; |
|
181 |
u32 inftransdelay; |
|
182 |
list nbma_list; |
|
183 |
u32 priority; |
|
184 |
u32 voa; |
|
185 |
u32 vid; |
|
186 |
int tx_tos; |
|
187 |
int tx_priority; |
|
188 |
u16 tx_length; |
|
189 |
u16 rx_buffer; |
|
169 | 190 |
|
170 |
/* Generic option flags */ |
|
171 |
#define OPT_V6 0x01 /* OSPFv3, LSA relevant for IPv6 routing calculation */ |
|
172 |
#define OPT_E 0x02 /* Related to AS-external LSAs */ |
|
173 |
#define OPT_MC 0x04 /* Related to MOSPF, not used and obsolete */ |
|
174 |
#define OPT_N 0x08 /* Related to NSSA */ |
|
175 |
#define OPT_P 0x08 /* OSPFv2, flags P and N share position, see NSSA RFC */ |
|
176 |
#define OPT_EA 0x10 /* OSPFv2, external attributes, not used and obsolete */ |
|
177 |
#define OPT_R 0x10 /* OSPFv3, originator is active router */ |
|
178 |
#define OPT_DC 0x20 /* Related to demand circuits, not used */ |
|
179 |
|
|
180 |
/* Router-LSA VEB flags are are stored together with links (OSPFv2) or options (OSPFv3) */ |
|
181 |
#define OPT_RT_B (0x01 << 24) |
|
182 |
#define OPT_RT_E (0x02 << 24) |
|
183 |
#define OPT_RT_V (0x04 << 24) |
|
184 |
#define OPT_RT_NT (0x10 << 24) |
|
185 |
|
|
186 |
/* Prefix flags, specific for OSPFv3 */ |
|
187 |
#define OPT_PX_NU 0x01 |
|
188 |
#define OPT_PX_LA 0x02 |
|
189 |
#define OPT_PX_P 0x08 |
|
190 |
#define OPT_PX_DN 0x10 |
|
191 |
|
|
192 |
|
|
193 |
/* OSPF interface types */ |
|
194 |
#define OSPF_IT_BCAST 0 |
|
195 |
#define OSPF_IT_NBMA 1 |
|
196 |
#define OSPF_IT_PTP 2 |
|
197 |
#define OSPF_IT_PTMP 3 |
|
198 |
#define OSPF_IT_VLINK 4 |
|
199 |
#define OSPF_IT_UNDEF 5 |
|
200 |
|
|
201 |
/* OSPF interface states */ |
|
202 |
#define OSPF_IS_DOWN 0 /* Not active */ |
|
203 |
#define OSPF_IS_LOOP 1 /* Iface with no link */ |
|
204 |
#define OSPF_IS_WAITING 2 /* Waiting for Wait timer */ |
|
205 |
#define OSPF_IS_PTP 3 /* PTP operational */ |
|
206 |
#define OSPF_IS_DROTHER 4 /* I'm on BCAST or NBMA and I'm not DR */ |
|
207 |
#define OSPF_IS_BACKUP 5 /* I'm BDR */ |
|
208 |
#define OSPF_IS_DR 6 /* I'm DR */ |
|
209 |
|
|
191 |
#define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ |
|
192 |
u8 instance_id; |
|
193 |
u8 autype; /* Not really used in OSPFv3 */ |
|
194 |
#define OSPF_AUTH_NONE 0 |
|
195 |
#define OSPF_AUTH_SIMPLE 1 |
|
196 |
#define OSPF_AUTH_CRYPT 2 |
|
197 |
#define OSPF_AUTH_CRYPT_SIZE 16 |
|
198 |
u8 strictnbma; |
|
199 |
u8 check_link; |
|
200 |
u8 ecmp_weight; |
|
201 |
u8 link_lsa_suppression; |
|
202 |
u8 real_bcast; /* Not really used in OSPFv3 */ |
|
203 |
u8 ptp_netmask; /* bool + 2 for unspecified */ |
|
204 |
u8 ttl_security; /* bool + 2 for TX only */ |
|
205 |
u8 bfd; |
|
206 |
u8 bsd_secondary; |
|
207 |
list *passwords; |
|
208 |
}; |
|
210 | 209 |
|
211 | 210 |
/* Default values for interface parameters */ |
212 | 211 |
#define COST_D 10 |
... | ... | |
220 | 219 |
/* Value of Wait timer - not found it in RFC * - using 4*HELLO */ |
221 | 220 |
|
222 | 221 |
|
222 |
|
|
223 |
struct ospf_proto |
|
224 |
{ |
|
225 |
struct proto p; |
|
226 |
timer *disp_timer; /* OSPF proto dispatcher */ |
|
227 |
uint tick; |
|
228 |
struct top_graph *gr; /* LSA graph */ |
|
229 |
slist lsal; /* List of all LSA's */ |
|
230 |
int calcrt; /* Routing table calculation scheduled? |
|
231 |
0=no, 1=normal, 2=forced reload */ |
|
232 |
list iface_list; /* List of OSPF interfaces (struct ospf_iface) */ |
|
233 |
list area_list; /* List of OSPF areas (struct ospf_area) */ |
|
234 |
int areano; /* Number of area I belong to */ |
|
235 |
int padj; /* Number of neighbors in Exchange or Loading state */ |
|
236 |
struct fib rtf; /* Routing table */ |
|
237 |
byte ospf2; /* OSPF v2 or v3 */ |
|
238 |
byte rfc1583; /* RFC1583 compatibility */ |
|
239 |
byte stub_router; /* Do not forward transit traffic */ |
|
240 |
byte merge_external; /* Should i merge external routes? */ |
|
241 |
byte asbr; /* May i originate any ext/NSSA lsa? */ |
|
242 |
byte ecmp; /* Maximal number of nexthops in ECMP route, or 0 */ |
|
243 |
struct ospf_area *backbone; /* If exists */ |
|
244 |
void *lsab; /* LSA buffer used when originating router LSAs */ |
|
245 |
int lsab_size, lsab_used; |
|
246 |
linpool *nhpool; /* Linpool used for next hops computed in SPF */ |
|
247 |
sock *vlink_sk; /* IP socket used for vlink TX */ |
|
248 |
u32 router_id; |
|
249 |
u32 last_vlink_id; /* Interface IDs for vlinks (starts at 0x80000000) */ |
|
250 |
}; |
|
251 |
|
|
252 |
struct ospf_area |
|
253 |
{ |
|
254 |
node n; |
|
255 |
u32 areaid; |
|
256 |
struct ospf_area_config *ac; /* Related area config */ |
|
257 |
struct top_hash_entry *rt; /* My own router LSA */ |
|
258 |
struct top_hash_entry *pxr_lsa; /* Originated prefix LSA */ |
|
259 |
list cand; /* List of candidates for RT calc. */ |
|
260 |
struct fib net_fib; /* Networks to advertise or not */ |
|
261 |
struct fib enet_fib; /* External networks for NSSAs */ |
|
262 |
u32 options; /* Optional features */ |
|
263 |
u8 update_rt_lsa; /* Rt lsa origination scheduled? */ |
|
264 |
u8 trcap; /* Transit capability? */ |
|
265 |
u8 marked; /* Used in OSPF reconfigure */ |
|
266 |
u8 translate; /* Translator state (TRANS_*), for NSSA ABR */ |
|
267 |
timer *translator_timer; /* For NSSA translator switch */ |
|
268 |
struct ospf_proto *po; |
|
269 |
struct fib rtr; /* Routing tables for routers */ |
|
270 |
}; |
|
271 |
|
|
272 |
|
|
273 |
|
|
223 | 274 |
struct ospf_iface |
224 | 275 |
{ |
225 | 276 |
node n; |
... | ... | |
231 | 282 |
|
232 | 283 |
pool *pool; |
233 | 284 |
sock *sk; /* IP socket */ |
234 |
list neigh_list; /* List of neigbours */ |
|
285 |
list neigh_list; /* List of neigbours (struct ospf_neighbor) */
|
|
235 | 286 |
u32 cost; /* Cost of iface */ |
236 | 287 |
u32 waitint; /* number of sec before changing state from wait */ |
237 | 288 |
u32 rxmtint; /* number of seconds between LSA retransmissions */ |
... | ... | |
295 | 346 |
u8 bfd; /* Use BFD on iface */ |
296 | 347 |
}; |
297 | 348 |
|
349 |
struct ospf_neighbor |
|
350 |
{ |
|
351 |
node n; |
|
352 |
pool *pool; |
|
353 |
struct ospf_iface *ifa; |
|
354 |
u8 state; |
|
355 |
timer *inactim; /* Inactivity timer */ |
|
356 |
u8 imms; /* I, M, Master/slave received */ |
|
357 |
u8 myimms; /* I, M Master/slave */ |
|
358 |
u32 dds; /* DD Sequence number being sent */ |
|
359 |
u32 ddr; /* last Dat Des packet received */ |
|
360 |
|
|
361 |
u32 rid; /* Router ID */ |
|
362 |
ip_addr ip; /* IP of it's interface */ |
|
363 |
u8 priority; /* Priority */ |
|
364 |
u8 adj; /* built adjacency? */ |
|
365 |
u8 want_lsreq; /* Set to 1 when lsrql was shortened during LSUPD */ |
|
366 |
u32 options; /* Options received */ |
|
367 |
|
|
368 |
/* Entries dr and bdr store IP addresses in OSPFv2 and router IDs in |
|
369 |
OSPFv3, we use the same type to simplify handling */ |
|
370 |
u32 dr; /* Neigbour's idea of DR */ |
|
371 |
u32 bdr; /* Neigbour's idea of BDR */ |
|
372 |
u32 iface_id; /* ID of Neighbour's iface connected to common network */ |
|
373 |
|
|
374 |
/* Database summary list iterator, controls initial dbdes exchange. |
|
375 |
* Advances in the LSA list as dbdes packets are sent. |
|
376 |
*/ |
|
377 |
siterator dbsi; /* iterator of po->lsal */ |
|
378 |
|
|
379 |
/* Link state request list, controls initial LSA exchange. |
|
380 |
* Entries added when received in dbdes packets, removed as sent in lsreq packets. |
|
381 |
*/ |
|
382 |
slist lsrql; /* slist of struct top_hash_entry from n->lsrqh */ |
|
383 |
struct top_graph *lsrqh; |
|
384 |
|
|
385 |
/* Link state retransmission list, controls LSA retransmission during flood. |
|
386 |
* Entries added as sent in lsupd packets, removed when received in lsack packets. |
|
387 |
* These entries hold ret_count in appropriate LSA entries. |
|
388 |
*/ |
|
389 |
slist lsrtl; /* slist of struct top_hash_entry from n->lsrth */ |
|
390 |
struct top_graph *lsrth; |
|
391 |
timer *rxmt_timer; /* RXMT timer */ |
|
392 |
list ackl[2]; |
|
393 |
#define ACKL_DIRECT 0 |
|
394 |
#define ACKL_DELAY 1 |
|
395 |
timer *ackd_timer; /* Delayed ack timer */ |
|
396 |
struct bfd_request *bfd_req; /* BFD request, if BFD is used */ |
|
397 |
void *ldd_buffer; /* Last database description packet */ |
|
398 |
u32 ldd_bsize; /* Buffer size for ldd_buffer */ |
|
399 |
u32 csn; /* Last received crypt seq number (for MD5) */ |
|
400 |
}; |
|
401 |
|
|
402 |
|
|
403 |
/* OSPF interface types */ |
|
404 |
#define OSPF_IT_BCAST 0 |
|
405 |
#define OSPF_IT_NBMA 1 |
|
406 |
#define OSPF_IT_PTP 2 |
|
407 |
#define OSPF_IT_PTMP 3 |
|
408 |
#define OSPF_IT_VLINK 4 |
|
409 |
#define OSPF_IT_UNDEF 5 |
|
410 |
|
|
411 |
/* OSPF interface states */ |
|
412 |
#define OSPF_IS_DOWN 0 /* Not active */ |
|
413 |
#define OSPF_IS_LOOP 1 /* Iface with no link */ |
|
414 |
#define OSPF_IS_WAITING 2 /* Waiting for Wait timer */ |
|
415 |
#define OSPF_IS_PTP 3 /* PTP operational */ |
|
416 |
#define OSPF_IS_DROTHER 4 /* I'm on BCAST or NBMA and I'm not DR */ |
|
417 |
#define OSPF_IS_BACKUP 5 /* I'm BDR */ |
|
418 |
#define OSPF_IS_DR 6 /* I'm DR */ |
|
419 |
|
|
420 |
/* Definitions for interface state machine */ |
|
421 |
#define ISM_UP 0 /* Interface Up */ |
|
422 |
#define ISM_WAITF 1 /* Wait timer fired */ |
|
423 |
#define ISM_BACKS 2 /* Backup seen */ |
|
424 |
#define ISM_NEICH 3 /* Neighbor change */ |
|
425 |
#define ISM_LOOP 4 /* Link down */ |
|
426 |
#define ISM_UNLOOP 5 /* Link up */ |
|
427 |
#define ISM_DOWN 6 /* Interface down */ |
|
428 |
|
|
429 |
|
|
430 |
/* OSPF neighbor states */ |
|
431 |
#define NEIGHBOR_DOWN 0 |
|
432 |
#define NEIGHBOR_ATTEMPT 1 |
|
433 |
#define NEIGHBOR_INIT 2 |
|
434 |
#define NEIGHBOR_2WAY 3 |
|
435 |
#define NEIGHBOR_EXSTART 4 |
|
436 |
#define NEIGHBOR_EXCHANGE 5 |
|
437 |
#define NEIGHBOR_LOADING 6 |
|
438 |
#define NEIGHBOR_FULL 7 |
|
439 |
|
|
440 |
/* Definitions for neighbor state machine */ |
|
441 |
#define INM_HELLOREC 0 /* Hello Received */ |
|
442 |
#define INM_START 1 /* Neighbor start - for NBMA */ |
|
443 |
#define INM_2WAYREC 2 /* 2-Way received */ |
|
444 |
#define INM_NEGDONE 3 /* Negotiation done */ |
|
445 |
#define INM_EXDONE 4 /* Exchange done */ |
|
446 |
#define INM_BADLSREQ 5 /* Bad LS Request */ |
|
447 |
#define INM_LOADDONE 6 /* Load done */ |
|
448 |
#define INM_ADJOK 7 /* AdjOK? */ |
|
449 |
#define INM_SEQMIS 8 /* Sequence number mismatch */ |
|
450 |
#define INM_1WAYREC 9 /* 1-Way */ |
|
451 |
#define INM_KILLNBR 10 /* Kill Neighbor */ |
|
452 |
#define INM_INACTTIM 11 /* Inactivity timer */ |
|
453 |
#define INM_LLDOWN 12 /* Line down */ |
|
454 |
|
|
455 |
#define TRANS_OFF 0 |
|
456 |
#define TRANS_ON 1 |
|
457 |
#define TRANS_WAIT 2 /* Waiting before the end of translation */ |
|
458 |
|
|
459 |
|
|
460 |
|
|
461 |
/* Generic option flags */ |
|
462 |
#define OPT_V6 0x01 /* OSPFv3, LSA relevant for IPv6 routing calculation */ |
|
463 |
#define OPT_E 0x02 /* Related to AS-external LSAs */ |
|
464 |
#define OPT_MC 0x04 /* Related to MOSPF, not used and obsolete */ |
|
465 |
#define OPT_N 0x08 /* Related to NSSA */ |
|
466 |
#define OPT_P 0x08 /* OSPFv2, flags P and N share position, see NSSA RFC */ |
|
467 |
#define OPT_EA 0x10 /* OSPFv2, external attributes, not used and obsolete */ |
|
468 |
#define OPT_R 0x10 /* OSPFv3, originator is active router */ |
|
469 |
#define OPT_DC 0x20 /* Related to demand circuits, not used */ |
|
470 |
|
|
471 |
/* Router-LSA VEB flags are are stored together with links (OSPFv2) or options (OSPFv3) */ |
|
472 |
#define OPT_RT_B (0x01 << 24) |
|
473 |
#define OPT_RT_E (0x02 << 24) |
|
474 |
#define OPT_RT_V (0x04 << 24) |
|
475 |
#define OPT_RT_NT (0x10 << 24) |
|
476 |
|
|
477 |
/* Prefix flags, specific for OSPFv3 */ |
|
478 |
#define OPT_PX_NU 0x01 |
|
479 |
#define OPT_PX_LA 0x02 |
|
480 |
#define OPT_PX_P 0x08 |
|
481 |
#define OPT_PX_DN 0x10 |
|
482 |
|
|
483 |
|
|
484 |
struct ospf_packet |
|
485 |
{ |
|
486 |
u8 version; |
|
487 |
u8 type; |
|
488 |
u16 length; |
|
489 |
u32 routerid; |
|
490 |
u32 areaid; |
|
491 |
u16 checksum; |
|
492 |
u8 instance_id; /* See RFC 6549 */ |
|
493 |
u8 autype; /* Undefined for OSPFv3 */ |
|
494 |
}; |
|
495 |
|
|
298 | 496 |
struct ospf_md5 |
299 | 497 |
{ |
300 | 498 |
u16 zero; |
... | ... | |
309 | 507 |
struct ospf_md5 md5; |
310 | 508 |
}; |
311 | 509 |
|
312 |
|
|
313 | 510 |
/* Packet types */ |
314 | 511 |
#define HELLO_P 1 /* Hello */ |
315 | 512 |
#define DBDES_P 2 /* Database description */ |
... | ... | |
317 | 514 |
#define LSUPD_P 4 /* Link state update */ |
318 | 515 |
#define LSACK_P 5 /* Link state acknowledgement */ |
319 | 516 |
|
320 |
/* Area IDs */ |
|
321 |
#define BACKBONE 0 |
|
322 | 517 |
|
323 | 518 |
#define DBDES_I 4 /* Init bit */ |
324 | 519 |
#define DBDES_M 2 /* More bit */ |
... | ... | |
326 | 521 |
#define DBDES_IMMS (DBDES_I | DBDES_M | DBDES_MS) |
327 | 522 |
|
328 | 523 |
|
329 |
struct ospf_packet |
|
330 |
{ |
|
331 |
u8 version; |
|
332 |
u8 type; |
|
333 |
u16 length; |
|
334 |
u32 routerid; |
|
335 |
u32 areaid; |
|
336 |
u16 checksum; |
|
337 |
u8 instance_id; /* See RFC 6549 */ |
|
338 |
u8 autype; /* Undefined for OSPFv3 */ |
|
339 |
}; |
|
340 |
|
|
341 |
|
|
342 | 524 |
#define LSA_T_RT 0x2001 |
343 | 525 |
#define LSA_T_NET 0x2002 |
344 | 526 |
#define LSA_T_SUM_NET 0x2003 |
... | ... | |
530 | 712 |
}; |
531 | 713 |
|
532 | 714 |
|
533 |
static inline unsigned
|
|
715 |
static inline uint
|
|
534 | 716 |
lsa_net_count(struct ospf_lsa_header *lsa) |
535 | 717 |
{ |
536 | 718 |
return (lsa->length - sizeof(struct ospf_lsa_header) - sizeof(struct ospf_lsa_net)) |
... | ... | |
558 | 740 |
|
559 | 741 |
*addr = IPA_NONE; |
560 | 742 |
|
743 |
#ifdef IPV6 |
|
561 | 744 |
if (pxl > 0) |
562 | 745 |
_I0(*addr) = *buf++; |
563 | 746 |
if (pxl > 32) |
... | ... | |
570 | 753 |
/* Clean up remaining bits */ |
571 | 754 |
if (pxl < 128) |
572 | 755 |
addr->addr[pxl / 32] &= u32_mkmask(pxl % 32); |
756 |
#endif |
|
573 | 757 |
|
574 | 758 |
return buf; |
575 | 759 |
} |
... | ... | |
613 | 797 |
}; |
614 | 798 |
|
615 | 799 |
|
616 |
struct ospf_neighbor |
|
617 |
{ |
|
618 |
node n; |
|
619 |
pool *pool; |
|
620 |
struct ospf_iface *ifa; |
|
621 |
u8 state; |
|
622 |
#define NEIGHBOR_DOWN 0 |
|
623 |
#define NEIGHBOR_ATTEMPT 1 |
|
624 |
#define NEIGHBOR_INIT 2 |
|
625 |
#define NEIGHBOR_2WAY 3 |
|
626 |
#define NEIGHBOR_EXSTART 4 |
|
627 |
#define NEIGHBOR_EXCHANGE 5 |
|
628 |
#define NEIGHBOR_LOADING 6 |
|
629 |
#define NEIGHBOR_FULL 7 |
|
630 |
timer *inactim; /* Inactivity timer */ |
|
631 |
u8 imms; /* I, M, Master/slave received */ |
|
632 |
u8 myimms; /* I, M Master/slave */ |
|
633 |
u32 dds; /* DD Sequence number being sent */ |
|
634 |
u32 ddr; /* last Dat Des packet received */ |
|
635 |
|
|
636 |
u32 rid; /* Router ID */ |
|
637 |
ip_addr ip; /* IP of it's interface */ |
|
638 |
u8 priority; /* Priority */ |
|
639 |
u8 adj; /* built adjacency? */ |
|
640 |
u32 options; /* Options received */ |
|
641 |
|
|
642 |
/* Entries dr and bdr store IP addresses in OSPFv2 and router IDs in |
|
643 |
OSPFv3, we use the same type to simplify handling */ |
|
644 |
u32 dr; /* Neigbour's idea of DR */ |
|
645 |
u32 bdr; /* Neigbour's idea of BDR */ |
|
646 |
u32 iface_id; /* ID of Neighbour's iface connected to common network */ |
|
647 |
|
|
648 |
/* Database summary list iterator, controls initial dbdes exchange. |
|
649 |
* Advances in the LSA list as dbdes packets are sent. |
|
650 |
*/ |
|
651 |
siterator dbsi; /* iterator of po->lsal */ |
|
652 |
|
|
653 |
/* Link state request list, controls initial LSA exchange. |
|
654 |
* Entries added when received in dbdes packets, removed as sent in lsreq packets. |
|
655 |
*/ |
|
656 |
slist lsrql; /* slist of struct top_hash_entry from n->lsrqh */ |
|
657 |
struct top_graph *lsrqh; |
|
658 |
|
|
659 |
/* Link state retransmission list, controls LSA retransmission during flood. |
|
660 |
* Entries added as sent in lsupd packets, removed when received in lsack packets. |
|
661 |
*/ |
|
662 |
slist lsrtl; /* slist of struct top_hash_entry from n->lsrth */ |
|
663 |
struct top_graph *lsrth; |
|
664 |
timer *rxmt_timer; /* RXMT timer */ |
|
665 |
list ackl[2]; |
|
666 |
#define ACKL_DIRECT 0 |
|
667 |
#define ACKL_DELAY 1 |
|
668 |
timer *ackd_timer; /* Delayed ack timer */ |
|
669 |
struct bfd_request *bfd_req; /* BFD request, if BFD is used */ |
|
670 |
void *ldd_buffer; /* Last database description packet */ |
|
671 |
u32 ldd_bsize; /* Buffer size for ldd_buffer */ |
|
672 |
u32 csn; /* Last received crypt seq number (for MD5) */ |
|
673 |
}; |
|
674 |
|
|
675 |
/* Definitions for interface state machine */ |
|
676 |
#define ISM_UP 0 /* Interface Up */ |
|
677 |
#define ISM_WAITF 1 /* Wait timer fired */ |
|
678 |
#define ISM_BACKS 2 /* Backup seen */ |
|
679 |
#define ISM_NEICH 3 /* Neighbor change */ |
|
680 |
#define ISM_LOOP 4 /* Link down */ |
|
681 |
#define ISM_UNLOOP 5 /* Link up */ |
|
682 |
#define ISM_DOWN 6 /* Interface down */ |
|
683 |
|
|
684 |
/* Definitions for neighbor state machine */ |
|
685 |
#define INM_HELLOREC 0 /* Hello Received */ |
|
686 |
#define INM_START 1 /* Neighbor start - for NBMA */ |
|
687 |
#define INM_2WAYREC 2 /* 2-Way received */ |
|
688 |
#define INM_NEGDONE 3 /* Negotiation done */ |
|
689 |
#define INM_EXDONE 4 /* Exchange done */ |
|
690 |
#define INM_BADLSREQ 5 /* Bad LS Request */ |
|
691 |
#define INM_LOADDONE 6 /* Load done */ |
|
692 |
#define INM_ADJOK 7 /* AdjOK? */ |
|
693 |
#define INM_SEQMIS 8 /* Sequence number mismatch */ |
|
694 |
#define INM_1WAYREC 9 /* 1-Way */ |
|
695 |
#define INM_KILLNBR 10 /* Kill Neighbor */ |
|
696 |
#define INM_INACTTIM 11 /* Inactivity timer */ |
|
697 |
#define INM_LLDOWN 12 /* Line down */ |
|
698 |
|
|
699 |
struct ospf_area |
|
700 |
{ |
|
701 |
node n; |
|
702 |
u32 areaid; |
|
703 |
struct ospf_area_config *ac; /* Related area config */ |
|
704 |
struct top_hash_entry *rt; /* My own router LSA */ |
|
705 |
struct top_hash_entry *pxr_lsa; /* Originated prefix LSA */ |
|
706 |
list cand; /* List of candidates for RT calc. */ |
|
707 |
struct fib net_fib; /* Networks to advertise or not */ |
|
708 |
struct fib enet_fib; /* External networks for NSSAs */ |
|
709 |
u32 options; /* Optional features */ |
|
710 |
u8 update_rt_lsa; /* Rt lsa origination scheduled? */ |
|
711 |
u8 trcap; /* Transit capability? */ |
|
712 |
u8 marked; /* Used in OSPF reconfigure */ |
|
713 |
u8 translate; /* Translator state (TRANS_*), for NSSA ABR */ |
|
714 |
timer *translator_timer; /* For NSSA translator switch */ |
|
715 |
struct ospf_proto *po; |
|
716 |
struct fib rtr; /* Routing tables for routers */ |
|
717 |
}; |
|
718 |
|
|
719 |
#define TRANS_OFF 0 |
|
720 |
#define TRANS_ON 1 |
|
721 |
#define TRANS_WAIT 2 /* Waiting before the end of translation */ |
|
722 |
|
|
723 |
struct ospf_proto |
|
724 |
{ |
|
725 |
struct proto p; |
|
726 |
timer *disp_timer; /* OSPF proto dispatcher */ |
|
727 |
unsigned tick; |
|
728 |
struct top_graph *gr; /* LSA graph */ |
|
729 |
slist lsal; /* List of all LSA's */ |
|
730 |
int calcrt; /* Routing table calculation scheduled? |
|
731 |
0=no, 1=normal, 2=forced reload */ |
|
732 |
list iface_list; /* Interfaces we really use */ |
|
733 |
list area_list; |
|
734 |
int areano; /* Number of area I belong to */ |
|
735 |
int padj; /* Number of neighbors in Exchange or Loading state */ |
|
736 |
struct fib rtf; /* Routing table */ |
|
737 |
byte ospf2; /* OSPF v2 or v3 */ |
|
738 |
byte rfc1583; /* RFC1583 compatibility */ |
|
739 |
byte stub_router; /* Do not forward transit traffic */ |
|
740 |
byte merge_external; /* Should i merge external routes? */ |
|
741 |
byte asbr; /* May i originate any ext/NSSA lsa? */ |
|
742 |
byte ecmp; /* Maximal number of nexthops in ECMP route, or 0 */ |
|
743 |
struct ospf_area *backbone; /* If exists */ |
|
744 |
void *lsab; /* LSA buffer used when originating router LSAs */ |
|
745 |
int lsab_size, lsab_used; |
|
746 |
linpool *nhpool; /* Linpool used for next hops computed in SPF */ |
|
747 |
sock *vlink_sk; /* IP socket used for vlink TX */ |
|
748 |
u32 router_id; |
|
749 |
u32 last_vlink_id; /* Interface IDs for vlinks (starts at 0x80000000) */ |
|
750 |
}; |
|
751 |
|
|
752 |
struct ospf_iface_patt |
|
753 |
{ |
|
754 |
struct iface_patt i; |
|
755 |
u32 type; |
|
756 |
u32 stub; |
|
757 |
u32 cost; |
|
758 |
u32 helloint; |
|
759 |
u32 rxmtint; |
|
760 |
u32 pollint; |
|
761 |
u32 waitint; |
|
762 |
u32 deadc; |
|
763 |
u32 deadint; |
|
764 |
u32 inftransdelay; |
|
765 |
list nbma_list; |
|
766 |
u32 priority; |
|
767 |
u32 voa; |
|
768 |
u32 vid; |
|
769 |
int tx_tos; |
|
770 |
int tx_priority; |
|
771 |
u16 tx_length; |
|
772 |
u16 rx_buffer; |
|
773 |
|
|
774 |
#define OSPF_RXBUF_MINSIZE 256 /* Minimal allowed size */ |
|
775 |
u8 instance_id; |
|
776 |
u8 autype; /* Not really used in OSPFv3 */ |
|
777 |
#define OSPF_AUTH_NONE 0 |
|
778 |
#define OSPF_AUTH_SIMPLE 1 |
|
779 |
#define OSPF_AUTH_CRYPT 2 |
|
780 |
#define OSPF_AUTH_CRYPT_SIZE 16 |
|
781 |
u8 strictnbma; |
|
782 |
u8 check_link; |
|
783 |
u8 ecmp_weight; |
|
784 |
u8 link_lsa_suppression; |
|
785 |
u8 real_bcast; /* Not really used in OSPFv3 */ |
Also available in: Unified diff