2
* Copyright (C) 2003 Yasuhiro Ohara
4
* This file is part of GNU Zebra.
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
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.
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.
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"
42
unsigned char conf_debug_ospf6_zebra = 0;
44
/* information about zebra. */
45
struct zclient *zclient = NULL;
47
struct in_addr router_id_zebra;
49
/* Router-id update message from zebra. */
51
ospf6_router_id_update_zebra (int command, struct zclient *zclient,
54
struct prefix router_id;
55
struct ospf6 *o = ospf6;
57
zebra_router_id_update_read(zclient->ibuf,&router_id);
58
router_id_zebra = router_id.u.prefix4;
63
if (o->router_id == 0)
64
o->router_id = (u_int32_t) router_id_zebra.s_addr;
69
/* redistribute function */
71
ospf6_zebra_redistribute (int type)
73
if (zclient->redist[type])
75
zclient->redist[type] = 1;
76
if (zclient->sock > 0)
77
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type);
81
ospf6_zebra_no_redistribute (int type)
83
if (! zclient->redist[type])
85
zclient->redist[type] = 0;
86
if (zclient->sock > 0)
87
zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
90
/* Inteface addition message from zebra. */
92
ospf6_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
94
struct interface *ifp;
96
ifp = zebra_interface_add_read (zclient->ibuf);
97
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
98
zlog_debug ("Zebra Interface add: %s index %d mtu %d",
99
ifp->name, ifp->ifindex, ifp->mtu6);
100
ospf6_interface_if_add (ifp);
105
ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
107
struct interface *ifp;
109
if (!(ifp = zebra_interface_state_read(zclient->ibuf)))
113
zlog_warn ("Zebra: got delete of %s, but interface is still up", ifp->name);
115
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
116
zlog_debug ("Zebra Interface delete: %s index %d mtu %d",
117
ifp->name, ifp->ifindex, ifp->mtu6);
120
/* Why is this commented out? */
121
ospf6_interface_if_del (ifp);
124
ifp->ifindex = IFINDEX_INTERNAL;
129
ospf6_zebra_if_state_update (int command, struct zclient *zclient,
132
struct interface *ifp;
134
ifp = zebra_interface_state_read (zclient->ibuf);
135
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
136
zlog_debug ("Zebra Interface state change: "
137
"%s index %d flags %ld metric %d mtu %d",
138
ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu6);
140
ospf6_interface_state_update (ifp);
145
ospf6_zebra_if_address_update_add (int command, struct zclient *zclient,
151
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf);
155
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
156
zlog_debug ("Zebra Interface address add: %s %5s %s/%d",
157
c->ifp->name, prefix_family_str (c->address),
158
inet_ntop (c->address->family, &c->address->u.prefix,
159
buf, sizeof (buf)), c->address->prefixlen);
161
if (c->address->family == AF_INET6)
162
ospf6_interface_connected_route_update (c->ifp);
168
ospf6_zebra_if_address_update_delete (int command, struct zclient *zclient,
174
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, zclient->ibuf);
178
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
179
zlog_debug ("Zebra Interface address delete: %s %5s %s/%d",
180
c->ifp->name, prefix_family_str (c->address),
181
inet_ntop (c->address->family, &c->address->u.prefix,
182
buf, sizeof (buf)), c->address->prefixlen);
184
if (c->address->family == AF_INET6)
185
ospf6_interface_connected_route_update (c->ifp);
192
const char *zebra_route_name[ZEBRA_ROUTE_MAX] =
193
{ "System", "Kernel", "Connect", "Static", "RIP", "RIPng", "OSPF",
194
"OSPF6", "ISIS", "BGP" };
196
const char *zebra_route_abname[ZEBRA_ROUTE_MAX] =
197
{ "X", "K", "C", "S", "r", "R", "o", "O", "I", "B" };
200
ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
204
struct zapi_ipv6 api;
205
unsigned long ifindex;
206
struct prefix_ipv6 p;
207
struct in6_addr *nexthop;
212
memset (&api, 0, sizeof (api));
214
/* Type, flags, message. */
215
api.type = stream_getc (s);
216
api.flags = stream_getc (s);
217
api.message = stream_getc (s);
220
memset (&p, 0, sizeof (struct prefix_ipv6));
222
p.prefixlen = stream_getc (s);
223
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
225
/* Nexthop, ifindex, distance, metric. */
226
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
228
api.nexthop_num = stream_getc (s);
229
nexthop = (struct in6_addr *)
230
malloc (api.nexthop_num * sizeof (struct in6_addr));
231
stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr));
233
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
235
api.ifindex_num = stream_getc (s);
236
ifindex = stream_getl (s);
238
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
239
api.distance = stream_getc (s);
242
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
243
api.metric = stream_getl (s);
247
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
249
char prefixstr[128], nexthopstr[128];
250
prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
252
inet_ntop (AF_INET6, nexthop, nexthopstr, sizeof (nexthopstr));
254
snprintf (nexthopstr, sizeof (nexthopstr), "::");
256
zlog_debug ("Zebra Receive route %s: %s %s nexthop %s ifindex %ld",
257
(command == ZEBRA_IPV6_ROUTE_ADD ? "add" : "delete"),
258
zebra_route_name[api.type], prefixstr, nexthopstr, ifindex);
261
if (command == ZEBRA_IPV6_ROUTE_ADD)
262
ospf6_asbr_redistribute_add (api.type, ifindex, (struct prefix *) &p,
263
api.nexthop_num, nexthop);
265
ospf6_asbr_redistribute_remove (api.type, ifindex, (struct prefix *) &p);
267
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
280
"Zebra information\n")
285
vty_out (vty, "Not connected to zebra%s", VNL);
289
vty_out (vty, "Zebra Infomation%s", VNL);
290
vty_out (vty, " enable: %d fail: %d%s",
291
zclient->enable, zclient->fail, VNL);
292
vty_out (vty, " redistribute default: %d%s", zclient->redist_default,
294
vty_out (vty, " redistribute:");
295
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
297
if (zclient->redist[i])
298
vty_out (vty, " %s", zebra_route_name[i]);
300
vty_out (vty, "%s", VNL);
307
"Enable a routing process\n"
308
"Make connection to zebra daemon\n")
310
vty->node = ZEBRA_NODE;
312
zclient_start (zclient);
316
DEFUN (no_router_zebra,
320
"Configure routing process\n"
321
"Disable connection to zebra daemon\n")
324
zclient_stop (zclient);
328
/* Zebra configuration write function. */
330
config_write_ospf6_zebra (struct vty *vty)
332
if (! zclient->enable)
334
vty_out (vty, "no router zebra%s", VNL);
335
vty_out (vty, "!%s", VNL);
337
else if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
339
vty_out (vty, "router zebra%s", VNL);
340
vty_out (vty, " no redistribute ospf6%s", VNL);
341
vty_out (vty, "!%s", VNL);
346
/* Zebra node structure. */
347
struct cmd_node zebra_node =
350
"%s(config-zebra)# ",
356
ospf6_zebra_route_update (int type, struct ospf6_route *request)
358
struct zapi_ipv6 api;
361
struct in6_addr **nexthops;
362
unsigned int *ifindexes;
364
struct prefix_ipv6 *dest;
366
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
368
prefix2str (&request->prefix, buf, sizeof (buf));
369
zlog_debug ("Send %s route: %s",
370
(type == REM ? "remove" : "add"), buf);
373
if (zclient->sock < 0)
375
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
376
zlog_debug (" Not connected to Zebra");
380
if (request->path.origin.adv_router == ospf6->router_id &&
381
(request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
382
request->path.type == OSPF6_PATH_TYPE_EXTERNAL2))
384
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
385
zlog_debug (" Ignore self-originated external route");
389
/* If removing is the best path and if there's another path,
390
treat this request as add the secondary path */
391
if (type == REM && ospf6_route_is_best (request) &&
392
request->next && ospf6_route_is_same (request, request->next))
394
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
395
zlog_debug (" Best-path removal resulted Sencondary addition");
397
request = request->next;
400
/* Only the best path will be sent to zebra. */
401
if (! ospf6_route_is_best (request))
403
/* this is not preferred best route, ignore */
404
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
405
zlog_debug (" Ignore non-best route");
410
for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
411
if (ospf6_nexthop_is_set (&request->nexthop[i]))
416
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
417
zlog_debug (" No nexthop, ignore");
421
/* allocate memory for nexthop_list */
422
nexthops = XCALLOC (MTYPE_OSPF6_OTHER,
423
nhcount * sizeof (struct in6_addr *));
424
if (nexthops == NULL)
426
zlog_warn ("Can't send route to zebra: malloc failed");
430
/* allocate memory for ifindex_list */
431
ifindexes = XCALLOC (MTYPE_OSPF6_OTHER,
432
nhcount * sizeof (unsigned int));
433
if (ifindexes == NULL)
435
zlog_warn ("Can't send route to zebra: malloc failed");
436
XFREE (MTYPE_OSPF6_OTHER, nexthops);
440
for (i = 0; i < nhcount; i++)
442
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
444
char ifname[IFNAMSIZ];
445
inet_ntop (AF_INET6, &request->nexthop[i].address,
447
if (!if_indextoname(request->nexthop[i].ifindex, ifname))
448
strlcpy(ifname, "unknown", sizeof(ifname));
449
zlog_debug (" nexthop: %s%%%.*s(%d)", buf, IFNAMSIZ, ifname,
450
request->nexthop[i].ifindex);
452
nexthops[i] = &request->nexthop[i].address;
453
ifindexes[i] = request->nexthop[i].ifindex;
456
api.type = ZEBRA_ROUTE_OSPF6;
459
SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
460
api.nexthop_num = nhcount;
461
api.nexthop = nexthops;
462
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
463
api.ifindex_num = nhcount;
464
api.ifindex = ifindexes;
465
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
466
api.metric = (request->path.metric_type == 2 ?
467
request->path.cost_e2 : request->path.cost);
469
dest = (struct prefix_ipv6 *) &request->prefix;
471
ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, &api);
473
ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, dest, &api);
476
zlog_err ("zapi_ipv6_route() %s failed: %s",
477
(type == REM ? "delete" : "add"), safe_strerror (errno));
479
XFREE (MTYPE_OSPF6_OTHER, nexthops);
480
XFREE (MTYPE_OSPF6_OTHER, ifindexes);
486
ospf6_zebra_route_update_add (struct ospf6_route *request)
488
if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
490
ospf6->route_table->hook_add = NULL;
491
ospf6->route_table->hook_remove = NULL;
494
ospf6_zebra_route_update (ADD, request);
498
ospf6_zebra_route_update_remove (struct ospf6_route *request)
500
if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
502
ospf6->route_table->hook_add = NULL;
503
ospf6->route_table->hook_remove = NULL;
506
ospf6_zebra_route_update (REM, request);
509
DEFUN (redistribute_ospf6,
510
redistribute_ospf6_cmd,
511
"redistribute ospf6",
512
"Redistribute control\n"
515
struct ospf6_route *route;
517
if (zclient->redist[ZEBRA_ROUTE_OSPF6])
520
zclient->redist[ZEBRA_ROUTE_OSPF6] = 1;
525
/* send ospf6 route to zebra route table */
526
for (route = ospf6_route_head (ospf6->route_table); route;
527
route = ospf6_route_next (route))
528
ospf6_zebra_route_update_add (route);
530
ospf6->route_table->hook_add = ospf6_zebra_route_update_add;
531
ospf6->route_table->hook_remove = ospf6_zebra_route_update_remove;
536
DEFUN (no_redistribute_ospf6,
537
no_redistribute_ospf6_cmd,
538
"no redistribute ospf6",
540
"Redistribute control\n"
543
struct ospf6_route *route;
545
if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
548
zclient->redist[ZEBRA_ROUTE_OSPF6] = 0;
553
ospf6->route_table->hook_add = NULL;
554
ospf6->route_table->hook_remove = NULL;
556
/* withdraw ospf6 route from zebra route table */
557
for (route = ospf6_route_head (ospf6->route_table); route;
558
route = ospf6_route_next (route))
559
ospf6_zebra_route_update_remove (route);
567
/* Allocate zebra structure. */
568
zclient = zclient_new ();
569
zclient_init (zclient, ZEBRA_ROUTE_OSPF6);
570
zclient->router_id_update = ospf6_router_id_update_zebra;
571
zclient->interface_add = ospf6_zebra_if_add;
572
zclient->interface_delete = ospf6_zebra_if_del;
573
zclient->interface_up = ospf6_zebra_if_state_update;
574
zclient->interface_down = ospf6_zebra_if_state_update;
575
zclient->interface_address_add = ospf6_zebra_if_address_update_add;
576
zclient->interface_address_delete = ospf6_zebra_if_address_update_delete;
577
zclient->ipv4_route_add = NULL;
578
zclient->ipv4_route_delete = NULL;
579
zclient->ipv6_route_add = ospf6_zebra_read_ipv6;
580
zclient->ipv6_route_delete = ospf6_zebra_read_ipv6;
582
/* redistribute connected route by default */
583
/* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */
585
/* Install zebra node. */
586
install_node (&zebra_node, config_write_ospf6_zebra);
588
/* Install command element for zebra node. */
589
install_element (VIEW_NODE, &show_zebra_cmd);
590
install_element (ENABLE_NODE, &show_zebra_cmd);
591
install_element (CONFIG_NODE, &router_zebra_cmd);
592
install_element (CONFIG_NODE, &no_router_zebra_cmd);
594
install_default (ZEBRA_NODE);
595
install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
596
install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);
603
DEFUN (debug_ospf6_zebra_sendrecv,
604
debug_ospf6_zebra_sendrecv_cmd,
605
"debug ospf6 zebra (send|recv)",
608
"Debug connection between zebra\n"
609
"Debug Sending zebra\n"
610
"Debug Receiving zebra\n"
613
unsigned char level = 0;
617
if (! strncmp (argv[0], "s", 1))
618
level = OSPF6_DEBUG_ZEBRA_SEND;
619
else if (! strncmp (argv[0], "r", 1))
620
level = OSPF6_DEBUG_ZEBRA_RECV;
623
level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
625
OSPF6_DEBUG_ZEBRA_ON (level);
629
ALIAS (debug_ospf6_zebra_sendrecv,
630
debug_ospf6_zebra_cmd,
634
"Debug connection between zebra\n"
638
DEFUN (no_debug_ospf6_zebra_sendrecv,
639
no_debug_ospf6_zebra_sendrecv_cmd,
640
"no debug ospf6 zebra (send|recv)",
644
"Debug connection between zebra\n"
645
"Debug Sending zebra\n"
646
"Debug Receiving zebra\n"
649
unsigned char level = 0;
653
if (! strncmp (argv[0], "s", 1))
654
level = OSPF6_DEBUG_ZEBRA_SEND;
655
else if (! strncmp (argv[0], "r", 1))
656
level = OSPF6_DEBUG_ZEBRA_RECV;
659
level = OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV;
661
OSPF6_DEBUG_ZEBRA_OFF (level);
665
ALIAS (no_debug_ospf6_zebra_sendrecv,
666
no_debug_ospf6_zebra_cmd,
667
"no debug ospf6 zebra",
671
"Debug connection between zebra\n"
675
config_write_ospf6_debug_zebra (struct vty *vty)
677
if (IS_OSPF6_DEBUG_ZEBRA (SEND) && IS_OSPF6_DEBUG_ZEBRA (RECV))
678
vty_out (vty, "debug ospf6 zebra%s", VNL);
681
if (IS_OSPF6_DEBUG_ZEBRA (SEND))
682
vty_out (vty, "debug ospf6 zebra send%s", VNL);
683
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
684
vty_out (vty, "debug ospf6 zebra recv%s", VNL);
690
install_element_ospf6_debug_zebra ()
692
install_element (ENABLE_NODE, &debug_ospf6_zebra_cmd);
693
install_element (ENABLE_NODE, &no_debug_ospf6_zebra_cmd);
694
install_element (ENABLE_NODE, &debug_ospf6_zebra_sendrecv_cmd);
695
install_element (ENABLE_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);
696
install_element (CONFIG_NODE, &debug_ospf6_zebra_cmd);
697
install_element (CONFIG_NODE, &no_debug_ospf6_zebra_cmd);
698
install_element (CONFIG_NODE, &debug_ospf6_zebra_sendrecv_cmd);
699
install_element (CONFIG_NODE, &no_debug_ospf6_zebra_sendrecv_cmd);