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