]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_zebra.c
*: Convert from ->interface_up to the interface callback
[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 #include "lib_errors.h"
32
33 #include "ospf6_proto.h"
34 #include "ospf6_top.h"
35 #include "ospf6_interface.h"
36 #include "ospf6_route.h"
37 #include "ospf6_lsa.h"
38 #include "ospf6_lsdb.h"
39 #include "ospf6_asbr.h"
40 #include "ospf6_zebra.h"
41 #include "ospf6d.h"
42
43 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance")
44
45 unsigned char conf_debug_ospf6_zebra = 0;
46
47 /* information about zebra. */
48 struct zclient *zclient = NULL;
49
50 /* Router-id update message from zebra. */
51 static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
52 {
53 struct prefix router_id;
54 struct ospf6 *o = ospf6;
55
56 zebra_router_id_update_read(zclient->ibuf, &router_id);
57
58 om6->zebra_router_id = router_id.u.prefix4.s_addr;
59
60 if (o == NULL)
61 return 0;
62
63 o->router_id_zebra = router_id.u.prefix4;
64 if (IS_OSPF6_DEBUG_ZEBRA(RECV)) {
65 char buf[INET_ADDRSTRLEN];
66
67 zlog_debug("%s: zebra router-id %s update",
68 __PRETTY_FUNCTION__,
69 inet_ntop(AF_INET, &router_id.u.prefix4,
70 buf, INET_ADDRSTRLEN));
71 }
72
73 ospf6_router_id_update();
74
75 return 0;
76 }
77
78 /* redistribute function */
79 void ospf6_zebra_redistribute(int type)
80 {
81 if (vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT))
82 return;
83 vrf_bitmap_set(zclient->redist[AFI_IP6][type], VRF_DEFAULT);
84
85 if (zclient->sock > 0)
86 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient,
87 AFI_IP6, type, 0, VRF_DEFAULT);
88 }
89
90 void ospf6_zebra_no_redistribute(int type)
91 {
92 if (!vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT))
93 return;
94 vrf_bitmap_unset(zclient->redist[AFI_IP6][type], VRF_DEFAULT);
95 if (zclient->sock > 0)
96 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
97 AFI_IP6, type, 0, VRF_DEFAULT);
98 }
99
100 static int ospf6_zebra_if_del(ZAPI_CALLBACK_ARGS)
101 {
102 struct interface *ifp;
103
104 if (!(ifp = zebra_interface_state_read(zclient->ibuf, vrf_id)))
105 return 0;
106
107 if (if_is_up(ifp))
108 zlog_warn("Zebra: got delete of %s, but interface is still up",
109 ifp->name);
110
111 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
112 zlog_debug("Zebra Interface delete: %s index %d mtu %d",
113 ifp->name, ifp->ifindex, ifp->mtu6);
114
115 if_set_index(ifp, IFINDEX_INTERNAL);
116 return 0;
117 }
118
119 static int ospf6_zebra_if_state_update(ZAPI_CALLBACK_ARGS)
120 {
121 struct interface *ifp;
122
123 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
124 if (ifp == NULL)
125 return 0;
126
127 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
128 zlog_debug(
129 "Zebra Interface state change: "
130 "%s index %d flags %llx metric %d mtu %d bandwidth %d",
131 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
132 ifp->metric, ifp->mtu6, ifp->bandwidth);
133
134 ospf6_interface_state_update(ifp);
135 return 0;
136 }
137
138 static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
139 {
140 struct connected *c;
141 char buf[128];
142
143 c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
144 zclient->ibuf, vrf_id);
145 if (c == NULL)
146 return 0;
147
148 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
149 zlog_debug("Zebra Interface address add: %s %5s %s/%d",
150 c->ifp->name, prefix_family_str(c->address),
151 inet_ntop(c->address->family, &c->address->u.prefix,
152 buf, sizeof(buf)),
153 c->address->prefixlen);
154
155 if (c->address->family == AF_INET6) {
156 ospf6_interface_state_update(c->ifp);
157 ospf6_interface_connected_route_update(c->ifp);
158 }
159 return 0;
160 }
161
162 static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS)
163 {
164 struct connected *c;
165 char buf[128];
166
167 c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
168 zclient->ibuf, vrf_id);
169 if (c == NULL)
170 return 0;
171
172 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
173 zlog_debug("Zebra Interface address delete: %s %5s %s/%d",
174 c->ifp->name, prefix_family_str(c->address),
175 inet_ntop(c->address->family, &c->address->u.prefix,
176 buf, sizeof(buf)),
177 c->address->prefixlen);
178
179 if (c->address->family == AF_INET6) {
180 ospf6_interface_connected_route_update(c->ifp);
181 ospf6_interface_state_update(c->ifp);
182 }
183
184 connected_free(c);
185
186 return 0;
187 }
188
189 static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
190 {
191 struct zapi_route api;
192 unsigned long ifindex;
193 struct in6_addr *nexthop;
194
195 if (ospf6 == NULL)
196 return 0;
197
198 if (zapi_route_decode(zclient->ibuf, &api) < 0)
199 return -1;
200
201 /* we completely ignore srcdest routes for now. */
202 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
203 return 0;
204
205 if (IN6_IS_ADDR_LINKLOCAL(&api.prefix.u.prefix6))
206 return 0;
207
208 ifindex = api.nexthops[0].ifindex;
209 nexthop = &api.nexthops[0].gate.ipv6;
210
211 if (IS_OSPF6_DEBUG_ZEBRA(RECV)) {
212 char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128];
213 prefix2str((struct prefix *)&api.prefix, prefixstr,
214 sizeof(prefixstr));
215 inet_ntop(AF_INET6, nexthop, nexthopstr, sizeof(nexthopstr));
216
217 zlog_debug(
218 "Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %" ROUTE_TAG_PRI,
219 (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD ? "add"
220 : "delete"),
221 zebra_route_string(api.type), prefixstr, nexthopstr,
222 ifindex, api.tag);
223 }
224
225 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
226 ospf6_asbr_redistribute_add(api.type, ifindex, &api.prefix,
227 api.nexthop_num, nexthop, api.tag);
228 else
229 ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix);
230
231 return 0;
232 }
233
234 DEFUN (show_zebra,
235 show_ospf6_zebra_cmd,
236 "show ipv6 ospf6 zebra",
237 SHOW_STR
238 IPV6_STR
239 OSPF6_STR
240 ZEBRA_STR)
241 {
242 int i;
243 if (zclient == NULL) {
244 vty_out(vty, "Not connected to zebra\n");
245 return CMD_SUCCESS;
246 }
247
248 vty_out(vty, "Zebra Information\n");
249 vty_out(vty, " fail: %d\n", zclient->fail);
250 vty_out(vty, " redistribute default: %d\n",
251 vrf_bitmap_check(zclient->default_information[AFI_IP6],
252 VRF_DEFAULT));
253 vty_out(vty, " redistribute:");
254 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
255 if (vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT))
256 vty_out(vty, " %s", zebra_route_string(i));
257 }
258 vty_out(vty, "\n");
259 return CMD_SUCCESS;
260 }
261
262 #define ADD 0
263 #define REM 1
264 static void ospf6_zebra_route_update(int type, struct ospf6_route *request)
265 {
266 struct zapi_route api;
267 char buf[PREFIX2STR_BUFFER];
268 int nhcount;
269 int ret = 0;
270 struct prefix *dest;
271
272 if (IS_OSPF6_DEBUG_ZEBRA(SEND)) {
273 prefix2str(&request->prefix, buf, sizeof(buf));
274 zlog_debug("Send %s route: %s",
275 (type == REM ? "remove" : "add"), buf);
276 }
277
278 if (zclient->sock < 0) {
279 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
280 zlog_debug(" Not connected to Zebra");
281 return;
282 }
283
284 if (request->path.origin.adv_router == ospf6->router_id
285 && (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1
286 || request->path.type == OSPF6_PATH_TYPE_EXTERNAL2)) {
287 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
288 zlog_debug(" Ignore self-originated external route");
289 return;
290 }
291
292 /* If removing is the best path and if there's another path,
293 treat this request as add the secondary path */
294 if (type == REM && ospf6_route_is_best(request) && request->next
295 && ospf6_route_is_same(request, request->next)) {
296 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
297 zlog_debug(
298 " Best-path removal resulted Sencondary addition");
299 type = ADD;
300 request = request->next;
301 }
302
303 /* Only the best path will be sent to zebra. */
304 if (!ospf6_route_is_best(request)) {
305 /* this is not preferred best route, ignore */
306 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
307 zlog_debug(" Ignore non-best route");
308 return;
309 }
310
311 nhcount = ospf6_route_num_nexthops(request);
312 if (nhcount == 0) {
313 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
314 zlog_debug(" No nexthop, ignore");
315 return;
316 }
317
318 dest = &request->prefix;
319
320 memset(&api, 0, sizeof(api));
321 api.vrf_id = VRF_DEFAULT;
322 api.type = ZEBRA_ROUTE_OSPF6;
323 api.safi = SAFI_UNICAST;
324 api.prefix = *dest;
325 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
326 api.nexthop_num = MIN(nhcount, MULTIPATH_NUM);
327 ospf6_route_zebra_copy_nexthops(request, api.nexthops, api.nexthop_num);
328 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
329 api.metric = (request->path.metric_type == 2 ? request->path.u.cost_e2
330 : request->path.cost);
331 if (request->path.tag) {
332 SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
333 api.tag = request->path.tag;
334 }
335
336 SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
337 api.distance =
338 ospf6_distance_apply((struct prefix_ipv6 *)dest, request);
339
340 if (type == REM)
341 ret = zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
342 else
343 ret = zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
344
345 if (ret < 0)
346 flog_err(EC_LIB_ZAPI_SOCKET,
347 "zclient_route_send() %s failed: %s",
348 (type == REM ? "delete" : "add"),
349 safe_strerror(errno));
350
351 return;
352 }
353
354 void ospf6_zebra_route_update_add(struct ospf6_route *request)
355 {
356 ospf6_zebra_route_update(ADD, request);
357 }
358
359 void ospf6_zebra_route_update_remove(struct ospf6_route *request)
360 {
361 ospf6_zebra_route_update(REM, request);
362 }
363
364 void ospf6_zebra_add_discard(struct ospf6_route *request)
365 {
366 struct zapi_route api;
367 char buf[INET6_ADDRSTRLEN];
368 struct prefix *dest = &request->prefix;
369
370 if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
371 memset(&api, 0, sizeof(api));
372 api.vrf_id = VRF_DEFAULT;
373 api.type = ZEBRA_ROUTE_OSPF6;
374 api.safi = SAFI_UNICAST;
375 api.prefix = *dest;
376 zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
377
378 zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
379
380 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
381 zlog_debug("Zebra: Route add discard %s/%d",
382 inet_ntop(AF_INET6, &dest->u.prefix6, buf,
383 INET6_ADDRSTRLEN),
384 dest->prefixlen);
385
386 SET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
387 } else {
388 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
389 zlog_debug(
390 "Zebra: Blackhole route present already %s/%d",
391 inet_ntop(AF_INET6, &dest->u.prefix6, buf,
392 INET6_ADDRSTRLEN),
393 dest->prefixlen);
394 }
395 }
396
397 void ospf6_zebra_delete_discard(struct ospf6_route *request)
398 {
399 struct zapi_route api;
400 char buf[INET6_ADDRSTRLEN];
401 struct prefix *dest = &request->prefix;
402
403 if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
404 memset(&api, 0, sizeof(api));
405 api.vrf_id = VRF_DEFAULT;
406 api.type = ZEBRA_ROUTE_OSPF6;
407 api.safi = SAFI_UNICAST;
408 api.prefix = *dest;
409 zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
410
411 zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
412
413 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
414 zlog_debug("Zebra: Route delete discard %s/%d",
415 inet_ntop(AF_INET6, &dest->u.prefix6, buf,
416 INET6_ADDRSTRLEN),
417 dest->prefixlen);
418
419 UNSET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
420 } else {
421 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
422 zlog_debug(
423 "Zebra: Blackhole route already deleted %s/%d",
424 inet_ntop(AF_INET6, &dest->u.prefix6, buf,
425 INET6_ADDRSTRLEN),
426 dest->prefixlen);
427 }
428 }
429
430 static struct ospf6_distance *ospf6_distance_new(void)
431 {
432 return XCALLOC(MTYPE_OSPF6_DISTANCE, sizeof(struct ospf6_distance));
433 }
434
435 static void ospf6_distance_free(struct ospf6_distance *odistance)
436 {
437 XFREE(MTYPE_OSPF6_DISTANCE, odistance);
438 }
439
440 int ospf6_distance_set(struct vty *vty, struct ospf6 *o,
441 const char *distance_str, const char *ip_str,
442 const char *access_list_str)
443 {
444 int ret;
445 struct prefix_ipv6 p;
446 uint8_t distance;
447 struct route_node *rn;
448 struct ospf6_distance *odistance;
449
450 ret = str2prefix_ipv6(ip_str, &p);
451 if (ret == 0) {
452 vty_out(vty, "Malformed prefix\n");
453 return CMD_WARNING_CONFIG_FAILED;
454 }
455
456 distance = atoi(distance_str);
457
458 /* Get OSPF6 distance node. */
459 rn = route_node_get(o->distance_table, (struct prefix *)&p);
460 if (rn->info) {
461 odistance = rn->info;
462 route_unlock_node(rn);
463 } else {
464 odistance = ospf6_distance_new();
465 rn->info = odistance;
466 }
467
468 /* Set distance value. */
469 odistance->distance = distance;
470
471 /* Reset access-list configuration. */
472 if (odistance->access_list) {
473 free(odistance->access_list);
474 odistance->access_list = NULL;
475 }
476 if (access_list_str)
477 odistance->access_list = strdup(access_list_str);
478
479 return CMD_SUCCESS;
480 }
481
482 int ospf6_distance_unset(struct vty *vty, struct ospf6 *o,
483 const char *distance_str, const char *ip_str,
484 const char *access_list_str)
485 {
486 int ret;
487 struct prefix_ipv6 p;
488 struct route_node *rn;
489 struct ospf6_distance *odistance;
490
491 ret = str2prefix_ipv6(ip_str, &p);
492 if (ret == 0) {
493 vty_out(vty, "Malformed prefix\n");
494 return CMD_WARNING_CONFIG_FAILED;
495 }
496
497 rn = route_node_lookup(o->distance_table, (struct prefix *)&p);
498 if (!rn) {
499 vty_out(vty, "Cant't find specified prefix\n");
500 return CMD_WARNING_CONFIG_FAILED;
501 }
502
503 odistance = rn->info;
504
505 if (odistance->access_list)
506 free(odistance->access_list);
507 ospf6_distance_free(odistance);
508
509 rn->info = NULL;
510 route_unlock_node(rn);
511 route_unlock_node(rn);
512
513 return CMD_SUCCESS;
514 }
515
516 void ospf6_distance_reset(struct ospf6 *o)
517 {
518 struct route_node *rn;
519 struct ospf6_distance *odistance;
520
521 for (rn = route_top(o->distance_table); rn; rn = route_next(rn))
522 if ((odistance = rn->info) != NULL) {
523 if (odistance->access_list)
524 free(odistance->access_list);
525 ospf6_distance_free(odistance);
526 rn->info = NULL;
527 route_unlock_node(rn);
528 }
529 }
530
531 uint8_t ospf6_distance_apply(struct prefix_ipv6 *p, struct ospf6_route * or)
532 {
533 struct ospf6 *o;
534
535 o = ospf6;
536 if (o == NULL)
537 return 0;
538
539 if (o->distance_intra)
540 if (or->path.type == OSPF6_PATH_TYPE_INTRA)
541 return o->distance_intra;
542
543 if (o->distance_inter)
544 if (or->path.type == OSPF6_PATH_TYPE_INTER)
545 return o->distance_inter;
546
547 if (o->distance_external)
548 if (or->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
549 or->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
550 return o->distance_external;
551
552 if (o->distance_all)
553 return o->distance_all;
554
555 return 0;
556 }
557
558 static void ospf6_zebra_connected(struct zclient *zclient)
559 {
560 /* Send the client registration */
561 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT);
562
563 zclient_send_reg_requests(zclient, VRF_DEFAULT);
564 }
565
566 void ospf6_zebra_init(struct thread_master *master)
567 {
568 /* Allocate zebra structure. */
569 zclient = zclient_new(master, &zclient_options_default);
570 zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
571 zclient->zebra_connected = ospf6_zebra_connected;
572 zclient->router_id_update = ospf6_router_id_update_zebra;
573 zclient->interface_delete = ospf6_zebra_if_del;
574 zclient->interface_down = ospf6_zebra_if_state_update;
575 zclient->interface_address_add = ospf6_zebra_if_address_update_add;
576 zclient->interface_address_delete =
577 ospf6_zebra_if_address_update_delete;
578 zclient->redistribute_route_add = ospf6_zebra_read_route;
579 zclient->redistribute_route_del = ospf6_zebra_read_route;
580
581 /* Install command element for zebra node. */
582 install_element(VIEW_NODE, &show_ospf6_zebra_cmd);
583 }
584
585 /* Debug */
586
587 DEFUN (debug_ospf6_zebra_sendrecv,
588 debug_ospf6_zebra_sendrecv_cmd,
589 "debug ospf6 zebra [<send|recv>]",
590 DEBUG_STR
591 OSPF6_STR
592 "Debug connection between zebra\n"
593 "Debug Sending zebra\n"
594 "Debug Receiving zebra\n"
595 )
596 {
597 int idx_send_recv = 3;
598 unsigned char level = 0;
599
600 if (argc == 4) {
601 if (strmatch(argv[idx_send_recv]->text, "send"))
602 level = OSPF6_DEBUG_ZEBRA_SEND;
603 else if (strmatch(argv[idx_send_recv]->text, "recv"))
604 level = OSPF6_DEBUG_ZEBRA_RECV;
605 } else
606 level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
607
608 OSPF6_DEBUG_ZEBRA_ON(level);
609 return CMD_SUCCESS;
610 }
611
612 DEFUN (no_debug_ospf6_zebra_sendrecv,
613 no_debug_ospf6_zebra_sendrecv_cmd,
614 "no debug ospf6 zebra [<send|recv>]",
615 NO_STR
616 DEBUG_STR
617 OSPF6_STR
618 "Debug connection between zebra\n"
619 "Debug Sending zebra\n"
620 "Debug Receiving zebra\n"
621 )
622 {
623 int idx_send_recv = 4;
624 unsigned char level = 0;
625
626 if (argc == 5) {
627 if (strmatch(argv[idx_send_recv]->text, "send"))
628 level = OSPF6_DEBUG_ZEBRA_SEND;
629 else if (strmatch(argv[idx_send_recv]->text, "recv"))
630 level = OSPF6_DEBUG_ZEBRA_RECV;
631 } else
632 level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
633
634 OSPF6_DEBUG_ZEBRA_OFF(level);
635 return CMD_SUCCESS;
636 }
637
638
639 int config_write_ospf6_debug_zebra(struct vty *vty)
640 {
641 if (IS_OSPF6_DEBUG_ZEBRA(SEND) && IS_OSPF6_DEBUG_ZEBRA(RECV))
642 vty_out(vty, "debug ospf6 zebra\n");
643 else {
644 if (IS_OSPF6_DEBUG_ZEBRA(SEND))
645 vty_out(vty, "debug ospf6 zebra send\n");
646 if (IS_OSPF6_DEBUG_ZEBRA(RECV))
647 vty_out(vty, "debug ospf6 zebra recv\n");
648 }
649 return 0;
650 }
651
652 void install_element_ospf6_debug_zebra(void)
653 {
654 install_element(ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd);
655 install_element(ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
656 install_element(CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd);
657 install_element(CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
658 }