Coverage Report

Created: 2025-07-14 06:48

/src/frr/ospfd/ospf_interface.c
Line
Count
Source (jump to first uncovered line)
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * OSPF Interface functions.
4
 * Copyright (C) 1999, 2000 Toshiaki Takada
5
 */
6
7
#include <zebra.h>
8
9
#include "frrevent.h"
10
#include "linklist.h"
11
#include "prefix.h"
12
#include "if.h"
13
#include "table.h"
14
#include "memory.h"
15
#include "command.h"
16
#include "stream.h"
17
#include "log.h"
18
#include "network.h"
19
#include "zclient.h"
20
#include "bfd.h"
21
#include "ldp_sync.h"
22
23
#include "ospfd/ospfd.h"
24
#include "ospfd/ospf_bfd.h"
25
#include "ospfd/ospf_spf.h"
26
#include "ospfd/ospf_interface.h"
27
#include "ospfd/ospf_ism.h"
28
#include "ospfd/ospf_asbr.h"
29
#include "ospfd/ospf_lsa.h"
30
#include "ospfd/ospf_lsdb.h"
31
#include "ospfd/ospf_neighbor.h"
32
#include "ospfd/ospf_nsm.h"
33
#include "ospfd/ospf_packet.h"
34
#include "ospfd/ospf_abr.h"
35
#include "ospfd/ospf_network.h"
36
#include "ospfd/ospf_dump.h"
37
#include "ospfd/ospf_ldp_sync.h"
38
#include "ospfd/ospf_route.h"
39
#include "ospfd/ospf_te.h"
40
41
DEFINE_QOBJ_TYPE(ospf_interface);
42
DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd));
43
DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd));
44
DEFINE_HOOK(ospf_if_update, (struct interface * ifp), (ifp));
45
DEFINE_HOOK(ospf_if_delete, (struct interface * ifp), (ifp));
46
47
int ospf_interface_neighbor_count(struct ospf_interface *oi)
48
0
{
49
0
  int count = 0;
50
0
  struct route_node *rn;
51
0
  struct ospf_neighbor *nbr = NULL;
52
53
0
  for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
54
0
    nbr = rn->info;
55
0
    if (!nbr)
56
0
      continue;
57
58
    /* Do not show myself. */
59
0
    if (nbr == oi->nbr_self)
60
0
      continue;
61
    /* Down state is not shown. */
62
0
    if (nbr->state == NSM_Down)
63
0
      continue;
64
0
    count++;
65
0
  }
66
67
0
  return count;
68
0
}
69
70
int ospf_if_get_output_cost(struct ospf_interface *oi)
71
1
{
72
  /* If all else fails, use default OSPF cost */
73
1
  uint32_t cost;
74
1
  uint32_t bw, refbw;
75
76
  /* if LDP-IGP Sync is running on interface set cost so interface
77
   * is used only as last resort
78
   */
79
1
  if (ldp_sync_if_is_enabled(IF_DEF_PARAMS(oi->ifp)->ldp_sync_info))
80
0
    return (LDP_OSPF_LSINFINITY);
81
82
  /* ifp speed and bw can be 0 in some platforms, use ospf default bw
83
     if bw is configured under interface it would be used.
84
   */
85
1
  if (!oi->ifp->bandwidth && oi->ifp->speed)
86
0
    bw = oi->ifp->speed;
87
1
  else
88
1
    bw = oi->ifp->bandwidth ? oi->ifp->bandwidth
89
1
          : OSPF_DEFAULT_BANDWIDTH;
90
1
  refbw = oi->ospf->ref_bandwidth;
91
92
  /* A specified ip ospf cost overrides a calculated one. */
93
1
  if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp), output_cost_cmd)
94
1
      || OSPF_IF_PARAM_CONFIGURED(oi->params, output_cost_cmd))
95
0
    cost = OSPF_IF_PARAM(oi, output_cost_cmd);
96
  /* See if a cost can be calculated from the zebra processes
97
     interface bandwidth field. */
98
1
  else {
99
1
    cost = (uint32_t)((double)refbw / (double)bw + (double)0.5);
100
1
    if (cost < 1)
101
0
      cost = 1;
102
1
    else if (cost > 65535)
103
0
      cost = 65535;
104
105
1
    if (if_is_loopback(oi->ifp))
106
0
      cost = 0;
107
1
  }
108
109
1
  return cost;
110
1
}
111
112
void ospf_if_recalculate_output_cost(struct interface *ifp)
113
0
{
114
0
  uint32_t newcost;
115
0
  struct route_node *rn;
116
117
0
  for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
118
0
    struct ospf_interface *oi;
119
120
0
    if ((oi = rn->info) == NULL)
121
0
      continue;
122
123
0
    newcost = ospf_if_get_output_cost(oi);
124
125
    /* Is actual output cost changed? */
126
0
    if (oi->output_cost != newcost) {
127
0
      oi->output_cost = newcost;
128
0
      ospf_router_lsa_update_area(oi->area);
129
0
    }
130
0
  }
131
0
}
132
133
/* Simulate down/up on the interface.  This is needed, for example, when
134
   the MTU changes. */
135
void ospf_if_reset(struct interface *ifp)
136
0
{
137
0
  struct route_node *rn;
138
139
0
  for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
140
0
    struct ospf_interface *oi;
141
142
0
    if ((oi = rn->info) == NULL)
143
0
      continue;
144
145
0
    ospf_if_down(oi);
146
0
    ospf_if_up(oi);
147
0
  }
148
0
}
149
150
void ospf_if_reset_variables(struct ospf_interface *oi)
151
1
{
152
  /* Set default values. */
153
  /* don't clear this flag.  oi->flag = OSPF_IF_DISABLE; */
154
155
1
  if (oi->vl_data)
156
0
    oi->type = OSPF_IFTYPE_VIRTUALLINK;
157
1
  else
158
    /* preserve network-type */
159
1
    if (oi->type != OSPF_IFTYPE_NBMA)
160
1
    oi->type = OSPF_IFTYPE_BROADCAST;
161
162
1
  oi->state = ISM_Down;
163
164
1
  oi->crypt_seqnum = 0;
165
166
  /* This must be short, (less than RxmtInterval)
167
     - RFC 2328 Section 13.5 para 3.  Set to 1 second to avoid Acks being
168
       held back for too long - MAG */
169
1
  oi->v_ls_ack = 1;
170
1
}
171
172
/* lookup oi for specified prefix/ifp */
173
struct ospf_interface *ospf_if_table_lookup(struct interface *ifp,
174
              struct prefix *prefix)
175
1
{
176
1
  struct prefix p;
177
1
  struct route_node *rn;
178
1
  struct ospf_interface *rninfo = NULL;
179
180
1
  p = *prefix;
181
1
  p.prefixlen = IPV4_MAX_BITLEN;
182
183
  /* route_node_get implicitely locks */
184
1
  if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) {
185
0
    rninfo = (struct ospf_interface *)rn->info;
186
0
    route_unlock_node(rn);
187
0
  }
188
189
1
  return rninfo;
