+ initial edition of meta-queue for RIB updates processing (bug #431)
[jleu-quagga.git] / ospfd / ospf_zebra.c
blobf302d28d60827d026f378db046d511278a008b2b
1 /*
2 * Zebra connect library for OSPFd
3 * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
5 * This file is part of GNU Zebra.
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.
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.
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.
23 #include <zebra.h>
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"
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_zebra.h"
48 #ifdef HAVE_SNMP
49 #include "ospfd/ospf_snmp.h"
50 #endif /* HAVE_SNMP */
52 /* Zebra structure to hold current status. */
53 struct zclient *zclient = NULL;
55 /* For registering threads. */
56 extern struct thread_master *master;
57 struct in_addr router_id_zebra;
59 /* Router-id update message from zebra. */
60 static int
61 ospf_router_id_update_zebra (int command, struct zclient *zclient,
62 zebra_size_t length)
64 struct ospf *ospf;
65 struct prefix router_id;
66 zebra_router_id_update_read(zclient->ibuf,&router_id);
68 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
70 char buf[128];
71 prefix2str(&router_id, buf, sizeof(buf));
72 zlog_debug("Zebra rcvd: router id update %s", buf);
75 router_id_zebra = router_id.u.prefix4;
77 ospf = ospf_lookup ();
79 if (ospf != NULL)
80 ospf_router_id_update (ospf);
82 return 0;
85 /* Inteface addition message from zebra. */
86 static int
87 ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
89 struct interface *ifp;
90 struct ospf *ospf;
92 ifp = zebra_interface_add_read (zclient->ibuf);
94 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
95 zlog_debug ("Zebra: interface add %s index %d flags %ld metric %d mtu %d",
96 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
98 assert (ifp->info);
100 if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
102 SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
103 IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
106 ospf = ospf_lookup ();
107 if (ospf != NULL)
108 ospf_if_update (ospf);
110 #ifdef HAVE_SNMP
111 ospf_snmp_if_update (ifp);
112 #endif /* HAVE_SNMP */
114 return 0;
117 static int
118 ospf_interface_delete (int command, struct zclient *zclient,
119 zebra_size_t length)
121 struct interface *ifp;
122 struct stream *s;
123 struct route_node *rn;
125 s = zclient->ibuf;
126 /* zebra_interface_state_read() updates interface structure in iflist */
127 ifp = zebra_interface_state_read (s);
129 if (ifp == NULL)
130 return 0;
132 if (if_is_up (ifp))
133 zlog_warn ("Zebra: got delete of %s, but interface is still up",
134 ifp->name);
136 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
137 zlog_debug
138 ("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",
139 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
141 #ifdef HAVE_SNMP
142 ospf_snmp_if_delete (ifp);
143 #endif /* HAVE_SNMP */
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);
149 ifp->ifindex = IFINDEX_INTERNAL;
150 return 0;
153 static struct interface *
154 zebra_interface_if_lookup (struct stream *s)
156 char ifname_tmp[INTERFACE_NAMSIZ];
158 /* Read interface name. */
159 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
161 /* And look it up. */
162 return if_lookup_by_name_len(ifname_tmp,
163 strnlen(ifname_tmp, INTERFACE_NAMSIZ));
166 static int
167 ospf_interface_state_up (int command, struct zclient *zclient,
168 zebra_size_t length)
170 struct interface *ifp;
171 struct ospf_interface *oi;
172 struct route_node *rn;
174 ifp = zebra_interface_if_lookup (zclient->ibuf);
176 if (ifp == NULL)
177 return 0;
179 /* Interface is already up. */
180 if (if_is_operative (ifp))
182 /* Temporarily keep ifp values. */
183 struct interface if_tmp;
184 memcpy (&if_tmp, ifp, sizeof (struct interface));
186 zebra_interface_if_set_value (zclient->ibuf, ifp);
188 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
189 zlog_debug ("Zebra: Interface[%s] state update.", ifp->name);
191 if (if_tmp.bandwidth != ifp->bandwidth)
193 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
194 zlog_debug ("Zebra: Interface[%s] bandwidth change %d -> %d.",
195 ifp->name, if_tmp.bandwidth, ifp->bandwidth);
197 ospf_if_recalculate_output_cost (ifp);
200 if (if_tmp.mtu != ifp->mtu)
202 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
203 zlog_debug ("Zebra: Interface[%s] MTU change %u -> %u.",
204 ifp->name, if_tmp.mtu, ifp->mtu);
206 /* Must reset the interface (simulate down/up) when MTU changes. */
207 ospf_if_reset(ifp);
209 return 0;
212 zebra_interface_if_set_value (zclient->ibuf, ifp);
214 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
215 zlog_debug ("Zebra: Interface[%s] state change to up.", ifp->name);
217 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
219 if ((oi = rn->info) == NULL)
220 continue;
222 ospf_if_up (oi);
225 return 0;
228 static int
229 ospf_interface_state_down (int command, struct zclient *zclient,
230 zebra_size_t length)
232 struct interface *ifp;
233 struct ospf_interface *oi;
234 struct route_node *node;
236 ifp = zebra_interface_state_read (zclient->ibuf);
238 if (ifp == NULL)
239 return 0;
241 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
242 zlog_debug ("Zebra: Interface[%s] state change to down.", ifp->name);
244 for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
246 if ((oi = node->info) == NULL)
247 continue;
248 ospf_if_down (oi);
251 return 0;
254 static int
255 ospf_interface_address_add (int command, struct zclient *zclient,
256 zebra_size_t length)
258 struct ospf *ospf;
259 struct connected *c;
261 c = zebra_interface_address_read (command, zclient->ibuf);
263 if (c == NULL)
264 return 0;
266 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
268 char buf[128];
269 prefix2str(c->address, buf, sizeof(buf));
270 zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
273 ospf = ospf_lookup ();
274 if (ospf != NULL)
275 ospf_if_update (ospf);
277 #ifdef HAVE_SNMP
278 ospf_snmp_if_update (c->ifp);
279 #endif /* HAVE_SNMP */
281 return 0;
284 static int
285 ospf_interface_address_delete (int command, struct zclient *zclient,
286 zebra_size_t length)
288 struct ospf *ospf;
289 struct connected *c;
290 struct interface *ifp;
291 struct ospf_interface *oi;
292 struct route_node *rn;
293 struct prefix p;
295 c = zebra_interface_address_read (command, zclient->ibuf);
297 if (c == NULL)
298 return 0;
300 if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
302 char buf[128];
303 prefix2str(c->address, buf, sizeof(buf));
304 zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf);
307 ifp = c->ifp;
308 p = *c->address;
309 p.prefixlen = IPV4_MAX_PREFIXLEN;
311 rn = route_node_lookup (IF_OIFS (ifp), &p);
312 if (!rn)
314 connected_free (c);
315 return 0;
318 assert (rn->info);
319 oi = rn->info;
321 /* Call interface hook functions to clean up */
322 ospf_if_free (oi);
324 #ifdef HAVE_SNMP
325 ospf_snmp_if_update (c->ifp);
326 #endif /* HAVE_SNMP */
328 connected_free (c);
330 ospf = ospf_lookup ();
331 if (ospf != NULL)
332 ospf_if_update (ospf);
334 return 0;
337 void
338 ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
340 u_char message;
341 u_char distance;
342 u_char flags;
343 int psize;
344 struct stream *s;
345 struct ospf_path *path;
346 struct listnode *node;
348 if (zclient->redist[ZEBRA_ROUTE_OSPF])
350 message = 0;
351 flags = 0;
353 /* OSPF pass nexthop and metric */
354 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
355 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
357 /* Distance value. */
358 distance = ospf_distance_apply (p, or);
359 if (distance)
360 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
362 /* Make packet. */
363 s = zclient->obuf;
364 stream_reset (s);
366 /* Put command, type, flags, message. */
367 zclient_create_header (s, ZEBRA_IPV4_ROUTE_ADD);
368 stream_putc (s, ZEBRA_ROUTE_OSPF);
369 stream_putc (s, flags);
370 stream_putc (s, message);
372 /* Put prefix information. */
373 psize = PSIZE (p->prefixlen);
374 stream_putc (s, p->prefixlen);
375 stream_write (s, (u_char *) & p->prefix, psize);
377 /* Nexthop count. */
378 stream_putc (s, or->paths->count);
380 /* Nexthop, ifindex, distance and metric information. */
381 for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
383 if (path->nexthop.s_addr != INADDR_ANY)
385 stream_putc (s, ZEBRA_NEXTHOP_IPV4);
386 stream_put_in_addr (s, &path->nexthop);
388 else
390 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
391 if (path->oi)
392 stream_putl (s, path->oi->ifp->ifindex);
393 else
394 stream_putl (s, 0);
397 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
399 char buf[2][INET_ADDRSTRLEN];
400 zlog_debug("Zebra: Route add %s/%d nexthop %s",
401 inet_ntop(AF_INET, &p->prefix,
402 buf[0], sizeof(buf[0])),
403 p->prefixlen,
404 inet_ntop(AF_INET, &path->nexthop,
405 buf[1], sizeof(buf[1])));
409 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
410 stream_putc (s, distance);
411 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
413 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)
414 stream_putl (s, or->cost + or->u.ext.type2_cost);
415 else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
416 stream_putl (s, or->u.ext.type2_cost);
417 else
418 stream_putl (s, or->cost);
421 stream_putw_at (s, 0, stream_get_endp (s));
423 zclient_send_message(zclient);
427 void
428 ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or)
430 struct zapi_ipv4 api;
431 struct ospf_path *path;
432 struct in_addr *nexthop;
433 struct listnode *node, *nnode;
435 if (zclient->redist[ZEBRA_ROUTE_OSPF])
437 api.type = ZEBRA_ROUTE_OSPF;
438 api.flags = 0;
439 api.message = 0;
440 api.ifindex_num = 0;
441 api.nexthop_num = 0;
443 for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
445 if (path->nexthop.s_addr != INADDR_ANY)
447 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
448 api.nexthop_num = 1;
449 nexthop = &path->nexthop;
450 api.nexthop = &nexthop;
452 else if (ospf_if_exists(path->oi) && (path->oi->ifp))
454 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
455 api.ifindex_num = 1;
456 api.ifindex = &path->oi->ifp->ifindex;
458 else if ( IS_DEBUG_OSPF(zebra,ZEBRA_REDISTRIBUTE) )
460 zlog_debug("Zebra: no ifp %s %d",
461 inet_ntoa(p->prefix),
462 p->prefixlen);
465 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
467 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.nexthop_num)
469 char buf[2][INET_ADDRSTRLEN];
470 zlog_debug("Zebra: Route delete %s/%d nexthop %s",
471 inet_ntop(AF_INET, &p->prefix, buf[0], sizeof(buf[0])),
472 p->prefixlen,
473 inet_ntop(AF_INET, *api.nexthop,
474 buf[1], sizeof(buf[1])));
476 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE) && api.ifindex_num)
478 zlog_debug ("Zebra: Route delete %s/%d ifindex %d",
479 inet_ntoa (p->prefix),
480 p->prefixlen, *api.ifindex);
486 void
487 ospf_zebra_add_discard (struct prefix_ipv4 *p)
489 struct zapi_ipv4 api;
491 if (zclient->redist[ZEBRA_ROUTE_OSPF])
493 api.type = ZEBRA_ROUTE_OSPF;
494 api.flags = ZEBRA_FLAG_BLACKHOLE;
495 api.message = 0;
496 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
497 api.nexthop_num = 0;
498 api.ifindex_num = 0;
500 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api);
502 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
503 zlog_debug ("Zebra: Route add discard %s/%d",
504 inet_ntoa (p->prefix), p->prefixlen);
508 void
509 ospf_zebra_delete_discard (struct prefix_ipv4 *p)
511 struct zapi_ipv4 api;
513 if (zclient->redist[ZEBRA_ROUTE_OSPF])
515 api.type = ZEBRA_ROUTE_OSPF;
516 api.flags = ZEBRA_FLAG_BLACKHOLE;
517 api.message = 0;
518 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
519 api.nexthop_num = 0;
520 api.ifindex_num = 0;
522 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, p, &api);
524 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
525 zlog_debug ("Zebra: Route delete discard %s/%d",
526 inet_ntoa (p->prefix), p->prefixlen);
532 ospf_is_type_redistributed (int type)
534 return (DEFAULT_ROUTE_TYPE (type)) ?
535 zclient->default_information : zclient->redist[type];
539 ospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue)
541 int force = 0;
543 if (ospf_is_type_redistributed (type))
545 if (mtype != ospf->dmetric[type].type)
547 ospf->dmetric[type].type = mtype;
548 force = LSA_REFRESH_FORCE;
550 if (mvalue != ospf->dmetric[type].value)
552 ospf->dmetric[type].value = mvalue;
553 force = LSA_REFRESH_FORCE;
556 ospf_external_lsa_refresh_type (ospf, type, force);
558 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
559 zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
560 ospf_redist_string(type),
561 metric_type (ospf, type), metric_value (ospf, type));
563 return CMD_SUCCESS;
566 ospf->dmetric[type].type = mtype;
567 ospf->dmetric[type].value = mvalue;
569 zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
571 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
572 zlog_debug ("Redistribute[%s]: Start Type[%d], Metric[%d]",
573 ospf_redist_string(type),
574 metric_type (ospf, type), metric_value (ospf, type));
576 ospf_asbr_status_update (ospf, ++ospf->redistribute);
578 return CMD_SUCCESS;
582 ospf_redistribute_unset (struct ospf *ospf, int type)
584 if (type == zclient->redist_default)
585 return CMD_SUCCESS;
587 if (!ospf_is_type_redistributed (type))
588 return CMD_SUCCESS;
590 zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
592 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
593 zlog_debug ("Redistribute[%s]: Stop",
594 ospf_redist_string(type));
596 ospf->dmetric[type].type = -1;
597 ospf->dmetric[type].value = -1;
599 /* Remove the routes from OSPF table. */
600 ospf_redistribute_withdraw (ospf, type);
602 ospf_asbr_status_update (ospf, --ospf->redistribute);
604 return CMD_SUCCESS;
608 ospf_redistribute_default_set (struct ospf *ospf, int originate,
609 int mtype, int mvalue)
611 ospf->default_originate = originate;
612 ospf->dmetric[DEFAULT_ROUTE].type = mtype;
613 ospf->dmetric[DEFAULT_ROUTE].value = mvalue;
615 if (ospf_is_type_redistributed (DEFAULT_ROUTE))
617 /* if ospf->default_originate changes value, is calling
618 ospf_external_lsa_refresh_default sufficient to implement
619 the change? */
620 ospf_external_lsa_refresh_default (ospf);
622 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
623 zlog_debug ("Redistribute[%s]: Refresh Type[%d], Metric[%d]",
624 ospf_redist_string(DEFAULT_ROUTE),
625 metric_type (ospf, DEFAULT_ROUTE),
626 metric_value (ospf, DEFAULT_ROUTE));
627 return CMD_SUCCESS;
630 zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient);
632 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
633 zlog_debug ("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]",
634 metric_type (ospf, DEFAULT_ROUTE),
635 metric_value (ospf, DEFAULT_ROUTE));
637 if (ospf->router_id.s_addr == 0)
638 ospf->external_origin |= (1 << DEFAULT_ROUTE);
639 else
640 thread_add_timer (master, ospf_default_originate_timer, ospf, 1);
642 ospf_asbr_status_update (ospf, ++ospf->redistribute);
644 return CMD_SUCCESS;
648 ospf_redistribute_default_unset (struct ospf *ospf)
650 if (!ospf_is_type_redistributed (DEFAULT_ROUTE))
651 return CMD_SUCCESS;
653 ospf->default_originate = DEFAULT_ORIGINATE_NONE;
654 ospf->dmetric[DEFAULT_ROUTE].type = -1;
655 ospf->dmetric[DEFAULT_ROUTE].value = -1;
657 zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient);
659 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
660 zlog_debug ("Redistribute[DEFAULT]: Stop");
662 ospf_asbr_status_update (ospf, --ospf->redistribute);
664 return CMD_SUCCESS;
667 static int
668 ospf_external_lsa_originate_check (struct ospf *ospf,
669 struct external_info *ei)
671 /* If prefix is multicast, then do not originate LSA. */
672 if (IN_MULTICAST (htonl (ei->p.prefix.s_addr)))
674 zlog_info ("LSA[Type5:%s]: Not originate AS-external-LSA, "
675 "Prefix belongs multicast", inet_ntoa (ei->p.prefix));
676 return 0;
679 /* Take care of default-originate. */
680 if (is_prefix_default (&ei->p))
681 if (ospf->default_originate == DEFAULT_ORIGINATE_NONE)
683 zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA "
684 "for default");
685 return 0;
688 return 1;
691 /* If connected prefix is OSPF enable interface, then do not announce. */
693 ospf_distribute_check_connected (struct ospf *ospf, struct external_info *ei)
695 struct route_node *rn;
697 for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
698 if (rn->info != NULL)
699 if (prefix_match (&rn->p, (struct prefix *) &ei->p))
701 route_unlock_node (rn);
702 return 0;
705 return 1;
708 /* return 1 if external LSA must be originated, 0 otherwise */
710 ospf_redistribute_check (struct ospf *ospf,
711 struct external_info *ei, int *changed)
713 struct route_map_set_values save_values;
714 struct prefix_ipv4 *p = &ei->p;
715 u_char type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
717 if (changed)
718 *changed = 0;
720 if (!ospf_external_lsa_originate_check (ospf, ei))
721 return 0;
723 /* Take care connected route. */
724 if (type == ZEBRA_ROUTE_CONNECT &&
725 !ospf_distribute_check_connected (ospf, ei))
726 return 0;
728 if (!DEFAULT_ROUTE_TYPE (type) && DISTRIBUTE_NAME (ospf, type))
729 /* distirbute-list exists, but access-list may not? */
730 if (DISTRIBUTE_LIST (ospf, type))
731 if (access_list_apply (DISTRIBUTE_LIST (ospf, type), p) == FILTER_DENY)
733 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
734 zlog_debug ("Redistribute[%s]: %s/%d filtered by ditribute-list.",
735 ospf_redist_string(type),
736 inet_ntoa (p->prefix), p->prefixlen);
737 return 0;
740 save_values = ei->route_map_set;
741 ospf_reset_route_map_set_values (&ei->route_map_set);
743 /* apply route-map if needed */
744 if (ROUTEMAP_NAME (ospf, type))
746 int ret;
748 ret = route_map_apply (ROUTEMAP (ospf, type), (struct prefix *) p,
749 RMAP_OSPF, ei);
751 if (ret == RMAP_DENYMATCH)
753 ei->route_map_set = save_values;
754 if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))
755 zlog_debug ("Redistribute[%s]: %s/%d filtered by route-map.",
756 ospf_redist_string(type),
757 inet_ntoa (p->prefix), p->prefixlen);
758 return 0;
761 /* check if 'route-map set' changed something */
762 if (changed)
763 *changed = !ospf_route_map_set_compare (&ei->route_map_set,
764 &save_values);
767 return 1;
770 /* OSPF route-map set for redistribution */
771 void
772 ospf_routemap_set (struct ospf *ospf, int type, const char *name)
774 if (ROUTEMAP_NAME (ospf, type))
775 free (ROUTEMAP_NAME (ospf, type));
777 ROUTEMAP_NAME (ospf, type) = strdup (name);
778 ROUTEMAP (ospf, type) = route_map_lookup_by_name (name);
781 void
782 ospf_routemap_unset (struct ospf *ospf, int type)
784 if (ROUTEMAP_NAME (ospf, type))
785 free (ROUTEMAP_NAME (ospf, type));
787 ROUTEMAP_NAME (ospf, type) = NULL;
788 ROUTEMAP (ospf, type) = NULL;
791 /* Zebra route add and delete treatment. */
792 static int
793 ospf_zebra_read_ipv4 (int command, struct zclient *zclient,
794 zebra_size_t length)
796 struct stream *s;
797 struct zapi_ipv4 api;
798 unsigned long ifindex;
799 struct in_addr nexthop;
800 struct prefix_ipv4 p;
801 struct external_info *ei;
802 struct ospf *ospf;
804 s = zclient->ibuf;
805 ifindex = 0;
806 nexthop.s_addr = 0;
808 /* Type, flags, message. */
809 api.type = stream_getc (s);
810 api.flags = stream_getc (s);
811 api.message = stream_getc (s);
813 /* IPv4 prefix. */
814 memset (&p, 0, sizeof (struct prefix_ipv4));
815 p.family = AF_INET;
816 p.prefixlen = stream_getc (s);
817 stream_get (&p.prefix, s, PSIZE (p.prefixlen));
819 if (IPV4_NET127(ntohl(p.prefix.s_addr)))
820 return 0;
822 /* Nexthop, ifindex, distance, metric. */
823 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
825 api.nexthop_num = stream_getc (s);
826 nexthop.s_addr = stream_get_ipv4 (s);
828 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
830 api.ifindex_num = stream_getc (s);
831 /* XXX assert(api.ifindex_num == 1); */
832 ifindex = stream_getl (s);
834 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
835 api.distance = stream_getc (s);
836 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
837 api.metric = stream_getl (s);
839 ospf = ospf_lookup ();
840 if (ospf == NULL)
841 return 0;
843 if (command == ZEBRA_IPV4_ROUTE_ADD)
845 /* XXX|HACK|TODO|FIXME:
846 * Maybe we should ignore reject/blackhole routes? Testing shows that
847 * there is no problems though and this is only way to "summarize"
848 * routes in ASBR at the moment. Maybe we need just a better generalised
849 * solution for these types?
851 * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE)
852 * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT))
853 * return 0;
856 ei = ospf_external_info_add (api.type, p, ifindex, nexthop);
858 if (ospf->router_id.s_addr == 0)
859 /* Set flags to generate AS-external-LSA originate event
860 for each redistributed protocols later. */
861 ospf->external_origin |= (1 << api.type);
862 else
864 if (ei)
866 if (is_prefix_default (&p))
867 ospf_external_lsa_refresh_default (ospf);
868 else
870 struct ospf_lsa *current;
872 current = ospf_external_info_find_lsa (ospf, &ei->p);
873 if (!current)
874 ospf_external_lsa_originate (ospf, ei);
875 else if (IS_LSA_MAXAGE (current))
876 ospf_external_lsa_refresh (ospf, current,
877 ei, LSA_REFRESH_FORCE);
878 else
879 zlog_warn ("ospf_zebra_read_ipv4() : %s already exists",
880 inet_ntoa (p.prefix));
885 else /* if (command == ZEBRA_IPV4_ROUTE_DELETE) */
887 ospf_external_info_delete (api.type, p);
888 if (is_prefix_default (&p))
889 ospf_external_lsa_refresh_default (ospf);
890 else
891 ospf_external_lsa_flush (ospf, api.type, &p, ifindex /*, nexthop */);
894 return 0;
899 ospf_distribute_list_out_set (struct ospf *ospf, int type, const char *name)
901 /* Lookup access-list for distribute-list. */
902 DISTRIBUTE_LIST (ospf, type) = access_list_lookup (AFI_IP, name);
904 /* Clear previous distribute-name. */
905 if (DISTRIBUTE_NAME (ospf, type))
906 free (DISTRIBUTE_NAME (ospf, type));
908 /* Set distribute-name. */
909 DISTRIBUTE_NAME (ospf, type) = strdup (name);
911 /* If access-list have been set, schedule update timer. */
912 if (DISTRIBUTE_LIST (ospf, type))
913 ospf_distribute_list_update (ospf, type);
915 return CMD_SUCCESS;
919 ospf_distribute_list_out_unset (struct ospf *ospf, int type, const char *name)
921 /* Schedule update timer. */
922 if (DISTRIBUTE_LIST (ospf, type))
923 ospf_distribute_list_update (ospf, type);
925 /* Unset distribute-list. */
926 DISTRIBUTE_LIST (ospf, type) = NULL;
928 /* Clear distribute-name. */
929 if (DISTRIBUTE_NAME (ospf, type))
930 free (DISTRIBUTE_NAME (ospf, type));
932 DISTRIBUTE_NAME (ospf, type) = NULL;
934 return CMD_SUCCESS;
937 /* distribute-list update timer. */
938 static int
939 ospf_distribute_list_update_timer (struct thread *thread)
941 struct route_node *rn;
942 struct external_info *ei;
943 struct route_table *rt;
944 struct ospf_lsa *lsa;
945 intptr_t type;
946 struct ospf *ospf;
948 type = (intptr_t)THREAD_ARG (thread);
949 assert (type <= ZEBRA_ROUTE_MAX);
951 rt = EXTERNAL_INFO (type);
953 ospf = ospf_lookup ();
954 if (ospf == NULL)
955 return 0;
957 ospf->t_distribute_update = NULL;
959 zlog_info ("Zebra[Redistribute]: distribute-list update timer fired!");
961 /* foreach all external info. */
962 if (rt)
963 for (rn = route_top (rt); rn; rn = route_next (rn))
964 if ((ei = rn->info) != NULL)
966 if (is_prefix_default (&ei->p))
967 ospf_external_lsa_refresh_default (ospf);
968 else if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
969 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_IF_CHANGED);
970 else
971 ospf_external_lsa_originate (ospf, ei);
973 return 0;
976 #define OSPF_DISTRIBUTE_UPDATE_DELAY 5
978 /* Update distribute-list and set timer to apply access-list. */
979 void
980 ospf_distribute_list_update (struct ospf *ospf, int type)
982 struct route_table *rt;
984 /* External info does not exist. */
985 if (!(rt = EXTERNAL_INFO (type)))
986 return;
988 /* If exists previously invoked thread, then cancel it. */
989 if (ospf->t_distribute_update)
990 OSPF_TIMER_OFF (ospf->t_distribute_update);
992 /* Set timer. */
993 ospf->t_distribute_update =
994 thread_add_timer (master, ospf_distribute_list_update_timer,
995 (void *) type, OSPF_DISTRIBUTE_UPDATE_DELAY);
998 /* If access-list is updated, apply some check. */
999 static void
1000 ospf_filter_update (struct access_list *access)
1002 struct ospf *ospf;
1003 int type;
1004 int abr_inv = 0;
1005 struct ospf_area *area;
1006 struct listnode *node;
1008 /* If OSPF instatnce does not exist, return right now. */
1009 ospf = ospf_lookup ();
1010 if (ospf == NULL)
1011 return;
1013 /* Update distribute-list, and apply filter. */
1014 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1016 if (ROUTEMAP (ospf, type) != NULL)
1018 /* if route-map is not NULL it may be using this access list */
1019 ospf_distribute_list_update (ospf, type);
1020 continue;
1023 /* There is place for route-map for default-information (ZEBRA_ROUTE_MAX),
1024 * but no distribute list. */
1025 if (type == ZEBRA_ROUTE_MAX)
1026 break;
1028 if (DISTRIBUTE_NAME (ospf, type))
1030 /* Keep old access-list for distribute-list. */
1031 struct access_list *old = DISTRIBUTE_LIST (ospf, type);
1033 /* Update access-list for distribute-list. */
1034 DISTRIBUTE_LIST (ospf, type) =
1035 access_list_lookup (AFI_IP, DISTRIBUTE_NAME (ospf, type));
1037 /* No update for this distribute type. */
1038 if (old == NULL && DISTRIBUTE_LIST (ospf, type) == NULL)
1039 continue;
1041 /* Schedule distribute-list update timer. */
1042 if (DISTRIBUTE_LIST (ospf, type) == NULL ||
1043 strcmp (DISTRIBUTE_NAME (ospf, type), access->name) == 0)
1044 ospf_distribute_list_update (ospf, type);
1048 /* Update Area access-list. */
1049 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1051 if (EXPORT_NAME (area))
1053 EXPORT_LIST (area) = NULL;
1054 abr_inv++;
1057 if (IMPORT_NAME (area))
1059 IMPORT_LIST (area) = NULL;
1060 abr_inv++;
1064 /* Schedule ABR tasks -- this will be changed -- takada. */
1065 if (IS_OSPF_ABR (ospf) && abr_inv)
1066 ospf_schedule_abr_task (ospf);
1069 /* If prefix-list is updated, do some updates. */
1070 void
1071 ospf_prefix_list_update (struct prefix_list *plist)
1073 struct ospf *ospf;
1074 int type;
1075 int abr_inv = 0;
1076 struct ospf_area *area;
1077 struct listnode *node;
1079 /* If OSPF instatnce does not exist, return right now. */
1080 ospf = ospf_lookup ();
1081 if (ospf == NULL)
1082 return;
1084 /* Update all route-maps which are used as redistribution filters.
1085 * They might use prefix-list.
1087 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1089 if (ROUTEMAP (ospf, type) != NULL)
1091 /* If route-map is not NULL it may be using this prefix list */
1092 ospf_distribute_list_update (ospf, type);
1093 continue;
1097 /* Update area filter-lists. */
1098 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
1100 /* Update filter-list in. */
1101 if (PREFIX_NAME_IN (area))
1102 if (strcmp (PREFIX_NAME_IN (area), plist->name) == 0)
1104 PREFIX_LIST_IN (area) =
1105 prefix_list_lookup (AFI_IP, PREFIX_NAME_IN (area));
1106 abr_inv++;
1109 /* Update filter-list out. */
1110 if (PREFIX_NAME_OUT (area))
1111 if (strcmp (PREFIX_NAME_OUT (area), plist->name) == 0)
1113 PREFIX_LIST_IN (area) =
1114 prefix_list_lookup (AFI_IP, PREFIX_NAME_OUT (area));
1115 abr_inv++;
1119 /* Schedule ABR task. */
1120 if (IS_OSPF_ABR (ospf) && abr_inv)
1121 ospf_schedule_abr_task (ospf);
1124 static struct ospf_distance *
1125 ospf_distance_new (void)
1127 struct ospf_distance *new;
1128 new = XMALLOC (MTYPE_OSPF_DISTANCE, sizeof (struct ospf_distance));
1129 memset (new, 0, sizeof (struct ospf_distance));
1130 return new;
1133 static void
1134 ospf_distance_free (struct ospf_distance *odistance)
1136 XFREE (MTYPE_OSPF_DISTANCE, odistance);
1140 ospf_distance_set (struct vty *vty, struct ospf *ospf,
1141 const char *distance_str,
1142 const char *ip_str,
1143 const char *access_list_str)
1145 int ret;
1146 struct prefix_ipv4 p;
1147 u_char distance;
1148 struct route_node *rn;
1149 struct ospf_distance *odistance;
1151 ret = str2prefix_ipv4 (ip_str, &p);
1152 if (ret == 0)
1154 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1155 return CMD_WARNING;
1158 distance = atoi (distance_str);
1160 /* Get OSPF distance node. */
1161 rn = route_node_get (ospf->distance_table, (struct prefix *) &p);
1162 if (rn->info)
1164 odistance = rn->info;
1165 route_unlock_node (rn);
1167 else
1169 odistance = ospf_distance_new ();
1170 rn->info = odistance;
1173 /* Set distance value. */
1174 odistance->distance = distance;
1176 /* Reset access-list configuration. */
1177 if (odistance->access_list)
1179 free (odistance->access_list);
1180 odistance->access_list = NULL;
1182 if (access_list_str)
1183 odistance->access_list = strdup (access_list_str);
1185 return CMD_SUCCESS;
1189 ospf_distance_unset (struct vty *vty, struct ospf *ospf,
1190 const char *distance_str,
1191 const char *ip_str, char
1192 const *access_list_str)
1194 int ret;
1195 struct prefix_ipv4 p;
1196 u_char distance;
1197 struct route_node *rn;
1198 struct ospf_distance *odistance;
1200 ret = str2prefix_ipv4 (ip_str, &p);
1201 if (ret == 0)
1203 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
1204 return CMD_WARNING;
1207 distance = atoi (distance_str);
1209 rn = route_node_lookup (ospf->distance_table, (struct prefix *) &p);
1210 if (!rn)
1212 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
1213 return CMD_WARNING;
1216 odistance = rn->info;
1218 if (odistance->access_list)
1219 free (odistance->access_list);
1220 ospf_distance_free (odistance);
1222 rn->info = NULL;
1223 route_unlock_node (rn);
1224 route_unlock_node (rn);
1226 return CMD_SUCCESS;
1229 void
1230 ospf_distance_reset (struct ospf *ospf)
1232 struct route_node *rn;
1233 struct ospf_distance *odistance;
1235 for (rn = route_top (ospf->distance_table); rn; rn = route_next (rn))
1236 if ((odistance = rn->info) != NULL)
1238 if (odistance->access_list)
1239 free (odistance->access_list);
1240 ospf_distance_free (odistance);
1241 rn->info = NULL;
1242 route_unlock_node (rn);
1246 u_char
1247 ospf_distance_apply (struct prefix_ipv4 *p, struct ospf_route *or)
1249 struct ospf *ospf;
1251 ospf = ospf_lookup ();
1252 if (ospf == NULL)
1253 return 0;
1255 if (ospf->distance_intra)
1256 if (or->path_type == OSPF_PATH_INTRA_AREA)
1257 return ospf->distance_intra;
1259 if (ospf->distance_inter)
1260 if (or->path_type == OSPF_PATH_INTER_AREA)
1261 return ospf->distance_inter;
1263 if (ospf->distance_external)
1264 if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL
1265 || or->path_type == OSPF_PATH_TYPE2_EXTERNAL)
1266 return ospf->distance_external;
1268 if (ospf->distance_all)
1269 return ospf->distance_all;
1271 return 0;
1274 void
1275 ospf_zebra_init ()
1277 /* Allocate zebra structure. */
1278 zclient = zclient_new ();
1279 zclient_init (zclient, ZEBRA_ROUTE_OSPF);
1280 zclient->router_id_update = ospf_router_id_update_zebra;
1281 zclient->interface_add = ospf_interface_add;
1282 zclient->interface_delete = ospf_interface_delete;
1283 zclient->interface_up = ospf_interface_state_up;
1284 zclient->interface_down = ospf_interface_state_down;
1285 zclient->interface_address_add = ospf_interface_address_add;
1286 zclient->interface_address_delete = ospf_interface_address_delete;
1287 zclient->ipv4_route_add = ospf_zebra_read_ipv4;
1288 zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
1290 access_list_add_hook (ospf_filter_update);
1291 access_list_delete_hook (ospf_filter_update);
1292 prefix_list_add_hook (ospf_prefix_list_update);
1293 prefix_list_delete_hook (ospf_prefix_list_update);