]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_zebra.c
This patch changes BGP from only listening mode for BFD status updates to interactive...
[mirror_frr.git] / ospfd / ospf_zebra.c
1 /*
2 * Zebra connect library for OSPFd
3 * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, 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 it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * 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 "command.h"
27 #include "network.h"
28 #include "prefix.h"
29 #include "routemap.h"
30 #include "table.h"
31 #include "stream.h"
32 #include "memory.h"
33 #include "zclient.h"
34 #include "filter.h"
35 #include "plist.h"
36 #include "log.h"
37
38 #include "ospfd/ospfd.h"
39 #include "ospfd/ospf_interface.h"
40 #include "ospfd/ospf_ism.h"
41 #include "ospfd/ospf_asbr.h"
42 #include "ospfd/ospf_asbr.h"
43 #include "ospfd/ospf_abr.h"
44 #include "ospfd/ospf_lsa.h"
45 #include "ospfd/ospf_dump.h"
46 #include "ospfd/ospf_route.h"
47 #include "ospfd/ospf_lsdb.h"
48 #include "ospfd/ospf_neighbor.h"
49 #include "ospfd/ospf_nsm.h"
50 #include "ospfd/ospf_zebra.h"
51 #ifdef HAVE_SNMP
52 #include "ospfd/ospf_snmp.h"
53 #endif /* HAVE_SNMP */
54
55 /* Zebra structure to hold current status. */
56 struct zclient *zclient = NULL;
57
58 /* For registering threads. */
59 extern struct thread_master *master;
60 struct in_addr router_id_zebra;
61
62 /* Router-id update message from zebra. */
63 static int
64 ospf_router_id_update_zebra (int command, struct zclient *zclient,
65 zebra_size_t length)
66 {
67 struct ospf *ospf;
68 struct prefix router_id;
69 zebra_router_id_update_read(zclient->ibuf,&router_id);
70
71 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
72 {
73 char buf[128];
74 prefix2str(&router_id, buf, sizeof(buf));
75 zlog_debug("Zebra rcvd: router id update %s", buf);
76 }
77
78 router_id_zebra = router_id.u.prefix4;
79
80 ospf = ospf_lookup ();
81
82 if (ospf != NULL)
83 ospf_router_id_update (ospf);
84
85 return 0;
86 }
87
88 /* Inteface addition message from zebra. */
89 static int
90 ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
91 {
92 struct interface *ifp;
93
94 ifp = zebra_interface_add_read (zclient->ibuf);
95
96 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
97 zlog_debug ("Zebra: interface add %s index %d flags %llx metric %d mtu %d",
98 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
99 ifp->metric, ifp->mtu);
100
101 assert (ifp->info);
102
103 if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
104 {
105 SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
106 IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
107 }
108
109 ospf_if_update (NULL, ifp);
110
111 #ifdef HAVE_SNMP
112 ospf_snmp_if_update (ifp);
113 #endif /* HAVE_SNMP */
114
115 return 0;
116 }
117
118 static int
119 ospf_interface_delete (int command, struct zclient *zclient,
120 zebra_size_t length)
121 {
122 struct interface *ifp;
123 struct stream *s;
124 struct route_node *rn;
125
126 s = zclient->ibuf;
127 /* zebra_interface_state_read() updates interface structure in iflist */
128 ifp = zebra_interface_state_read (s);
129
130 if (ifp == NULL)
131 return 0;
132
133 if (if_is_up (ifp))
134 zlog_warn ("Zebra: got delete of %s, but interface is still up",
135 ifp->name);
136
137 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
138 zlog_debug
139 ("Zebra: interface delete %s index %d flags %llx metric %d mtu %d",
140 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, ifp->metric, ifp->mtu);
141
142 #ifdef HAVE_SNMP
143 ospf_snmp_if_delete (ifp);
144 #endif /* HAVE_SNMP */
145
146 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
147 if (rn->info)
148 ospf_if_free ((struct ospf_interface *) rn->info);
149
150 ifp->ifindex = IFINDEX_INTERNAL;
151 return 0;
152 }
153
154 static struct interface *
155 zebra_interface_if_lookup (struct stream *s)
156 {
157 char ifname_tmp[INTERFACE_NAMSIZ];
158
159 /* Read interface name. */
160 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
161
162 /* And look it up. */
163 return if_lookup_by_name_len(ifname_tmp,
164 strnlen(ifname_tmp, INTERFACE_NAMSIZ));
165 }
166
167 static int
168 ospf_interface_state_up (int command, struct zclient *zclient,
169 zebra_size_t length)
170 {
171 struct interface *ifp;
172 struct ospf_interface *oi;
173 struct route_node *rn;
174
175 ifp = zebra_interface_if_lookup (zclient->ibuf);
176
177 if (ifp == NULL)
178 return 0;
179
180 /* Interface is already up. */
181 if (if_is_operative (ifp))
182 {
183 /* Temporarily keep ifp values. */
184 struct interface if_tmp;
185 memcpy (&if_tmp, ifp, sizeof (struct interface));
186
187 zebra_interface_if_set_value (zclient->ibuf, ifp);
188
189 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
190 zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
191
192 if (if_tmp.bandwidth != ifp->bandwidth)
193 {
194 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
195 zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
196 ifp->name, if_tmp.bandwidth, ifp->bandwidth);
197
198 ospf_if_recalculate_output_cost (ifp);
199 }
200
201 if (if_tmp.mtu != ifp->mtu)
202 {
203 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
204 zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
205 ifp->name, if_tmp.mtu, ifp->mtu);
206
207 /* Must reset the interface (simulate down/up) when MTU changes. */
208 ospf_if_reset(ifp);
209 }
210 return 0;
211 }
212
213 zebra_interface_if_set_value (zclient->ibuf, ifp);
214
215 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
216 zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
217
218 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
219 {
220 if ((oi = rn->info) == NULL)
221 continue;
222
223 ospf_if_up (oi);
224 }
225
226 return 0;
227 }
228
229 static int
230 ospf_interface_state_down (int command, struct zclient *zclient,
231 zebra_size_t length)
232 {
233 struct interface *ifp;
234 struct ospf_interface *oi;
235 struct route_node *node;
236
237 ifp = zebra_interface_state_read (zclient->ibuf);
238
239 if (ifp == NULL)
240 return 0;
241
242 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
243 zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
244
245 for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
246 {
247 if ((oi = node->info) == NULL)
248 continue;
249 ospf_if_down (oi);
250 }
251
252 return 0;
253 }
254
255 static int
256 ospf_interface_address_add (int command, struct zclient *zclient,
257 zebra_size_t length)
258 {
259 struct connected *c;
260
261 c = zebra_interface_address_read (command, zclient->ibuf);
262
263 if (c == NULL)
264 return 0;
265
266 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
267 {
268 char buf[128];
269 prefix2str(c->address, buf, sizeof(buf));
270 zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
271 }
272
273 ospf_if_update (NULL, c->ifp);
274
275 #ifdef HAVE_SNMP
276 ospf_snmp_if_update (c->ifp);
277 #endif /* HAVE_SNMP */
278
279 return 0;
280 }
281
282 static int
283 ospf_interface_address_delete (int command, struct zclient *zclient,
284 zebra_size_t length)
285 {
286 struct connected *c;
287 struct interface *ifp;
288 struct ospf_interface *oi;
289 struct route_node *rn;
290 struct prefix p;
291
292 c = zebra_interface_address_read (command, zclient->ibuf);
293
294 if (c == NULL)
295 return 0;
296
297 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
298 {
299 char buf[128];
300 prefix2str(c->address, buf, sizeof(buf));
301 zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf);
302 }
303
304 ifp = c->ifp;
305 p = *c->address;
306 p.prefixlen = IPV4_MAX_PREFIXLEN;
307
308 rn = route_node_lookup (IF_OIFS (ifp), &p);
309 if (!rn)
310 {
311 connected_free (c);
312 return 0;
313 }
314
315 assert (rn->info);
316 oi = rn->info;
317
318 /* Call interface hook functions to clean up */
319 ospf_if_free (oi);
320
321 #ifdef HAVE_SNMP
322 ospf_snmp_if_update (c->ifp);
323 #endif /* HAVE_SNMP */
324
325 connected_free (c);
326
327 return 0;
328 }
329
330 static int
331 ospf_interface_bfd_dest_down (int command, struct zclient *zclient,
332 zebra_size_t length)
333 {
334 struct interface *ifp;
335 struct ospf_interface *oi;
336 struct ospf_if_params *params;
337 struct ospf_neighbor *nbr;
338 struct route_node *node;
339 struct prefix p;
340
341 ifp = zebra_interface_bfd_read (zclient->ibuf, &p, NULL);
342
343 if (ifp == NULL)
344 return 0;
345
346 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
347 {
348 char buf[128];
349 prefix2str(&p, buf, sizeof(buf));
350 zlog_debug("Zebra: interface %s bfd destination %s down", ifp->name, buf);
351 }
352
353 params = IF_DEF_PARAMS (ifp);
354 if (!OSPF_IF_PARAM_CONFIGURED (params, bfd))
355 return 0;
356
357 for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
358 {
359 if ((oi = node->info) == NULL)
360 continue;
361
362 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &p.u.prefix4);
363 if (!nbr)
364 continue;
365
366 if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
367 zlog_debug ("NSM[%s:%s]: BFD Down",
368 IF_NAME (nbr->oi), inet_ntoa (nbr->address.u.prefix4));
369
370 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer);
371 }
372
373 return 0;
374 }
375
376 void
377 ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
378 {
379 u_char message;
380 u_char distance;
381 u_char flags;
382 int psize;
383 struct stream *s;
384 struct ospf_path *path;
385 struct listnode *node;
386 struct ospf *ospf = ospf_lookup ();
387
388 if (redist_check_instance(&zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance))
389 {
390 message = 0;
391 flags = 0;
392
393 /* OSPF pass nexthop and metric */
394 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
395 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
396
397 /* Distance value. */
398 distance = ospf_distance_apply (p, or);
399 if (distance)
400 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
401
402 /* Check if path type is ASE and use only 16bit tags */
403 if (((or->path_type == OSPF_PATH_TYPE1_EXTERNAL) ||
404 (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)) &&
405 (or->u.ext.tag > 0) && (or->u.ext.tag < UINT16_MAX))
406 SET_FLAG (message, ZAPI_MESSAGE_TAG);
407
408 /* Make packet. */
409 s = zclient->obuf;
410 stream_reset (s);
411
412 /* Put command, type, flags, message. */
413 zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
414 stream_putc (s, ZEBRA_ROUTE_OSPF);
415 stream_putw (s, ospf->instance);
416 stream_putc (s, flags);
417 stream_putc (s, message);
418 stream_putw (s, SAFI_UNICAST);
419
420 /* Put prefix information. */
421 psize = PSIZE (p->prefixlen);
422 stream_putc (s, p->prefixlen);
423 stream_write (s, (u_char *) & p->prefix, psize);
424
425 /* Nexthop count. */
426 stream_putc (s, or->paths->count);
427
428 /* Nexthop, ifindex, distance and metric information. */
429 for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
430 {
431 #ifdef HAVE_NETLINK
432 if (path->unnumbered)
433 {
434 stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK);
435 stream_put_in_addr (s, &path->nexthop);
436 if (path->ifindex)
437 stream_putl (s, path->ifindex);
438 else
439 stream_putl (s, 0);
440 }
441 else
442 {
443 if (path->nexthop.s_addr != INADDR_ANY &&
444 path->ifindex != 0)
445 {
446 stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
447 stream_put_in_addr (s, &path->nexthop);
448 stream_putl (s, path->ifindex);
449 }
450 else if (path->nexthop.s_addr != INADDR_ANY)
451 {
452 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
453 stream_put_in_addr (s, &path->nexthop);
454 }
455 else
456 {
457 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
458 if (path->ifindex)
459 stream_putl (s, path->ifindex);
460 else
461 stream_putl (s, 0);
462 }
463 }
464 #else /* HAVE_NETLINK */
465 if (path->nexthop.s_addr != INADDR_ANY &&
466 path->ifindex != 0)
467 {
468 stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
469 stream_put_in_addr (s, &path->nexthop);
470 stream_putl (s, path->ifindex);
471 }
472 else if (path->nexthop.s_addr != INADDR_ANY)
473 {
474 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
475 stream_put_in_addr (s, &path->nexthop);
476 }
477 else
478 {
479 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
480 if (path->ifindex)
481 stream_putl (s, path->ifindex);
482 else
483 stream_putl (s, 0);
484 }
485 #endif /* HAVE_NETLINK */
486
487 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
488 {
489 char buf[2][INET_ADDRSTRLEN];
490 zlog_debug("Zebra: Route add %s/%d nexthop %s, ifindex=%d",
491 inet_ntop(AF_INET, &p->prefix,
492 buf[0], sizeof(buf[0])),
493 p->prefixlen,
494 inet_ntop(AF_INET, &path->nexthop,
495 buf[1], sizeof(buf[1])),
496 path->ifindex);
497 }
498 }
499
500 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
501 stream_putc (s, distance);
502 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
503 {
504 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
505 stream_putl (s, or->cost + or->u.ext.type2_cost);
506 else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
507 stream_putl (s, or->u.ext.type2_cost);
508 else
509 stream_putl (s, or->cost);
510 }
511
512 if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG))
513 stream_putw (s, (u_short)or->u.ext.tag);
514
515 stream_putw_at (s, 0, stream_get_endp (s));
516
517 zclient_send_message(zclient);
518 }
519 }
520
521 void
522 ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
523 {
524 u_char message;
525 u_char distance;
526 u_char flags;
527 int psize;
528 struct stream *s;
529 struct ospf_path *path;
530 struct listnode *node;
531 struct ospf *ospf = ospf_lookup ();
532
533 if (redist_check_instance(&zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance))
534 {
535 message = 0;
536 flags = 0;
537 /* Distance value. */
538 distance = ospf_distance_apply (p, or);
539 /* Make packet. */
540 s = zclient->obuf;
541 stream_reset (s);
542
543 /* Put command, type, flags, message. */
544 zclient_create_header (s, ZEBRA_IPV4_ROUTE_DELETE);
545 stream_putc (s, ZEBRA_ROUTE_OSPF);
546 stream_putw (s, ospf->instance);
547 stream_putc (s, flags);
548 stream_putc (s, message);
549 stream_putw (s, SAFI_UNICAST);
550
551 /* Put prefix information. */
552 psize = PSIZE (p->prefixlen);
553 stream_putc (s, p->prefixlen);
554 stream_write (s, (u_char *) & p->prefix, psize);
555
556 /* Nexthop count. */
557 stream_putc (s, or->paths->count);
558
559 /* Nexthop, ifindex, distance and metric information. */
560 for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
561 {
562 if (path->nexthop.s_addr != INADDR_ANY &&
563 path->ifindex != 0)
564 {
565 stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX);
566 stream_put_in_addr (s, &path->nexthop);
567 stream_putl (s, path->ifindex);
568 }
569 else if (path->nexthop.s_addr != INADDR_ANY)
570 {
571 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
572 stream_put_in_addr (s, &path->nexthop);
573 }
574 else
575 {
576 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
577 stream_putl (s, path->ifindex);
578 }
579
580 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
581 {
582 char buf[2][INET_ADDRSTRLEN];
583 zlog_debug("Zebra: Route delete %s/%d nexthop %s",
584 inet_ntop(AF_INET, &p->prefix,
585 buf[0], sizeof(buf[0])),
586 p->prefixlen,
587 inet_ntop(AF_INET, &path->nexthop,
588 buf[1], sizeof(buf[1])));
589 }
590 }
591
592 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
593 stream_putc (s, distance);
594 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
595 {
596 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
597 stream_putl (s, or->cost + or->u.ext.type2_cost);
598 else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
599 stream_putl (s, or->u.ext.type2_cost);
600 else
601 stream_putl (s, or->cost);
602 }
603
604 stream_putw_at (s, 0, stream_get_endp (s));
605
606 zclient_send_message(zclient);
607 }
608 }
609
610 void
611 ospf_zebra_add_discard (struct prefix_ipv4 *p)
612 {
613 struct zapi_ipv4 api;
614 struct ospf *ospf = ospf_lookup ();
615
616 if (redist_check_instance(&zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance))
617 {
618 api.type = ZEBRA_ROUTE_OSPF;
619 api.instance = ospf->instance;
620 api.flags = ZEBRA_FLAG_BLACKHOLE;
621 api.message = 0;
622 api.safi = SAFI_UNICAST;
623 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
624 api.nexthop_num = 0;
625 api.ifindex_num = 0;
626 api.tag = 0;
627
628 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
629
630 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
631 zlog_debug ("Zebra: Route add discard %s/%d",
632 inet_ntoa (p->prefix), p->prefixlen);
633 }
634 }
635
636 void
637 ospf_zebra_delete_discard (struct prefix_ipv4 *p)
638 {
639 struct zapi_ipv4 api;
640 struct ospf *ospf = ospf_lookup ();
641
642 if (redist_check_instance(&zclient->redist[AFI_IP][ZEBRA_ROUTE_OSPF], ospf->instance))
643 {
644 api.type = ZEBRA_ROUTE_OSPF;
645 api.instance = ospf->instance;
646 api.flags = ZEBRA_FLAG_BLACKHOLE;
647 api.message = 0;
648 api.safi = SAFI_UNICAST;
649 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
650 api.nexthop_num = 0;
651 api.ifindex_num = 0;
652 api.tag = 0;
653
654 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
655
656 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
657 zlog_debug ("Zebra: Route delete discard %s/%d",
658 inet_ntoa (p->prefix), p->prefixlen);
659
660 }
661 }
662
663 struct ospf_external *
664 ospf_external_lookup (u_char type, u_short instance)
665 {
666 struct list *ext_list;
667 struct listnode *node;
668 struct ospf_external *ext;
669
670 ext_list = om->external[type];
671 if (!ext_list)
672 return(NULL);
673
674 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
675 if (ext->instance == instance)
676 return ext;
677
678 return NULL;
679 }
680
681 struct ospf_external *
682 ospf_external_add (u_char type, u_short instance)
683 {
684 struct list *ext_list;
685 struct ospf_external *ext;
686
687 ext = ospf_external_lookup(type, instance);
688 if (ext)
689 return ext;
690
691 if (!om->external[type])
692 om->external[type] = list_new();
693
694 ext_list = om->external[type];
695 ext = (struct ospf_external *)calloc (1, sizeof(struct ospf_external));
696 ext->instance = instance;
697 EXTERNAL_INFO (ext) = route_table_init ();
698
699 listnode_add(ext_list, ext);
700
701 return ext;
702 }
703
704 void
705 ospf_external_del (u_char type, u_short instance)
706 {
707 struct ospf_external *ext;
708
709 ext = ospf_external_lookup(type, instance);
710
711 if (ext)
712 {
713 if (EXTERNAL_INFO (ext))
714 route_table_finish(EXTERNAL_INFO (ext));
715
716 listnode_delete(om->external[type], ext);
717 if (!om->external[type]->count)
718 {
719 list_free(om->external[type]);
720 om->external[type] = NULL;
721 }
722 }
723 }
724
725 struct ospf_redist *
726 ospf_redist_lookup (struct ospf *ospf, u_char type, u_short instance)
727 {
728 struct list *red_list;
729 struct listnode *node;
730 struct ospf_redist *red;
731
732 red_list = ospf->redist[type];
733 if (!red_list)
734 return(NULL);
735
736 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
737 if (red->instance == instance)
738 return red;
739
740 return NULL;
741 }
742
743 struct ospf_redist *
744 ospf_redist_add (struct ospf *ospf, u_char type, u_short instance)
745 {
746 struct list *red_list;
747 struct ospf_redist *red;
748
749 red = ospf_redist_lookup(ospf, type, instance);
750 if (red)
751 return red;
752
753 if (!ospf->redist[type])
754 ospf->redist[type] = list_new();
755
756 red_list = ospf->redist[type];
757 red = (struct ospf_redist *)calloc (1, sizeof(struct ospf_redist));
758 red->instance = instance;
759 red->dmetric.type = -1;
760 red->dmetric.value = -1;
761
762 listnode_add(red_list, red);
763
764 return red;
765 }
766
767 void
768 ospf_redist_del (struct ospf *ospf, u_char type, u_short instance)
769 {
770 struct ospf_redist *red;
771
772 red = ospf_redist_lookup(ospf, type, instance);
773
774 if (red)
775 {
776 listnode_delete(ospf->redist[type], red);
777 if (!ospf->redist[type]->count)
778 {
779 list_free(ospf->redist[type]);
780 ospf->redist[type] = NULL;
781 }
782 }
783 }
784
785
786 int
787 ospf_is_type_redistributed (int type, u_short instance)
788 {
789 return (DEFAULT_ROUTE_TYPE (type) ?
790 zclient->default_information :
791 redist_check_instance(&zclient->redist[AFI_IP][type], instance));
792 }
793
794 int
795 ospf_redistribute_set (struct ospf *ospf, int type, u_short instance, int mtype,
796 int mvalue)
797 {
798 int force = 0;
799 struct ospf_redist *red;
800
801 red = ospf_redist_lookup(ospf, type, instance);
802 if (ospf_is_type_redistributed (type, instance))
803 {
804 if (mtype != red->dmetric.type)
805 {
806 red->dmetric.type = mtype;
807 force = LSA_REFRESH_FORCE;
808 }
809 if (mvalue != red->dmetric.value)
810 {
811 red->dmetric.value = mvalue;
812 force = LSA_REFRESH_FORCE;
813 }
814
815 ospf_external_lsa_refresh_type (ospf, type, instance, force);
816
817 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
818 zlog_debug ("Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
819 ospf_redist_string(type), instance,
820 metric_type (ospf, type, instance),
821 metric_value (ospf, type, instance));
822
823 return CMD_SUCCESS;
824 }
825
826 red->dmetric.type = mtype;
827 red->dmetric.value = mvalue;
828
829 ospf_external_add(type, instance);
830
831 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, instance);
832
833 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
834 zlog_debug ("Redistribute[%s][%d]: Start Type[%d], Metric[%d]",
835 ospf_redist_string(type), instance,
836 metric_type (ospf, type, instance), metric_value (ospf, type, instance));
837
838 ospf_asbr_status_update (ospf, ++ospf->redistribute);
839
840 return CMD_SUCCESS;
841 }
842
843 int
844 ospf_redistribute_unset (struct ospf *ospf, int type, u_short instance)
845 {
846 if (type == zclient->redist_default && instance == zclient->instance)
847 return CMD_SUCCESS;
848
849 if (!ospf_is_type_redistributed (type, instance))
850 return CMD_SUCCESS;
851
852 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, instance);
853
854 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
855 zlog_debug ("Redistribute[%s][%d]: Stop",
856 ospf_redist_string(type), instance);
857
858 ospf_redist_del (ospf, type, instance);
859
860 /* Remove the routes from OSPF table. */
861 ospf_redistribute_withdraw (ospf, type, instance);
862
863 ospf_external_del(type, instance);
864
865 ospf_asbr_status_update (ospf, --ospf->redistribute);
866
867 return CMD_SUCCESS;
868 }
869
870 int
871 ospf_redistribute_default_set (struct ospf *ospf, int originate,
872 int mtype, int mvalue)
873 {
874 struct ospf_redist *red;
875
876 ospf->default_originate = originate;
877
878 red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0);
879 red->dmetric.type = mtype;
880 red->dmetric.value = mvalue;
881
882 ospf_external_add(DEFAULT_ROUTE, 0);
883
884 if (ospf_is_type_redistributed (DEFAULT_ROUTE, 0))
885 {
886 /* if ospf->default_originate changes value, is calling
887 ospf_external_lsa_refresh_default sufficient to implement
888 the change? */
889 ospf_external_lsa_refresh_default (ospf);
890
891 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
892 zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
893 ospf_redist_string(DEFAULT_ROUTE),
894 metric_type (ospf, DEFAULT_ROUTE, 0),
895 metric_value (ospf, DEFAULT_ROUTE, 0));
896 return CMD_SUCCESS;
897 }
898
899 zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
900
901 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
902 zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
903 metric_type (ospf, DEFAULT_ROUTE, 0),
904 metric_value (ospf, DEFAULT_ROUTE, 0));
905
906 if (ospf->router_id.s_addr == 0)
907 ospf->external_origin |= (1 << DEFAULT_ROUTE);
908 else
909 thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
910
911 ospf_asbr_status_update (ospf, ++ospf->redistribute);
912
913 return CMD_SUCCESS;
914 }
915
916 int
917 ospf_redistribute_default_unset (struct ospf *ospf)
918 {
919 if (!ospf_is_type_redistributed (DEFAULT_ROUTE, 0))
920 return CMD_SUCCESS;
921
922 ospf->default_originate = DEFAULT_ORIGINATE_NONE;
923 ospf_redist_del(ospf, DEFAULT_ROUTE, 0);
924
925 zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
926
927 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
928 zlog_debug ("Redistribute[DEFAULT]: Stop");
929
930 //Pending: how does the external_info cleanup work in this case?
931
932 ospf_asbr_status_update (ospf, --ospf->redistribute);
933
934 return CMD_SUCCESS;
935 }
936
937 static int
938 ospf_external_lsa_originate_check (struct ospf *ospf,
939 struct external_info *ei)
940 {
941 /* If prefix is multicast, then do not originate LSA. */
942 if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
943 {
944 zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
945 "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
946 return 0;
947 }
948
949 /* Take care of default-originate. */
950 if (is_prefix_default (&ei->p))
951 if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
952 {
953 zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
954 "for default");
955 return 0;
956 }
957
958 return 1;
959 }
960
961 /* If connected prefix is OSPF enable interface, then do not announce. */
962 int
963 ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
964 {
965 struct listnode *node;
966 struct ospf_interface *oi;
967
968
969 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
970 if (prefix_match (oi->address, (struct prefix *) &ei->p))
971 return 0;
972 return 1;
973 }
974
975 /* return 1 if external LSA must be originated, 0 otherwise */
976 int
977 ospf_redistribute_check (struct ospf *ospf,
978 struct external_info *ei, int *changed)
979 {
980 struct route_map_set_values save_values;
981 struct prefix_ipv4 *p = &ei->p;
982 struct ospf_redist *red;
983 u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
984 u_short instance = is_prefix_default (&ei->p) ? 0 : ei->instance;
985
986 if (changed)
987 *changed = 0;
988
989 if (!ospf_external_lsa_originate_check (ospf, ei))
990 return 0;
991
992 /* Take care connected route. */
993 if (type == ZEBRA_ROUTE_CONNECT &&
994 !ospf_distribute_check_connected (ospf, ei))
995 return 0;
996
997 if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
998 /* distirbute-list exists, but access-list may not? */
999 if (DISTRIBUTE_LIST (ospf, type))
1000 if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
1001 {
1002 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
1003 zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
1004 ospf_redist_string(type),
1005 inet_ntoa (p->prefix), p->prefixlen);
1006 return 0;
1007 }
1008
1009 save_values = ei->route_map_set;
1010 ospf_reset_route_map_set_values (&ei->route_map_set);
1011
1012 /* apply route-map if needed */
1013 red = ospf_redist_lookup (ospf, type, instance);
1014 if (red && ROUTEMAP_NAME(red))
1015 {
1016 int ret;
1017
1018 ret = route_map_apply (ROUTEMAP (red), (struct prefix *) p,
1019 RMAP_OSPF, ei);
1020
1021 if (ret == RMAP_DENYMATCH)
1022 {
1023 ei->route_map_set = save_values;
1024 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
1025 zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.",
1026 ospf_redist_string(type),
1027 inet_ntoa (p->prefix), p->prefixlen);
1028 return 0;
1029 }
1030
1031 /* check if 'route-map set' changed something */
1032 if (changed)
1033 *changed = !ospf_route_map_set_compare (&ei->route_map_set,
1034 &save_values);
1035 }
1036
1037 return 1;
1038 }
1039
1040 /* OSPF route-map set for redistribution */
1041 void
1042 ospf_routemap_set (struct ospf_redist *red, const char *name)
1043 {
1044 if (ROUTEMAP_NAME (red))
1045 free (ROUTEMAP_NAME (red));
1046
1047 ROUTEMAP_NAME (red) = strdup (name);
1048 ROUTEMAP (red) = route_map_lookup_by_name (name);
1049 }
1050
1051 void
1052 ospf_routemap_unset (struct ospf_redist *red)
1053 {
1054 if (ROUTEMAP_NAME (red))
1055 free (ROUTEMAP_NAME (red));
1056
1057 ROUTEMAP_NAME (red) = NULL;
1058 ROUTEMAP (red) = NULL;
1059 }
1060
1061 /* Zebra route add and delete treatment. */
1062 static int
1063 ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
1064 zebra_size_t length)
1065 {
1066 struct stream *s;
1067 struct zapi_ipv4 api;
1068 unsigned long ifindex;
1069 struct in_addr nexthop;
1070 struct prefix_ipv4 p;
1071 struct external_info *ei;
1072 struct ospf *ospf;
1073
1074 s = zclient->ibuf;
1075 ifindex = 0;
1076 nexthop.s_addr = 0;
1077
1078 /* Type, flags, message. */
1079 api.type = stream_getc (s);
1080 api.instance = stream_getw (s);
1081 api.flags = stream_getc (s);
1082 api.message = stream_getc (s);
1083
1084 /* IPv4 prefix. */
1085 memset (&p, 0, sizeof (struct prefix_ipv4));
1086 p.family = AF_INET;
1087 p.prefixlen = stream_getc (s);
1088 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
1089
1090 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
1091 return 0;
1092
1093 /* Nexthop, ifindex, distance, metric. */
1094 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
1095 {
1096 api.nexthop_num = stream_getc (s);
1097 nexthop.s_addr = stream_get_ipv4 (s);
1098 }
1099 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
1100 {
1101 api.ifindex_num = stream_getc (s);
1102 /* XXX assert(api.ifindex_num == 1); */
1103 ifindex = stream_getl (s);
1104 }
1105 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
1106 api.distance = stream_getc (s);
1107 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
1108 api.metric = stream_getl (s);
1109 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
1110 api.tag = stream_getw (s);
1111 else
1112 api.tag = 0;
1113
1114 ospf = ospf_lookup ();
1115 if (ospf == NULL)
1116 return 0;
1117
1118 if (command == ZEBRA_IPV4_ROUTE_ADD)
1119 {
1120 /* XXX|HACK|TODO|FIXME:
1121 * Maybe we should ignore reject/blackhole routes? Testing shows that
1122 * there is no problems though and this is only way to "summarize"
1123 * routes in ASBR at the moment. Maybe we need just a better generalised
1124 * solution for these types?
1125 *
1126 * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
1127 * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
1128 * return 0;
1129 */
1130
1131 /* Protocol tag overwrites all other tag value send by zebra */
1132 if (ospf->dtag[api.type] > 0)
1133 api.tag = ospf->dtag[api.type];
1134
1135 ei = ospf_external_info_add (api.type, api.instance, p, ifindex,
1136 nexthop, api.tag);
1137
1138 if (ospf->router_id.s_addr == 0)
1139 /* Set flags to generate AS-external-LSA originate event
1140 for each redistributed protocols later. */
1141 ospf->external_origin |= (1 << api.type);
1142 else
1143 {
1144 if (ei)
1145 {
1146 if (is_prefix_default (&p))
1147 ospf_external_lsa_refresh_default (ospf);
1148 else
1149 {
1150 struct ospf_lsa *current;
1151
1152 current = ospf_external_info_find_lsa (ospf, &ei->p);
1153 if (!current)
1154 ospf_external_lsa_originate (ospf, ei);
1155 else if (IS_LSA_MAXAGE (current))
1156 ospf_external_lsa_refresh (ospf, current,
1157 ei, LSA_REFRESH_FORCE);
1158 else
1159 zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
1160 inet_ntoa (p.prefix));
1161 }
1162 }
1163 }
1164 }
1165 else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
1166 {
1167 ospf_external_info_delete (api.type, api.instance, p);
1168 if (is_prefix_default (&p))
1169 ospf_external_lsa_refresh_default (ospf);
1170 else
1171 ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
1172 }
1173
1174 return 0;
1175 }
1176
1177
1178 int
1179 ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
1180 {
1181 /* Lookup access-list for distribute-list. */
1182 DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
1183
1184 /* Clear previous distribute-name. */
1185 if (DISTRIBUTE_NAME (ospf, type))
1186 free (DISTRIBUTE_NAME (ospf, type));
1187
1188 /* Set distribute-name. */
1189 DISTRIBUTE_NAME (ospf, type) = strdup (name);
1190
1191 /* If access-list have been set, schedule update timer. */
1192 if (DISTRIBUTE_LIST (ospf, type))
1193 ospf_distribute_list_update (ospf, type, 0);
1194
1195 return CMD_SUCCESS;
1196 }
1197
1198 int
1199 ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
1200 {
1201 /* Schedule update timer. */
1202 if (DISTRIBUTE_LIST (ospf, type))
1203 ospf_distribute_list_update (ospf, type, 0);
1204
1205 /* Unset distribute-list. */
1206 DISTRIBUTE_LIST (ospf, type) = NULL;
1207
1208 /* Clear distribute-name. */
1209 if (DISTRIBUTE_NAME (ospf, type))
1210 free (DISTRIBUTE_NAME (ospf, type));
1211
1212 DISTRIBUTE_NAME (ospf, type) = NULL;
1213
1214 return CMD_SUCCESS;
1215 }
1216
1217 /* distribute-list update timer. */
1218 static int
1219 ospf_distribute_list_update_timer (struct thread *thread)
1220 {
1221 struct route_node *rn;
1222 struct external_info *ei;
1223 struct route_table *rt;
1224 struct ospf_lsa *lsa;
1225 int type, default_refresh = 0;
1226 struct ospf *ospf;
1227
1228 ospf = ospf_lookup ();
1229 if (ospf == NULL)
1230 return 0;
1231
1232 ospf->t_distribute_update = NULL;
1233
1234 zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
1235
1236 /* foreach all external info. */
1237 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1238 {
1239 struct list *ext_list;
1240 struct listnode *node;
1241 struct ospf_external *ext;
1242
1243 ext_list = om->external[type];
1244 if (!ext_list)
1245 continue;
1246
1247 for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
1248 {
1249 rt = ext->external_info;
1250 if (!rt)
1251 continue;
1252 for (rn = route_top (rt); rn; rn = route_next (rn))
1253 if ((ei = rn->info) != NULL)
1254 {
1255 if (is_prefix_default (&ei->p))
1256 default_refresh = 1;
1257 else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
1258 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
1259 else
1260 ospf_external_lsa_originate (ospf, ei);
1261 }
1262 }
1263 }
1264 if (default_refresh)
1265 ospf_external_lsa_refresh_default (ospf);
1266 return 0;
1267 }
1268
1269 #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
1270
1271 /* Update distribute-list and set timer to apply access-list. */
1272 void
1273 ospf_distribute_list_update (struct ospf *ospf, uintptr_t type,
1274 u_short instance)
1275 {
1276 struct route_table *rt;
1277 struct ospf_external *ext;
1278
1279 /* External info does not exist. */
1280 ext = ospf_external_lookup(type, instance);
1281 if (!ext || !(rt = EXTERNAL_INFO (ext)))
1282 return;
1283
1284 /* If exists previously invoked thread, then let it continue. */
1285 if (ospf->t_distribute_update)
1286 return;
1287
1288 /* Set timer. */
1289 ospf->t_distribute_update =
1290 thread_add_timer (master, ospf_distribute_list_update_timer,
1291 (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
1292 }
1293
1294 /* If access-list is updated, apply some check. */
1295 static void
1296 ospf_filter_update (struct access_list *access)
1297 {
1298 struct ospf *ospf;
1299 int type;
1300 int abr_inv = 0;
1301 struct ospf_area *area;
1302 struct listnode *node;
1303
1304 /* If OSPF instance does not exist, return right now. */
1305 ospf = ospf_lookup ();
1306 if (ospf == NULL)
1307 return;
1308
1309 /* Update distribute-list, and apply filter. */
1310 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1311 {
1312 struct list *red_list;
1313 struct listnode *node;
1314 struct ospf_redist *red;
1315
1316 red_list = ospf->redist[type];
1317 if (red_list)
1318 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
1319 {
1320 if (ROUTEMAP (red))
1321 {
1322 /* if route-map is not NULL it may be using this access list */
1323 ospf_distribute_list_update (ospf, type, red->instance);
1324 }
1325 }
1326
1327 /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
1328 * but no distribute list. */
1329 if (type == ZEBRA_ROUTE_MAX)
1330 break;
1331
1332 if (DISTRIBUTE_NAME (ospf, type))
1333 {
1334 /* Keep old access-list for distribute-list. */
1335 struct access_list *old = DISTRIBUTE_LIST (ospf, type);
1336
1337 /* Update access-list for distribute-list. */
1338 DISTRIBUTE_LIST (ospf, type) =
1339 access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
1340
1341 /* No update for this distribute type. */
1342 if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
1343 continue;
1344
1345 /* Schedule distribute-list update timer. */
1346 if (DISTRIBUTE_LIST (ospf, type) == NULL ||
1347 strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
1348 ospf_distribute_list_update (ospf, type, 0);
1349 }
1350 }
1351
1352 /* Update Area access-list. */
1353 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1354 {
1355 if (EXPORT_NAME (area))
1356 {
1357 EXPORT_LIST (area) = NULL;
1358 abr_inv++;
1359 }
1360
1361 if (IMPORT_NAME (area))
1362 {
1363 IMPORT_LIST (area) = NULL;
1364 abr_inv++;
1365 }
1366 }
1367
1368 /* Schedule ABR tasks -- this will be changed -- takada. */
1369 if (IS_OSPF_ABR (ospf) && abr_inv)
1370 ospf_schedule_abr_task (ospf);
1371 }
1372
1373 /* If prefix-list is updated, do some updates. */
1374 void
1375 ospf_prefix_list_update (struct prefix_list *plist)
1376 {
1377 struct ospf *ospf;
1378 int type;
1379 int abr_inv = 0;
1380 struct ospf_area *area;
1381 struct listnode *node;
1382
1383 /* If OSPF instatnce does not exist, return right now. */
1384 ospf = ospf_lookup ();
1385 if (ospf == NULL)
1386 return;
1387
1388 /* Update all route-maps which are used as redistribution filters.
1389 * They might use prefix-list.
1390 */
1391 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1392 {
1393 struct list *red_list;
1394 struct listnode *node;
1395 struct ospf_redist *red;
1396
1397 red_list = ospf->redist[type];
1398 if (red_list)
1399 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
1400 {
1401 if (ROUTEMAP (red))
1402 {
1403 /* if route-map is not NULL it may be using this prefix list */
1404 ospf_distribute_list_update (ospf, type, red->instance);
1405 }
1406 }
1407 }
1408
1409 /* Update area filter-lists. */
1410 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1411 {
1412 /* Update filter-list in. */
1413 if (PREFIX_NAME_IN (area))
1414 if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
1415 {
1416 PREFIX_LIST_IN (area) =
1417 prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
1418 abr_inv++;
1419 }
1420
1421 /* Update filter-list out. */
1422 if (PREFIX_NAME_OUT (area))
1423 if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
1424 {
1425 PREFIX_LIST_IN (area) =
1426 prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
1427 abr_inv++;
1428 }
1429 }
1430
1431 /* Schedule ABR task. */
1432 if (IS_OSPF_ABR (ospf) && abr_inv)
1433 ospf_schedule_abr_task (ospf);
1434 }
1435
1436 static struct ospf_distance *
1437 ospf_distance_new (void)
1438 {
1439 return XCALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
1440 }
1441
1442 static void
1443 ospf_distance_free (struct ospf_distance *odistance)
1444 {
1445 XFREE (MTYPE_OSPF_DISTANCE, odistance);
1446 }
1447
1448 int
1449 ospf_distance_set (struct vty *vty, struct ospf *ospf,
1450 const char *distance_str,
1451 const char *ip_str,
1452 const char *access_list_str)
1453 {
1454 int ret;
1455 struct prefix_ipv4 p;
1456 u_char distance;
1457 struct route_node *rn;
1458 struct ospf_distance *odistance;
1459
1460 ret = str2prefix_ipv4 (ip_str, &p);
1461 if (ret == 0)
1462 {
1463 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1464 return CMD_WARNING;
1465 }
1466
1467 distance = atoi (distance_str);
1468
1469 /* Get OSPF distance node. */
1470 rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
1471 if (rn->info)
1472 {
1473 odistance = rn->info;
1474 route_unlock_node (rn);
1475 }
1476 else
1477 {
1478 odistance = ospf_distance_new ();
1479 rn->info = odistance;
1480 }
1481
1482 /* Set distance value. */
1483 odistance->distance = distance;
1484
1485 /* Reset access-list configuration. */
1486 if (odistance->access_list)
1487 {
1488 free (odistance->access_list);
1489 odistance->access_list = NULL;
1490 }
1491 if (access_list_str)
1492 odistance->access_list = strdup (access_list_str);
1493
1494 return CMD_SUCCESS;
1495 }
1496
1497 int
1498 ospf_distance_unset (struct vty *vty, struct ospf *ospf,
1499 const char *distance_str,
1500 const char *ip_str, char
1501 const *access_list_str)
1502 {
1503 int ret;
1504 struct prefix_ipv4 p;
1505 struct route_node *rn;
1506 struct ospf_distance *odistance;
1507
1508 ret = str2prefix_ipv4 (ip_str, &p);
1509 if (ret == 0)
1510 {
1511 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1512 return CMD_WARNING;
1513 }
1514
1515 rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
1516 if (!rn)
1517 {
1518 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
1519 return CMD_WARNING;
1520 }
1521
1522 odistance = rn->info;
1523
1524 if (odistance->access_list)
1525 free (odistance->access_list);
1526 ospf_distance_free (odistance);
1527
1528 rn->info = NULL;
1529 route_unlock_node (rn);
1530 route_unlock_node (rn);
1531
1532 return CMD_SUCCESS;
1533 }
1534
1535 void
1536 ospf_distance_reset (struct ospf *ospf)
1537 {
1538 struct route_node *rn;
1539 struct ospf_distance *odistance;
1540
1541 for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
1542 if ((odistance = rn->info) != NULL)
1543 {
1544 if (odistance->access_list)
1545 free (odistance->access_list);
1546 ospf_distance_free (odistance);
1547 rn->info = NULL;
1548 route_unlock_node (rn);
1549 }
1550 }
1551
1552 u_char
1553 ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
1554 {
1555 struct ospf *ospf;
1556
1557 ospf = ospf_lookup ();
1558 if (ospf == NULL)
1559 return 0;
1560
1561 if (ospf->distance_intra)
1562 if (or->path_type == OSPF_PATH_INTRA_AREA)
1563 return ospf->distance_intra;
1564
1565 if (ospf->distance_inter)
1566 if (or->path_type == OSPF_PATH_INTER_AREA)
1567 return ospf->distance_inter;
1568
1569 if (ospf->distance_external)
1570 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
1571 || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1572 return ospf->distance_external;
1573
1574 if (ospf->distance_all)
1575 return ospf->distance_all;
1576
1577 return 0;
1578 }
1579
1580 void
1581 ospf_zebra_init (u_short instance)
1582 {
1583 /* Allocate zebra structure. */
1584 zclient = zclient_new ();
1585 zclient_init (zclient, ZEBRA_ROUTE_OSPF, instance);
1586 zclient->router_id_update = ospf_router_id_update_zebra;
1587 zclient->interface_add = ospf_interface_add;
1588 zclient->interface_delete = ospf_interface_delete;
1589 zclient->interface_up = ospf_interface_state_up;
1590 zclient->interface_down = ospf_interface_state_down;
1591 zclient->interface_address_add = ospf_interface_address_add;
1592 zclient->interface_address_delete = ospf_interface_address_delete;
1593 zclient->interface_bfd_dest_down = ospf_interface_bfd_dest_down;
1594 zclient->ipv4_route_add = ospf_zebra_read_ipv4;
1595 zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
1596
1597 access_list_add_hook (ospf_filter_update);
1598 access_list_delete_hook (ospf_filter_update);
1599 prefix_list_add_hook (ospf_prefix_list_update);
1600 prefix_list_delete_hook (ospf_prefix_list_update);
1601 }