190
1
}
191
192
static void ospf_add_to_if(struct interface *ifp, struct ospf_interface *oi)
193
1
{
194
1
  struct route_node *rn;
195
1
  struct prefix p;
196
197
1
  p = *oi->address;
198
1
  p.prefixlen = IPV4_MAX_BITLEN;
199
1
  apply_mask(&p);
200
201
1
  rn = route_node_get(IF_OIFS(ifp), &p);
202
  /* rn->info should either be NULL or equal to this oi
203
   * as route_node_get may return an existing node
204
   */
205
1
  assert(!rn->info || rn->info == oi);
206
1
  rn->info = oi;
207
1
}
208
209
static void ospf_delete_from_if(struct interface *ifp,
210
        struct ospf_interface *oi)
211
0
{
212
0
  struct route_node *rn;
213
0
  struct prefix p;
214
215
0
  p = *oi->address;
216
0
  p.prefixlen = IPV4_MAX_BITLEN;
217
218
0
  rn = route_node_lookup(IF_OIFS(oi->ifp), &p);
219
0
  assert(rn);
220
0
  assert(rn->info);
221
0
  rn->info = NULL;
222
0
  route_unlock_node(rn);
223
0
  route_unlock_node(rn);
224
0
}
225
226
struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
227
           struct prefix *p)
228
1
{
229
1
  struct ospf_interface *oi;
230
231
1
  oi = ospf_if_table_lookup(ifp, p);
232
1
  if (oi)
233
0
    return oi;
234
235
1
  oi = XCALLOC(MTYPE_OSPF_IF, sizeof(struct ospf_interface));
236
237
1
  oi->obuf = ospf_fifo_new();
238
239
  /* Set zebra interface pointer. */
240
1
  oi->ifp = ifp;
241
1
  oi->address = p;
242
243
1
  ospf_add_to_if(ifp, oi);
244
1
  listnode_add(ospf->oiflist, oi);
245
246
  /* Initialize neighbor list. */
247
1
  oi->nbrs = route_table_init();
248
249
  /* Initialize static neighbor list. */
250
1
  oi->nbr_nbma = list_new();
251
252
  /* Initialize Link State Acknowledgment list. */
253
1
  oi->ls_ack = list_new();
254
1
  oi->ls_ack_direct.ls_ack = list_new();
255
256
  /* Set default values. */
257
1
  ospf_if_reset_variables(oi);
258
259
  /* Set pseudo neighbor to Null */
260
1
  oi->nbr_self = NULL;
261
262
1
  oi->ls_upd_queue = route_table_init();
263
1
  oi->t_ls_upd_event = NULL;
264
1
  oi->t_ls_ack_direct = NULL;
265
266
1
  oi->crypt_seqnum = frr_sequence32_next();
267
268
1
  ospf_opaque_type9_lsa_init(oi);
269
270
1
  oi->ospf = ospf;
271
272
1
  QOBJ_REG(oi, ospf_interface);
273
274
1
  if (IS_DEBUG_OSPF_EVENT)
275
0
    zlog_debug("%s: ospf interface %s vrf %s id %u created",
276
1
         __func__, ifp->name, ospf_get_name(ospf),
277
1
         ospf->vrf_id);
278
279
1
  return oi;
280
1
}
281
282
/* Restore an interface to its pre UP state
283
   Used from ism_interface_down only */
284
void ospf_if_cleanup(struct ospf_interface *oi)
285
0
{
286
0
  struct route_node *rn;
287
0
  struct listnode *node, *nnode;
288
0
  struct ospf_neighbor *nbr;
289
0
  struct ospf_nbr_nbma *nbr_nbma;
290
0
  struct ospf_lsa *lsa;
291
292
  /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
293
  /* delete all static neighbors attached to this interface */
294
0
  for (ALL_LIST_ELEMENTS(oi->nbr_nbma, node, nnode, nbr_nbma)) {
295
0
    EVENT_OFF(nbr_nbma->t_poll);
296
297
0
    if (nbr_nbma->nbr) {
298
0
      nbr_nbma->nbr->nbr_nbma = NULL;
299
0
      nbr_nbma->nbr = NULL;
300
0
    }
301
302
0
    nbr_nbma->oi = NULL;
303
304
0
    listnode_delete(oi->nbr_nbma, nbr_nbma);
305
0
  }
306
307
  /* send Neighbor event KillNbr to all associated neighbors. */
308
0
  for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
309
0
    if ((nbr = rn->info) != NULL)
310
0
      if (nbr != oi->nbr_self)
311
0
        OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
312
0
  }
313
314
  /* Cleanup Link State Acknowlegdment list. */
315
0
  for (ALL_LIST_ELEMENTS(oi->ls_ack, node, nnode, lsa))
316
0
    ospf_lsa_unlock(&lsa); /* oi->ls_ack */
317
0
  list_delete_all_node(oi->ls_ack);
318
319
0
  oi->crypt_seqnum = 0;
320
321
  /* Empty link state update queue */
322
0
  ospf_ls_upd_queue_empty(oi);
323
324
  /* Reset pseudo neighbor. */
325
0
  ospf_nbr_self_reset(oi, oi->ospf->router_id);
326
0
}
327
328
void ospf_if_free(struct ospf_interface *oi)
329
0
{
330
0
  ospf_if_down(oi);
331
332
0
  ospf_fifo_free(oi->obuf);
333
334
0
  assert(oi->state == ISM_Down);
335
336
0
  ospf_opaque_type9_lsa_term(oi);
337
338
0
  QOBJ_UNREG(oi);
339
340
  /* Free Pseudo Neighbour */
341
0
  ospf_nbr_delete(oi->nbr_self);
342
343
0
  route_table_finish(oi->nbrs);
344
0
  route_table_finish(oi->ls_upd_queue);
345
346
  /* Free any lists that should be freed */
347
0
  list_delete(&oi->nbr_nbma);
348
349
0
  list_delete(&oi->ls_ack);
350
0
  list_delete(&oi->ls_ack_direct.ls_ack);
351
352
0
  if (IS_DEBUG_OSPF_EVENT)
353
0
    zlog_debug("%s: ospf interface %s vrf %s id %u deleted",
354
0
         __func__, oi->ifp->name, oi->ifp->vrf->name,
355
0
         oi->ifp->vrf->vrf_id);
356
357
0
  ospf_delete_from_if(oi->ifp, oi);
358
359
0
  listnode_delete(oi->ospf->oiflist, oi);
360
0
  listnode_delete(oi->area->oiflist, oi);
361
362
0
  event_cancel_event(master, oi);
363
364
0
  memset(oi, 0, sizeof(*oi));
365
0
  XFREE(MTYPE_OSPF_IF, oi);
366
0
}
367
368
int ospf_if_is_up(struct ospf_interface *oi)
369
0
{
370
0
  return if_is_up(oi->ifp);
371
0
}
372
373
struct ospf_interface *ospf_if_exists(struct ospf_interface *oic)
374
0
{
375
0
  struct listnode *node;
376
0
  struct ospf *ospf;
377
0
  struct ospf_interface *oi;
378
379
0
  if (!oic)
380
0
    return NULL;
381
382
0
  ospf = oic->ospf;
383
0
  if (ospf == NULL)
384
0
    return NULL;
385
386
0
  for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
387
0
    if (oi == oic)
388
0
      return oi;
389
390
0
  return NULL;
391
0
}
392
393
/* Lookup OSPF interface by router LSA posistion */
394
struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *area,
395
             int lsa_pos)
