1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2003 Yasuhiro Ohara
15 #include "route_opaque.h"
17 #include "lib_errors.h"
19 #include "ospf6_proto.h"
20 #include "ospf6_top.h"
21 #include "ospf6_interface.h"
22 #include "ospf6_route.h"
23 #include "ospf6_lsa.h"
24 #include "ospf6_lsdb.h"
25 #include "ospf6_asbr.h"
26 #include "ospf6_nssa.h"
27 #include "ospf6_zebra.h"
29 #include "ospf6_area.h"
33 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_DISTANCE
, "OSPF6 distance");
35 unsigned char conf_debug_ospf6_zebra
= 0;
37 /* information about zebra. */
38 struct zclient
*zclient
= NULL
;
40 void ospf6_zebra_vrf_register(struct ospf6
*ospf6
)
42 if (!zclient
|| zclient
->sock
< 0 || !ospf6
)
45 if (ospf6
->vrf_id
!= VRF_UNKNOWN
) {
46 if (IS_OSPF6_DEBUG_ZEBRA(RECV
)) {
47 zlog_debug("%s: Register VRF %s id %u", __func__
,
48 ospf6_vrf_id_to_name(ospf6
->vrf_id
),
51 zclient_send_reg_requests(zclient
, ospf6
->vrf_id
);
55 void ospf6_zebra_vrf_deregister(struct ospf6
*ospf6
)
57 if (!zclient
|| zclient
->sock
< 0 || !ospf6
)
60 if (ospf6
->vrf_id
!= VRF_DEFAULT
&& ospf6
->vrf_id
!= VRF_UNKNOWN
) {
61 if (IS_OSPF6_DEBUG_ZEBRA(RECV
)) {
62 zlog_debug("%s: De-Register VRF %s id %u to Zebra.",
64 ospf6_vrf_id_to_name(ospf6
->vrf_id
),
67 /* Deregister for router-id, interfaces,
68 * redistributed routes. */
69 zclient_send_dereg_requests(zclient
, ospf6
->vrf_id
);
73 /* Router-id update message from zebra. */
74 static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS
)
76 struct prefix router_id
;
79 zebra_router_id_update_read(zclient
->ibuf
, &router_id
);
81 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
82 zlog_debug("Zebra router-id update %pI4 vrf %s id %u",
83 &router_id
.u
.prefix4
, ospf6_vrf_id_to_name(vrf_id
),
86 o
= ospf6_lookup_by_vrf_id(vrf_id
);
90 o
->router_id_zebra
= router_id
.u
.prefix4
.s_addr
;
92 ospf6_router_id_update(o
, false);
97 /* redistribute function */
98 void ospf6_zebra_redistribute(int type
, vrf_id_t vrf_id
)
100 if (vrf_bitmap_check(zclient
->redist
[AFI_IP6
][type
], vrf_id
))
102 vrf_bitmap_set(zclient
->redist
[AFI_IP6
][type
], vrf_id
);
104 if (zclient
->sock
> 0)
105 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD
, zclient
,
106 AFI_IP6
, type
, 0, vrf_id
);
109 void ospf6_zebra_no_redistribute(int type
, vrf_id_t vrf_id
)
111 if (!vrf_bitmap_check(zclient
->redist
[AFI_IP6
][type
], vrf_id
))
113 vrf_bitmap_unset(zclient
->redist
[AFI_IP6
][type
], vrf_id
);
114 if (zclient
->sock
> 0)
115 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE
, zclient
,
116 AFI_IP6
, type
, 0, vrf_id
);
119 void ospf6_zebra_import_default_route(struct ospf6
*ospf6
, bool unreg
)
121 struct prefix prefix
= {};
124 if (zclient
->sock
< 0) {
125 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
126 zlog_debug(" Not connected to Zebra");
130 prefix
.family
= AF_INET6
;
131 prefix
.prefixlen
= 0;
134 command
= ZEBRA_NEXTHOP_UNREGISTER
;
136 command
= ZEBRA_NEXTHOP_REGISTER
;
138 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
139 zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__
,
140 zserv_command_string(command
), &prefix
,
143 if (zclient_send_rnh(zclient
, command
, &prefix
, SAFI_UNICAST
, false,
145 == ZCLIENT_SEND_FAILURE
)
146 flog_err(EC_LIB_ZAPI_SOCKET
, "%s: zclient_send_rnh() failed",
150 static int ospf6_zebra_import_check_update(ZAPI_CALLBACK_ARGS
)
153 struct zapi_route nhr
;
154 struct prefix matched
;
156 ospf6
= ospf6_lookup_by_vrf_id(vrf_id
);
157 if (ospf6
== NULL
|| !IS_OSPF6_ASBR(ospf6
))
160 if (!zapi_nexthop_update_decode(zclient
->ibuf
, &matched
, &nhr
)) {
161 zlog_err("%s[%u]: Failure to decode route", __func__
,
166 if (matched
.family
!= AF_INET6
|| matched
.prefixlen
!= 0 ||
167 nhr
.type
== ZEBRA_ROUTE_OSPF6
)
170 ospf6
->nssa_default_import_check
.status
= !!nhr
.nexthop_num
;
171 ospf6_abr_nssa_type_7_defaults(ospf6
);
176 static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS
)
180 c
= zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD
,
181 zclient
->ibuf
, vrf_id
);
185 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
186 zlog_debug("Zebra Interface address add: %s %5s %pFX",
187 c
->ifp
->name
, prefix_family_str(c
->address
),
190 if (c
->address
->family
== AF_INET6
) {
191 ospf6_interface_state_update(c
->ifp
);
192 ospf6_interface_connected_route_update(c
->ifp
);
197 static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS
)
201 c
= zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE
,
202 zclient
->ibuf
, vrf_id
);
206 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
207 zlog_debug("Zebra Interface address delete: %s %5s %pFX",
208 c
->ifp
->name
, prefix_family_str(c
->address
),
211 if (c
->address
->family
== AF_INET6
) {
212 ospf6_interface_connected_route_update(c
->ifp
);
213 ospf6_interface_state_update(c
->ifp
);
221 static int ospf6_zebra_gr_update(struct ospf6
*ospf6
, int command
,
226 if (!zclient
|| zclient
->sock
< 0 || !ospf6
)
229 memset(&api
, 0, sizeof(api
));
231 api
.stale_removal_time
= stale_time
;
232 api
.vrf_id
= ospf6
->vrf_id
;
234 (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES
, zclient
,
240 int ospf6_zebra_gr_enable(struct ospf6
*ospf6
, uint32_t stale_time
)
242 return ospf6_zebra_gr_update(ospf6
, ZEBRA_CLIENT_GR_CAPABILITIES
,
246 int ospf6_zebra_gr_disable(struct ospf6
*ospf6
)
248 return ospf6_zebra_gr_update(ospf6
, ZEBRA_CLIENT_GR_DISABLE
, 0);
251 static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS
)
253 struct zapi_route api
;
254 unsigned long ifindex
;
255 struct in6_addr
*nexthop
;
257 struct prefix_ipv6 p
;
259 ospf6
= ospf6_lookup_by_vrf_id(vrf_id
);
264 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
267 /* we completely ignore srcdest routes for now. */
268 if (CHECK_FLAG(api
.message
, ZAPI_MESSAGE_SRCPFX
))
271 if (IN6_IS_ADDR_LINKLOCAL(&api
.prefix
.u
.prefix6
))
274 ifindex
= api
.nexthops
[0].ifindex
;
275 nexthop
= &api
.nexthops
[0].gate
.ipv6
;
277 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
279 "Zebra Receive route %s: %s %pFX nexthop %pI6 ifindex %ld tag %" ROUTE_TAG_PRI
,
280 (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
? "add"
282 zebra_route_string(api
.type
), &api
.prefix
, nexthop
,
285 memcpy(&p
, &api
.prefix
, sizeof(p
));
286 if (is_default_prefix6(&p
))
287 api
.type
= DEFAULT_ROUTE
;
289 if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
)
290 ospf6_asbr_redistribute_add(api
.type
, ifindex
, &api
.prefix
,
291 api
.nexthop_num
, nexthop
, api
.tag
,
294 ospf6_asbr_redistribute_remove(api
.type
, ifindex
, &api
.prefix
,
301 show_ospf6_zebra_cmd
,
302 "show ipv6 ospf6 zebra [json]",
310 bool uj
= use_json(argc
, argv
);
312 json_object
*json_zebra
;
313 json_object
*json_array
;
315 if (zclient
== NULL
) {
316 vty_out(vty
, "Not connected to zebra\n");
321 json
= json_object_new_object();
322 json_zebra
= json_object_new_object();
323 json_array
= json_object_new_array();
325 json_object_int_add(json_zebra
, "fail", zclient
->fail
);
327 json_zebra
, "redistributeDefault",
328 vrf_bitmap_check(zclient
->default_information
[AFI_IP6
],
330 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
331 if (vrf_bitmap_check(zclient
->redist
[AFI_IP6
][i
],
333 json_object_array_add(
335 json_object_new_string(
336 zebra_route_string(i
)));
338 json_object_object_add(json_zebra
, "redistribute", json_array
);
339 json_object_object_add(json
, "zebraInformation", json_zebra
);
343 vty_out(vty
, "Zebra Information\n");
344 vty_out(vty
, " fail: %d\n", zclient
->fail
);
345 vty_out(vty
, " redistribute default: %d\n",
346 vrf_bitmap_check(zclient
->default_information
[AFI_IP6
],
348 vty_out(vty
, " redistribute:");
349 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++) {
350 if (vrf_bitmap_check(zclient
->redist
[AFI_IP6
][i
],
352 vty_out(vty
, " %s", zebra_route_string(i
));
359 static void ospf6_zebra_append_opaque_attr(struct ospf6_route
*request
,
360 struct zapi_route
*api
)
362 struct ospf_zebra_opaque ospf_opaque
= {};
365 snprintf(ospf_opaque
.path_type
, sizeof(ospf_opaque
.path_type
), "%s",
366 OSPF6_PATH_TYPE_NAME(request
->path
.type
));
368 switch (request
->path
.type
) {
369 case OSPF6_PATH_TYPE_INTRA
:
370 case OSPF6_PATH_TYPE_INTER
:
372 (void)inet_ntop(AF_INET
, &request
->path
.area_id
,
374 sizeof(ospf_opaque
.area_id
));
376 case OSPF6_PATH_TYPE_EXTERNAL1
:
377 case OSPF6_PATH_TYPE_EXTERNAL2
:
379 snprintf(ospf_opaque
.tag
, sizeof(ospf_opaque
.tag
), "%u",
386 SET_FLAG(api
->message
, ZAPI_MESSAGE_OPAQUE
);
387 api
->opaque
.length
= sizeof(struct ospf_zebra_opaque
);
388 memcpy(api
->opaque
.data
, &ospf_opaque
, api
->opaque
.length
);
393 static void ospf6_zebra_route_update(int type
, struct ospf6_route
*request
,
396 struct zapi_route api
;
401 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
402 zlog_debug("Zebra Send %s route: %pFX",
403 (type
== REM
? "remove" : "add"), &request
->prefix
);
405 if (zclient
->sock
< 0) {
406 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
407 zlog_debug(" Not connected to Zebra");
411 if (request
->path
.origin
.adv_router
== ospf6
->router_id
412 && (request
->path
.type
== OSPF6_PATH_TYPE_EXTERNAL1
413 || request
->path
.type
== OSPF6_PATH_TYPE_EXTERNAL2
)) {
414 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
415 zlog_debug(" Ignore self-originated external route");
419 /* If removing is the best path and if there's another path,
420 * treat this request as add the secondary path - if there are
423 if (type
== REM
&& ospf6_route_is_best(request
) && request
->next
&&
424 ospf6_route_is_same(request
, request
->next
) &&
425 ospf6_route_num_nexthops(request
->next
) > 0) {
426 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
428 " Best-path removal resulted Secondary addition");
430 request
= request
->next
;
433 /* Only the best path will be sent to zebra. */
434 if (!ospf6_route_is_best(request
)) {
435 /* this is not preferred best route, ignore */
436 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
437 zlog_debug(" Ignore non-best route");
441 nhcount
= ospf6_route_num_nexthops(request
);
444 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
445 zlog_debug(" No nexthop, ignore");
447 } else if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
448 zlog_debug(" No nexthop, rem ok");
451 dest
= &request
->prefix
;
453 memset(&api
, 0, sizeof(api
));
454 api
.vrf_id
= ospf6
->vrf_id
;
455 api
.type
= ZEBRA_ROUTE_OSPF6
;
456 api
.safi
= SAFI_UNICAST
;
459 if (nhcount
> ospf6
->max_multipath
) {
460 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
462 " Nexthop count is greater than configured maximum-path, hence ignore the extra nexthops");
465 api
.nexthop_num
= MIN(nhcount
, ospf6
->max_multipath
);
466 if (api
.nexthop_num
> 0) {
467 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
468 ospf6_route_zebra_copy_nexthops(request
, api
.nexthops
,
469 api
.nexthop_num
, api
.vrf_id
);
472 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
473 api
.metric
= (request
->path
.metric_type
== 2 ? request
->path
.u
.cost_e2
474 : request
->path
.cost
);
475 if (request
->path
.tag
) {
476 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
477 api
.tag
= request
->path
.tag
;
480 SET_FLAG(api
.message
, ZAPI_MESSAGE_DISTANCE
);
481 api
.distance
= ospf6_distance_apply((struct prefix_ipv6
*)dest
, request
,
485 && CHECK_FLAG(ospf6
->config_flags
, OSPF6_SEND_EXTRA_DATA_TO_ZEBRA
))
486 ospf6_zebra_append_opaque_attr(request
, &api
);
489 ret
= zclient_route_send(ZEBRA_ROUTE_DELETE
, zclient
, &api
);
491 ret
= zclient_route_send(ZEBRA_ROUTE_ADD
, zclient
, &api
);
493 if (ret
== ZCLIENT_SEND_FAILURE
)
494 flog_err(EC_LIB_ZAPI_SOCKET
,
495 "zclient_route_send() %s failed: %s",
496 (type
== REM
? "delete" : "add"),
497 safe_strerror(errno
));
502 void ospf6_zebra_route_update_add(struct ospf6_route
*request
,
505 if (ospf6
->gr_info
.restart_in_progress
506 || ospf6
->gr_info
.prepare_in_progress
) {
507 if (IS_DEBUG_OSPF6_GR
)
509 "Zebra: Graceful Restart in progress -- not installing %pFX",
514 ospf6_zebra_route_update(ADD
, request
, ospf6
);
517 void ospf6_zebra_route_update_remove(struct ospf6_route
*request
,
520 if (ospf6
->gr_info
.restart_in_progress
521 || ospf6
->gr_info
.prepare_in_progress
) {
522 if (IS_DEBUG_OSPF6_GR
)
524 "Zebra: Graceful Restart in progress -- not uninstalling %pFX",
529 ospf6_zebra_route_update(REM
, request
, ospf6
);
532 void ospf6_zebra_add_discard(struct ospf6_route
*request
, struct ospf6
*ospf6
)
534 struct zapi_route api
;
535 struct prefix
*dest
= &request
->prefix
;
537 if (ospf6
->gr_info
.restart_in_progress
538 || ospf6
->gr_info
.prepare_in_progress
) {
539 if (IS_DEBUG_OSPF6_GR
)
541 "Zebra: Graceful Restart in progress -- not installing %pFX",
546 if (!CHECK_FLAG(request
->flag
, OSPF6_ROUTE_BLACKHOLE_ADDED
)) {
547 memset(&api
, 0, sizeof(api
));
548 api
.vrf_id
= ospf6
->vrf_id
;
549 api
.type
= ZEBRA_ROUTE_OSPF6
;
550 api
.safi
= SAFI_UNICAST
;
552 zapi_route_set_blackhole(&api
, BLACKHOLE_NULL
);
554 zclient_route_send(ZEBRA_ROUTE_ADD
, zclient
, &api
);
556 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
557 zlog_debug("Zebra: Route add discard %pFX", dest
);
559 SET_FLAG(request
->flag
, OSPF6_ROUTE_BLACKHOLE_ADDED
);
561 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
563 "Zebra: Blackhole route present already %pFX",
568 void ospf6_zebra_delete_discard(struct ospf6_route
*request
,
571 struct zapi_route api
;
572 struct prefix
*dest
= &request
->prefix
;
574 if (ospf6
->gr_info
.restart_in_progress
575 || ospf6
->gr_info
.prepare_in_progress
) {
576 if (IS_DEBUG_OSPF6_GR
)
578 "Zebra: Graceful Restart in progress -- not uninstalling %pFX",
583 if (CHECK_FLAG(request
->flag
, OSPF6_ROUTE_BLACKHOLE_ADDED
)) {
584 memset(&api
, 0, sizeof(api
));
585 api
.vrf_id
= ospf6
->vrf_id
;
586 api
.type
= ZEBRA_ROUTE_OSPF6
;
587 api
.safi
= SAFI_UNICAST
;
589 zapi_route_set_blackhole(&api
, BLACKHOLE_NULL
);
591 zclient_route_send(ZEBRA_ROUTE_DELETE
, zclient
, &api
);
593 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
594 zlog_debug("Zebra: Route delete discard %pFX", dest
);
596 UNSET_FLAG(request
->flag
, OSPF6_ROUTE_BLACKHOLE_ADDED
);
598 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
600 "Zebra: Blackhole route already deleted %pFX",
605 static struct ospf6_distance
*ospf6_distance_new(void)
607 return XCALLOC(MTYPE_OSPF6_DISTANCE
, sizeof(struct ospf6_distance
));
610 static void ospf6_distance_free(struct ospf6_distance
*odistance
)
612 XFREE(MTYPE_OSPF6_DISTANCE
, odistance
);
615 int ospf6_distance_set(struct vty
*vty
, struct ospf6
*o
,
616 const char *distance_str
, const char *ip_str
,
617 const char *access_list_str
)
620 struct prefix_ipv6 p
;
622 struct route_node
*rn
;
623 struct ospf6_distance
*odistance
;
625 ret
= str2prefix_ipv6(ip_str
, &p
);
627 vty_out(vty
, "Malformed prefix\n");
628 return CMD_WARNING_CONFIG_FAILED
;
631 distance
= atoi(distance_str
);
633 /* Get OSPF6 distance node. */
634 rn
= route_node_get(o
->distance_table
, (struct prefix
*)&p
);
636 odistance
= rn
->info
;
637 route_unlock_node(rn
);
639 odistance
= ospf6_distance_new();
640 rn
->info
= odistance
;
643 /* Set distance value. */
644 odistance
->distance
= distance
;
646 /* Reset access-list configuration. */
647 if (odistance
->access_list
) {
648 free(odistance
->access_list
);
649 odistance
->access_list
= NULL
;
652 odistance
->access_list
= strdup(access_list_str
);
657 int ospf6_distance_unset(struct vty
*vty
, struct ospf6
*o
,
658 const char *distance_str
, const char *ip_str
,
659 const char *access_list_str
)
662 struct prefix_ipv6 p
;
663 struct route_node
*rn
;
664 struct ospf6_distance
*odistance
;
666 ret
= str2prefix_ipv6(ip_str
, &p
);
668 vty_out(vty
, "Malformed prefix\n");
669 return CMD_WARNING_CONFIG_FAILED
;
672 rn
= route_node_lookup(o
->distance_table
, (struct prefix
*)&p
);
674 vty_out(vty
, "Cant't find specified prefix\n");
675 return CMD_WARNING_CONFIG_FAILED
;
678 odistance
= rn
->info
;
680 if (odistance
->access_list
)
681 free(odistance
->access_list
);
682 ospf6_distance_free(odistance
);
685 route_unlock_node(rn
);
686 route_unlock_node(rn
);
691 void ospf6_distance_reset(struct ospf6
*o
)
693 struct route_node
*rn
;
694 struct ospf6_distance
*odistance
;
696 for (rn
= route_top(o
->distance_table
); rn
; rn
= route_next(rn
))
697 if ((odistance
= rn
->info
) != NULL
) {
698 if (odistance
->access_list
)
699 free(odistance
->access_list
);
700 ospf6_distance_free(odistance
);
702 route_unlock_node(rn
);
706 uint8_t ospf6_distance_apply(struct prefix_ipv6
*p
, struct ospf6_route
* or,
715 if (o
->distance_intra
)
716 if (or->path
.type
== OSPF6_PATH_TYPE_INTRA
)
717 return o
->distance_intra
;
719 if (o
->distance_inter
)
720 if (or->path
.type
== OSPF6_PATH_TYPE_INTER
)
721 return o
->distance_inter
;
723 if (o
->distance_external
)
724 if (or->path
.type
== OSPF6_PATH_TYPE_EXTERNAL1
||
725 or->path
.type
== OSPF6_PATH_TYPE_EXTERNAL2
)
726 return o
->distance_external
;
729 return o
->distance_all
;
734 static void ospf6_zebra_connected(struct zclient
*zclient
)
736 /* Send the client registration */
737 bfd_client_sendmsg(zclient
, ZEBRA_BFD_CLIENT_REGISTER
, VRF_DEFAULT
);
739 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
742 static zclient_handler
*const ospf6_handlers
[] = {
743 [ZEBRA_ROUTER_ID_UPDATE
] = ospf6_router_id_update_zebra
,
744 [ZEBRA_INTERFACE_ADDRESS_ADD
] = ospf6_zebra_if_address_update_add
,
745 [ZEBRA_INTERFACE_ADDRESS_DELETE
] = ospf6_zebra_if_address_update_delete
,
746 [ZEBRA_REDISTRIBUTE_ROUTE_ADD
] = ospf6_zebra_read_route
,
747 [ZEBRA_REDISTRIBUTE_ROUTE_DEL
] = ospf6_zebra_read_route
,
748 [ZEBRA_NEXTHOP_UPDATE
] = ospf6_zebra_import_check_update
,
751 void ospf6_zebra_init(struct thread_master
*master
)
753 /* Allocate zebra structure. */
754 zclient
= zclient_new(master
, &zclient_options_default
, ospf6_handlers
,
755 array_size(ospf6_handlers
));
756 zclient_init(zclient
, ZEBRA_ROUTE_OSPF6
, 0, &ospf6d_privs
);
757 zclient
->zebra_connected
= ospf6_zebra_connected
;
759 /* Install command element for zebra node. */
760 install_element(VIEW_NODE
, &show_ospf6_zebra_cmd
);
765 DEFUN (debug_ospf6_zebra_sendrecv
,
766 debug_ospf6_zebra_sendrecv_cmd
,
767 "debug ospf6 zebra [<send|recv>]",
770 "Debug connection between zebra\n"
771 "Debug Sending zebra\n"
772 "Debug Receiving zebra\n"
775 int idx_send_recv
= 3;
776 unsigned char level
= 0;
779 if (strmatch(argv
[idx_send_recv
]->text
, "send"))
780 level
= OSPF6_DEBUG_ZEBRA_SEND
;
781 else if (strmatch(argv
[idx_send_recv
]->text
, "recv"))
782 level
= OSPF6_DEBUG_ZEBRA_RECV
;
784 level
= OSPF6_DEBUG_ZEBRA_SEND
| OSPF6_DEBUG_ZEBRA_RECV
;
786 OSPF6_DEBUG_ZEBRA_ON(level
);
790 DEFUN (no_debug_ospf6_zebra_sendrecv
,
791 no_debug_ospf6_zebra_sendrecv_cmd
,
792 "no debug ospf6 zebra [<send|recv>]",
796 "Debug connection between zebra\n"
797 "Debug Sending zebra\n"
798 "Debug Receiving zebra\n"
801 int idx_send_recv
= 4;
802 unsigned char level
= 0;
805 if (strmatch(argv
[idx_send_recv
]->text
, "send"))
806 level
= OSPF6_DEBUG_ZEBRA_SEND
;
807 else if (strmatch(argv
[idx_send_recv
]->text
, "recv"))
808 level
= OSPF6_DEBUG_ZEBRA_RECV
;
810 level
= OSPF6_DEBUG_ZEBRA_SEND
| OSPF6_DEBUG_ZEBRA_RECV
;
812 OSPF6_DEBUG_ZEBRA_OFF(level
);
817 int config_write_ospf6_debug_zebra(struct vty
*vty
)
819 if (IS_OSPF6_DEBUG_ZEBRA(SEND
) && IS_OSPF6_DEBUG_ZEBRA(RECV
))
820 vty_out(vty
, "debug ospf6 zebra\n");
822 if (IS_OSPF6_DEBUG_ZEBRA(SEND
))
823 vty_out(vty
, "debug ospf6 zebra send\n");
824 if (IS_OSPF6_DEBUG_ZEBRA(RECV
))
825 vty_out(vty
, "debug ospf6 zebra recv\n");
830 void install_element_ospf6_debug_zebra(void)
832 install_element(ENABLE_NODE
, &debug_ospf6_zebra_sendrecv_cmd
);
833 install_element(ENABLE_NODE
, &no_debug_ospf6_zebra_sendrecv_cmd
);
834 install_element(CONFIG_NODE
, &debug_ospf6_zebra_sendrecv_cmd
);
835 install_element(CONFIG_NODE
, &no_debug_ospf6_zebra_sendrecv_cmd
);