]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_interface.c
Merge pull request #1369 from LabNConsulting/working/3.0/cherry-pick/minusS
[mirror_frr.git] / ospfd / ospf_interface.c
CommitLineData
718e3744 1/*
2 * OSPF Interface functions.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
ac4d0be5 6 *
718e3744 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
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "thread.h"
26#include "linklist.h"
27#include "prefix.h"
28#include "if.h"
29#include "table.h"
30#include "memory.h"
31#include "command.h"
32#include "stream.h"
33#include "log.h"
c0325cfa 34#include "zclient.h"
7f342629 35#include "bfd.h"
718e3744 36
68980084 37#include "ospfd/ospfd.h"
718e3744 38#include "ospfd/ospf_spf.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_abr.h"
718e3744 48#include "ospfd/ospf_network.h"
49#include "ospfd/ospf_dump.h"
718e3744 50
ae19c240 51DEFINE_QOBJ_TYPE(ospf_interface)
ac4d0be5 52DEFINE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd))
53DEFINE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd))
6b0655a2 54
ac4d0be5 55int ospf_if_get_output_cost(struct ospf_interface *oi)
718e3744 56{
ac4d0be5 57 /* If all else fails, use default OSPF cost */
58 u_int32_t cost;
59 u_int32_t bw, refbw;
60
61 /* ifp speed and bw can be 0 in some platforms, use ospf default bw
62 if bw is configured under interface it would be used.
63 */
64 if (!oi->ifp->bandwidth && oi->ifp->speed)
65 bw = oi->ifp->speed;
66 else
67 bw = oi->ifp->bandwidth ? oi->ifp->bandwidth
68 : OSPF_DEFAULT_BANDWIDTH;
69 refbw = oi->ospf->ref_bandwidth;
70
71 /* A specifed ip ospf cost overrides a calculated one. */
72 if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(oi->ifp), output_cost_cmd)
73 || OSPF_IF_PARAM_CONFIGURED(oi->params, output_cost_cmd))
74 cost = OSPF_IF_PARAM(oi, output_cost_cmd);
75 /* See if a cost can be calculated from the zebra processes
76 interface bandwidth field. */
77 else {
78 cost = (u_int32_t)((double)refbw / (double)bw + (double)0.5);
79 if (cost < 1)
80 cost = 1;
81 else if (cost > 65535)
82 cost = 65535;
83 }
84
85 return cost;
718e3744 86}
87
ac4d0be5 88void ospf_if_recalculate_output_cost(struct interface *ifp)
718e3744 89{
ac4d0be5 90 u_int32_t newcost;
91 struct route_node *rn;
92
93 for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
94 struct ospf_interface *oi;
95
96 if ((oi = rn->info) == NULL)
97 continue;
98
99 newcost = ospf_if_get_output_cost(oi);
100
101 /* Is actual output cost changed? */
102 if (oi->output_cost != newcost) {
103 oi->output_cost = newcost;
104 ospf_router_lsa_update_area(oi->area);
105 }
718e3744 106 }
718e3744 107}
108
ac4d0be5 109/* Simulate down/up on the interface. This is needed, for example, when
a608bbf2 110 the MTU changes. */
ac4d0be5 111void ospf_if_reset(struct interface *ifp)
a608bbf2 112{
ac4d0be5 113 struct route_node *rn;
114
115 for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
116 struct ospf_interface *oi;
117
118 if ((oi = rn->info) == NULL)
119 continue;
120
121 ospf_if_down(oi);
122 ospf_if_up(oi);
123 }
a608bbf2 124}
125
ac4d0be5 126void ospf_if_reset_variables(struct ospf_interface *oi)
718e3744 127{
ac4d0be5 128 /* Set default values. */
129 /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */
718e3744 130
ac4d0be5 131 if (oi->vl_data)
132 oi->type = OSPF_IFTYPE_VIRTUALLINK;
133 else
134 /* preserve network-type */
135 if (oi->type != OSPF_IFTYPE_NBMA)
136 oi->type = OSPF_IFTYPE_BROADCAST;
718e3744 137
ac4d0be5 138 oi->state = ISM_Down;
718e3744 139
ac4d0be5 140 oi->crypt_seqnum = 0;
718e3744 141
ac4d0be5 142 /* This must be short, (less than RxmtInterval)
143 - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being
144 held back for too long - MAG */
145 oi->v_ls_ack = 1;
718e3744 146}
147
20916fba 148/* lookup oi for specified prefix/ifp */
ac4d0be5 149struct ospf_interface *ospf_if_table_lookup(struct interface *ifp,
150 struct prefix *prefix)
20916fba 151{
ac4d0be5 152 struct prefix p;
153 struct route_node *rn;
154 struct ospf_interface *rninfo = NULL;
155
156 p = *prefix;
157 p.prefixlen = IPV4_MAX_PREFIXLEN;
158
159 /* route_node_get implicitely locks */
160 if ((rn = route_node_lookup(IF_OIFS(ifp), &p))) {
161 rninfo = (struct ospf_interface *)rn->info;
162 route_unlock_node(rn);
163 }
164
165 return rninfo;
20916fba 166}
167
ac4d0be5 168static void ospf_add_to_if(struct interface *ifp, struct ospf_interface *oi)
718e3744 169{
ac4d0be5 170 struct route_node *rn;
171 struct prefix p;
172
173 p = *oi->address;
174 p.prefixlen = IPV4_MAX_PREFIXLEN;
175
176 rn = route_node_get(IF_OIFS(ifp), &p);
177 /* rn->info should either be NULL or equal to this oi
178 * as route_node_get may return an existing node
179 */
180 assert(!rn->info || rn->info == oi);
181 rn->info = oi;
718e3744 182}
183
ac4d0be5 184static void ospf_delete_from_if(struct interface *ifp,
185 struct ospf_interface *oi)
718e3744 186{
ac4d0be5 187 struct route_node *rn;
188 struct prefix p;
189
190 p = *oi->address;
191 p.prefixlen = IPV4_MAX_PREFIXLEN;
192
193 rn = route_node_lookup(IF_OIFS(oi->ifp), &p);
194 assert(rn);
195 assert(rn->info);
196 rn->info = NULL;
197 route_unlock_node(rn);
198 route_unlock_node(rn);
718e3744 199}
200
ac4d0be5 201struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
202 struct prefix *p)
718e3744 203{
ac4d0be5 204 struct ospf_interface *oi;
205
206 if ((oi = ospf_if_table_lookup(ifp, p)) == NULL) {
207 oi = XCALLOC(MTYPE_OSPF_IF, sizeof(struct ospf_interface));
208 memset(oi, 0, sizeof(struct ospf_interface));
209 } else
210 return oi;
211
212 /* Set zebra interface pointer. */
213 oi->ifp = ifp;
214 oi->address = p;
215
216 ospf_add_to_if(ifp, oi);
217 listnode_add(ospf->oiflist, oi);
218
219 /* Initialize neighbor list. */
220 oi->nbrs = route_table_init();
221
222 /* Initialize static neighbor list. */
223 oi->nbr_nbma = list_new();
224
225 /* Initialize Link State Acknowledgment list. */
226 oi->ls_ack = list_new();
227 oi->ls_ack_direct.ls_ack = list_new();
228
229 /* Set default values. */
230 ospf_if_reset_variables(oi);
231
232 /* Set pseudo neighbor to Null */
233 oi->nbr_self = NULL;
234
235 oi->ls_upd_queue = route_table_init();
236 oi->t_ls_upd_event = NULL;
237 oi->t_ls_ack_direct = NULL;
238
239 oi->crypt_seqnum = time(NULL);
240
241 ospf_opaque_type9_lsa_init(oi);
242
243 oi->ospf = ospf;
244 QOBJ_REG(oi, ospf_interface);
245
246 return oi;
718e3744 247}
248
249/* Restore an interface to its pre UP state
250 Used from ism_interface_down only */
ac4d0be5 251void ospf_if_cleanup(struct ospf_interface *oi)
718e3744 252{
ac4d0be5 253 struct route_node *rn;
254 struct listnode *node, *nnode;
255 struct ospf_neighbor *nbr;
256 struct ospf_nbr_nbma *nbr_nbma;
257 struct ospf_lsa *lsa;
258
259 /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
260 /* delete all static neighbors attached to this interface */
261 for (ALL_LIST_ELEMENTS(oi->nbr_nbma, node, nnode, nbr_nbma)) {
262 OSPF_POLL_TIMER_OFF(nbr_nbma->t_poll);
263
264 if (nbr_nbma->nbr) {
265 nbr_nbma->nbr->nbr_nbma = NULL;
266 nbr_nbma->nbr = NULL;
267 }
268
269 nbr_nbma->oi = NULL;
270
271 listnode_delete(oi->nbr_nbma, nbr_nbma);
718e3744 272 }
273
ac4d0be5 274 /* send Neighbor event KillNbr to all associated neighbors. */
275 for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
276 if ((nbr = rn->info) != NULL)
277 if (nbr != oi->nbr_self)
278 OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
279
280 /* Cleanup Link State Acknowlegdment list. */
281 for (ALL_LIST_ELEMENTS(oi->ls_ack, node, nnode, lsa))
282 ospf_lsa_unlock(&lsa); /* oi->ls_ack */
283 list_delete_all_node(oi->ls_ack);
284
285 oi->crypt_seqnum = 0;
286
287 /* Empty link state update queue */
288 ospf_ls_upd_queue_empty(oi);
289
290 /* Reset pseudo neighbor. */
291 ospf_nbr_self_reset(oi, oi->ospf->router_id);
718e3744 292}
293
ac4d0be5 294void ospf_if_free(struct ospf_interface *oi)
718e3744 295{
ac4d0be5 296 ospf_if_down(oi);
297
298 assert(oi->state == ISM_Down);
299
300 ospf_opaque_type9_lsa_term(oi);
301
302 QOBJ_UNREG(oi);
303
304 /* Free Pseudo Neighbour */
305 ospf_nbr_delete(oi->nbr_self);
718e3744 306
ac4d0be5 307 route_table_finish(oi->nbrs);
308 route_table_finish(oi->ls_upd_queue);
718e3744 309
ac4d0be5 310 /* Free any lists that should be freed */
311 list_free(oi->nbr_nbma);
718e3744 312
ac4d0be5 313 list_free(oi->ls_ack);
314 list_free(oi->ls_ack_direct.ls_ack);
ae19c240 315
ac4d0be5 316 ospf_delete_from_if(oi->ifp, oi);
718e3744 317
ac4d0be5 318 listnode_delete(oi->ospf->oiflist, oi);
319 listnode_delete(oi->area->oiflist, oi);
718e3744 320
ac4d0be5 321 thread_cancel_event(master, oi);
cfd670f3 322
ac4d0be5 323 memset(oi, 0, sizeof(*oi));
324 XFREE(MTYPE_OSPF_IF, oi);
718e3744 325}
326
ac4d0be5 327int ospf_if_is_up(struct ospf_interface *oi)
718e3744 328{
ac4d0be5 329 return if_is_up(oi->ifp);
718e3744 330}
331
ac4d0be5 332struct ospf_interface *ospf_if_exists(struct ospf_interface *oic)
333{
334 struct listnode *node;
335 struct ospf *ospf;
336 struct ospf_interface *oi;
2db3d05d 337
ac4d0be5 338 if ((ospf = ospf_lookup()) == NULL)
339 return NULL;
2db3d05d 340
ac4d0be5 341 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
342 if (oi == oic)
343 return oi;
1eb8ef25 344
ac4d0be5 345 return NULL;
2db3d05d 346}
347
c81ee5c9 348/* Lookup OSPF interface by router LSA posistion */
ac4d0be5 349struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *area,
350 int lsa_pos)
c81ee5c9 351{
ac4d0be5 352 struct listnode *node;
353 struct ospf_interface *oi;
c81ee5c9 354
ac4d0be5 355 for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) {
356 if (lsa_pos >= oi->lsa_pos_beg && lsa_pos < oi->lsa_pos_end)
357 return oi;
358 }
359 return NULL;
c81ee5c9
JT
360}
361
ac4d0be5 362struct ospf_interface *ospf_if_lookup_by_local_addr(struct ospf *ospf,
363 struct interface *ifp,
364 struct in_addr address)
718e3744 365{
ac4d0be5 366 struct listnode *node;
367 struct ospf_interface *oi;
368
369 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
370 if (oi->type != OSPF_IFTYPE_VIRTUALLINK) {
371 if (ifp && oi->ifp != ifp)
372 continue;
373
374 if (IPV4_ADDR_SAME(&address, &oi->address->u.prefix4))
375 return oi;
376 }
377
378 return NULL;
718e3744 379}
380
ac4d0be5 381struct ospf_interface *ospf_if_lookup_by_prefix(struct ospf *ospf,
382 struct prefix_ipv4 *p)
718e3744 383{
ac4d0be5 384 struct listnode *node;
385 struct ospf_interface *oi;
386
387 /* Check each Interface. */
388 for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
389 if (oi->type != OSPF_IFTYPE_VIRTUALLINK) {
390 struct prefix ptmp;
391
392 prefix_copy(&ptmp, CONNECTED_PREFIX(oi->connected));
393 apply_mask(&ptmp);
394 if (prefix_same(&ptmp, (struct prefix *)p))
395 return oi;
396 }
68980084 397 }
ac4d0be5 398 return NULL;
718e3744 399}
400
05cf46ba 401/* determine receiving interface by ifp and source address */
ac4d0be5 402struct ospf_interface *ospf_if_lookup_recv_if(struct ospf *ospf,
403 struct in_addr src,
404 struct interface *ifp)
718e3744 405{
ac4d0be5 406 struct route_node *rn;
407 struct prefix_ipv4 addr;
408 struct ospf_interface *oi, *match;
409
410 addr.family = AF_INET;
411 addr.prefix = src;
412 addr.prefixlen = IPV4_MAX_BITLEN;
413
414 match = NULL;
415
416 for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
417 oi = rn->info;
418
419 if (!oi) /* oi can be NULL for PtP aliases */
420 continue;
421
422 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
423 continue;
424
425 if (if_is_loopback(oi->ifp))
426 continue;
427
428 if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
429 match = oi;
430 else if (prefix_match(CONNECTED_PREFIX(oi->connected),
431 (struct prefix *)&addr)) {
432 if ((match == NULL) || (match->address->prefixlen
433 < oi->address->prefixlen))
434 match = oi;
435 }
718e3744 436 }
718e3744 437
ac4d0be5 438 return match;
718e3744 439}
6b0655a2 440
ac4d0be5 441void ospf_if_stream_set(struct ospf_interface *oi)
718e3744 442{
ac4d0be5 443 /* set output fifo queue. */
444 if (oi->obuf == NULL)
445 oi->obuf = ospf_fifo_new();
718e3744 446}
447
ac4d0be5 448void ospf_if_stream_unset(struct ospf_interface *oi)
718e3744 449{
ac4d0be5 450 struct ospf *ospf = oi->ospf;
451
452 if (oi->obuf) {
453 ospf_fifo_free(oi->obuf);
454 oi->obuf = NULL;
455
456 if (oi->on_write_q) {
457 listnode_delete(ospf->oi_write_q, oi);
458 if (list_isempty(ospf->oi_write_q))
459 OSPF_TIMER_OFF(ospf->t_write);
460 oi->on_write_q = 0;
461 }
462 }
718e3744 463}
68980084 464
6b0655a2 465
ac4d0be5 466static struct ospf_if_params *ospf_new_if_params(void)
718e3744 467{
ac4d0be5 468 struct ospf_if_params *oip;
469
470 oip = XCALLOC(MTYPE_OSPF_IF_PARAMS, sizeof(struct ospf_if_params));
471
472 if (!oip)
473 return NULL;
474
475 UNSET_IF_PARAM(oip, output_cost_cmd);
476 UNSET_IF_PARAM(oip, transmit_delay);
477 UNSET_IF_PARAM(oip, retransmit_interval);
478 UNSET_IF_PARAM(oip, passive_interface);
479 UNSET_IF_PARAM(oip, v_hello);
480 UNSET_IF_PARAM(oip, fast_hello);
481 UNSET_IF_PARAM(oip, v_wait);
482 UNSET_IF_PARAM(oip, priority);
483 UNSET_IF_PARAM(oip, type);
484 UNSET_IF_PARAM(oip, auth_simple);
485 UNSET_IF_PARAM(oip, auth_crypt);
486 UNSET_IF_PARAM(oip, auth_type);
487
488 oip->auth_crypt = list_new();
489
490 oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
491
492 return oip;
718e3744 493}
494
ac4d0be5 495void ospf_del_if_params(struct ospf_if_params *oip)
718e3744 496{
ac4d0be5 497 list_delete(oip->auth_crypt);
498 bfd_info_free(&(oip->bfd_info));
499 XFREE(MTYPE_OSPF_IF_PARAMS, oip);
718e3744 500}
501
ac4d0be5 502void ospf_free_if_params(struct interface *ifp, struct in_addr addr)
718e3744 503{
ac4d0be5 504 struct ospf_if_params *oip;
505 struct prefix_ipv4 p;
506 struct route_node *rn;
507
508 p.family = AF_INET;
509 p.prefixlen = IPV4_MAX_PREFIXLEN;
510 p.prefix = addr;
511 rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
512 if (!rn || !rn->info)
513 return;
514
515 oip = rn->info;
516 route_unlock_node(rn);
517
518 if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd)
519 && !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay)
520 && !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval)
521 && !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface)
522 && !OSPF_IF_PARAM_CONFIGURED(oip, v_hello)
523 && !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello)
524 && !OSPF_IF_PARAM_CONFIGURED(oip, v_wait)
525 && !OSPF_IF_PARAM_CONFIGURED(oip, priority)
526 && !OSPF_IF_PARAM_CONFIGURED(oip, type)
527 && !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple)
528 && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type)
529 && listcount(oip->auth_crypt) == 0
530 && ntohl(oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) {
531 ospf_del_if_params(oip);
532 rn->info = NULL;
533 route_unlock_node(rn);
534 }
718e3744 535}
536
ac4d0be5 537struct ospf_if_params *ospf_lookup_if_params(struct interface *ifp,
538 struct in_addr addr)
718e3744 539{
ac4d0be5 540 struct prefix_ipv4 p;
541 struct route_node *rn;
542
543 p.family = AF_INET;
544 p.prefixlen = IPV4_MAX_PREFIXLEN;
545 p.prefix = addr;
546
547 rn = route_node_lookup(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
548
549 if (rn) {
550 route_unlock_node(rn);
551 return rn->info;
552 }
553
554 return NULL;
718e3744 555}
556
ac4d0be5 557struct ospf_if_params *ospf_get_if_params(struct interface *ifp,
558 struct in_addr addr)
718e3744 559{
ac4d0be5 560 struct prefix_ipv4 p;
561 struct route_node *rn;
562
563 p.family = AF_INET;
564 p.prefixlen = IPV4_MAX_PREFIXLEN;
565 p.prefix = addr;
566
567 rn = route_node_get(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
568
569 if (rn->info == NULL)
570 rn->info = ospf_new_if_params();
571 else
572 route_unlock_node(rn);
573
574 return rn->info;
718e3744 575}
576
ac4d0be5 577void ospf_if_update_params(struct interface *ifp, struct in_addr addr)
718e3744 578{
ac4d0be5 579 struct route_node *rn;
580 struct ospf_interface *oi;
581
582 for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
583 if ((oi = rn->info) == NULL)
584 continue;
585
586 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &addr))
587 oi->params = ospf_lookup_if_params(
588 ifp, oi->address->u.prefix4);
589 }
718e3744 590}
591
ac4d0be5 592int ospf_if_new_hook(struct interface *ifp)
718e3744 593{
ac4d0be5 594 int rc = 0;
595
596 ifp->info = XCALLOC(MTYPE_OSPF_IF_INFO, sizeof(struct ospf_if_info));
597
598 IF_OIFS(ifp) = route_table_init();
599 IF_OIFS_PARAMS(ifp) = route_table_init();
600
601 IF_DEF_PARAMS(ifp) = ospf_new_if_params();
602
603 SET_IF_PARAM(IF_DEF_PARAMS(ifp), transmit_delay);
604 IF_DEF_PARAMS(ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
605
606 SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_interval);
607 IF_DEF_PARAMS(ifp)->retransmit_interval =
608 OSPF_RETRANSMIT_INTERVAL_DEFAULT;
609
610 SET_IF_PARAM(IF_DEF_PARAMS(ifp), priority);
611 IF_DEF_PARAMS(ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
612
613 IF_DEF_PARAMS(ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;
614
615 SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_hello);
616 IF_DEF_PARAMS(ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
617
618 SET_IF_PARAM(IF_DEF_PARAMS(ifp), fast_hello);
619 IF_DEF_PARAMS(ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
620
621 SET_IF_PARAM(IF_DEF_PARAMS(ifp), v_wait);
622 IF_DEF_PARAMS(ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
623
624 SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_simple);
625 memset(IF_DEF_PARAMS(ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
626
627 SET_IF_PARAM(IF_DEF_PARAMS(ifp), auth_type);
628 IF_DEF_PARAMS(ifp)->auth_type = OSPF_AUTH_NOTSET;
629
630 rc = ospf_opaque_new_if(ifp);
631 return rc;
718e3744 632}
633
ac4d0be5 634static int ospf_if_delete_hook(struct interface *ifp)
718e3744 635{
ac4d0be5 636 int rc = 0;
637 struct route_node *rn;
638 rc = ospf_opaque_del_if(ifp);
940b01aa 639
ac4d0be5 640 route_table_finish(IF_OIFS(ifp));
940b01aa 641
ac4d0be5 642 for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
643 if (rn->info)
644 ospf_del_if_params(rn->info);
645 route_table_finish(IF_OIFS_PARAMS(ifp));
940b01aa 646
ac4d0be5 647 ospf_del_if_params((struct ospf_if_params *)IF_DEF_PARAMS(ifp));
648 XFREE(MTYPE_OSPF_IF_INFO, ifp->info);
649 ifp->info = NULL;
718e3744 650
ac4d0be5 651 return rc;
718e3744 652}
653
ac4d0be5 654int ospf_if_is_enable(struct ospf_interface *oi)
718e3744 655{
ac4d0be5 656 if (!if_is_loopback(oi->ifp))
657 if (if_is_up(oi->ifp))
658 return 1;
718e3744 659
ac4d0be5 660 return 0;
718e3744 661}
662
ac4d0be5 663void ospf_if_set_multicast(struct ospf_interface *oi)
ba6454ec 664{
ac4d0be5 665 if ((oi->state > ISM_Loopback) && (oi->type != OSPF_IFTYPE_LOOPBACK)
666 && (oi->type != OSPF_IFTYPE_VIRTUALLINK)
667 && (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) {
668 /* The interface should belong to the OSPF-all-routers group. */
669 if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)
670 && (ospf_if_add_allspfrouters(oi->ospf, oi->address,
671 oi->ifp->ifindex)
672 >= 0))
673 /* Set the flag only if the system call to join
674 * succeeded. */
675 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
676 } else {
677 /* The interface should NOT belong to the OSPF-all-routers
678 * group. */
679 if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) {
680 /* Only actually drop if this is the last reference */
681 if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
682 ospf_if_drop_allspfrouters(oi->ospf,
683 oi->address,
684 oi->ifp->ifindex);
685 /* Unset the flag regardless of whether the system call
686 to leave
687 the group succeeded, since it's much safer to assume
688 that
689 we are not a member. */
690 OI_MEMBER_LEFT(oi, MEMBER_ALLROUTERS);
691 }
692 }
693
694 if (((oi->type == OSPF_IFTYPE_BROADCAST)
695 || (oi->type == OSPF_IFTYPE_POINTOPOINT))
696 && ((oi->state == ISM_DR) || (oi->state == ISM_Backup))
697 && (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE)) {
698 /* The interface should belong to the OSPF-designated-routers
699 * group. */
700 if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)
701 && (ospf_if_add_alldrouters(oi->ospf, oi->address,
702 oi->ifp->ifindex)
703 >= 0))
704 /* Set the flag only if the system call to join
705 * succeeded. */
706 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
707 } else {
708 /* The interface should NOT belong to the
709 * OSPF-designated-routers group */
710 if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) {
711 /* drop only if last reference */
712 if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
713 ospf_if_drop_alldrouters(oi->ospf, oi->address,
714 oi->ifp->ifindex);
715
716 /* Unset the flag regardless of whether the system call
717 to leave
718 the group succeeded, since it's much safer to assume
719 that
720 we are not a member. */
721 OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
722 }
723 }
ba6454ec 724}
725
ac4d0be5 726int ospf_if_up(struct ospf_interface *oi)
718e3744 727{
ac4d0be5 728 if (oi == NULL)
729 return 0;
730
731 if (oi->type == OSPF_IFTYPE_LOOPBACK)
732 OSPF_ISM_EVENT_SCHEDULE(oi, ISM_LoopInd);
733 else {
734 ospf_if_stream_set(oi);
735 OSPF_ISM_EVENT_SCHEDULE(oi, ISM_InterfaceUp);
736 }
737
738 return 1;
718e3744 739}
740
ac4d0be5 741int ospf_if_down(struct ospf_interface *oi)
718e3744 742{
ac4d0be5 743 if (oi == NULL)
744 return 0;
718e3744 745
ac4d0be5 746 OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
747 /* delete position in router LSA */
748 oi->lsa_pos_beg = 0;
749 oi->lsa_pos_end = 0;
750 /* Shutdown packet reception and sending */
751 ospf_if_stream_unset(oi);
718e3744 752
ac4d0be5 753 return 1;
718e3744 754}
755
6b0655a2 756
718e3744 757/* Virtual Link related functions. */
758
ac4d0be5 759struct ospf_vl_data *ospf_vl_data_new(struct ospf_area *area,
760 struct in_addr vl_peer)
718e3744 761{
ac4d0be5 762 struct ospf_vl_data *vl_data;
718e3744 763
ac4d0be5 764 vl_data = XCALLOC(MTYPE_OSPF_VL_DATA, sizeof(struct ospf_vl_data));
718e3744 765
ac4d0be5 766 vl_data->vl_peer.s_addr = vl_peer.s_addr;
767 vl_data->vl_area_id = area->area_id;
768 vl_data->vl_area_id_fmt = area->area_id_fmt;
718e3744 769
ac4d0be5 770 return vl_data;
718e3744 771}
772
ac4d0be5 773void ospf_vl_data_free(struct ospf_vl_data *vl_data)
718e3744 774{
ac4d0be5 775 XFREE(MTYPE_OSPF_VL_DATA, vl_data);
718e3744 776}
777
778u_int vlink_count = 0;
779
ac4d0be5 780struct ospf_interface *ospf_vl_new(struct ospf *ospf,
781 struct ospf_vl_data *vl_data)
718e3744 782{
ac4d0be5 783 struct ospf_interface *voi;
784 struct interface *vi;
785 char ifname[INTERFACE_NAMSIZ + 1];
786 struct ospf_area *area;
787 struct in_addr area_id;
788 struct connected *co;
789 struct prefix_ipv4 *p;
790
791 if (IS_DEBUG_OSPF_EVENT)
792 zlog_debug("ospf_vl_new(): Start");
793 if (vlink_count == OSPF_VL_MAX_COUNT) {
794 if (IS_DEBUG_OSPF_EVENT)
795 zlog_debug(
796 "ospf_vl_new(): Alarm: "
797 "cannot create more than OSPF_MAX_VL_COUNT virtual links");
798 return NULL;
799 }
800
801 if (IS_DEBUG_OSPF_EVENT)
802 zlog_debug("ospf_vl_new(): creating pseudo zebra interface");
803
804 snprintf(ifname, sizeof(ifname), "VLINK%d", vlink_count);
805 vi = if_create(ifname, strnlen(ifname, sizeof(ifname)), VRF_DEFAULT);
806 /*
807 * if_create sets ZEBRA_INTERFACE_LINKDETECTION
808 * virtual links don't need this.
809 */
810 UNSET_FLAG(vi->status, ZEBRA_INTERFACE_LINKDETECTION);
811 co = connected_new();
812 co->ifp = vi;
813 listnode_add(vi->connected, co);
814
815 p = prefix_ipv4_new();
816 p->family = AF_INET;
817 p->prefix.s_addr = 0;
818 p->prefixlen = 0;
819
820 co->address = (struct prefix *)p;
821
822 voi = ospf_if_new(ospf, vi, co->address);
823 if (voi == NULL) {
824 if (IS_DEBUG_OSPF_EVENT)
825 zlog_debug(
826 "ospf_vl_new(): Alarm: OSPF int structure is not created");
827 return NULL;
828 }
829 voi->connected = co;
830 voi->vl_data = vl_data;
831 voi->ifp->mtu = OSPF_VL_MTU;
832 voi->type = OSPF_IFTYPE_VIRTUALLINK;
833
834 vlink_count++;
835 if (IS_DEBUG_OSPF_EVENT)
836 zlog_debug("ospf_vl_new(): Created name: %s", ifname);
837 if (IS_DEBUG_OSPF_EVENT)
838 zlog_debug("ospf_vl_new(): set if->name to %s", vi->name);
839
840 area_id.s_addr = 0;
841 area = ospf_area_get(ospf, area_id);
842 voi->area = area;
843
844 if (IS_DEBUG_OSPF_EVENT)
845 zlog_debug(
846 "ospf_vl_new(): set associated area to the backbone");
847
848 /* Add pseudo neighbor. */
849 ospf_nbr_self_reset(voi, voi->ospf->router_id);
850
851 ospf_area_add_if(voi->area, voi);
852
853 ospf_if_stream_set(voi);
854
855 if (IS_DEBUG_OSPF_EVENT)
856 zlog_debug("ospf_vl_new(): Stop");
857 return voi;
718e3744 858}
859
ac4d0be5 860static void ospf_vl_if_delete(struct ospf_vl_data *vl_data)
718e3744 861{
ac4d0be5 862 struct interface *ifp = vl_data->vl_oi->ifp;
863 vl_data->vl_oi->address->u.prefix4.s_addr = 0;
864 vl_data->vl_oi->address->prefixlen = 0;
865 ospf_if_free(vl_data->vl_oi);
866 if_delete(ifp);
867 vlink_count--;
718e3744 868}
869
9c27ef9b
PJ
870/* Look up vl_data for given peer, optionally qualified to be in the
871 * specified area. NULL area returns first found..
872 */
ac4d0be5 873struct ospf_vl_data *ospf_vl_lookup(struct ospf *ospf, struct ospf_area *area,
874 struct in_addr vl_peer)
718e3744 875{
ac4d0be5 876 struct ospf_vl_data *vl_data;
877 struct listnode *node;
878
879 if (IS_DEBUG_OSPF_EVENT) {
880 zlog_debug("%s: Looking for %s", __func__, inet_ntoa(vl_peer));
881 if (area)
882 zlog_debug("%s: in area %s", __func__,
883 inet_ntoa(area->area_id));
884 }
885
886 for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
887 if (IS_DEBUG_OSPF_EVENT)
888 zlog_debug("%s: VL %s, peer %s", __func__,
889 vl_data->vl_oi->ifp->name,
890 inet_ntoa(vl_data->vl_peer));
891
892 if (area
893 && !IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
894 continue;
895
896 if (IPV4_ADDR_SAME(&vl_data->vl_peer, &vl_peer))
897 return vl_data;
898 }
899
900 return NULL;
718e3744 901}
902
ac4d0be5 903static void ospf_vl_shutdown(struct ospf_vl_data *vl_data)
718e3744 904{
ac4d0be5 905 struct ospf_interface *oi;
718e3744 906
ac4d0be5 907 if ((oi = vl_data->vl_oi) == NULL)
908 return;
718e3744 909
ac4d0be5 910 oi->address->u.prefix4.s_addr = 0;
911 oi->address->prefixlen = 0;
718e3744 912
ac4d0be5 913 UNSET_FLAG(oi->ifp->flags, IFF_UP);
914 /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
915 OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
718e3744 916}
917
ac4d0be5 918void ospf_vl_add(struct ospf *ospf, struct ospf_vl_data *vl_data)
718e3744 919{
ac4d0be5 920 listnode_add(ospf->vlinks, vl_data);
921 hook_call(ospf_vl_add, vl_data);
718e3744 922}
923
ac4d0be5 924void ospf_vl_delete(struct ospf *ospf, struct ospf_vl_data *vl_data)
718e3744 925{
ac4d0be5 926 ospf_vl_shutdown(vl_data);
927 ospf_vl_if_delete(vl_data);
718e3744 928
ac4d0be5 929 hook_call(ospf_vl_delete, vl_data);
930 listnode_delete(ospf->vlinks, vl_data);
718e3744 931
ac4d0be5 932 ospf_vl_data_free(vl_data);
718e3744 933}
934
ac4d0be5 935static int ospf_vl_set_params(struct ospf_vl_data *vl_data, struct vertex *v)
718e3744 936{
ac4d0be5 937 int changed = 0;
938 struct ospf_interface *voi;
939 struct listnode *node;
940 struct vertex_parent *vp = NULL;
941 unsigned int i;
942 struct router_lsa *rl;
943
944 voi = vl_data->vl_oi;
945
946 if (voi->output_cost != v->distance) {
947
948 voi->output_cost = v->distance;
949 changed = 1;
950 }
951
952 for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
953 vl_data->nexthop.oi = vp->nexthop->oi;
954 vl_data->nexthop.router = vp->nexthop->router;
955
956 if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
957 &vl_data->nexthop.oi->address->u.prefix4))
958 changed = 1;
959
960 voi->address->u.prefix4 =
961 vl_data->nexthop.oi->address->u.prefix4;
962 voi->address->prefixlen =
963 vl_data->nexthop.oi->address->prefixlen;
964
965 break; /* We take the first interface. */
966 }
967
968 rl = (struct router_lsa *)v->lsa;
969
970 /* use SPF determined backlink index in struct vertex
971 * for virtual link destination address
972 */
973 if (vp && vp->backlink >= 0) {
974 if (!IPV4_ADDR_SAME(&vl_data->peer_addr,
975 &rl->link[vp->backlink].link_data))
976 changed = 1;
977 vl_data->peer_addr = rl->link[vp->backlink].link_data;
978 } else {
979 /* This is highly odd, there is no backlink index
980 * there should be due to the ospf_spf_has_link() check
981 * in SPF. Lets warn and try pick a link anyway.
982 */
983 zlog_warn("ospf_vl_set_params: No backlink for %s!",
984 vl_data->vl_oi->ifp->name);
985 for (i = 0; i < ntohs(rl->links); i++) {
986 switch (rl->link[i].type) {
987 case LSA_LINK_TYPE_VIRTUALLINK:
988 if (IS_DEBUG_OSPF_EVENT)
989 zlog_debug(
990 "found back link through VL");
991 case LSA_LINK_TYPE_TRANSIT:
992 case LSA_LINK_TYPE_POINTOPOINT:
993 if (!IPV4_ADDR_SAME(&vl_data->peer_addr,
994 &rl->link[i].link_data))
995 changed = 1;
996 vl_data->peer_addr = rl->link[i].link_data;
997 }
998 }
999 }
1000
1001 if (IS_DEBUG_OSPF_EVENT)
1002 zlog_debug("%s: %s peer address: %s, cost: %d,%schanged",
1003 __func__, vl_data->vl_oi->ifp->name,
1004 inet_ntoa(vl_data->peer_addr), voi->output_cost,
1005 (changed ? " " : " un"));
1006
1007 return changed;
718e3744 1008}
1009
1010
ac4d0be5 1011void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid,
1012 struct vertex *v)
718e3744 1013{
ac4d0be5 1014 struct ospf *ospf = area->ospf;
1015 struct listnode *node;
1016 struct ospf_vl_data *vl_data;
1017 struct ospf_interface *oi;
1018
1019 if (IS_DEBUG_OSPF_EVENT) {
1020 zlog_debug("ospf_vl_up_check(): Start");
1021 zlog_debug("ospf_vl_up_check(): Router ID is %s",
1022 inet_ntoa(rid));
1023 zlog_debug("ospf_vl_up_check(): Area is %s",
1024 inet_ntoa(area->area_id));
718e3744 1025 }
1026
ac4d0be5 1027 for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
1028 if (IS_DEBUG_OSPF_EVENT) {
1029 zlog_debug("%s: considering VL, %s in area %s",
1030 __func__, vl_data->vl_oi->ifp->name,
1031 inet_ntoa(vl_data->vl_area_id));
1032 zlog_debug("%s: peer ID: %s", __func__,
1033 inet_ntoa(vl_data->vl_peer));
1034 }
1035
1036 if (IPV4_ADDR_SAME(&vl_data->vl_peer, &rid)
1037 && IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id)) {
1038 oi = vl_data->vl_oi;
1039 SET_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED);
1040
1041 if (IS_DEBUG_OSPF_EVENT)
1042 zlog_debug(
1043 "ospf_vl_up_check(): this VL matched");
1044
1045 if (oi->state == ISM_Down) {
1046 if (IS_DEBUG_OSPF_EVENT)
1047 zlog_debug(
1048 "ospf_vl_up_check(): VL is down, waking it up");
1049 SET_FLAG(oi->ifp->flags, IFF_UP);
1050 OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
1051 }
1052
1053 if (ospf_vl_set_params(vl_data, v)) {
1054 if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
1055 zlog_debug(
1056 "ospf_vl_up_check: VL cost change,"
1057 " scheduling router lsa refresh");
1058 if (ospf->backbone)
1059 ospf_router_lsa_update_area(
1060 ospf->backbone);
1061 else if (IS_DEBUG_OSPF(ism, ISM_EVENTS))
1062 zlog_debug(
1063 "ospf_vl_up_check: VL cost change, no backbone!");
1064 }
1065 }
1066 }
718e3744 1067}
1068
ac4d0be5 1069void ospf_vl_unapprove(struct ospf *ospf)
718e3744 1070{
ac4d0be5 1071 struct listnode *node;
1072 struct ospf_vl_data *vl_data;
718e3744 1073
ac4d0be5 1074 for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data))
1075 UNSET_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED);
718e3744 1076}
1077
ac4d0be5 1078void ospf_vl_shut_unapproved(struct ospf *ospf)
718e3744 1079{
ac4d0be5 1080 struct listnode *node, *nnode;
1081 struct ospf_vl_data *vl_data;
718e3744 1082
ac4d0be5 1083 for (ALL_LIST_ELEMENTS(ospf->vlinks, node, nnode, vl_data))
1084 if (!CHECK_FLAG(vl_data->flags, OSPF_VL_FLAG_APPROVED))
1085 ospf_vl_shutdown(vl_data);
718e3744 1086}
1087
ac4d0be5 1088int ospf_full_virtual_nbrs(struct ospf_area *area)
718e3744 1089{
ac4d0be5 1090 if (IS_DEBUG_OSPF_EVENT) {
1091 zlog_debug(
1092 "counting fully adjacent virtual neighbors in area %s",
1093 inet_ntoa(area->area_id));
1094 zlog_debug("there are %d of them", area->full_vls);
1095 }
1096
1097 return area->full_vls;
718e3744 1098}
1099
ac4d0be5 1100int ospf_vls_in_area(struct ospf_area *area)
718e3744 1101{
ac4d0be5 1102 struct listnode *node;
1103 struct ospf_vl_data *vl_data;
1104 int c = 0;
718e3744 1105
ac4d0be5 1106 for (ALL_LIST_ELEMENTS_RO(area->ospf->vlinks, node, vl_data))
1107 if (IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
1108 c++;
718e3744 1109
ac4d0be5 1110 return c;
718e3744 1111}
1112
6b0655a2 1113
ac4d0be5 1114struct crypt_key *ospf_crypt_key_new()
718e3744 1115{
ac4d0be5 1116 return XCALLOC(MTYPE_OSPF_CRYPT_KEY, sizeof(struct crypt_key));
718e3744 1117}
1118
ac4d0be5 1119void ospf_crypt_key_add(struct list *crypt, struct crypt_key *ck)
718e3744 1120{
ac4d0be5 1121 listnode_add(crypt, ck);
718e3744 1122}
1123
ac4d0be5 1124struct crypt_key *ospf_crypt_key_lookup(struct list *auth_crypt, u_char key_id)
718e3744 1125{
ac4d0be5 1126 struct listnode *node;
1127 struct crypt_key *ck;
718e3744 1128
ac4d0be5 1129 for (ALL_LIST_ELEMENTS_RO(auth_crypt, node, ck))
1130 if (ck->key_id == key_id)
1131 return ck;
718e3744 1132
ac4d0be5 1133 return NULL;
718e3744 1134}
1135
ac4d0be5 1136int ospf_crypt_key_delete(struct list *auth_crypt, u_char key_id)
718e3744 1137{
ac4d0be5 1138 struct listnode *node, *nnode;
1139 struct crypt_key *ck;
1140
1141 for (ALL_LIST_ELEMENTS(auth_crypt, node, nnode, ck)) {
1142 if (ck->key_id == key_id) {
1143 listnode_delete(auth_crypt, ck);
1144 XFREE(MTYPE_OSPF_CRYPT_KEY, ck);
1145 return 1;
1146 }
1147 }
1148
1149 return 0;
718e3744 1150}
1151
ac4d0be5 1152u_char ospf_default_iftype(struct interface *ifp)
bc18d616 1153{
ac4d0be5 1154 if (if_is_pointopoint(ifp))
1155 return OSPF_IFTYPE_POINTOPOINT;
1156 else if (if_is_loopback(ifp))
1157 return OSPF_IFTYPE_LOOPBACK;
1158 else
1159 return OSPF_IFTYPE_BROADCAST;
bc18d616 1160}
1161
ac4d0be5 1162void ospf_if_init()
718e3744 1163{
ac4d0be5 1164 /* Initialize Zebra interface data structure. */
1165 om->iflist = vrf_iflist(VRF_DEFAULT);
1166 if_add_hook(IF_NEW_HOOK, ospf_if_new_hook);
1167 if_add_hook(IF_DELETE_HOOK, ospf_if_delete_hook);
718e3744 1168}