396
0
{
397
0
  struct listnode *node;
398
0
  struct ospf_interface *oi;
399
400
0
  for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) {
401
0
    if (lsa_pos >= oi->lsa_pos_beg && lsa_pos < oi->lsa_pos_end)
402
0
      return oi;
403
0
  }
404
0
  return NULL;
405
0
}
406
407
struct ospf_interface *ospf_if_lookup_by_local_addr(struct ospf *ospf,
408
                struct interface *ifp,
409
                struct in_addr address)
410
3.22k
{
411
3.22k
  struct listnode *node;
412
3.22k
  struct ospf_interface *oi;
413
414
3.22k
  for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
415
3.22k
    if (oi->type != OSPF_IFTYPE_VIRTUALLINK) {
416
3.22k
      if (ifp && oi->ifp != ifp)
417
0
        continue;
418
419
3.22k
      if (IPV4_ADDR_SAME(&address, &oi->address->u.prefix4))
420
2
        return oi;
421
3.22k
    }
422
423
3.22k
  return NULL;
424
3.22k
}
425
426
struct ospf_interface *ospf_if_lookup_by_prefix(struct ospf *ospf,
427
            struct prefix_ipv4 *p)
428
0
{
429
0
  struct listnode *node;
430
0
  struct ospf_interface *oi;
431
432
  /* Check each Interface. */
433
0
  for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
434
0
    if (oi->type != OSPF_IFTYPE_VIRTUALLINK) {
435
0
      struct prefix ptmp;
436
437
0
      prefix_copy(&ptmp, CONNECTED_PREFIX(oi->connected));
438
0
      apply_mask(&ptmp);
439
0
      if (prefix_same(&ptmp, (struct prefix *)p))
440
0
        return oi;
441
0
    }
442
0
  }
443
0
  return NULL;
444
0
}
445
446
/* determine receiving interface by ifp and source address */
447
struct ospf_interface *ospf_if_lookup_recv_if(struct ospf *ospf,
448
                struct in_addr src,
449
                struct interface *ifp)
450
2.82k
{
451
2.82k
  struct route_node *rn;
452
2.82k
  struct prefix_ipv4 addr;
453
2.82k
  struct ospf_interface *oi, *match, *unnumbered_match;
454
455
2.82k
  addr.family = AF_INET;
456
2.82k
  addr.prefix = src;
457
2.82k
  addr.prefixlen = IPV4_MAX_BITLEN;
458
459
2.82k
  match = unnumbered_match = NULL;
460
461
5.64k
  for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
462
2.82k
    oi = rn->info;
463
464
2.82k
    if (!oi) /* oi can be NULL for PtP aliases */
465
0
      continue;
466
467
2.82k
    if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
468
0
      continue;
469
470
2.82k
    if (if_is_loopback(oi->ifp))
471
0
      continue;
472
473
2.82k
    if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
474
0
      unnumbered_match = oi;
475
2.82k
    else if (prefix_match(CONNECTED_PREFIX(oi->connected),
476
2.82k
              (struct prefix *)&addr)) {
477
2.75k
      if ((match == NULL) || (match->address->prefixlen
478
0
            < oi->address->prefixlen))
479
2.75k
        match = oi;
480
2.75k
    }
481
2.82k
  }
482
483
2.82k
  if (match)
484
2.75k
    return match;
485
486
68
  return unnumbered_match;
487
2.82k
}
488
489
void ospf_interface_fifo_flush(struct ospf_interface *oi)
490
0
{
491
0
  struct ospf *ospf = oi->ospf;
492
493
0
  ospf_fifo_flush(oi->obuf);
494
495
0
  if (oi->on_write_q) {
496
0
    listnode_delete(ospf->oi_write_q, oi);
497
0
    if (list_isempty(ospf->oi_write_q))
498
0
      EVENT_OFF(ospf->t_write);
499
0
    oi->on_write_q = 0;
500
0
  }
501
0
}
502
503
static void ospf_if_reset_stats(struct ospf_interface *oi)
504
0
{
505
0
  oi->hello_in = oi->hello_out = 0;
506
0
  oi->db_desc_in = oi->db_desc_out = 0;
507
0
  oi->ls_req_in = oi->ls_req_out = 0;
508
0
  oi->ls_upd_in = oi->ls_upd_out = 0;
509
0
  oi->ls_ack_in = oi->ls_ack_out = 0;
510
0
}
511
512
void ospf_if_stream_unset(struct ospf_interface *oi)
513
0
{
514
  /* flush the interface packet queue */
515
0
  ospf_interface_fifo_flush(oi);
516
  /*reset protocol stats */
517
0
  ospf_if_reset_stats(oi);
518
0
}
519
520
521
static struct ospf_if_params *ospf_new_if_params(void)
522
1
{
523
1
  struct ospf_if_params *oip;
524
525
1
  oip = XCALLOC(MTYPE_OSPF_IF_PARAMS, sizeof(struct ospf_if_params));
526
527
1
  UNSET_IF_PARAM(oip, output_cost_cmd);
528
1
  UNSET_IF_PARAM(oip, transmit_delay);
529
1
  UNSET_IF_PARAM(oip, retransmit_interval);
530
1
  UNSET_IF_PARAM(oip, passive_interface);
531
1
  UNSET_IF_PARAM(oip, v_hello);
532
1
  UNSET_IF_PARAM(oip, fast_hello);
533
1
  UNSET_IF_PARAM(oip, v_gr_hello_delay);
534
1
  UNSET_IF_PARAM(oip, v_wait);
535
1
  UNSET_IF_PARAM(oip, priority);
536
1
  UNSET_IF_PARAM(oip, type);
537
1
  UNSET_IF_PARAM(oip, auth_simple);
538
1
  UNSET_IF_PARAM(oip, auth_crypt);
539
1
  UNSET_IF_PARAM(oip, auth_type);
540
1
  UNSET_IF_PARAM(oip, if_area);
541
542
1
  oip->auth_crypt = list_new();
543
544
1
  oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
545
1
  oip->is_v_wait_set = false;
546
547
1
  oip->ptp_dmvpn = 0;
548
1
  oip->p2mp_delay_reflood = OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
549
550
1
  return oip;
551
1
}
552
553
static void ospf_del_if_params(struct interface *ifp,
554
             struct ospf_if_params *oip)
555
0
{
556
0
  list_delete(&oip->auth_crypt);
557
0
  ospf_interface_disable_bfd(ifp, oip);
558
0
  ldp_sync_info_free(&(oip->ldp_sync_info));
559
0
  XFREE(MTYPE_OSPF_IF_PARAMS, oip);
560
0
}
561
562
void ospf_free_if_params(struct interface *ifp, struct in_addr addr)
563
0
{
564
0
  struct ospf_if_params *oip;
565
0
  struct prefix_ipv4 p;
566
0
  struct route_node *rn;
567
568
0
  p.family = AF_INET;
569
0
  p.prefixlen = IPV4_MAX_BITLEN;
570
0
  p.prefix = addr;
571
0
  rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
572
0
  if (!rn || !rn->info)
573
0
    return;
574
575
0
  oip = rn->info;
576
0
  route_unlock_node(rn);
577
578
0
  if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd)
579
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay)
580
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval)
581
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface)
582
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, v_hello)
583
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello)
584
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, v_wait)
585
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, priority)
586
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, type)
587
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple)
588
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type)
589
0
      && !OSPF_IF_PARAM_CONFIGURED(oip, if_area)
