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