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