]> git.ipfire.org Git - thirdparty/bird.git/blame - proto/ospf/iface.c
Temporary OSPFv3 development commit (changing multicast support).
[thirdparty/bird.git] / proto / ospf / iface.c
CommitLineData
4364b47e
OF
1/*
2 * BIRD -- OSPF
3 *
e300066d 4 * (c) 1999--2005 Ondrej Filip <feela@network.cz>
4364b47e
OF
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9#include "ospf.h"
10
b9ed99f7
OF
11char *ospf_is[] = { "down", "loop", "waiting", "point-to-point", "drother",
12 "backup", "dr"
13};
8914e37d 14
b9ed99f7
OF
15char *ospf_ism[] = { "interface up", "wait timer fired", "backup seen",
16 "neighbor change", "loop indicated", "unloop indicated", "interface down"
17};
79f036ef 18
b9ed99f7 19char *ospf_it[] = { "broadcast", "nbma", "point-to-point", "virtual link" };
c4f0f014 20
9831e591 21static void
b9ed99f7 22poll_timer_hook(timer * timer)
39e517d4 23{
3b16080c 24 log("POLL!");
39e517d4
OF
25 ospf_hello_send(timer, 1, NULL);
26}
27
9831e591 28static void
b9ed99f7 29hello_timer_hook(timer * timer)
39e517d4
OF
30{
31 ospf_hello_send(timer, 0, NULL);
32}
33
9831e591 34static void
b9ed99f7 35wait_timer_hook(timer * timer)
39e517d4 36{
b9ed99f7 37 struct ospf_iface *ifa = (struct ospf_iface *) timer->data;
86c84d76 38 struct proto *p = &ifa->oa->po->proto;
39e517d4 39
b9ed99f7
OF
40 OSPF_TRACE(D_EVENTS, "Wait timer fired on interface %s.", ifa->iface->name);
41 ospf_iface_sm(ifa, ISM_WAITF);
39e517d4
OF
42}
43
94c42054
OF
44u32
45rxbufsize(struct ospf_iface *ifa)
46{
47 switch(ifa->rxbuf)
48 {
49 case OSPF_RXBUF_NORMAL:
50 return (ifa->iface->mtu * 2);
51 break;
52 case OSPF_RXBUF_LARGE:
53 return OSPF_MAX_PKT_SIZE;
54 break;
55 default:
56 return ifa->rxbuf;
57 break;
58 }
59}
60
3b16080c 61static sock *
f9c799a0 62ospf_open_socket(struct ospf_iface *ifa, int mc)
3b16080c
OF
63{
64 sock *ipsk;
86c84d76 65 struct proto *p = &ifa->oa->po->proto;
3b16080c
OF
66
67 ipsk = sk_new(p->pool);
68 ipsk->type = SK_IP;
69 ipsk->dport = OSPF_PROTO;
061ab802
OZ
70
71#ifdef OSPFv2
f9c799a0
OZ
72 // ipsk->saddr = ifa->iface->addr->ip;
73 ipsk->saddr = IPA_NONE;
061ab802
OZ
74#else /* OSPFv3 */
75 ipsk->saddr = ifa->lladdr;
76#endif
77
3b16080c
OF
78 ipsk->tos = IP_PREC_INTERNET_CONTROL;
79 ipsk->ttl = 1;
80 if (ifa->type == OSPF_IT_VLINK)
81 ipsk->ttl = 255;
82 ipsk->rx_hook = ospf_rx_hook;
83 ipsk->tx_hook = ospf_tx_hook;
84 ipsk->err_hook = ospf_err_hook;
85 ipsk->iface = ifa->iface;
94c42054 86 ipsk->rbsize = rxbufsize(ifa);
3b16080c
OF
87 ipsk->tbsize = ifa->iface->mtu;
88 ipsk->data = (void *) ifa;
89 if (sk_open(ipsk) != 0)
f9c799a0
OZ
90 goto err;
91
92 if (mc)
3b16080c 93 {
f9c799a0
OZ
94 if (sk_setup_multicast(ipsk) < 0)
95 goto err;
96
97 if (sk_join_group(ipsk, AllSPFRouters) < 0)
98 goto err;
3b16080c 99 }
f9c799a0
OZ
100
101 return ipsk;
102
103 err:
104 rfree(ipsk);
105 return NULL;
3b16080c
OF
106}
107
39e517d4 108
d5e4b518 109/**
b9ed99f7 110 * ospf_iface_chstate - handle changes of interface state
d5e4b518
OF
111 * @ifa: OSPF interface
112 * @state: new state
113 *
baa5dd6c
OF
114 * Many actions must be taken according to interface state changes. New network
115 * LSAs must be originated, flushed, new multicast sockets to listen for messages for
116 * %ALLDROUTERS have to be opened, etc.
d5e4b518 117 */
4364b47e 118void
b9ed99f7 119ospf_iface_chstate(struct ospf_iface *ifa, u8 state)
4364b47e 120{
86c84d76 121 struct proto_ospf *po = ifa->oa->po;
b9ed99f7 122 struct proto *p = &po->proto;
3b16080c 123 u8 oldstate = ifa->state;
4364b47e 124
3b16080c 125 if (oldstate != state)
2a092594 126 {
b9ed99f7 127 ifa->state = state;
3b16080c
OF
128
129 if (ifa->type == OSPF_IT_VLINK)
2a092594 130 {
3b16080c 131 OSPF_TRACE(D_EVENTS,
3aab39f5
OZ
132 "Changing state of virtual link %R from \"%s\" into \"%s\".",
133 ifa->vid, ospf_is[oldstate], ospf_is[state]);
3b16080c 134 if (state == OSPF_IS_PTP)
2a092594 135 {
f9c799a0 136 ifa->sk = ospf_open_socket(ifa, 0);
3b16080c
OF
137 }
138 }
139 else
140 {
141 OSPF_TRACE(D_EVENTS,
142 "Changing state of iface: %s from \"%s\" into \"%s\".",
143 ifa->iface->name, ospf_is[oldstate], ospf_is[state]);
144 if (ifa->iface->flags & IF_MULTICAST)
145 {
f9c799a0
OZ
146 if ((ifa->type != OSPF_IT_NBMA) && (ifa->ioprob == OSPF_I_OK) &&
147 ((state == OSPF_IS_BACKUP) || (state == OSPF_IS_DR)))
b9ed99f7 148 {
f9c799a0
OZ
149 /* FIXME some error handing ? */
150 sk_join_group(ifa->sk, AllDRouters);
151 ifa->dr_up = 1;
b9ed99f7 152 }
f9c799a0 153 else if (ifa->dr_up)
eb2c99a1 154 {
f9c799a0
OZ
155 sk_leave_group(ifa->sk, AllDRouters);
156 ifa->dr_up = 0;
3b16080c 157 }
c3226991 158 if ((oldstate == OSPF_IS_DR) && (ifa->net_lsa != NULL))
3b16080c 159 {
c3226991 160 ifa->net_lsa->lsa.age = LSA_MAXAGE;
3b16080c
OF
161 if (state >= OSPF_IS_WAITING)
162 {
c3226991 163 ospf_lsupd_flush_nlsa(po, ifa->net_lsa);
3b16080c 164 }
86c84d76 165 if (can_flush_lsa(po))
c3226991
OZ
166 flush_lsa(ifa->net_lsa, po);
167 ifa->net_lsa = NULL;
eb2c99a1 168 }
dc2548d2 169 }
2a092594
OF
170 }
171 }
4364b47e
OF
172}
173
b9ed99f7
OF
174static void
175ospf_iface_down(struct ospf_iface *ifa)
4364b47e 176{
b9ed99f7 177 struct ospf_neighbor *n, *nx;
86c84d76
OF
178 struct proto_ospf *po = ifa->oa->po;
179 struct proto *p = &po->proto;
98ac6176 180 struct ospf_iface *iff;
18a0c0bb 181
3b16080c
OF
182 /* First of all kill all the related vlinks */
183 if (ifa->type != OSPF_IT_VLINK)
184 {
185 WALK_LIST(iff, po->iface_list)
186 {
187 if ((iff->type == OSPF_IT_VLINK) && (iff->iface == ifa->iface))
188 ospf_iface_down(iff);
189 }
190 }
191
b9ed99f7 192 WALK_LIST_DELSAFE(n, nx, ifa->neigh_list)
18a0c0bb 193 {
1ae494a7 194 OSPF_TRACE(D_EVENTS, "Removing neighbor %I", n->ip);
18a0c0bb
OF
195 ospf_neigh_remove(n);
196 }
f9c799a0
OZ
197
198 rfree(ifa->sk);
199 ifa->sk = NULL;
c9f6cf8a 200
3b16080c 201 if (ifa->type == OSPF_IT_VLINK)
98ac6176 202 {
98ac6176
OF
203 ifa->iface = NULL;
204 return;
205 }
206 else
207 {
208 rfree(ifa->wait_timer);
209 rfree(ifa->hello_timer);
210 rfree(ifa->poll_timer);
211 rfree(ifa->lock);
212 rem_node(NODE ifa);
213 mb_free(ifa);
214 }
4364b47e
OF
215}
216
d5e4b518 217/**
b9ed99f7 218 * ospf_iface_sm - OSPF interface state machine
d5e4b518
OF
219 * @ifa: OSPF interface
220 * @event: event comming to state machine
221 *
98ac6176 222 * This fully respects 9.3 of RFC 2328 except we don't use %LOOP state of
d5e4b518
OF
223 * interface.
224 */
4364b47e 225void
b9ed99f7 226ospf_iface_sm(struct ospf_iface *ifa, int event)
4364b47e 227{
b9ed99f7 228 struct ospf_area *oa = ifa->oa;
4364b47e 229
23d67029 230 DBG("SM on iface %s. Event is '%s'\n", ifa->iface->name, ospf_ism[event]);
4364b47e 231
b9ed99f7 232 switch (event)
4364b47e 233 {
b9ed99f7
OF
234 case ISM_UP:
235 if (ifa->state == OSPF_IS_DOWN)
236 {
237 /* Now, nothing should be adjacent */
b9ed99f7 238 if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_VLINK))
3b16080c 239 {
b9ed99f7 240 ospf_iface_chstate(ifa, OSPF_IS_PTP);
3b16080c 241 }
b9ed99f7 242 else
4364b47e 243 {
b9ed99f7
OF
244 if (ifa->priority == 0)
245 ospf_iface_chstate(ifa, OSPF_IS_DROTHER);
246 else
247 {
248 ospf_iface_chstate(ifa, OSPF_IS_WAITING);
249 tm_start(ifa->wait_timer, ifa->waitint);
250 }
4364b47e 251 }
3b16080c
OF
252
253 tm_start(ifa->hello_timer, ifa->helloint);
254
255 if (ifa->poll_timer)
256 tm_start(ifa->poll_timer, ifa->pollint);
257
897999c2 258 hello_timer_hook(ifa->hello_timer);
b9ed99f7
OF
259 }
260 schedule_rt_lsa(ifa->oa);
261 break;
262 case ISM_BACKS:
263 case ISM_WAITF:
264 if (ifa->state == OSPF_IS_WAITING)
265 {
266 bdr_election(ifa);
267 }
268 break;
269 case ISM_NEICH:
270 if ((ifa->state == OSPF_IS_DROTHER) || (ifa->state == OSPF_IS_DR) ||
271 (ifa->state == OSPF_IS_BACKUP))
272 {
273 bdr_election(ifa);
70a38319 274 schedule_rt_lsa(ifa->oa);
b9ed99f7
OF
275 }
276 break;
277 case ISM_DOWN:
278 ospf_iface_chstate(ifa, OSPF_IS_DOWN);
279 ospf_iface_down(ifa);
280 schedule_rt_lsa(oa);
281 break;
282 case ISM_LOOP: /* Useless? */
283 ospf_iface_chstate(ifa, OSPF_IS_LOOP);
284 ospf_iface_down(ifa);
285 schedule_rt_lsa(ifa->oa);
286 break;
287 case ISM_UNLOOP:
288 ospf_iface_chstate(ifa, OSPF_IS_DOWN);
289 schedule_rt_lsa(ifa->oa);
290 break;
291 default:
292 bug("OSPF_I_SM - Unknown event?");
293 break;
4364b47e 294 }
b9ed99f7 295
4364b47e
OF
296}
297
f9c799a0 298#if 0
b9ed99f7 299static sock *
4364b47e
OF
300ospf_open_mc_socket(struct ospf_iface *ifa)
301{
302 sock *mcsk;
86c84d76 303 struct proto *p = &ifa->oa->po->proto;
b9ed99f7
OF
304
305 mcsk = sk_new(p->pool);
306 mcsk->type = SK_IP_MC;
307 mcsk->sport = 0;
308 mcsk->dport = OSPF_PROTO;
061ab802
OZ
309
310#ifdef OSPFv2
d2ceaf4e 311 mcsk->saddr = AllSPFRouters;
061ab802 312#else /* OSPFv3 */
d2ceaf4e 313 // mcsk->saddr = AllSPFRouters;
061ab802
OZ
314 mcsk->saddr = ifa->lladdr;
315#endif
316
b9ed99f7
OF
317 mcsk->daddr = AllSPFRouters;
318 mcsk->tos = IP_PREC_INTERNET_CONTROL;
319 mcsk->ttl = 1;
320 mcsk->rx_hook = ospf_rx_hook;
321 mcsk->tx_hook = ospf_tx_hook;
322 mcsk->err_hook = ospf_err_hook;
323 mcsk->iface = ifa->iface;
94c42054 324 mcsk->rbsize = rxbufsize(ifa);
b9ed99f7
OF
325 mcsk->tbsize = ifa->iface->mtu;
326 mcsk->data = (void *) ifa;
327 if (sk_open(mcsk) != 0)
4364b47e 328 {
b9ed99f7
OF
329 DBG("%s: SK_OPEN: mc open failed.\n", p->name);
330 return (NULL);
4364b47e 331 }
b9ed99f7
OF
332 DBG("%s: SK_OPEN: mc opened.\n", p->name);
333 return (mcsk);
4364b47e 334}
f9c799a0 335#endif
4364b47e 336
4364b47e 337u8
2e10a170 338ospf_iface_clasify(struct iface * ifa)
4364b47e 339{
b9ed99f7
OF
340 if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) ==
341 (IF_MULTIACCESS | IF_MULTICAST))
342 return OSPF_IT_BCAST;
343
344 if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) == IF_MULTIACCESS)
4364b47e 345 return OSPF_IT_NBMA;
b9ed99f7 346
4364b47e
OF
347 return OSPF_IT_PTP;
348}
349
b9ed99f7
OF
350struct ospf_iface *
351ospf_iface_find(struct proto_ospf *p, struct iface *what)
4364b47e
OF
352{
353 struct ospf_iface *i;
354
3b16080c 355 WALK_LIST(i, p->iface_list) if ((i->iface == what) && (i->type != OSPF_IT_VLINK))
b9ed99f7 356 return i;
4364b47e
OF
357 return NULL;
358}
359
b9ed99f7
OF
360static void
361ospf_iface_add(struct object_lock *lock)
362{
363 struct ospf_iface *ifa = lock->data;
86c84d76 364 struct proto_ospf *po = ifa->oa->po;
b9ed99f7 365 struct proto *p = &po->proto;
86c84d76 366 struct iface *iface = lock->iface;
b9ed99f7 367
98ac6176
OF
368 ifa->lock = lock;
369
b9ed99f7
OF
370 ifa->ioprob = OSPF_I_OK;
371
f9c799a0
OZ
372 ifa->sk = ospf_open_socket(ifa, ifa->type != OSPF_IT_NBMA);
373 if (ifa->sk == NULL)
b9ed99f7
OF
374 {
375 log("%s: Huh? could not open ip socket on interface %s?", p->name,
376 iface->name);
377 log("%s: Declaring as stub.", p->name);
378 ifa->stub = 1;
379 ifa->ioprob += OSPF_I_IP;
380 }
b9ed99f7
OF
381
382 ifa->state = OSPF_IS_DOWN;
383 ospf_iface_sm(ifa, ISM_UP);
384}
385
98ac6176 386void
3b16080c
OF
387ospf_iface_new(struct proto_ospf *po, struct iface *iface,
388 struct ospf_area_config *ac, struct ospf_iface_patt *ip)
98ac6176
OF
389{
390 struct proto *p = &po->proto;
391 struct ospf_iface *ifa;
392 struct nbma_node *nbma, *nb;
393 struct object_lock *lock;
394 struct ospf_area *oa;
395
396 ifa = mb_allocz(p->pool, sizeof(struct ospf_iface));
98ac6176
OF
397 ifa->iface = iface;
398
98ac6176
OF
399 ifa->cost = ip->cost;
400 ifa->rxmtint = ip->rxmtint;
401 ifa->inftransdelay = ip->inftransdelay;
402 ifa->priority = ip->priority;
403 ifa->helloint = ip->helloint;
404 ifa->pollint = ip->pollint;
405 ifa->strictnbma = ip->strictnbma;
406 ifa->waitint = ip->waitint;
d8c7d9e8 407 ifa->dead = (ip->dead == 0) ? ip->deadc * ifa->helloint : ip->dead;
98ac6176 408 ifa->stub = ip->stub;
c3226991
OZ
409
410#ifdef OSPFv2
98ac6176 411 ifa->autype = ip->autype;
3e2bd0f1 412 ifa->passwords = ip->passwords;
c3226991
OZ
413#endif
414
415#ifdef OSPFv3
416 ifa->instance_id = ip->instance_id;
b49e6f5a
OZ
417
418 ifa->lladdr = IPA_NONE;
419
420 /* Find link-local address */
421 if (ifa->type != OSPF_IT_VLINK)
422 {
423 struct ifa *a;
424 WALK_LIST(a, iface->addrs)
425 if (a->scope == SCOPE_LINK)
426 {
427 ifa->lladdr = a->ip;
428 break;
429 }
430
431 if (! ipa_nonzero(ifa->lladdr))
432 log(L_WARN "%s: Missing link local address on interface %s", p->name, iface->name);
433 }
c3226991
OZ
434#endif
435
94c42054 436 ifa->rxbuf = ip->rxbuf;
98ac6176
OF
437
438 if (ip->type == OSPF_IT_UNDEF)
439 ifa->type = ospf_iface_clasify(ifa->iface);
440 else
441 ifa->type = ip->type;
442
443 init_list(&ifa->neigh_list);
444 init_list(&ifa->nbma_list);
3b16080c 445
98ac6176
OF
446 WALK_LIST(nb, ip->nbma_list)
447 {
448 nbma = mb_alloc(p->pool, sizeof(struct nbma_node));
449 nbma->ip = nb->ip;
450 nbma->eligible = nb->eligible;
451 add_tail(&ifa->nbma_list, NODE nbma);
452 }
453
454 /* Add hello timer */
455 ifa->hello_timer = tm_new(p->pool);
456 ifa->hello_timer->data = ifa;
457 ifa->hello_timer->randomize = 0;
458 ifa->hello_timer->hook = hello_timer_hook;
459 ifa->hello_timer->recurrent = ifa->helloint;
460 DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
461
462 if (ifa->type == OSPF_IT_NBMA)
463 {
464 ifa->poll_timer = tm_new(p->pool);
465 ifa->poll_timer->data = ifa;
466 ifa->poll_timer->randomize = 0;
467 ifa->poll_timer->hook = poll_timer_hook;
468 ifa->poll_timer->recurrent = ifa->pollint;
469 DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint);
470 }
471 else
472 ifa->poll_timer = NULL;
473
474 ifa->wait_timer = tm_new(p->pool);
475 ifa->wait_timer->data = ifa;
476 ifa->wait_timer->randomize = 0;
477 ifa->wait_timer->hook = wait_timer_hook;
478 ifa->wait_timer->recurrent = 0;
479 DBG("%s: Installing wait timer. (%u)\n", p->name, ifa->waitint);
480 add_tail(&((struct proto_ospf *) p)->iface_list, NODE ifa);
481 ifa->state = OSPF_IS_DOWN;
482
3b16080c 483 ifa->oa = NULL;
98ac6176
OF
484 WALK_LIST(oa, po->area_list)
485 {
3b16080c
OF
486 if (oa->areaid == ac->areaid)
487 {
488 ifa->oa = oa;
98ac6176 489 break;
3b16080c 490 }
98ac6176
OF
491 }
492
3b16080c 493 if (!ifa->oa)
98ac6176
OF
494 bug("Cannot add any area to accepted Interface");
495 else
98ac6176
OF
496
497 if (ifa->type == OSPF_IT_VLINK)
498 {
499 ifa->oa = po->backbone;
500 ifa->voa = oa;
501 ifa->vid = ip->vid;
3b16080c 502 return; /* Don't lock, don't add sockets */
98ac6176
OF
503 }
504
505 lock = olock_new(p->pool);
506 lock->addr = AllSPFRouters;
507 lock->type = OBJLOCK_IP;
508 lock->port = OSPF_PROTO;
509 lock->iface = iface;
510 lock->data = ifa;
511 lock->hook = ospf_iface_add;
512
513 olock_acquire(lock);
514}
515
94c42054
OF
516void
517ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa)
518{
519 struct proto *p = &po->proto;
520 struct ospf_packet *op;
521 struct ospf_neighbor *n;
522 OSPF_TRACE(D_EVENTS, "Changing MTU on interface %s.", ifa->iface->name);
f9c799a0
OZ
523
524 if (ifa->sk)
94c42054 525 {
f9c799a0
OZ
526 ifa->sk->rbsize = rxbufsize(ifa);
527 ifa->sk->tbsize = ifa->iface->mtu;
528 sk_reallocate(ifa->sk);
94c42054
OF
529 }
530
531 WALK_LIST(n, ifa->neigh_list)
532 {
533 op = (struct ospf_packet *) n->ldbdes;
534 n->ldbdes = mb_allocz(n->pool, ifa->iface->mtu);
535
536 if (ntohs(op->length) <= ifa->iface->mtu) /* If the packet in old buffer is bigger, let it filled by zeros */
537 memcpy(n->ldbdes, op, ifa->iface->mtu); /* If the packet is old is same or smaller, copy it */
538
539 rfree(op);
540 }
541}
542
4364b47e 543void
b9ed99f7 544ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
4364b47e 545{
b9ed99f7
OF
546 struct proto_ospf *po = (struct proto_ospf *) p;
547 struct ospf_config *c = (struct ospf_config *) (p->cf);
3b580a23 548 struct ospf_area_config *ac;
b9ed99f7 549 struct ospf_iface_patt *ip = NULL;
f8f1e1f1 550 struct ospf_iface *ifa;
4364b47e 551
e6fcf113 552 DBG("%s: If notify called\n", p->name);
4364b47e
OF
553 if (iface->flags & IF_IGNORE)
554 return;
555
b9ed99f7 556 if (flags & IF_CHANGE_UP)
4364b47e 557 {
3b580a23 558 WALK_LIST(ac, c->area_list)
4364b47e 559 {
b9ed99f7 560 if (ip = (struct ospf_iface_patt *)
20e94fb8 561 iface_patt_find(&ac->patt_list, iface))
b9ed99f7 562 break;
3b580a23 563 }
4364b47e 564
b9ed99f7 565 if (ip)
3b580a23 566 {
abcbfd04 567 OSPF_TRACE(D_EVENTS, "Using interface %s.", iface->name);
98ac6176 568 ospf_iface_new(po, iface, ac, ip);
4364b47e 569 }
4364b47e
OF
570 }
571
b9ed99f7 572 if (flags & IF_CHANGE_DOWN)
4364b47e 573 {
b9ed99f7 574 if ((ifa = ospf_iface_find((struct proto_ospf *) p, iface)) != NULL)
4364b47e 575 {
abcbfd04 576 OSPF_TRACE(D_EVENTS, "Killing interface %s.", iface->name);
b9ed99f7 577 ospf_iface_sm(ifa, ISM_DOWN);
4364b47e
OF
578 }
579 }
580
b9ed99f7 581 if (flags & IF_CHANGE_MTU)
4364b47e 582 {
b9ed99f7 583 if ((ifa = ospf_iface_find((struct proto_ospf *) p, iface)) != NULL)
94c42054 584 ospf_iface_change_mtu(po, ifa);
4364b47e
OF
585 }
586}
587
c4f0f014
OF
588void
589ospf_iface_info(struct ospf_iface *ifa)
590{
b9ed99f7
OF
591 char *strict = "(strict)";
592
593 if ((ifa->type != OSPF_IT_NBMA) || (ifa->strictnbma == 0))
594 strict = "";
3b16080c
OF
595 if (ifa->type == OSPF_IT_VLINK)
596 {
3aab39f5
OZ
597 cli_msg(-1015, "Virtual link to %R:", ifa->vid);
598 cli_msg(-1015, "\tTransit area: %R (%u)", ifa->voa->areaid,
3b16080c
OF
599 ifa->voa->areaid);
600 }
601 else
602 {
603 cli_msg(-1015, "Interface \"%s\":",
604 (ifa->iface ? ifa->iface->name : "(none)"));
605 cli_msg(-1015, "\tType: %s %s", ospf_it[ifa->type], strict);
3aab39f5 606 cli_msg(-1015, "\tArea: %R (%u)", ifa->oa->areaid, ifa->oa->areaid);
3b16080c 607 }
b9ed99f7
OF
608 cli_msg(-1015, "\tState: %s %s", ospf_is[ifa->state],
609 ifa->stub ? "(stub)" : "");
610 cli_msg(-1015, "\tPriority: %u", ifa->priority);
611 cli_msg(-1015, "\tCost: %u", ifa->cost);
612 cli_msg(-1015, "\tHello timer: %u", ifa->helloint);
f9bdcad4 613
b9ed99f7 614 if (ifa->type == OSPF_IT_NBMA)
f8f1e1f1 615 {
b9ed99f7 616 cli_msg(-1015, "\tPoll timer: %u", ifa->pollint);
f8f1e1f1 617 }
b9ed99f7 618 cli_msg(-1015, "\tWait timer: %u", ifa->waitint);
d8c7d9e8 619 cli_msg(-1015, "\tDead timer: %u", ifa->dead);
b9ed99f7
OF
620 cli_msg(-1015, "\tRetransmit timer: %u", ifa->rxmtint);
621 if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA))
f8f1e1f1 622 {
3aab39f5 623 cli_msg(-1015, "\tDesigned router (ID): %R", ifa->drid);
b9ed99f7 624 cli_msg(-1015, "\tDesigned router (IP): %I", ifa->drip);
3aab39f5 625 cli_msg(-1015, "\tBackup designed router (ID): %R", ifa->bdrid);
b9ed99f7 626 cli_msg(-1015, "\tBackup designed router (IP): %I", ifa->bdrip);
f8f1e1f1 627 }
78e2c6cc 628}
39e517d4
OF
629
630void
631ospf_iface_shutdown(struct ospf_iface *ifa)
632{
633 init_list(&ifa->neigh_list);
634 hello_timer_hook(ifa->hello_timer);
635}