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