590
0
      && listcount(oip->auth_crypt) == 0) {
591
0
    ospf_del_if_params(ifp, oip);
592
0
    rn->info = NULL;
593
0
    route_unlock_node(rn);
594
0
  }
595
0
}
596
597
struct ospf_if_params *ospf_lookup_if_params(struct interface *ifp,
598
               struct in_addr addr)
599
1
{
600
1
  struct prefix_ipv4 p;
601
1
  struct route_node *rn;
602
603
1
  p.family = AF_INET;
604
1
  p.prefixlen = IPV4_MAX_BITLEN;
605
1
  p.prefix = addr;
606
607
1
  rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
608
609
1
  if (rn) {
610
0
    route_unlock_node(rn);
611
0
    return rn->info;
612
0
  }
613
614
1
  return NULL;
615
1
}
616
617
struct ospf_if_params *ospf_get_if_params(struct interface *ifp,
618
            struct in_addr addr)
619
0
{
620
0
  struct prefix_ipv4 p;
621
0
  struct route_node *rn;
622
623
0
  p.family = AF_INET;
624
0
  p.prefixlen = IPV4_MAX_BITLEN;
625
0
  p.prefix = addr;
626
0
  apply_mask_ipv4(&p);
627
628
0
  rn = route_node_get(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
629
630
0
  if (rn->info == NULL)
631
0
    rn->info = ospf_new_if_params();
632
0
  else
633
0
    route_unlock_node(rn);
634
635
0
  return rn->info;
636
0
}
637
638
void ospf_if_update_params(struct interface *ifp, struct in_addr addr)
639
0
{
640
0
  struct route_node *rn;
641
0
  struct ospf_interface *oi;
642
643
0
  for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
644
0
    if ((oi = rn->info) == NULL)
645
0
      continue;
646
647
0
    if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &addr))
648
0
      oi->params = ospf_lookup_if_params(
649
0
        ifp, oi->address->u.prefix4);
650
0
  }
651
0
}
652
653
int ospf_if_new_hook(struct interface *ifp)
654
1
{
655
1
  int rc = 0;
656
657
1
  ifp->info = XCALLOC(MTYPE_OSPF_IF_INFO, sizeof(struct ospf_if_info));
658
659
1
  IF_OSPF_IF_INFO(ifp)->oii_fd = -1;
660
661
1
  IF_OIFS(ifp) = route_table_init();
662
1
  IF_OIFS_PARAMS(ifp) = route_table_init();
663
664
1
  IF_DEF_PARAMS(ifp) = ospf_new_if_params();
665
666
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), transmit_delay);
667
1
  IF_DEF_PARAMS(ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
668
669
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_interval);
670
1
  IF_DEF_PARAMS(ifp)->retransmit_interval =
671
1
    OSPF_RETRANSMIT_INTERVAL_DEFAULT;
672
673
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), priority);
674
1
  IF_DEF_PARAMS(ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
675
676
1
  IF_DEF_PARAMS(ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;
677
678
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello);
679
1
  IF_DEF_PARAMS(ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
680
681
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), fast_hello);
682
1
  IF_DEF_PARAMS(ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
683
684
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_gr_hello_delay);
685
1
  IF_DEF_PARAMS(ifp)->v_gr_hello_delay = OSPF_HELLO_DELAY_DEFAULT;
686
687
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait);
688
1
  IF_DEF_PARAMS(ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
689
690
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_simple);
691
1
  memset(IF_DEF_PARAMS(ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
692
693
1
  SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type);
694
1
  IF_DEF_PARAMS(ifp)->auth_type = OSPF_AUTH_NOTSET;
695
696
1
  rc = ospf_opaque_new_if(ifp);
697
1
  return rc;
698
1
}
699
700
static int ospf_if_delete_hook(struct interface *ifp)
701
0
{
702
0
  int rc = 0;
703
0
  struct route_node *rn;
704
0
  struct ospf_if_info *oii;
705
706
0
  rc = ospf_opaque_del_if(ifp);
707
708
  /*
709
   * This function must be called before `route_table_finish` due to
710
   * BFD integration need to iterate over the interface neighbors to
711
   * remove all registrations.
712
   */
713
0
  ospf_del_if_params(ifp, IF_DEF_PARAMS(ifp));
714
715
0
  for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
716
0
    if (rn->info)
717
0
      ospf_del_if_params(ifp, rn->info);
718
719
0
  route_table_finish(IF_OIFS(ifp));
720
0
  route_table_finish(IF_OIFS_PARAMS(ifp));
721
722
  /* Close per-interface socket */
723
0
  oii = ifp->info;
724
0
  if (oii && oii->oii_fd > 0) {
725
0
    close(oii->oii_fd);
726
0
    oii->oii_fd = -1;
727
0
  }
728
729
0
  XFREE(MTYPE_OSPF_IF_INFO, ifp->info);
730
731
0
  return rc;
732
0
}
733
734
int ospf_if_is_enable(struct ospf_interface *oi)
735
2.45k
{
736
2.45k
  if (!(if_is_loopback(oi->ifp)))
737
2.45k
    if (if_is_up(oi->ifp))
738
0
      return 1;
739
740
2.45k
  return 0;
741
2.45k
}
742
743
void ospf_if_set_multicast(struct ospf_interface *oi)
744
0
{
745
0
  if ((oi->state > ISM_Loopback) && (oi->type != OSPF_IFTYPE_LOOPBACK)
746
0
      && (oi->type != OSPF_IFTYPE_VIRTUALLINK)
747
0
      && (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) {
748
    /* The interface should belong to the OSPF-all-routers group. */
749
0
    if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
750
0
        && (ospf_if_add_allspfrouters(oi->ospf, oi->address,
751
0
              oi->ifp->ifindex)
752
0
      >= 0))
753
      /* Set the flag only if the system call to join
754
       * succeeded. */
755
0
      OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
756
0
  } else {
757
    /* The interface should NOT belong to the OSPF-all-routers
758
     * group. */
759
0
    if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) {
760
      /* Only actually drop if this is the last reference */
761
0
      if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
762
0
        ospf_if_drop_allspfrouters(oi->ospf,
763
0
                 oi->address,
764
0
                 oi->ifp->ifindex);
765
      /* Unset the flag regardless of whether the system call
766
         to leave
767
         the group succeeded, since it's much safer to assume
768
         that
769
         we are not a member. */
770
0
      OI_MEMBER_LEFT(oi, MEMBER_ALLROUTERS);
771
0
    }
772
0
  }
773
774
0
  if (((oi->type == OSPF_IFTYPE_BROADCAST)
775
0
       || (oi->type == OSPF_IFTYPE_POINTOPOINT))
776
0
      && ((oi->state == ISM_DR) || (oi->state == ISM_Backup))
777
0
      && (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) {
778
    /* The interface should belong to the OSPF-designated-routers
779
     * group. */
780
0
    if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)
781
0
        && (ospf_if_add_alldrouters(oi->ospf, oi->address,
782
0
            oi->ifp->ifindex)
783
0
      >= 0))
784
      /* Set the flag only if the system call to join
785
       * succeeded. */
786
0
      OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
