]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_zebra.c
fdf2f299cbd04260ba48706d04e6d26d181710fe
[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
308
309
310 DEFUN (show_zebra,
311 show_zebra_cmd,
312 "show zebra",
313 SHOW_STR
314 "Zebra information\n")
315 {
316 int i;
317 if (zclient == NULL)
318 {
319 vty_out (vty, "Not connected to zebra%s", VNL);
320 return CMD_SUCCESS;
321 }
322
323 vty_out (vty, "Zebra Infomation%s", VNL);
324 vty_out (vty, " enable: %d fail: %d%s",
325 zclient->enable, zclient->fail, VNL);
326 vty_out (vty, " redistribute default: %d%s",
327 vrf_bitmap_check (zclient->default_information, VRF_DEFAULT),
328 VNL);
329 vty_out (vty, " redistribute:");
330 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
331 {
332 if (vrf_bitmap_check (zclient->redist[AFI_IP6][i], VRF_DEFAULT))
333 vty_out (vty, " %s", zebra_route_string(i));
334 }
335 vty_out (vty, "%s", VNL);
336 return CMD_SUCCESS;
337 }
338
339 /* Zebra configuration write function. */
340 static int
341 config_write_ospf6_zebra (struct vty *vty)
342 {
343 if (! zclient->enable)
344 {
345 vty_out (vty, "no router zebra%s", VNL);
346 vty_out (vty, "!%s", VNL);
347 }
348 else if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
349 VRF_DEFAULT))
350 {
351 vty_out (vty, "router zebra%s", VNL);
352 vty_out (vty, " no redistribute ospf6%s", VNL);
353 vty_out (vty, "!%s", VNL);
354 }
355 return 0;
356 }
357
358 /* Zebra node structure. */
359 static struct cmd_node zebra_node =
360 {
361 ZEBRA_NODE,
362 "%s(config-zebra)# ",
363 };
364
365 #define ADD 0
366 #define REM 1
367 static void
368 ospf6_zebra_route_update (int type, struct ospf6_route *request)
369 {
370 struct zapi_ipv6 api;
371 char buf[PREFIX2STR_BUFFER];
372 int nhcount;
373 struct in6_addr **nexthops;
374 ifindex_t *ifindexes;
375 int ret = 0;
376 struct prefix_ipv6 *dest;
377
378 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
379 {
380 prefix2str (&request->prefix, buf, sizeof (buf));
381 zlog_debug ("Send %s route: %s",
382 (type == REM ? "remove" : "add"), buf);
383 }
384
385 if (zclient->sock < 0)
386 {
387 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
388 zlog_debug (" Not connected to Zebra");
389 return;
390 }
391
392 if (request->path.origin.adv_router == ospf6->router_id &&
393 (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
394 request->path.type == OSPF6_PATH_TYPE_EXTERNAL2))
395 {
396 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
397 zlog_debug (" Ignore self-originated external route");
398 return;
399 }
400
401 /* If removing is the best path and if there's another path,
402 treat this request as add the secondary path */
403 if (type == REM && ospf6_route_is_best (request) &&
404 request->next && ospf6_route_is_same (request, request->next))
405 {
406 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
407 zlog_debug (" Best-path removal resulted Sencondary addition");
408 type = ADD;
409 request = request->next;
410 }
411
412 /* Only the best path will be sent to zebra. */
413 if (! ospf6_route_is_best (request))
414 {
415 /* this is not preferred best route, ignore */
416 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
417 zlog_debug (" Ignore non-best route");
418 return;
419 }
420
421 nhcount = ospf6_route_num_nexthops (request);
422 if (nhcount == 0)
423 {
424 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
425 zlog_debug (" No nexthop, ignore");
426 return;
427 }
428
429 /* allocate memory for nexthop_list */
430 nexthops = XCALLOC (MTYPE_OSPF6_OTHER,
431 nhcount * sizeof (struct in6_addr *));
432 if (nexthops == NULL)
433 {
434 zlog_warn ("Can't send route to zebra: malloc failed");
435 return;
436 }
437
438 /* allocate memory for ifindex_list */
439 ifindexes = XCALLOC (MTYPE_OSPF6_OTHER,
440 nhcount * sizeof (ifindex_t));
441 if (ifindexes == NULL)
442 {
443 zlog_warn ("Can't send route to zebra: malloc failed");
444 XFREE (MTYPE_OSPF6_OTHER, nexthops);
445 return;
446 }
447
448 ospf6_route_zebra_copy_nexthops (request, ifindexes, nexthops, nhcount);
449
450 api.vrf_id = VRF_DEFAULT;
451 api.type = ZEBRA_ROUTE_OSPF6;
452 api.instance = 0;
453 api.flags = 0;
454 api.message = 0;
455 api.safi = SAFI_UNICAST;
456 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
457 api.nexthop_num = nhcount;
458 api.nexthop = nexthops;
459 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
460 api.ifindex_num = nhcount;
461 api.ifindex = ifindexes;
462 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
463 api.metric = (request->path.metric_type == 2 ?
464 request->path.u.cost_e2 : request->path.cost);
465 if (request->path.tag)
466 {
467 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
468 api.tag = request->path.tag;
469 }
470
471 dest = (struct prefix_ipv6 *) &request->prefix;
472
473 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
474 api.distance = ospf6_distance_apply (dest, request);
475
476 if (type == REM)
477 ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
478 else
479 ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
480
481 if (ret < 0)
482 zlog_err ("zapi_ipv6_route() %s failed: %s",
483 (type == REM ? "delete" : "add"), safe_strerror (errno));
484
485 XFREE (MTYPE_OSPF6_OTHER, nexthops);
486 XFREE (MTYPE_OSPF6_OTHER, ifindexes);
487
488 return;
489 }
490
491 void
492 ospf6_zebra_route_update_add (struct ospf6_route *request)
493 {
494 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
495 VRF_DEFAULT))
496 {
497 ospf6->route_table->hook_add = NULL;
498 ospf6->route_table->hook_remove = NULL;
499 return;
500 }
501 ospf6_zebra_route_update (ADD, request);
502 }
503
504 void
505 ospf6_zebra_route_update_remove (struct ospf6_route *request)
506 {
507 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
508 VRF_DEFAULT))
509 {
510 ospf6->route_table->hook_add = NULL;
511 ospf6->route_table->hook_remove = NULL;
512 return;
513 }
514 ospf6_zebra_route_update (REM, request);
515 }
516
517 void
518 ospf6_zebra_add_discard (struct ospf6_route *request)
519 {
520 struct zapi_ipv6 api;
521 char buf[INET6_ADDRSTRLEN];
522 struct prefix_ipv6 *dest;
523
524 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
525 VRF_DEFAULT))
526 {
527 if (!CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
528 {
529 api.vrf_id = VRF_DEFAULT;
530 api.type = ZEBRA_ROUTE_OSPF6;
531 api.flags = ZEBRA_FLAG_BLACKHOLE;
532 api.instance = 0;
533 api.message = 0;
534 api.safi = SAFI_UNICAST;
535 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
536 api.nexthop_num = 0;
537 api.ifindex_num = 0;
538
539 dest = (struct prefix_ipv6 *) &request->prefix;
540
541 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
542
543 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
544 zlog_debug ("Zebra: Route add discard %s/%d",
545 inet_ntop (AF_INET6, &dest->prefix,
546 buf, INET6_ADDRSTRLEN),
547 dest->prefixlen);
548 SET_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
549 }
550 else
551 {
552 dest = (struct prefix_ipv6 *) &request->prefix;
553
554 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
555 zlog_debug ("Zebra: Blackhole route present already %s/%d",
556 inet_ntop (AF_INET6, &dest->prefix,
557 buf, INET6_ADDRSTRLEN),
558 dest->prefixlen);
559 }
560 }
561 }
562
563 void
564 ospf6_zebra_delete_discard (struct ospf6_route *request)
565 {
566 struct zapi_ipv6 api;
567 char buf[INET6_ADDRSTRLEN];
568 struct prefix_ipv6 *dest;
569
570 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
571 {
572 if (CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
573 {
574 api.vrf_id = VRF_DEFAULT;
575 api.type = ZEBRA_ROUTE_OSPF6;
576 api.flags = ZEBRA_FLAG_BLACKHOLE;
577 api.instance = 0;
578 api.message = 0;
579 api.safi = SAFI_UNICAST;
580 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
581 api.nexthop_num = 0;
582 api.ifindex_num = 0;
583
584 dest = (struct prefix_ipv6 *) &request->prefix;
585
586 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
587
588 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
589 zlog_debug ("Zebra: Route delete discard %s/%d",
590 inet_ntop (AF_INET6, &dest->prefix, buf,
591 INET6_ADDRSTRLEN), dest->prefixlen);
592 UNSET_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
593 }
594 else
595 {
596 dest = (struct prefix_ipv6 *) &request->prefix;
597 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
598 zlog_debug ("Zebra: Blackhole route already deleted %s/%d",
599 inet_ntop (AF_INET6, &dest->prefix, buf,
600 INET6_ADDRSTRLEN), dest->prefixlen);
601 }
602 }
603 }
604
605 DEFUN (redistribute_ospf6,
606 redistribute_ospf6_cmd,
607 "redistribute ospf6",
608 "Redistribute control\n"
609 "OSPF6 route\n")
610 {
611 struct ospf6_route *route;
612
613 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
614 return CMD_SUCCESS;
615
616 vrf_bitmap_set (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT);
617
618 if (ospf6 == NULL)
619 return CMD_SUCCESS;
620
621 /* send ospf6 route to zebra route table */
622 for (route = ospf6_route_head (ospf6->route_table); route;
623 route = ospf6_route_next (route))
624 ospf6_zebra_route_update_add (route);
625
626 ospf6->route_table->hook_add = ospf6_zebra_route_update_add;
627 ospf6->route_table->hook_remove = ospf6_zebra_route_update_remove;
628
629 return CMD_SUCCESS;
630 }
631
632 DEFUN (no_redistribute_ospf6,
633 no_redistribute_ospf6_cmd,
634 "no redistribute ospf6",
635 NO_STR
636 "Redistribute control\n"
637 "OSPF6 route\n")
638 {
639 struct ospf6_route *route;
640
641 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
642 return CMD_SUCCESS;
643
644 vrf_bitmap_unset (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT);
645
646 if (ospf6 == NULL)
647 return CMD_SUCCESS;
648
649 ospf6->route_table->hook_add = NULL;
650 ospf6->route_table->hook_remove = NULL;
651
652 /* withdraw ospf6 route from zebra route table */
653 for (route = ospf6_route_head (ospf6->route_table); route;
654 route = ospf6_route_next (route))
655 ospf6_zebra_route_update_remove (route);
656
657 return CMD_SUCCESS;
658 }
659
660 static struct ospf6_distance *
661 ospf6_distance_new (void)
662 {
663 return XCALLOC (MTYPE_OSPF6_DISTANCE, sizeof (struct ospf6_distance));
664 }
665
666 static void
667 ospf6_distance_free (struct ospf6_distance *odistance)
668 {
669 XFREE (MTYPE_OSPF6_DISTANCE, odistance);
670 }
671
672 int
673 ospf6_distance_set (struct vty *vty, struct ospf6 *o,
674 const char *distance_str,
675 const char *ip_str,
676 const char *access_list_str)
677 {
678 int ret;
679 struct prefix_ipv6 p;
680 u_char distance;
681 struct route_node *rn;
682 struct ospf6_distance *odistance;
683
684 ret = str2prefix_ipv6 (ip_str, &p);
685 if (ret == 0)
686 {
687 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
688 return CMD_WARNING;
689 }
690
691 distance = atoi (distance_str);
692
693 /* Get OSPF6 distance node. */
694 rn = route_node_get (o->distance_table, (struct prefix *) &p);
695 if (rn->info)
696 {
697 odistance = rn->info;
698 route_unlock_node (rn);
699 }
700 else
701 {
702 odistance = ospf6_distance_new ();
703 rn->info = odistance;
704 }
705
706 /* Set distance value. */
707 odistance->distance = distance;
708
709 /* Reset access-list configuration. */
710 if (odistance->access_list)
711 {
712 free (odistance->access_list);
713 odistance->access_list = NULL;
714 }
715 if (access_list_str)
716 odistance->access_list = strdup (access_list_str);
717
718 return CMD_SUCCESS;
719 }
720
721 int
722 ospf6_distance_unset (struct vty *vty, struct ospf6 *o,
723 const char *distance_str,
724 const char *ip_str,
725 const char *access_list_str)
726 {
727 int ret;
728 struct prefix_ipv6 p;
729 struct route_node *rn;
730 struct ospf6_distance *odistance;
731
732 ret = str2prefix_ipv6 (ip_str, &p);
733 if (ret == 0)
734 {
735 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
736 return CMD_WARNING;
737 }
738
739 rn = route_node_lookup (o->distance_table, (struct prefix *) &p);
740 if (!rn)
741 {
742 vty_out (vty, "Cant't find specified prefix%s", VTY_NEWLINE);
743 return CMD_WARNING;
744 }
745
746 odistance = rn->info;
747
748 if (odistance->access_list)
749 free (odistance->access_list);
750 ospf6_distance_free (odistance);
751
752 rn->info = NULL;
753 route_unlock_node (rn);
754 route_unlock_node (rn);
755
756 return CMD_SUCCESS;
757 }
758
759 void
760 ospf6_distance_reset (struct ospf6 *o)
761 {
762 struct route_node *rn;
763 struct ospf6_distance *odistance;
764
765 for (rn = route_top (o->distance_table); rn; rn = route_next (rn))
766 if ((odistance = rn->info) != NULL)
767 {
768 if (odistance->access_list)
769 free (odistance->access_list);
770 ospf6_distance_free (odistance);
771 rn->info = NULL;
772 route_unlock_node (rn);
773 }
774 }
775
776 u_char
777 ospf6_distance_apply (struct prefix_ipv6 *p, struct ospf6_route *or)
778 {
779 struct ospf6 *o;
780
781 o = ospf6;
782 if (o == NULL)
783 return 0;
784
785 if (o->distance_intra)
786 if (or->path.type == OSPF6_PATH_TYPE_INTRA)
787 return o->distance_intra;
788
789 if (o->distance_inter)
790 if (or->path.type == OSPF6_PATH_TYPE_INTER)
791 return o->distance_inter;
792
793 if (o->distance_external)
794 if(or->path.type == OSPF6_PATH_TYPE_EXTERNAL1
795 || or->path.type == OSPF6_PATH_TYPE_EXTERNAL2)
796 return o->distance_external;
797
798 if (o->distance_all)
799 return o->distance_all;
800
801 return 0;
802 }
803
804 static void
805 ospf6_zebra_connected (struct zclient *zclient)
806 {
807 /* Send the client registration */
808 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
809
810 zclient_send_reg_requests (zclient, VRF_DEFAULT);
811 }
812
813 void
814 ospf6_zebra_init (struct thread_master *master)
815 {
816 /* Allocate zebra structure. */
817 zclient = zclient_new(master);
818 zclient_init (zclient, ZEBRA_ROUTE_OSPF6, 0);
819 zclient->zebra_connected = ospf6_zebra_connected;
820 zclient->router_id_update = ospf6_router_id_update_zebra;
821 zclient->interface_add = ospf6_zebra_if_add;
822 zclient->interface_delete = ospf6_zebra_if_del;
823 zclient->interface_up = ospf6_zebra_if_state_update;
824 zclient->interface_down = ospf6_zebra_if_state_update;
825 zclient->interface_address_add = ospf6_zebra_if_address_update_add;
826 zclient->interface_address_delete = ospf6_zebra_if_address_update_delete;
827 zclient->redistribute_route_ipv4_add = NULL;
828 zclient->redistribute_route_ipv4_del = NULL;
829 zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6;
830 zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6;
831
832 /* redistribute connected route by default */
833 /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */
834
835 /* Install zebra node. */
836 install_node (&zebra_node, config_write_ospf6_zebra);
837
838 /* Install command element for zebra node. */
839 install_element (VIEW_NODE, &show_zebra_cmd);
840 install_default (ZEBRA_NODE);
841 install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
842 install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);
843
844 return;
845 }
846
847 /* Debug */
848
849 DEFUN (debug_ospf6_zebra_sendrecv,
850 debug_ospf6_zebra_sendrecv_cmd,
851 "debug ospf6 zebra [<send|recv>]",
852 DEBUG_STR
853 OSPF6_STR
854 "Debug connection between zebra\n"
855 "Debug Sending zebra\n"
856 "Debug Receiving zebra\n"
857 )
858 {
859 int idx_send_recv = 3;
860 unsigned char level = 0;
861
862 if (argc == 4)
863 {
864 if (strmatch(argv[idx_send_recv]->text, "send"))
865 level = OSPF6_DEBUG_ZEBRA_SEND;
866 else if (strmatch(argv[idx_send_recv]->text, "recv"))
867 level = OSPF6_DEBUG_ZEBRA_RECV;
868 }
869 else
870 level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
871
872 OSPF6_DEBUG_ZEBRA_ON (level);
873 return CMD_SUCCESS;
874 }
875
876 DEFUN (no_debug_ospf6_zebra_sendrecv,
877 no_debug_ospf6_zebra_sendrecv_cmd,
878 "no debug ospf6 zebra [<send|recv>]",
879 NO_STR
880 DEBUG_STR
881 OSPF6_STR
882 "Debug connection between zebra\n"
883 "Debug Sending zebra\n"
884 "Debug Receiving zebra\n"
885 )
886 {
887 int idx_send_recv = 4;
888 unsigned char level = 0;
889
890 if (argc == 5)
891 {
892 if (strmatch(argv[idx_send_recv]->text, "send"))
893 level = OSPF6_DEBUG_ZEBRA_SEND;
894 else if (strmatch(argv[idx_send_recv]->text, "recv"))
895 level = OSPF6_DEBUG_ZEBRA_RECV;
896 }
897 else
898 level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
899
900 OSPF6_DEBUG_ZEBRA_OFF (level);
901 return CMD_SUCCESS;
902 }
903
904
905 int
906 config_write_ospf6_debug_zebra (struct vty *vty)
907 {
908 if (IS_OSPF6_DEBUG_ZEBRA (SEND) && IS_OSPF6_DEBUG_ZEBRA (RECV))
909 vty_out (vty, "debug ospf6 zebra%s", VNL);
910 else
911 {
912 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
913 vty_out (vty, "debug ospf6 zebra send%s", VNL);
914 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
915 vty_out (vty, "debug ospf6 zebra recv%s", VNL);
916 }
917 return 0;
918 }
919
920 void
921 install_element_ospf6_debug_zebra (void)
922 {
923 install_element (ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd);
924 install_element (ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
925 install_element (CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd);
926 install_element (CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
927 }
928
929