]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_zebra.c
vtysh: return non-zero for configuration failures
[mirror_frr.git] / ospf6d / ospf6_zebra.c
1 /*
2 * Copyright (C) 2003 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "log.h"
24 #include "vty.h"
25 #include "command.h"
26 #include "prefix.h"
27 #include "stream.h"
28 #include "zclient.h"
29 #include "memory.h"
30 #include "lib/bfd.h"
31
32 #include "ospf6_proto.h"
33 #include "ospf6_top.h"
34 #include "ospf6_interface.h"
35 #include "ospf6_route.h"
36 #include "ospf6_lsa.h"
37 #include "ospf6_lsdb.h"
38 #include "ospf6_asbr.h"
39 #include "ospf6_zebra.h"
40 #include "ospf6d.h"
41
42 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance")
43
44 unsigned char conf_debug_ospf6_zebra = 0;
45
46 /* information about zebra. */
47 struct zclient *zclient = NULL;
48
49 struct in_addr router_id_zebra;
50
51 /* Router-id update message from zebra. */
52 static int
53 ospf6_router_id_update_zebra (int command, struct zclient *zclient,
54 zebra_size_t length, vrf_id_t vrf_id)
55 {
56 struct prefix router_id;
57 struct ospf6 *o = ospf6;
58
59 zebra_router_id_update_read(zclient->ibuf,&router_id);
60 router_id_zebra = router_id.u.prefix4;
61
62 if (o == NULL)
63 return 0;
64
65 if (o->router_id == 0)
66 o->router_id = (u_int32_t) router_id_zebra.s_addr;
67
68 return 0;
69 }
70
71 /* redistribute function */
72 void
73 ospf6_zebra_redistribute (int type)
74 {
75 if (vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT))
76 return;
77 vrf_bitmap_set (zclient->redist[AFI_IP6][type], VRF_DEFAULT);
78
79 if (zclient->sock > 0)
80 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
81 VRF_DEFAULT);
82 }
83
84 void
85 ospf6_zebra_no_redistribute (int type)
86 {
87 if (!vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT))
88 return;
89 vrf_bitmap_unset (zclient->redist[AFI_IP6][type], VRF_DEFAULT);
90 if (zclient->sock > 0)
91 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type,
92 0, VRF_DEFAULT);
93 }
94
95 /* Inteface addition message from zebra. */
96 static int
97 ospf6_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length,
98 vrf_id_t vrf_id)
99 {
100 struct interface *ifp;
101
102 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
103 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
104 zlog_debug ("Zebra Interface add: %s index %d mtu %d",
105 ifp->name, ifp->ifindex, ifp->mtu6);
106 ospf6_interface_if_add (ifp);
107 return 0;
108 }
109
110 static int
111 ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length,
112 vrf_id_t vrf_id)
113 {
114 struct interface *ifp;
115
116 if (!(ifp = zebra_interface_state_read (zclient->ibuf, vrf_id)))
117 return 0;
118
119 if (if_is_up (ifp))
120 zlog_warn ("Zebra: got delete of %s, but interface is still up", ifp->name);
121
122 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
123 zlog_debug ("Zebra Interface delete: %s index %d mtu %d",
124 ifp->name, ifp->ifindex, ifp->mtu6);
125
126 #if 0
127 /* XXX: ospf6_interface_if_del is not the right way to handle this,
128 * because among other thinkable issues, it will also clear all
129 * settings as they are contained in the struct ospf6_interface. */
130 ospf6_interface_if_del (ifp);
131 #endif /*0*/
132
133 ifp->ifindex = IFINDEX_DELETED;
134 return 0;
135 }
136
137 static int
138 ospf6_zebra_if_state_update (int command, struct zclient *zclient,
139 zebra_size_t length, vrf_id_t vrf_id)
140 {
141 struct interface *ifp;
142
143 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
144 if (ifp == NULL)
145 return 0;
146
147 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
148 zlog_debug ("Zebra Interface state change: "
149 "%s index %d flags %llx metric %d mtu %d bandwidth %d",
150 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
151 ifp->metric, ifp->mtu6, ifp->bandwidth);
152
153 ospf6_interface_state_update (ifp);
154 return 0;
155 }
156
157 static int
158 ospf6_zebra_if_address_update_add (int command, struct zclient *zclient,
159 zebra_size_t length, vrf_id_t vrf_id)
160 {
161 struct connected *c;
162 char buf[128];
163
164 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf,
165 vrf_id);
166 if (c == NULL)
167 return 0;
168
169 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
170 zlog_debug ("Zebra Interface address add: %s %5s %s/%d",
171 c->ifp->name, prefix_family_str (c->address),
172 inet_ntop (c->address->family, &c->address->u.prefix,
173 buf, sizeof (buf)), c->address->prefixlen);
174
175 if (c->address->family == AF_INET6)
176 {
177 ospf6_interface_state_update (c->ifp);
178 ospf6_interface_connected_route_update (c->ifp);
179 }
180 return 0;
181 }
182
183 static int
184 ospf6_zebra_if_address_update_delete (int command, struct zclient *zclient,
185 zebra_size_t length, vrf_id_t vrf_id)
186 {
187 struct connected *c;
188 char buf[128];
189
190 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf,
191 vrf_id);
192 if (c == NULL)
193 return 0;
194
195 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
196 zlog_debug ("Zebra Interface address delete: %s %5s %s/%d",
197 c->ifp->name, prefix_family_str (c->address),
198 inet_ntop (c->address->family, &c->address->u.prefix,
199 buf, sizeof (buf)), c->address->prefixlen);
200
201 if (c->address->family == AF_INET6)
202 {
203 ospf6_interface_connected_route_update (c->ifp);
204 ospf6_interface_state_update (c->ifp);
205 }
206
207 connected_free (c);
208
209 return 0;
210 }
211
212 static int
213 ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
214 zebra_size_t length, vrf_id_t vrf_id)
215 {
216 struct stream *s;
217 struct zapi_ipv6 api;
218 unsigned long ifindex;
219 struct prefix p, src_p;
220 struct in6_addr *nexthop;
221
222 if (ospf6 == NULL)
223 return 0;
224
225 s = zclient->ibuf;
226 ifindex = 0;
227 nexthop = NULL;
228 memset (&api, 0, sizeof (api));
229
230 /* Type, flags, message. */
231 api.type = stream_getc (s);
232 api.instance = stream_getw (s);
233 api.flags = stream_getl (s);
234 api.message = stream_getc (s);
235
236 /* IPv6 prefix. */
237 memset (&p, 0, sizeof (struct prefix));
238 p.family = AF_INET6;
239 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
240 stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
241
242 memset (&src_p, 0, sizeof (struct prefix));
243 src_p.family = AF_INET6;
244 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
245 {
246 src_p.prefixlen = stream_getc (s);
247 stream_get (&src_p.u.prefix6, s, PSIZE (src_p.prefixlen));
248 }
249
250 if (src_p.prefixlen)
251 /* we completely ignore srcdest routes for now. */
252 return 0;
253
254 /* Nexthop, ifindex, distance, metric. */
255 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
256 {
257 api.nexthop_num = stream_getc (s);
258 nexthop = (struct in6_addr *)
259 malloc (api.nexthop_num * sizeof (struct in6_addr));
260 stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr));
261 }
262 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
263 {
264 api.ifindex_num = stream_getc (s);
265 ifindex = stream_getl (s);
266 }
267 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
268 api.distance = stream_getc (s);
269 else
270 api.distance = 0;
271 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
272 api.metric = stream_getl (s);
273 else
274 api.metric = 0;
275
276 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
277 api.tag = stream_getl (s);
278 else
279 api.tag = 0;
280
281 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
282 {
283 char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128];
284 prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
285 if (nexthop)
286 inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr));
287 else
288 snprintf (nexthopstr, sizeof (nexthopstr), "::");
289
290 zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %"ROUTE_TAG_PRI,
291 (command == ZEBRA_REDISTRIBUTE_IPV6_ADD ? "add" : "delete"),
292 zebra_route_string(api.type), prefixstr, nexthopstr, ifindex, api.tag);
293 }
294
295 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
296 ospf6_asbr_redistribute_add (api.type, ifindex, &p,
297 api.nexthop_num, nexthop, api.tag);
298 else
299 ospf6_asbr_redistribute_remove (api.type, ifindex, &p);
300
301 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
302 free (nexthop);
303
304 return 0;
305 }
306
307 DEFUN (show_zebra,
308 show_ospf6_zebra_cmd,
309 "show ipv6 ospf6 zebra",
310 SHOW_STR
311 IPV6_STR
312 OSPF6_STR
313 "Zebra information\n")
314 {
315 int i;
316 if (zclient == NULL)
317 {
318 vty_out (vty, "Not connected to zebra%s", VNL);
319 return CMD_SUCCESS;
320 }
321
322 vty_out (vty, "Zebra Infomation%s", VNL);
323 vty_out (vty, " enable: %d fail: %d%s",
324 zclient->enable, zclient->fail, VNL);
325 vty_out (vty, " redistribute default: %d%s",
326 vrf_bitmap_check (zclient->default_information, VRF_DEFAULT),
327 VNL);
328 vty_out (vty, " redistribute:");
329 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
330 {
331 if (vrf_bitmap_check (zclient->redist[AFI_IP6][i], VRF_DEFAULT))
332 vty_out (vty, " %s", zebra_route_string(i));
333 }
334 vty_out (vty, "%s", VNL);
335 return CMD_SUCCESS;
336 }
337
338 /* Zebra configuration write function. */
339 static int
340 config_write_ospf6_zebra (struct vty *vty)
341 {
342 if (! zclient->enable)
343 {
344 vty_out (vty, "no router zebra%s", VNL);
345 vty_out (vty, "!%s", VNL);
346 }
347 else if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
348 VRF_DEFAULT))
349 {
350 vty_out (vty, "router zebra%s", VNL);
351 vty_out (vty, " no redistribute ospf6%s", VNL);
352 vty_out (vty, "!%s", VNL);
353 }
354 return 0;
355 }
356
357 /* Zebra node structure. */
358 static struct cmd_node zebra_node =
359 {
360 ZEBRA_NODE,
361 "%s(config-zebra)# ",
362 };
363
364 #define ADD 0
365 #define REM 1
366 static void
367 ospf6_zebra_route_update (int type, struct ospf6_route *request)
368 {
369 struct zapi_ipv6 api;
370 char buf[PREFIX2STR_BUFFER];
371 int nhcount;
372 struct in6_addr **nexthops;
373 ifindex_t *ifindexes;
374 int ret = 0;
375 struct prefix_ipv6 *dest;
376
377 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
378 {
379 prefix2str (&request->prefix, buf, sizeof (buf));
380 zlog_debug ("Send %s route: %s",
381 (type == REM ? "remove" : "add"), buf);
382 }
383
384 if (zclient->sock < 0)
385 {
386 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
387 zlog_debug (" Not connected to Zebra");
388 return;
389 }
390
391 if (request->path.origin.adv_router == ospf6->router_id &&
392 (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
393 request->path.type == OSPF6_PATH_TYPE_EXTERNAL2))
394 {
395 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
396 zlog_debug (" Ignore self-originated external route");
397 return;
398 }
399
400 /* If removing is the best path and if there's another path,
401 treat this request as add the secondary path */
402 if (type == REM && ospf6_route_is_best (request) &&
403 request->next && ospf6_route_is_same (request, request->next))
404 {
405 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
406 zlog_debug (" Best-path removal resulted Sencondary addition");
407 type = ADD;
408 request = request->next;
409 }
410
411 /* Only the best path will be sent to zebra. */
412 if (! ospf6_route_is_best (request))
413 {
414 /* this is not preferred best route, ignore */
415 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
416 zlog_debug (" Ignore non-best route");
417 return;
418 }
419
420 nhcount = ospf6_route_num_nexthops (request);
421 if (nhcount == 0)
422 {
423 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
424 zlog_debug (" No nexthop, ignore");
425 return;
426 }
427
428 /* allocate memory for nexthop_list */
429 nexthops = XCALLOC (MTYPE_OSPF6_OTHER,
430 nhcount * sizeof (struct in6_addr *));
431 if (nexthops == NULL)
432 {
433 zlog_warn ("Can't send route to zebra: malloc failed");
434 return;
435 }
436
437 /* allocate memory for ifindex_list */
438 ifindexes = XCALLOC (MTYPE_OSPF6_OTHER,
439 nhcount * sizeof (ifindex_t));
440 if (ifindexes == NULL)
441 {
442 zlog_warn ("Can't send route to zebra: malloc failed");
443 XFREE (MTYPE_OSPF6_OTHER, nexthops);
444 return;
445 }
446
447 ospf6_route_zebra_copy_nexthops (request, ifindexes, nexthops, nhcount);
448
449 api.vrf_id = VRF_DEFAULT;
450 api.type = ZEBRA_ROUTE_OSPF6;
451 api.instance = 0;
452 api.flags = 0;
453 api.message = 0;
454 api.safi = SAFI_UNICAST;
455 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
456 api.nexthop_num = nhcount;
457 api.nexthop = nexthops;
458 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
459 api.ifindex_num = nhcount;
460 api.ifindex = ifindexes;
461 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
462 api.metric = (request->path.metric_type == 2 ?
463 request->path.u.cost_e2 : request->path.cost);
464 if (request->path.tag)
465 {
466 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
467 api.tag = request->path.tag;
468 }
469
470 dest = (struct prefix_ipv6 *) &request->prefix;
471
472 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
473 api.distance = ospf6_distance_apply (dest, request);
474
475 if (type == REM)
476 ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
477 else
478 ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
479
480 if (ret < 0)
481 zlog_err ("zapi_ipv6_route() %s failed: %s",
482 (type == REM ? "delete" : "add"), safe_strerror (errno));
483
484 XFREE (MTYPE_OSPF6_OTHER, nexthops);
485 XFREE (MTYPE_OSPF6_OTHER, ifindexes);
486
487 return;
488 }
489
490 void
491 ospf6_zebra_route_update_add (struct ospf6_route *request)
492 {
493 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
494 VRF_DEFAULT))
495 {
496 ospf6->route_table->hook_add = NULL;
497 ospf6->route_table->hook_remove = NULL;
498 return;
499 }
500 ospf6_zebra_route_update (ADD, request);
501 }
502
503 void
504 ospf6_zebra_route_update_remove (struct ospf6_route *request)
505 {
506 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
507 VRF_DEFAULT))
508 {
509 ospf6->route_table->hook_add = NULL;
510 ospf6->route_table->hook_remove = NULL;
511 return;
512 }
513 ospf6_zebra_route_update (REM, request);
514 }
515
516 void
517 ospf6_zebra_add_discard (struct ospf6_route *request)
518 {
519 struct zapi_ipv6 api;
520 char buf[INET6_ADDRSTRLEN];
521 struct prefix_ipv6 *dest;
522
523 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
524 VRF_DEFAULT))
525 {
526 if (!CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
527 {
528 api.vrf_id = VRF_DEFAULT;
529 api.type = ZEBRA_ROUTE_OSPF6;
530 api.flags = ZEBRA_FLAG_BLACKHOLE;
531 api.instance = 0;
532 api.message = 0;
533 api.safi = SAFI_UNICAST;
534 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
535 api.nexthop_num = 0;
536 api.ifindex_num = 0;
537
538 dest = (struct prefix_ipv6 *) &request->prefix;
539
540 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
541
542 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
543 zlog_debug ("Zebra: Route add discard %s/%d",
544 inet_ntop (AF_INET6, &dest->prefix,
545 buf, INET6_ADDRSTRLEN),
546 dest->prefixlen);
547 SET_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
548 }
549 else
550 {
551 dest = (struct prefix_ipv6 *) &request->prefix;
552
553 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
554 zlog_debug ("Zebra: Blackhole route present already %s/%d",
555 inet_ntop (AF_INET6, &dest->prefix,
556 buf, INET6_ADDRSTRLEN),
557 dest->prefixlen);
558 }
559 }
560 }
561
562 void
563 ospf6_zebra_delete_discard (struct ospf6_route *request)
564 {
565 struct zapi_ipv6 api;
566 char buf[INET6_ADDRSTRLEN];
567 struct prefix_ipv6 *dest;
568
569 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
570 {
571 if (CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
572 {
573 api.vrf_id = VRF_DEFAULT;
574 api.type = ZEBRA_ROUTE_OSPF6;
575 api.flags = ZEBRA_FLAG_BLACKHOLE;
576 api.instance = 0;
577 api.message = 0;
578 api.safi = SAFI_UNICAST;
579 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
580 api.nexthop_num = 0;
581 api.ifindex_num = 0;
582
583 dest = (struct prefix_ipv6 *) &request->prefix;
584
585 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
586
587 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
588 zlog_debug ("Zebra: Route delete discard %s/%d",
589 inet_ntop (AF_INET6, &dest->prefix, buf,
590 INET6_ADDRSTRLEN), dest->prefixlen);
591 UNSET_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
592 }
593 else
594 {
595 dest = (struct prefix_ipv6 *) &request->prefix;
596 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
597 zlog_debug ("Zebra: Blackhole route already deleted %s/%d",
598 inet_ntop (AF_INET6, &dest->prefix, buf,
599 INET6_ADDRSTRLEN), dest->prefixlen);
600 }
601 }
602 }
603
604 DEFUN (redistribute_ospf6,
605 redistribute_ospf6_cmd,
606 "redistribute ospf6",
607 "Redistribute control\n"
608 "OSPF6 route\n")
609 {
610 struct ospf6_route *route;
611
612 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
613 return CMD_SUCCESS;
614
615 vrf_bitmap_set (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT);
616
617 if (ospf6 == NULL)
618 return CMD_SUCCESS;
619
620 /* send ospf6 route to zebra route table */
621 for (route = ospf6_route_head (ospf6->route_table); route;
622 route = ospf6_route_next (route))
623 ospf6_zebra_route_update_add (route);
624
625 ospf6->route_table->hook_add = ospf6_zebra_route_update_add;
626 ospf6->route_table->hook_remove = ospf6_zebra_route_update_remove;
627
628 return CMD_SUCCESS;
629 }
630
631 DEFUN (no_redistribute_ospf6,
632 no_redistribute_ospf6_cmd,
633 "no redistribute ospf6",
634 NO_STR
635 "Redistribute control\n"
636 "OSPF6 route\n")
637 {
638 struct ospf6_route *route;
639
640 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
641 return CMD_SUCCESS;
642
643 vrf_bitmap_unset (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT);
644
645 if (ospf6 == NULL)
646 return CMD_SUCCESS;
647
648 ospf6->route_table->hook_add = NULL;
649 ospf6->route_table->hook_remove = NULL;
650
651 /* withdraw ospf6 route from zebra route table */
652 for (route = ospf6_route_head (ospf6->route_table); route;
653 route = ospf6_route_next (route))
654 ospf6_zebra_route_update_remove (route);
655
656 return CMD_SUCCESS;
657 }
658
659 static struct ospf6_distance *
660 ospf6_distance_new (void)
661 {
662 return XCALLOC (MTYPE_OSPF6_DISTANCE, sizeof (struct ospf6_distance));
663 }
664
665 static void
666 ospf6_distance_free (struct ospf6_distance *odistance)
667 {
668 XFREE (MTYPE_OSPF6_DISTANCE, odistance);
669 }
670
671 int
672 ospf6_distance_set (struct vty *vty, struct ospf6 *o,
673 const char *distance_str,
674 const char *ip_str,
675 const char *access_list_str)
676 {
677 int ret;
678 struct prefix_ipv6 p;
679 u_char distance;
680 struct route_node *rn;
681 struct ospf6_distance *odistance;
682
683 ret = str2prefix_ipv6 (ip_str, &p);
684 if (ret == 0)
685 {
686 vty_outln (vty, "Malformed prefix");
687 return CMD_WARNING_CONFIG_FAILED;
688 }
689
690 distance = atoi (distance_str);
691
692 /* Get OSPF6 distance node. */
693 rn = route_node_get (o->distance_table, (struct prefix *) &p);
694 if (rn->info)
695 {
696 odistance = rn->info;
697 route_unlock_node (rn);
698 }
699 else
700 {
701 odistance = ospf6_distance_new ();
702 rn->info = odistance;
703 }
704
705 /* Set distance value. */
706 odistance->distance = distance;
707
708 /* Reset access-list configuration. */
709 if (odistance->access_list)
710 {
711 free (odistance->access_list);
712 odistance->access_list = NULL;
713 }
714 if (access_list_str)
715 odistance->access_list = strdup (access_list_str);
716
717 return CMD_SUCCESS;
718 }
719
720 int
721 ospf6_distance_unset (struct vty *vty, struct ospf6 *o,
722 const char *distance_str,
723 const char *ip_str,
724 const char *access_list_str)
725 {
726 int ret;
727 struct prefix_ipv6 p;
728 struct route_node *rn;
729 struct ospf6_distance *odistance;
730
731 ret = str2prefix_ipv6 (ip_str, &p);
732 if (ret == 0)
733 {
734 vty_outln (vty, "Malformed prefix");
735 return CMD_WARNING_CONFIG_FAILED;
736 }
737
738 rn = route_node_lookup (o->distance_table, (struct prefix *) &p);
739 if (!rn)
740 {
741 vty_outln (vty, "Can't find specified prefix");
742 return CMD_WARNING_CONFIG_FAILED;
743 }
744
745 odistance = rn->info;
746
747 if (odistance->access_list)
748 free (odistance->access_list);
749 ospf6_distance_free (odistance);
750
751 rn->info = NULL;
752 route_unlock_node (rn);
753 route_unlock_node (rn);
754
755 return CMD_SUCCESS;
756 }
757
758 void
759 ospf6_distance_reset (struct ospf6 *o)
760 {
761 struct route_node *rn;
762 struct ospf6_distance *odistance;
763
764 for (rn = route_top (o->distance_table); rn; rn = route_next (rn))
765 if ((odistance = rn->info) != NULL)
766 {
767 if (odistance->access_list)
768 free (odistance->access_list);
769 ospf6_distance_free (odistance);
770 rn->info = NULL;
771 route_unlock_node (rn);
772 }
773 }
774
775 u_char
776 ospf6_distance_apply (struct prefix_ipv6 *p, struct ospf6_route *or)
777 {
778 struct ospf6 *o;
779
780 o = ospf6;
781 if (o == NULL)
782 return 0;
783
784 if (o->distance_intra)
785 if (or->path.type == OSPF6_PATH_TYPE_INTRA)
786 return o->distance_intra;
787
788 if (o->distance_inter)
789 if (or->path.type == OSPF6_PATH_TYPE_INTER)
790 return o->distance_inter;
791
792 if (o->distance_external)
793 if(or->path.type == OSPF6_PATH_TYPE_EXTERNAL1
794 || or->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
795 return o->distance_external;
796
797 if (o->distance_all)
798 return o->distance_all;
799
800 return 0;
801 }
802
803 static void
804 ospf6_zebra_connected (struct zclient *zclient)
805 {
806 /* Send the client registration */
807 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
808
809 zclient_send_reg_requests (zclient, VRF_DEFAULT);
810 }
811
812 void
813 ospf6_zebra_init (struct thread_master *master)
814 {
815 /* Allocate zebra structure. */
816 zclient = zclient_new(master);
817 zclient_init (zclient, ZEBRA_ROUTE_OSPF6, 0);
818 zclient->zebra_connected = ospf6_zebra_connected;
819 zclient->router_id_update = ospf6_router_id_update_zebra;
820 zclient->interface_add = ospf6_zebra_if_add;
821 zclient->interface_delete = ospf6_zebra_if_del;
822 zclient->interface_up = ospf6_zebra_if_state_update;
823 zclient->interface_down = ospf6_zebra_if_state_update;
824 zclient->interface_address_add = ospf6_zebra_if_address_update_add;
825 zclient->interface_address_delete = ospf6_zebra_if_address_update_delete;
826 zclient->redistribute_route_ipv4_add = NULL;
827 zclient->redistribute_route_ipv4_del = NULL;
828 zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6;
829 zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6;
830
831 /* redistribute connected route by default */
832 /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */
833
834 /* Install zebra node. */
835 install_node (&zebra_node, config_write_ospf6_zebra);
836
837 /* Install command element for zebra node. */
838 install_element (VIEW_NODE, &show_ospf6_zebra_cmd);
839 install_default (ZEBRA_NODE);
840 install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
841 install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);
842
843 return;
844 }
845
846 /* Debug */
847
848 DEFUN (debug_ospf6_zebra_sendrecv,
849 debug_ospf6_zebra_sendrecv_cmd,
850 "debug ospf6 zebra [<send|recv>]",
851 DEBUG_STR
852 OSPF6_STR
853 "Debug connection between zebra\n"
854 "Debug Sending zebra\n"
855 "Debug Receiving zebra\n"
856 )
857 {
858 int idx_send_recv = 3;
859 unsigned char level = 0;
860
861 if (argc == 4)
862 {
863 if (strmatch(argv[idx_send_recv]->text, "send"))
864 level = OSPF6_DEBUG_ZEBRA_SEND;
865 else if (strmatch(argv[idx_send_recv]->text, "recv"))
866 level = OSPF6_DEBUG_ZEBRA_RECV;
867 }
868 else
869 level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
870
871 OSPF6_DEBUG_ZEBRA_ON (level);
872 return CMD_SUCCESS;
873 }
874
875 DEFUN (no_debug_ospf6_zebra_sendrecv,
876 no_debug_ospf6_zebra_sendrecv_cmd,
877 "no debug ospf6 zebra [<send|recv>]",
878 NO_STR
879 DEBUG_STR
880 OSPF6_STR
881 "Debug connection between zebra\n"
882 "Debug Sending zebra\n"
883 "Debug Receiving zebra\n"
884 )
885 {
886 int idx_send_recv = 4;
887 unsigned char level = 0;
888
889 if (argc == 5)
890 {
891 if (strmatch(argv[idx_send_recv]->text, "send"))
892 level = OSPF6_DEBUG_ZEBRA_SEND;
893 else if (strmatch(argv[idx_send_recv]->text, "recv"))
894 level = OSPF6_DEBUG_ZEBRA_RECV;
895 }
896 else
897 level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
898
899 OSPF6_DEBUG_ZEBRA_OFF (level);
900 return CMD_SUCCESS;
901 }
902
903
904 int
905 config_write_ospf6_debug_zebra (struct vty *vty)
906 {
907 if (IS_OSPF6_DEBUG_ZEBRA (SEND) && IS_OSPF6_DEBUG_ZEBRA (RECV))
908 vty_out (vty, "debug ospf6 zebra%s", VNL);
909 else
910 {
911 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
912 vty_out (vty, "debug ospf6 zebra send%s", VNL);
913 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
914 vty_out (vty, "debug ospf6 zebra recv%s", VNL);
915 }
916 return 0;
917 }
918
919 void
920 install_element_ospf6_debug_zebra (void)
921 {
922 install_element (ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd);
923 install_element (ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
924 install_element (CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd);
925 install_element (CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
926 }
927
928