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