787
0
  } else {
788
    /* The interface should NOT belong to the
789
     * OSPF-designated-routers group */
790
0
    if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
791
      /* drop only if last reference */
792
0
      if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
793
0
        ospf_if_drop_alldrouters(oi->ospf, oi->address,
794
0
               oi->ifp->ifindex);
795
796
      /* Unset the flag regardless of whether the system call
797
         to leave
798
         the group succeeded, since it's much safer to assume
799
         that
800
         we are not a member. */
801
0
      OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
802
0
    }
803
0
  }
804
0
}
805
806
int ospf_if_up(struct ospf_interface *oi)
807
0
{
808
0
  if (oi == NULL)
809
0
    return 0;
810
811
0
  if (oi->type == OSPF_IFTYPE_LOOPBACK)
812
0
    OSPF_ISM_EVENT_SCHEDULE(oi, ISM_LoopInd);
813
0
  else {
814
0
    OSPF_ISM_EVENT_SCHEDULE(oi, ISM_InterfaceUp);
815
0
  }
816
817
0
  return 1;
818
0
}
819
820
int ospf_if_down(struct ospf_interface *oi)
821
0
{
822
0
  struct ospf *ospf;
823
0
  struct route_node *rn;
824
0
  struct ospf_route *or;
825
0
  struct listnode *nh;
826
0
  struct ospf_path *op;
827
828
0
  if (oi == NULL)
829
0
    return 0;
830
831
0
  ospf = oi->ospf;
832
833
  /* Cease the HELPER role for all the neighbours
834
   * of this interface.
835
   */
836
0
  if (ospf->is_helper_supported) {
837
0
    struct route_node *rn = NULL;
838
839
0
    if (ospf_interface_neighbor_count(oi)) {
840
0
      for (rn = route_top(oi->nbrs); rn;
841
0
           rn = route_next(rn)) {
842
0
        struct ospf_neighbor *nbr = NULL;
843
844
0
        if (!rn->info)
845
0
          continue;
846
847
0
        nbr = rn->info;
848
849
0
        if (OSPF_GR_IS_ACTIVE_HELPER(nbr))
850
0
          ospf_gr_helper_exit(
851
0
            nbr, OSPF_GR_HELPER_TOPO_CHG);
852
0
      }
853
0
    }
854
0
  }
855
856
0
  OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
857
  /* delete position in router LSA */
858
0
  oi->lsa_pos_beg = 0;
859
0
  oi->lsa_pos_end = 0;
860
  /* Shutdown packet reception and sending */
861
0
  ospf_if_stream_unset(oi);
862
863
0
  if (!ospf->new_table)
864
0
    return 1;
865
0
  for (rn = route_top(ospf->new_table); rn; rn = route_next(rn)) {
866
0
    or = rn->info;
867
868
0
    if (!or)
869
0
      continue;
870
871
0
    for (nh = listhead(or->paths); nh;
872
0
         nh = listnextnode_unchecked(nh)) {
873
0
      op = listgetdata(nh);
874
0
      if (op->ifindex == oi->ifp->ifindex) {
875
0
        or->changed = true;
876
0
        break;
877
0
      }
878
0
    }
879
0
  }
880
881
0
  return 1;
882
0
}
883
884
885
/* Virtual Link related functions. */
886
887
struct ospf_vl_data *ospf_vl_data_new(struct ospf_area *area,
888
              struct in_addr vl_peer)
889
0
{
890
0
  struct ospf_vl_data *vl_data;
891
892
0
  vl_data = XCALLOC(MTYPE_OSPF_VL_DATA, sizeof(struct ospf_vl_data));
893
894
0
  vl_data->vl_peer.s_addr = vl_peer.s_addr;
895
0
  vl_data->vl_area_id = area->area_id;
896
0
  vl_data->vl_area_id_fmt = area->area_id_fmt;
897
898
0
  return vl_data;
899
0
}
900
901
void ospf_vl_data_free(struct ospf_vl_data *vl_data)
902
0
{
903
0
  XFREE(MTYPE_OSPF_VL_DATA, vl_data);
904
0
}
905
906
unsigned int vlink_count = 0;
907
908
struct ospf_interface *ospf_vl_new(struct ospf *ospf,
909
           struct ospf_vl_data *vl_data)
910
0
{
911
0
  struct ospf_interface *voi;
912
0
  struct interface *vi;
913
0
  char ifname[INTERFACE_NAMSIZ];
914
0
  struct ospf_area *area;
915
0
  struct in_addr area_id;
916
0
  struct connected *co;
917
0
  struct prefix_ipv4 *p;
918
919
0
  if (IS_DEBUG_OSPF_EVENT)
920
0
    zlog_debug("%s: (%s): Start", __func__, ospf_get_name(ospf));
921
0
  if (vlink_count == OSPF_VL_MAX_COUNT) {
922
0
    if (IS_DEBUG_OSPF_EVENT)
923
0
      zlog_debug(
924
0
        "%s: Alarm: cannot create more than OSPF_MAX_VL_COUNT virtual links",
925
0
        __func__);
926
927
0
    return NULL;
928
0
  }
929
930
0
  if (IS_DEBUG_OSPF_EVENT)
931
0
    zlog_debug("%s: creating pseudo zebra interface vrf id %u",
932
0
         __func__, ospf->vrf_id);
933
934
0
  snprintf(ifname, sizeof(ifname), "VLINK%u", vlink_count);
935
0
  vi = if_get_by_name(ifname, ospf->vrf_id, ospf->name);
936
  /*
937
   * if_get_by_name sets ZEBRA_INTERFACE_LINKDETECTION
938
   * virtual links don't need this.
939
   */
940
0
  UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION);
941
0
  co = connected_new();
942
0
  co->ifp = vi;
943
0
  listnode_add(vi->connected, co);
944
945
0
  p = prefix_ipv4_new();
946
0
  p->family = AF_INET;
947
0
  p->prefix.s_addr = INADDR_ANY;
948
0
  p->prefixlen = 0;
949
950
0
  co->address = (struct prefix *)p;
951
952
0
  voi = ospf_if_new(ospf, vi, co->address);
953
0
  if (voi == NULL) {
954
0
    if (IS_DEBUG_OSPF_EVENT)
955
0
      zlog_debug(
956
0
        "%s: Alarm: OSPF int structure is not created",
957
0
        __func__);
958
959
0
    return NULL;
960
0
  }
961
0
  voi->connected = co;
962
0
  voi->vl_data = vl_data;
963
0
  voi->ifp->mtu = OSPF_VL_MTU;
964
0
  voi->type = OSPF_IFTYPE_VIRTUALLINK;
965
966
0
  vlink_count++;
967
0
  if (IS_DEBUG_OSPF_EVENT)
968
0
    zlog_debug("%s: Created name: %s set if->name to %s", __func__,
969
0
         ifname, vi->name);
970
971
0
  area_id.s_addr = INADDR_ANY;
972
0
  area = ospf_area_get(ospf, area_id);
973
0
  voi->area = area;
974
975
0
  if (IS_DEBUG_OSPF_EVENT)
976
0
    zlog_debug("%s: set associated area to the backbone", __func__);
977
978
  /* Add pseudo neighbor. */
979
0
  ospf_nbr_self_reset(voi, voi->ospf->router_id);
980
981
0
  ospf_area_add_if(voi->area, voi);
982
983
0
  if (IS_DEBUG_OSPF_EVENT)
