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