Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / iface.c @ 23d67029

History | View | Annotate | Download (15 KB)

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