984
0
    zlog_debug("%s: Stop", __func__);
985
0
  return voi;
986
0
}
987
988
static void ospf_vl_if_delete(struct ospf_vl_data *vl_data)
989
0
{
990
0
  struct interface *ifp = vl_data->vl_oi->ifp;
991
0
  struct vrf *vrf = ifp->vrf;
992
993
0
  vl_data->vl_oi->address->u.prefix4.s_addr = INADDR_ANY;
994
0
  vl_data->vl_oi->address->prefixlen = 0;
995
0
  ospf_if_free(vl_data->vl_oi);
996
0
  if_delete(&ifp);
997
0
  if (!vrf_is_enabled(vrf))
998
0
    vrf_delete(vrf);
999
0
}
1000
1001
/* for a defined area, count the number of configured vl
1002
 */
1003
int ospf_vl_count(struct ospf *ospf, struct ospf_area *area)
1004
0
{
1005
0
  int count = 0;
1006
0
  struct ospf_vl_data *vl_data;
1007
0
  struct listnode *node;
1008
1009
0
  for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
1010
0
    if (area
1011
0
        && !IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
1012
0
      continue;
1013
0
    count++;
1014
0
  }
1015
0
  return count;
1016
0
}
1017
1018
/* Look up vl_data for given peer, optionally qualified to be in the
1019
 * specified area. NULL area returns first found..
1020
 */
1021
struct ospf_vl_data *ospf_vl_lookup(struct ospf *ospf, struct ospf_area *area,
1022
            struct in_addr vl_peer)
1023
0
{
1024
0
  struct ospf_vl_data *vl_data;
1025
0
  struct listnode *node;
1026
1027
0
  if (IS_DEBUG_OSPF_EVENT) {
1028
0
    zlog_debug("%s: Looking for %pI4", __func__, &vl_peer);
1029
0
    if (area)
1030
0
      zlog_debug("%s: in area %pI4", __func__,
1031
0
           &area->area_id);
1032
0
  }
1033
1034
0
  for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
1035
0
    if (IS_DEBUG_OSPF_EVENT)
1036
0
      zlog_debug("%s: VL %s, peer %pI4", __func__,
1037
0
           vl_data->vl_oi->ifp->name,
1038
0
           &vl_data->vl_peer);
1039
1040
0
    if (area
1041
0
        && !IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
1042
0
      continue;
1043
1044
0
    if (IPV4_ADDR_SAME(&vl_data->vl_peer, &vl_peer))
1045
0
      return vl_data;
1046
0
  }
1047
1048
0
  return NULL;
1049
0
}
1050
1051
static void ospf_vl_shutdown(struct ospf_vl_data *vl_data)
1052
0
{
1053
0
  struct ospf_interface *oi;
1054
1055
0
  if ((oi = vl_data->vl_oi) == NULL)
1056
0
    return;
1057
1058
0
  oi->address->u.prefix4.s_addr = INADDR_ANY;
1059
0
  oi->address->prefixlen = 0;
1060
1061
0
  UNSET_FLAG(oi->ifp->flags, IFF_UP);
1062
  /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
1063
0
  OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
1064
0
}
1065
1066
void ospf_vl_add(struct ospf *ospf, struct ospf_vl_data *vl_data)
1067
0
{
1068
0
  listnode_add(ospf->vlinks, vl_data);
1069
0
  hook_call(ospf_vl_add, vl_data);
1070
0
}
1071
1072
void ospf_vl_delete(struct ospf *ospf, struct ospf_vl_data *vl_data)
1073
0
{
1074
0
  ospf_vl_shutdown(vl_data);
1075
0
  ospf_vl_if_delete(vl_data);
1076
1077
0
  hook_call(ospf_vl_delete, vl_data);
1078
0
  listnode_delete(ospf->vlinks, vl_data);
1079
1080
0
  ospf_vl_data_free(vl_data);
1081
0
}
1082
1083
static int ospf_vl_set_params(struct ospf_area *area,
1084
            struct ospf_vl_data *vl_data, struct vertex *v)
1085
0
{
1086
0
  int changed = 0;
1087
0
  struct ospf_interface *voi;
1088
0
  struct listnode *node;
1089
0
  struct vertex_parent *vp = NULL;
1090
0
  unsigned int i;
1091
0
  struct router_lsa *rl;
1092
0
  struct ospf_interface *oi;
1093
1094
0
  voi = vl_data->vl_oi;
1095
1096
0
  if (voi->output_cost != v->distance) {
1097
1098
0
    voi->output_cost = v->distance;
1099
0
    changed = 1;
1100
0
  }
1101
1102
0
  for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
1103
0
    vl_data->nexthop.lsa_pos = vp->nexthop->lsa_pos;
1104
0
    vl_data->nexthop.router = vp->nexthop->router;
1105
1106
    /*
1107
     * Only deal with interface data when the local
1108
     * (calculating) node is the SPF root node
1109
     */
1110
0
    if (!area->spf_dry_run) {
1111
0
      oi = ospf_if_lookup_by_lsa_pos(
1112
0
        area, vl_data->nexthop.lsa_pos);
1113
1114
0
      if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
1115
0
              &oi->address->u.prefix4))
1116
0
        changed = 1;
1117
1118
0
      voi->address->u.prefix4 = oi->address->u.prefix4;
1119
0
      voi->address->prefixlen = oi->address->prefixlen;
1120
0
    }
1121
1122
0
    break; /* We take the first interface. */
1123
0
  }
1124
1125
0
  rl = (struct router_lsa *)v->lsa;
1126
1127
  /* use SPF determined backlink index in struct vertex
1128
   * for virtual link destination address
1129
   */
1130
0
  if (vp && vp->backlink >= 0) {
1131
0
    if (!IPV4_ADDR_SAME(&vl_data->peer_addr,
1132
0
            &rl->link[vp->backlink].link_data))
1133
0
      changed = 1;
1134
0
    vl_data->peer_addr = rl->link[vp->backlink].link_data;
1135
0
  } else {
1136
    /* This is highly odd, there is no backlink index
1137
     * there should be due to the ospf_spf_has_link() check
1138
     * in SPF. Lets warn and try pick a link anyway.
1139
     */
1140
0
    zlog_info("ospf_vl_set_params: No backlink for %s!",
1141
0
        vl_data->vl_oi->ifp->name);
1142
0
    for (i = 0; i < ntohs(rl->links); i++) {
1143
0
      switch (rl->link[i].type) {
1144
0
      case LSA_LINK_TYPE_VIRTUALLINK:
1145
0
        if (IS_DEBUG_OSPF_EVENT)
1146
0
          zlog_debug(
1147
0
            "found back link through VL");
1148
      /* fallthru */
1149
0
      case LSA_LINK_TYPE_TRANSIT:
1150
0
      case LSA_LINK_TYPE_POINTOPOINT:
1151
0
        if (!IPV4_ADDR_SAME(&vl_data->peer_addr,
1152
0
                &rl->link[i].link_data))
1153
0
          changed = 1;
1154
0
        vl_data->peer_addr = rl->link[i].link_data;
1155
0
      }
1156
0
    }
1157
0
  }
1158
1159
0
  if (IS_DEBUG_OSPF_EVENT)
