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