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