1160
0
    zlog_debug("%s: %s peer address: %pI4, cost: %d,%schanged",
1161
0
         __func__, vl_data->vl_oi->ifp->name,
1162
0
         &vl_data->peer_addr, voi->output_cost,
1163
0
         (changed ? " " : " un"));
1164
1165
0
  return changed;
1166
0
}
1167
1168
1169
void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid,
1170
          struct vertex *v)
1171
0
{
1172
0
  struct ospf *ospf = area->ospf;
1173
0
  struct listnode *node;
1174
0
  struct ospf_vl_data *vl_data;
1175
0
  struct ospf_interface *oi;
1176
1177
0
  if (IS_DEBUG_OSPF_EVENT) {
1178
0
    zlog_debug("%s: Start", __func__);
1179
0
    zlog_debug("%s: Router ID is %pI4 Area is %pI4", __func__, &rid,
1180
0
         &area->area_id);
1181
0
  }
1182
1183
0
  for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
1184
0
    if (IS_DEBUG_OSPF_EVENT) {
1185
0
      zlog_debug("%s: considering VL, %s in area %pI4",
1186
0
           __func__, vl_data->vl_oi->ifp->name,
1187
0
           &vl_data->vl_area_id);
1188
0
      zlog_debug("%s: peer ID: %pI4", __func__,
1189
0
           &vl_data->vl_peer);
1190
0
    }
1191
1192
0
    if (IPV4_ADDR_SAME(&vl_data->vl_peer, &rid)
1193
0
        && IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id)) {
1194
0
      oi = vl_data->vl_oi;
1195
0
      SET_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED);
1196
1197
0
      if (IS_DEBUG_OSPF_EVENT)
1198
0
        zlog_debug("%s: this VL matched", __func__);
1199
1200
0
      if (oi->state == ISM_Down) {
1201
0
        if (IS_DEBUG_OSPF_EVENT)
1202
0
          zlog_debug(
1203
0
            "%s: VL is down, waking it up",
1204
0
            __func__);
1205
0
        SET_FLAG(oi->ifp->flags, IFF_UP);
1206
0
        OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
1207
0
      }
1208
1209
0
      if (ospf_vl_set_params(area, vl_data, v)) {
1210
0
        if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
1211
0
          zlog_debug(
1212
0
            "%s: VL cost change, scheduling router lsa refresh",
1213
0
            __func__);
1214
0
        if (ospf->backbone)
1215
0
          ospf_router_lsa_update_area(
1216
0
            ospf->backbone);
1217
0
        else if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
1218
0
          zlog_debug(
1219
0
            "%s: VL cost change, no backbone!",
1220
0
            __func__);
1221
0
      }
1222
0
    }
1223
0
  }
1224
0
}
1225
1226
void ospf_vl_unapprove(struct ospf *ospf)
1227
0
{
1228
0
  struct listnode *node;
1229
0
  struct ospf_vl_data *vl_data;
1230
1231
0
  for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data))
1232
0
    UNSET_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED);
1233
0
}
1234
1235
void ospf_vl_shut_unapproved(struct ospf *ospf)
1236
0
{
1237
0
  struct listnode *node, *nnode;
1238
0
  struct ospf_vl_data *vl_data;
1239
1240
0
  for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
1241
0
    if (!CHECK_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED))
1242
0
      ospf_vl_shutdown(vl_data);
1243
0
}
1244
1245
int ospf_full_virtual_nbrs(struct ospf_area *area)
1246
1
{
1247
1
  if (IS_DEBUG_OSPF_EVENT) {
1248
0
    zlog_debug(
1249
0
      "counting fully adjacent virtual neighbors in area %pI4",
1250
0
      &area->area_id);
1251
0
    zlog_debug("there are %d of them", area->full_vls);
1252
0
  }
1253
1254
1
  return area->full_vls;
1255
1
}
1256
1257
int ospf_vls_in_area(struct ospf_area *area)
1258
0
{
1259
0
  struct listnode *node;
1260
0
  struct ospf_vl_data *vl_data;
1261
0
  int c = 0;
1262
1263
0
  for (ALL_LIST_ELEMENTS_RO(area->ospf->vlinks, node, vl_data))
1264
0
    if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
1265
0
      c++;
1266
1267
0
  return c;
1268
0
}
1269
1270
1271
struct crypt_key *ospf_crypt_key_new(void)
1272
0
{
1273
0
  return XCALLOC(MTYPE_OSPF_CRYPT_KEY, sizeof(struct crypt_key));
1274
0
}
1275
1276
void ospf_crypt_key_add(struct list *crypt, struct crypt_key *ck)
1277
0
{
1278
0
  listnode_add(crypt, ck);
1279
0
}
1280
1281
struct crypt_key *ospf_crypt_key_lookup(struct list *auth_crypt, uint8_t key_id)
1282
0
{
1283
0
  struct listnode *node;
1284
0
  struct crypt_key *ck;
1285
1286
0
  for (ALL_LIST_ELEMENTS_RO(auth_crypt, node, ck))
1287
0
    if (ck->key_id == key_id)
1288
0
      return ck;
1289
1290
0
  return NULL;
1291
0
}
1292
1293
int ospf_crypt_key_delete(struct list *auth_crypt, uint8_t key_id)
1294
0
{
1295
0
  struct listnode *node, *nnode;
1296
0
  struct crypt_key *ck;
1297
1298
0
  for (ALL_LIST_ELEMENTS(auth_crypt, node, nnode, ck)) {
1299
0
    if (ck->key_id == key_id) {
1300
0
      listnode_delete(auth_crypt, ck);
1301
0
      XFREE(MTYPE_OSPF_CRYPT_KEY, ck);
1302
0
      return 1;
1303
0
    }
1304
0
  }
1305
1306
0
  return 0;
1307
0
}
1308
1309
uint8_t ospf_default_iftype(struct interface *ifp)
1310
0
{
1311
0
  if (if_is_pointopoint(ifp))
1312
0
    return OSPF_IFTYPE_POINTOPOINT;
1313
0
  else if (if_is_loopback(ifp))
1314
0
    return OSPF_IFTYPE_LOOPBACK;
1315
0
  else
1316
0
    return OSPF_IFTYPE_BROADCAST;
1317
0
}
1318
1319
void ospf_if_interface(struct interface *ifp)
1320
0
{
1321
0
  hook_call(ospf_if_update, ifp);
1322
0
}
1323
1324
uint32_t ospf_if_count_area_params(struct interface *ifp)
1325
0
{
1326
0
  struct ospf_if_params *params;
1327
0
  struct route_node *rn;
1328
0
  uint32_t count = 0;
1329
1330
0
  params = IF_DEF_PARAMS(ifp);
1331
0
  if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
1332
0
    count++;
1333
1334
0
  for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
1335
0
    if ((params = rn->info)
1336
0
        && OSPF_IF_PARAM_CONFIGURED(params, if_area))
1337
0
      count++;
1338
1339
0
  return count;
1340
0
}
1341
1342
static int ospf_ifp_create(struct interface *ifp)
1343
0
{
1344
0
  struct ospf *ospf = NULL;
1345
0
  struct ospf_if_info *oii;
1346
1347
0
  if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
1348
0
    zlog_debug(
1349
0
      "Zebra: interface add %s vrf %s[%u] index %d flags %llx metric %d mtu %d speed %u status 0x%x",
1350
0
      ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
1351
0
      ifp->ifindex, (unsigned long long)ifp->flags,
1352
0
      ifp->metric, ifp->mtu, ifp->speed, ifp->status);
1353
1354
0
  assert(ifp->info);
1355
1356
0
  oii = ifp->info;
1357
0
  oii->curr_mtu = ifp->mtu;
1358
1359
  /* Change ospf type param based on following
1360
   * condition:
1361
   * ospf type params is not set (first creation),
1362
   * OR ospf param type is changed based on
1363
   * link event, currently only handle for
1364
   * loopback interface type, for other ospf interface,
1365
   * type can be set from user config which needs to be
1366
   * preserved.
1367
   */
1368
0
  if (IF_DEF_PARAMS(ifp) &&
1369
0
      (!OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(ifp), type) ||
1370
0
       if_is_loopback(ifp))) {
1371
0
    SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
1372
0
    IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
1373
0
  }
