]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_zebra.c
pimd: Fix indentation issue that is causing clang unhappiness
[mirror_frr.git] / ospf6d / ospf6_zebra.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 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 *
896014f4
DL
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
718e3744 19 */
20
508e53e2 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"
2376c3f2 30#include "lib/bfd.h"
718e3744 31
508e53e2 32#include "ospf6_proto.h"
33#include "ospf6_top.h"
718e3744 34#include "ospf6_interface.h"
508e53e2 35#include "ospf6_route.h"
36#include "ospf6_lsa.h"
049207c3 37#include "ospf6_lsdb.h"
718e3744 38#include "ospf6_asbr.h"
508e53e2 39#include "ospf6_zebra.h"
049207c3 40#include "ospf6d.h"
718e3744 41
baff583e
MZ
42DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance")
43
508e53e2 44unsigned char conf_debug_ospf6_zebra = 0;
718e3744 45
46/* information about zebra. */
47struct zclient *zclient = NULL;
48
18a6dce6 49struct in_addr router_id_zebra;
50
51/* Router-id update message from zebra. */
6ac29a51 52static int
18a6dce6 53ospf6_router_id_update_zebra (int command, struct zclient *zclient,
7076bb2f 54 zebra_size_t length, vrf_id_t vrf_id)
18a6dce6 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
c1ba9e8a 62 if (o == NULL)
63 return 0;
64
18a6dce6 65 if (o->router_id == 0)
66 o->router_id = (u_int32_t) router_id_zebra.s_addr;
67
68 return 0;
69}
70
718e3744 71/* redistribute function */
72void
73ospf6_zebra_redistribute (int type)
74{
7076bb2f 75 if (vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT))
718e3744 76 return;
7076bb2f
FL
77 vrf_bitmap_set (zclient->redist[AFI_IP6][type], VRF_DEFAULT);
78
718e3744 79 if (zclient->sock > 0)
7076bb2f
FL
80 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0,
81 VRF_DEFAULT);
718e3744 82}
83
84void
85ospf6_zebra_no_redistribute (int type)
86{
7076bb2f 87 if (!vrf_bitmap_check (zclient->redist[AFI_IP6][type], VRF_DEFAULT))
718e3744 88 return;
7076bb2f 89 vrf_bitmap_unset (zclient->redist[AFI_IP6][type], VRF_DEFAULT);
718e3744 90 if (zclient->sock > 0)
7076bb2f
FL
91 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type,
92 0, VRF_DEFAULT);
718e3744 93}
94
718e3744 95/* Inteface addition message from zebra. */
6ac29a51 96static int
7076bb2f
FL
97ospf6_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length,
98 vrf_id_t vrf_id)
718e3744 99{
100 struct interface *ifp;
101
7076bb2f 102 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
508e53e2 103 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
c6487d61 104 zlog_debug ("Zebra Interface add: %s index %d mtu %d",
105 ifp->name, ifp->ifindex, ifp->mtu6);
718e3744 106 ospf6_interface_if_add (ifp);
718e3744 107 return 0;
108}
109
6ac29a51 110static int
7076bb2f
FL
111ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length,
112 vrf_id_t vrf_id)
718e3744 113{
508e53e2 114 struct interface *ifp;
718e3744 115
7076bb2f 116 if (!(ifp = zebra_interface_state_read (zclient->ibuf, vrf_id)))
d2fc8896 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
508e53e2 122 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
c6487d61 123 zlog_debug ("Zebra Interface delete: %s index %d mtu %d",
124 ifp->name, ifp->ifindex, ifp->mtu6);
718e3744 125
d2fc8896 126#if 0
d9628728
CF
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. */
718e3744 130 ospf6_interface_if_del (ifp);
508e53e2 131#endif /*0*/
d2fc8896 132
84361d61 133 ifp->ifindex = IFINDEX_DELETED;
718e3744 134 return 0;
135}
136
6ac29a51 137static int
718e3744 138ospf6_zebra_if_state_update (int command, struct zclient *zclient,
7076bb2f 139 zebra_size_t length, vrf_id_t vrf_id)
718e3744 140{
141 struct interface *ifp;
142
7076bb2f 143 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
57c4f4f4
IF
144 if (ifp == NULL)
145 return 0;
146
508e53e2 147 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
c6487d61 148 zlog_debug ("Zebra Interface state change: "
c19543b2 149 "%s index %d flags %llx metric %d mtu %d bandwidth %d",
30d20590 150 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
c19543b2 151 ifp->metric, ifp->mtu6, ifp->bandwidth);
718e3744 152
153 ospf6_interface_state_update (ifp);
154 return 0;
155}
156
6ac29a51 157static int
718e3744 158ospf6_zebra_if_address_update_add (int command, struct zclient *zclient,
7076bb2f 159 zebra_size_t length, vrf_id_t vrf_id)
718e3744 160{
161 struct connected *c;
162 char buf[128];
163
7076bb2f
FL
164 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf,
165 vrf_id);
718e3744 166 if (c == NULL)
167 return 0;
168
508e53e2 169 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
c6487d61 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);
718e3744 174
175 if (c->address->family == AF_INET6)
b13c1d92
CF
176 {
177 ospf6_interface_state_update (c->ifp);
178 ospf6_interface_connected_route_update (c->ifp);
179 }
718e3744 180 return 0;
181}
182
6ac29a51 183static int
718e3744 184ospf6_zebra_if_address_update_delete (int command, struct zclient *zclient,
7076bb2f 185 zebra_size_t length, vrf_id_t vrf_id)
718e3744 186{
187 struct connected *c;
188 char buf[128];
189
7076bb2f
FL
190 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf,
191 vrf_id);
718e3744 192 if (c == NULL)
193 return 0;
194
508e53e2 195 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
c6487d61 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);
718e3744 200
201 if (c->address->family == AF_INET6)
b13c1d92
CF
202 {
203 ospf6_interface_connected_route_update (c->ifp);
204 ospf6_interface_state_update (c->ifp);
205 }
718e3744 206
3f6d6a5d
DS
207 connected_free (c);
208
718e3744 209 return 0;
210}
211
6ac29a51 212static int
718e3744 213ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
7076bb2f 214 zebra_size_t length, vrf_id_t vrf_id)
718e3744 215{
216 struct stream *s;
217 struct zapi_ipv6 api;
218 unsigned long ifindex;
b95e5c8c 219 struct prefix p, src_p;
718e3744 220 struct in6_addr *nexthop;
718e3744 221
87bb7354
DS
222 if (ospf6 == NULL)
223 return 0;
224
718e3744 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);
7c8ff89e 232 api.instance = stream_getw (s);
0fc452dc 233 api.flags = stream_getl (s);
718e3744 234 api.message = stream_getc (s);
235
236 /* IPv6 prefix. */
b95e5c8c 237 memset (&p, 0, sizeof (struct prefix));
718e3744 238 p.family = AF_INET6;
d9178828 239 p.prefixlen = MIN(IPV6_MAX_PREFIXLEN, stream_getc (s));
b95e5c8c 240 stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen));
718e3744 241
b95e5c8c 242 memset (&src_p, 0, sizeof (struct prefix));
81a164e2
CF
243 src_p.family = AF_INET6;
244 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX))
245 {
246 src_p.prefixlen = stream_getc (s);
b95e5c8c 247 stream_get (&src_p.u.prefix6, s, PSIZE (src_p.prefixlen));
81a164e2
CF
248 }
249
250 if (src_p.prefixlen)
251 /* we completely ignore srcdest routes for now. */
252 return 0;
253
718e3744 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
464015fa
CF
276 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG))
277 api.tag = stream_getl (s);
278 else
279 api.tag = 0;
280
508e53e2 281 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
718e3744 282 {
4690c7d7 283 char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128];
718e3744 284 prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
508e53e2 285 if (nexthop)
286 inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr));
718e3744 287 else
508e53e2 288 snprintf (nexthopstr, sizeof (nexthopstr), "::");
289
464015fa 290 zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %"ROUTE_TAG_PRI,
09b3c328 291 (command == ZEBRA_REDISTRIBUTE_IPV6_ADD ? "add" : "delete"),
464015fa 292 zebra_route_string(api.type), prefixstr, nexthopstr, ifindex, api.tag);
718e3744 293 }
294
5048fe14 295 if (command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
b95e5c8c 296 ospf6_asbr_redistribute_add (api.type, ifindex, &p,
464015fa 297 api.nexthop_num, nexthop, api.tag);
718e3744 298 else
b95e5c8c 299 ospf6_asbr_redistribute_remove (api.type, ifindex, &p);
718e3744 300
301 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
302 free (nexthop);
303
304 return 0;
305}
306
508e53e2 307
308
6b0655a2 309
718e3744 310DEFUN (show_zebra,
311 show_zebra_cmd,
312 "show zebra",
313 SHOW_STR
314 "Zebra information\n")
315{
316 int i;
508e53e2 317 if (zclient == NULL)
318 {
049207c3 319 vty_out (vty, "Not connected to zebra%s", VNL);
508e53e2 320 return CMD_SUCCESS;
321 }
718e3744 322
049207c3 323 vty_out (vty, "Zebra Infomation%s", VNL);
508e53e2 324 vty_out (vty, " enable: %d fail: %d%s",
049207c3 325 zclient->enable, zclient->fail, VNL);
7076bb2f
FL
326 vty_out (vty, " redistribute default: %d%s",
327 vrf_bitmap_check (zclient->default_information, VRF_DEFAULT),
049207c3 328 VNL);
508e53e2 329 vty_out (vty, " redistribute:");
718e3744 330 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
508e53e2 331 {
7076bb2f 332 if (vrf_bitmap_check (zclient->redist[AFI_IP6][i], VRF_DEFAULT))
f52d13cb 333 vty_out (vty, " %s", zebra_route_string(i));
508e53e2 334 }
049207c3 335 vty_out (vty, "%s", VNL);
718e3744 336 return CMD_SUCCESS;
337}
338
718e3744 339/* Zebra configuration write function. */
6ac29a51 340static int
508e53e2 341config_write_ospf6_zebra (struct vty *vty)
718e3744 342{
343 if (! zclient->enable)
344 {
049207c3 345 vty_out (vty, "no router zebra%s", VNL);
346 vty_out (vty, "!%s", VNL);
718e3744 347 }
7076bb2f
FL
348 else if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
349 VRF_DEFAULT))
718e3744 350 {
049207c3 351 vty_out (vty, "router zebra%s", VNL);
352 vty_out (vty, " no redistribute ospf6%s", VNL);
353 vty_out (vty, "!%s", VNL);
718e3744 354 }
355 return 0;
356}
357
358/* Zebra node structure. */
7fc626de 359static struct cmd_node zebra_node =
718e3744 360{
361 ZEBRA_NODE,
362 "%s(config-zebra)# ",
363};
364
365#define ADD 0
508e53e2 366#define REM 1
718e3744 367static void
508e53e2 368ospf6_zebra_route_update (int type, struct ospf6_route *request)
718e3744 369{
718e3744 370 struct zapi_ipv6 api;
4690c7d7 371 char buf[PREFIX2STR_BUFFER];
508e53e2 372 int nhcount;
718e3744 373 struct in6_addr **nexthops;
b892f1dd 374 ifindex_t *ifindexes;
c3c0ac83 375 int ret = 0;
508e53e2 376 struct prefix_ipv6 *dest;
718e3744 377
508e53e2 378 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
718e3744 379 {
508e53e2 380 prefix2str (&request->prefix, buf, sizeof (buf));
c6487d61 381 zlog_debug ("Send %s route: %s",
382 (type == REM ? "remove" : "add"), buf);
718e3744 383 }
384
385 if (zclient->sock < 0)
386 {
508e53e2 387 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
c6487d61 388 zlog_debug (" Not connected to Zebra");
718e3744 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 {
508e53e2 396 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
c6487d61 397 zlog_debug (" Ignore self-originated external route");
718e3744 398 return;
399 }
400
508e53e2 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))
718e3744 405 {
508e53e2 406 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
c6487d61 407 zlog_debug (" Best-path removal resulted Sencondary addition");
508e53e2 408 type = ADD;
409 request = request->next;
718e3744 410 }
411
508e53e2 412 /* Only the best path will be sent to zebra. */
413 if (! ospf6_route_is_best (request))
718e3744 414 {
508e53e2 415 /* this is not preferred best route, ignore */
416 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
c6487d61 417 zlog_debug (" Ignore non-best route");
508e53e2 418 return;
718e3744 419 }
420
c3c0ac83 421 nhcount = ospf6_route_num_nexthops (request);
508e53e2 422 if (nhcount == 0)
718e3744 423 {
508e53e2 424 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
c6487d61 425 zlog_debug (" No nexthop, ignore");
718e3744 426 return;
427 }
428
429 /* allocate memory for nexthop_list */
430 nexthops = XCALLOC (MTYPE_OSPF6_OTHER,
508e53e2 431 nhcount * sizeof (struct in6_addr *));
432 if (nexthops == NULL)
718e3744 433 {
508e53e2 434 zlog_warn ("Can't send route to zebra: malloc failed");
718e3744 435 return;
436 }
437
438 /* allocate memory for ifindex_list */
439 ifindexes = XCALLOC (MTYPE_OSPF6_OTHER,
b892f1dd 440 nhcount * sizeof (ifindex_t));
508e53e2 441 if (ifindexes == NULL)
718e3744 442 {
508e53e2 443 zlog_warn ("Can't send route to zebra: malloc failed");
718e3744 444 XFREE (MTYPE_OSPF6_OTHER, nexthops);
445 return;
446 }
447
c3c0ac83 448 ospf6_route_zebra_copy_nexthops (request, ifindexes, nexthops, nhcount);
718e3744 449
7076bb2f 450 api.vrf_id = VRF_DEFAULT;
718e3744 451 api.type = ZEBRA_ROUTE_OSPF6;
7c8ff89e 452 api.instance = 0;
718e3744 453 api.flags = 0;
454 api.message = 0;
b4e45f67 455 api.safi = SAFI_UNICAST;
718e3744 456 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
508e53e2 457 api.nexthop_num = nhcount;
718e3744 458 api.nexthop = nexthops;
508e53e2 459 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
460 api.ifindex_num = nhcount;
718e3744 461 api.ifindex = ifindexes;
508e53e2 462 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
463 api.metric = (request->path.metric_type == 2 ?
c3c0ac83 464 request->path.u.cost_e2 : request->path.cost);
464015fa
CF
465 if (request->path.tag)
466 {
467 SET_FLAG (api.message, ZAPI_MESSAGE_TAG);
468 api.tag = request->path.tag;
469 }
718e3744 470
508e53e2 471 dest = (struct prefix_ipv6 *) &request->prefix;
baff583e
MZ
472
473 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
474 api.distance = ospf6_distance_apply (dest, request);
475
508e53e2 476 if (type == REM)
d75f3b00 477 ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
718e3744 478 else
d75f3b00 479 ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
718e3744 480
481 if (ret < 0)
508e53e2 482 zlog_err ("zapi_ipv6_route() %s failed: %s",
6099b3b5 483 (type == REM ? "delete" : "add"), safe_strerror (errno));
718e3744 484
718e3744 485 XFREE (MTYPE_OSPF6_OTHER, nexthops);
486 XFREE (MTYPE_OSPF6_OTHER, ifindexes);
487
488 return;
489}
490
491void
508e53e2 492ospf6_zebra_route_update_add (struct ospf6_route *request)
718e3744 493{
7076bb2f
FL
494 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
495 VRF_DEFAULT))
718e3744 496 {
508e53e2 497 ospf6->route_table->hook_add = NULL;
498 ospf6->route_table->hook_remove = NULL;
499 return;
718e3744 500 }
508e53e2 501 ospf6_zebra_route_update (ADD, request);
718e3744 502}
503
508e53e2 504void
505ospf6_zebra_route_update_remove (struct ospf6_route *request)
718e3744 506{
7076bb2f
FL
507 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
508 VRF_DEFAULT))
718e3744 509 {
508e53e2 510 ospf6->route_table->hook_add = NULL;
511 ospf6->route_table->hook_remove = NULL;
512 return;
718e3744 513 }
508e53e2 514 ospf6_zebra_route_update (REM, request);
718e3744 515}
516
c3c0ac83
DS
517void
518ospf6_zebra_add_discard (struct ospf6_route *request)
519{
520 struct zapi_ipv6 api;
521 char buf[INET6_ADDRSTRLEN];
522 struct prefix_ipv6 *dest;
523
7076bb2f
FL
524 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6],
525 VRF_DEFAULT))
c3c0ac83
DS
526 {
527 if (!CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
528 {
1a1f4efa 529 api.vrf_id = VRF_DEFAULT;
c3c0ac83
DS
530 api.type = ZEBRA_ROUTE_OSPF6;
531 api.flags = ZEBRA_FLAG_BLACKHOLE;
7c8ff89e 532 api.instance = 0;
c3c0ac83
DS
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
d75f3b00 541 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, NULL, &api);
c3c0ac83
DS
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
563void
564ospf6_zebra_delete_discard (struct ospf6_route *request)
565{
566 struct zapi_ipv6 api;
567 char buf[INET6_ADDRSTRLEN];
568 struct prefix_ipv6 *dest;
569
7076bb2f 570 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
c3c0ac83
DS
571 {
572 if (CHECK_FLAG (request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED))
573 {
1a1f4efa 574 api.vrf_id = VRF_DEFAULT;
c3c0ac83
DS
575 api.type = ZEBRA_ROUTE_OSPF6;
576 api.flags = ZEBRA_FLAG_BLACKHOLE;
7c8ff89e 577 api.instance = 0;
c3c0ac83
DS
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
d75f3b00 586 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, NULL, &api);
c3c0ac83
DS
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
718e3744 605DEFUN (redistribute_ospf6,
606 redistribute_ospf6_cmd,
607 "redistribute ospf6",
608 "Redistribute control\n"
609 "OSPF6 route\n")
610{
508e53e2 611 struct ospf6_route *route;
612
7076bb2f 613 if (vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
508e53e2 614 return CMD_SUCCESS;
718e3744 615
7076bb2f 616 vrf_bitmap_set (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT);
718e3744 617
508e53e2 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;
718e3744 628
629 return CMD_SUCCESS;
630}
631
632DEFUN (no_redistribute_ospf6,
633 no_redistribute_ospf6_cmd,
634 "no redistribute ospf6",
635 NO_STR
636 "Redistribute control\n"
637 "OSPF6 route\n")
638{
508e53e2 639 struct ospf6_route *route;
640
7076bb2f 641 if (! vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT))
508e53e2 642 return CMD_SUCCESS;
718e3744 643
7076bb2f 644 vrf_bitmap_unset (zclient->redist[AFI_IP6][ZEBRA_ROUTE_OSPF6], VRF_DEFAULT);
718e3744 645
508e53e2 646 if (ospf6 == NULL)
718e3744 647 return CMD_SUCCESS;
648
508e53e2 649 ospf6->route_table->hook_add = NULL;
650 ospf6->route_table->hook_remove = NULL;
718e3744 651
508e53e2 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);
718e3744 656
657 return CMD_SUCCESS;
658}
659
baff583e
MZ
660static struct ospf6_distance *
661ospf6_distance_new (void)
662{
663 return XCALLOC (MTYPE_OSPF6_DISTANCE, sizeof (struct ospf6_distance));
664}
665
666static void
667ospf6_distance_free (struct ospf6_distance *odistance)
668{
669 XFREE (MTYPE_OSPF6_DISTANCE, odistance);
670}
671
672int
673ospf6_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
721int
722ospf6_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
759void
760ospf6_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
776u_char
777ospf6_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
7076bb2f
FL
804static void
805ospf6_zebra_connected (struct zclient *zclient)
806{
2376c3f2 807 /* Send the client registration */
808 bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
809
0e5223e7 810 zclient_send_reg_requests (zclient, VRF_DEFAULT);
7076bb2f
FL
811}
812
718e3744 813void
4140ca4d 814ospf6_zebra_init (struct thread_master *master)
718e3744 815{
816 /* Allocate zebra structure. */
4140ca4d 817 zclient = zclient_new(master);
7c8ff89e 818 zclient_init (zclient, ZEBRA_ROUTE_OSPF6, 0);
7076bb2f 819 zclient->zebra_connected = ospf6_zebra_connected;
18a6dce6 820 zclient->router_id_update = ospf6_router_id_update_zebra;
718e3744 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;
5048fe14 827 zclient->redistribute_route_ipv4_add = NULL;
828 zclient->redistribute_route_ipv4_del = NULL;
5048fe14 829 zclient->redistribute_route_ipv6_add = ospf6_zebra_read_ipv6;
830 zclient->redistribute_route_ipv6_del = ospf6_zebra_read_ipv6;
718e3744 831
832 /* redistribute connected route by default */
833 /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */
834
835 /* Install zebra node. */
508e53e2 836 install_node (&zebra_node, config_write_ospf6_zebra);
718e3744 837
838 /* Install command element for zebra node. */
839 install_element (VIEW_NODE, &show_zebra_cmd);
718e3744 840 install_default (ZEBRA_NODE);
841 install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
842 install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);
843
718e3744 844 return;
845}
846
508e53e2 847/* Debug */
6b0655a2 848
508e53e2 849DEFUN (debug_ospf6_zebra_sendrecv,
850 debug_ospf6_zebra_sendrecv_cmd,
1d68dbfe 851 "debug ospf6 zebra [<send|recv>]",
508e53e2 852 DEBUG_STR
853 OSPF6_STR
854 "Debug connection between zebra\n"
855 "Debug Sending zebra\n"
856 "Debug Receiving zebra\n"
857 )
858{
51c26414 859 int idx_send_recv = 3;
508e53e2 860 unsigned char level = 0;
861
1d68dbfe 862 if (argc == 4)
508e53e2 863 {
1d68dbfe 864 if (strmatch(argv[idx_send_recv]->text, "send"))
508e53e2 865 level = OSPF6_DEBUG_ZEBRA_SEND;
1d68dbfe 866 else if (strmatch(argv[idx_send_recv]->text, "recv"))
508e53e2 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
508e53e2 876DEFUN (no_debug_ospf6_zebra_sendrecv,
877 no_debug_ospf6_zebra_sendrecv_cmd,
1d68dbfe 878 "no debug ospf6 zebra [<send|recv>]",
508e53e2 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{
51c26414 887 int idx_send_recv = 4;
508e53e2 888 unsigned char level = 0;
889
1d68dbfe 890 if (argc == 5)
508e53e2 891 {
1d68dbfe 892 if (strmatch(argv[idx_send_recv]->text, "send"))
508e53e2 893 level = OSPF6_DEBUG_ZEBRA_SEND;
1d68dbfe 894 else if (strmatch(argv[idx_send_recv]->text, "recv"))
508e53e2 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
508e53e2 904
905int
906config_write_ospf6_debug_zebra (struct vty *vty)
907{
908 if (IS_OSPF6_DEBUG_ZEBRA (SEND) && IS_OSPF6_DEBUG_ZEBRA (RECV))
049207c3 909 vty_out (vty, "debug ospf6 zebra%s", VNL);
508e53e2 910 else
911 {
912 if (IS_OSPF6_DEBUG_ZEBRA (SEND))
049207c3 913 vty_out (vty, "debug ospf6 zebra send%s", VNL);
508e53e2 914 if (IS_OSPF6_DEBUG_ZEBRA (RECV))
049207c3 915 vty_out (vty, "debug ospf6 zebra recv%s", VNL);
508e53e2 916 }
917 return 0;
918}
919
718e3744 920void
6ac29a51 921install_element_ospf6_debug_zebra (void)
718e3744 922{
508e53e2 923 install_element (ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd);
924 install_element (ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
508e53e2 925 install_element (CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd);
926 install_element (CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
718e3744 927}
928
508e53e2 929