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