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