1374
1375
0
  ospf = ifp->vrf->info;
1376
0
  if (!ospf)
1377
0
    return 0;
1378
1379
0
  if (ospf_if_count_area_params(ifp) > 0)
1380
0
    ospf_interface_area_set(ospf, ifp);
1381
1382
0
  ospf_if_recalculate_output_cost(ifp);
1383
1384
0
  ospf_if_update(ospf, ifp);
1385
1386
0
  if (HAS_LINK_PARAMS(ifp))
1387
0
    ospf_mpls_te_update_if(ifp);
1388
1389
0
  hook_call(ospf_if_update, ifp);
1390
1391
0
  return 0;
1392
0
}
1393
1394
static int ospf_ifp_up(struct interface *ifp)
1395
0
{
1396
0
  struct ospf_interface *oi;
1397
0
  struct route_node *rn;
1398
0
  struct ospf_if_info *oii = ifp->info;
1399
0
  struct ospf *ospf;
1400
1401
0
  if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
1402
0
    zlog_debug("Zebra: Interface[%s] state change to up.",
1403
0
         ifp->name);
1404
1405
  /* Open per-intf write socket if configured */
1406
0
  ospf = ifp->vrf->info;
1407
0
  if (ospf && ospf->intf_socket_enabled)
1408
0
    ospf_ifp_sock_init(ifp);
1409
1410
0
  ospf_if_recalculate_output_cost(ifp);
1411
1412
0
  if (oii && oii->curr_mtu != ifp->mtu) {
1413
0
    if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
1414
0
      zlog_debug(
1415
0
        "Zebra: Interface[%s] MTU change %u -> %u.",
1416
0
        ifp->name, oii->curr_mtu, ifp->mtu);
1417
1418
0
    oii->curr_mtu = ifp->mtu;
1419
    /* Must reset the interface (simulate down/up) when MTU
1420
     * changes. */
1421
0
    ospf_if_reset(ifp);
1422
1423
0
    return 0;
1424
0
  }
1425
1426
0
  for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
1427
0
    if ((oi = rn->info) == NULL)
1428
0
      continue;
1429
1430
0
    ospf_if_up(oi);
1431
0
  }
1432
1433
0
  if (HAS_LINK_PARAMS(ifp))
1434
0
    ospf_mpls_te_update_if(ifp);
1435
1436
0
  return 0;
1437
0
}
1438
1439
static int ospf_ifp_down(struct interface *ifp)
1440
0
{
1441
0
  struct ospf_interface *oi;
1442
0
  struct route_node *node;
1443
1444
0
  if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
1445
0
    zlog_debug("Zebra: Interface[%s] state change to down.",
1446
0
         ifp->name);
1447
1448
0
  for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) {
1449
0
    if ((oi = node->info) == NULL)
1450
0
      continue;
1451
0
    ospf_if_down(oi);
1452
0
  }
1453
1454
  /* Close per-interface write socket if configured */
1455
0
  ospf_ifp_sock_close(ifp);
1456
1457
0
  return 0;
1458
0
}
1459
1460
static int ospf_ifp_destroy(struct interface *ifp)
1461
0
{
1462
0
  struct ospf *ospf;
1463
0
  struct route_node *rn;
1464
1465
0
  if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
1466
0
    zlog_debug(
1467
0
      "Zebra: interface delete %s vrf %s[%u] index %d flags %llx metric %d mtu %d",
1468
0
      ifp->name, ifp->vrf->name, ifp->vrf->vrf_id,
1469
0
      ifp->ifindex, (unsigned long long)ifp->flags,
1470
0
      ifp->metric, ifp->mtu);
1471
1472
0
  hook_call(ospf_if_delete, ifp);
1473
1474
0
  ospf = ifp->vrf->info;
1475
0
  if (ospf) {
1476
0
    if (ospf_if_count_area_params(ifp) > 0)
1477
0
      ospf_interface_area_unset(ospf, ifp);
1478
0
  }
1479
1480
0
  for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
1481
0
    if (rn->info)
1482
0
      ospf_if_free((struct ospf_interface *)rn->info);
1483
1484
0
  return 0;
1485
0
}
1486
1487
/* Resetting ospf hello timer */
1488
void ospf_reset_hello_timer(struct interface *ifp, struct in_addr addr,
1489
          bool is_addr)
1490
0
{
1491
0
  struct route_node *rn;
1492
1493
0
  if (is_addr) {
1494
0
    struct prefix p;
1495
0
    struct ospf_interface *oi = NULL;
1496
1497
0
    p.u.prefix4 = addr;
1498
0
    p.family = AF_INET;
1499
0
    p.prefixlen = IPV4_MAX_BITLEN;
1500
1501
0
    oi = ospf_if_table_lookup(ifp, &p);
1502
1503
0
    if (oi) {
1504
      /* Send hello before restart the hello timer
1505
       * to avoid session flaps in case of bigger
1506
       * hello interval configurations.
1507
       */
1508
0
      ospf_hello_send(oi);
1509
1510
      /* Restart hello timer for this interface */
1511
0
      EVENT_OFF(oi->t_hello);
1512
0
      OSPF_HELLO_TIMER_ON(oi);
1513
0
    }
1514
1515
0
    return;
1516
0
  }
1517
1518
0
  for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
1519
0
    struct ospf_interface *oi = rn->info;
1520
1521
0
    if (!oi)
1522
0
      continue;
1523
1524
    /* If hello interval configured on this oi, don't restart. */
1525
0
    if (OSPF_IF_PARAM_CONFIGURED(oi->params, v_hello))
1526
0
      continue;
1527
1528
    /* Send hello before restart the hello timer
1529
     * to avoid session flaps in case of bigger
1530
     * hello interval configurations.
1531
     */
1532
0
    ospf_hello_send(oi);
1533
1534
    /* Restart the hello timer. */
1535
0
    EVENT_OFF(oi->t_hello);
1536
0
    OSPF_HELLO_TIMER_ON(oi);
1537
0
  }
1538
0
}
1539
1540
void ospf_if_init(void)
1541
1
{
1542
1
  if_zapi_callbacks(ospf_ifp_create, ospf_ifp_up,
1543
1
        ospf_ifp_down, ospf_ifp_destroy);
1544
1545
  /* Initialize Zebra interface data structure. */
1546
1
  hook_register_prio(if_add, 0, ospf_if_new_hook);
1547
1
  hook_register_prio(if_del, 0, ospf_if_delete_hook);
1548
1
}