]> git.proxmox.com Git - mirror_frr.git/blame - isisd/isis_zebra.c
2005-04-02 Paul Jakma <paul@dishone.st>
[mirror_frr.git] / isisd / isis_zebra.c
CommitLineData
eb5d44eb 1/*
2 * IS-IS Rout(e)ing protocol - isis_zebra.c
3 *
4 * Copyright (C) 2001,2002 Sampo Saaristo
5 * Tampere University of Technology
6 * Institute of Communications Engineering
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public Licenseas published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#include <zebra.h>
eb5d44eb 24
25#include "thread.h"
26#include "command.h"
27#include "memory.h"
28#include "log.h"
29#include "if.h"
30#include "network.h"
31#include "prefix.h"
32#include "zclient.h"
33#include "stream.h"
34#include "linklist.h"
35
36#include "isisd/isis_constants.h"
37#include "isisd/isis_common.h"
38#include "isisd/isis_circuit.h"
39#include "isisd/isis_csm.h"
40#include "isisd/isis_route.h"
41#include "isisd/isis_zebra.h"
42
43struct zclient *zclient = NULL;
44
45extern struct thread_master *master;
18a6dce6 46struct in_addr router_id_zebra;
47
48/* Router-id update message from zebra. */
92365889 49static int
18a6dce6 50isis_router_id_update_zebra (int command, struct zclient *zclient,
51 zebra_size_t length)
52{
53 struct prefix router_id;
18a6dce6 54
55 zebra_router_id_update_read (zclient->ibuf,&router_id);
56 router_id_zebra = router_id.u.prefix4;
57
58 /* FIXME: Do we react somehow? */
59 return 0;
60}
eb5d44eb 61
92365889 62static int
eb5d44eb 63isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
64{
65 struct interface *ifp;
66
67 ifp = zebra_interface_add_read (zclient->ibuf);
f390d2c7 68
eb5d44eb 69
529d65b3 70 zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
71 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
f390d2c7 72
b30c5e67 73 if (if_is_operative (ifp))
eb5d44eb 74 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
f390d2c7 75
eb5d44eb 76 return 0;
77}
78
92365889 79static int
eb5d44eb 80isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
81{
82 struct interface *ifp;
83 struct stream *s;
84
85 s = zclient->ibuf;
86 ifp = zebra_interface_state_read (s);
f390d2c7 87
eb5d44eb 88 if (!ifp)
89 return 0;
90
b30c5e67 91 if (if_is_operative (ifp))
eb5d44eb 92 zlog_warn ("Zebra: got delete of %s, but interface is still up",
f390d2c7 93 ifp->name);
eb5d44eb 94
529d65b3 95 zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
96 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
eb5d44eb 97
98 if_delete (ifp);
f390d2c7 99
eb5d44eb 100 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
101
102 return 0;
103}
104
92365889 105static struct interface *
eb5d44eb 106zebra_interface_if_lookup (struct stream *s)
107{
108 struct interface *ifp;
109 u_char ifname_tmp[INTERFACE_NAMSIZ];
110
111 /* Read interface name. */
112 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
113
114 /* Lookup this by interface index. */
f7c43dcb 115 ifp = if_lookup_by_name ((char *) ifname_tmp);
eb5d44eb 116
117 /* If such interface does not exist, indicate an error */
118 if (!ifp)
119 return NULL;
120
121 return ifp;
122}
123
92365889 124static int
f390d2c7 125isis_zebra_if_state_up (int command, struct zclient *zclient,
eb5d44eb 126 zebra_size_t length)
127{
128 struct interface *ifp;
f390d2c7 129
eb5d44eb 130 ifp = zebra_interface_if_lookup (zclient->ibuf);
f390d2c7 131
eb5d44eb 132 if (!ifp)
133 return 0;
f390d2c7 134
b30c5e67 135 if (if_is_operative (ifp))
f390d2c7 136 {
137 zebra_interface_if_set_value (zclient->ibuf, ifp);
4660687a 138 /* HT: This is wrong actually. We can't assume that circuit exist
139 * if we delete circuit during if_state_down event. Needs rethink.
140 * TODO */
f390d2c7 141 isis_circuit_update_params (circuit_scan_by_ifp (ifp), ifp);
142 return 0;
143 }
144
eb5d44eb 145 zebra_interface_if_set_value (zclient->ibuf, ifp);
146 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
f390d2c7 147
eb5d44eb 148 return 0;
149}
150
92365889 151static int
f390d2c7 152isis_zebra_if_state_down (int command, struct zclient *zclient,
eb5d44eb 153 zebra_size_t length)
154{
155 struct interface *ifp;
f390d2c7 156
eb5d44eb 157 ifp = zebra_interface_if_lookup (zclient->ibuf);
f390d2c7 158
eb5d44eb 159 if (ifp == NULL)
160 return 0;
f390d2c7 161
b30c5e67 162 if (if_is_operative (ifp))
f390d2c7 163 {
164 zebra_interface_if_set_value (zclient->ibuf, ifp);
165 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
166 }
167
eb5d44eb 168 return 0;
169}
170
92365889 171static int
f390d2c7 172isis_zebra_if_address_add (int command, struct zclient *zclient,
173 zebra_size_t length)
eb5d44eb 174{
175 struct connected *c;
176 struct prefix *p;
f7c43dcb 177 char buf[BUFSIZ];
eb5d44eb 178
f390d2c7 179 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
180 zclient->ibuf);
181
eb5d44eb 182 if (c == NULL)
183 return 0;
f390d2c7 184
eb5d44eb 185 p = c->address;
f390d2c7 186
eb5d44eb 187 prefix2str (p, buf, BUFSIZ);
188#ifdef EXTREME_DEBUG
f390d2c7 189 if (p->family == AF_INET)
529d65b3 190 zlog_debug ("connected IP address %s", buf);
eb5d44eb 191#ifdef HAVE_IPV6
192 if (p->family == AF_INET6)
529d65b3 193 zlog_debug ("connected IPv6 address %s", buf);
eb5d44eb 194#endif /* HAVE_IPV6 */
195#endif /* EXTREME_DEBUG */
b30c5e67 196 if (if_is_operative (c->ifp))
197 isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
eb5d44eb 198
199 return 0;
200}
201
92365889 202static int
f390d2c7 203isis_zebra_if_address_del (int command, struct zclient *client,
204 zebra_size_t length)
eb5d44eb 205{
206 struct connected *c;
207 struct interface *ifp;
1cd80845 208#ifdef EXTREME_DEBUG
f891f443 209 struct prefix *p;
210 u_char buf[BUFSIZ];
1cd80845 211#endif /* EXTREME_DEBUG */
eb5d44eb 212
f390d2c7 213 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
214 zclient->ibuf);
215
eb5d44eb 216 if (c == NULL)
217 return 0;
f390d2c7 218
eb5d44eb 219 ifp = c->ifp;
f390d2c7 220
f891f443 221#ifdef EXTREME_DEBUG
222 p = c->address;
223 prefix2str (p, buf, BUFSIZ);
224
225 if (p->family == AF_INET)
529d65b3 226 zlog_debug ("disconnected IP address %s", buf);
f891f443 227#ifdef HAVE_IPV6
228 if (p->family == AF_INET6)
529d65b3 229 zlog_debug ("disconnected IPv6 address %s", buf);
f891f443 230#endif /* HAVE_IPV6 */
231#endif /* EXTREME_DEBUG */
f390d2c7 232
b30c5e67 233 if (if_is_operative (ifp))
234 isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
f891f443 235 connected_free (c);
f390d2c7 236
eb5d44eb 237 return 0;
238}
239
92365889 240static void
f390d2c7 241isis_zebra_route_add_ipv4 (struct prefix *prefix,
242 struct isis_route_info *route_info)
eb5d44eb 243{
244 u_char message, flags;
245 int psize;
246 struct stream *stream;
247 struct isis_nexthop *nexthop;
248 struct listnode *node;
249
250 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
251 return;
252
f390d2c7 253 if (zclient->redist[ZEBRA_ROUTE_ISIS])
254 {
255 message = 0;
256 flags = 0;
257
258 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
259 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
2097cd8a 260#if 0
f390d2c7 261 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
2097cd8a 262#endif
f390d2c7 263
264 stream = zclient->obuf;
265 stream_reset (stream);
266 /* Length place holder. */
267 stream_putw (stream, 0);
268 /* command */
269 stream_putc (stream, ZEBRA_IPV4_ROUTE_ADD);
270 /* type */
271 stream_putc (stream, ZEBRA_ROUTE_ISIS);
272 /* flags */
273 stream_putc (stream, flags);
274 /* message */
275 stream_putc (stream, message);
276 /* prefix information */
277 psize = PSIZE (prefix->prefixlen);
278 stream_putc (stream, prefix->prefixlen);
279 stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
280
281 stream_putc (stream, listcount (route_info->nexthops));
282
283 /* Nexthop, ifindex, distance and metric information */
284 for (node = listhead (route_info->nexthops); node; nextnode (node))
285 {
286 nexthop = getdata (node);
287 /* FIXME: can it be ? */
288 if (nexthop->ip.s_addr != INADDR_ANY)
289 {
290 stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
291 stream_put_in_addr (stream, &nexthop->ip);
292 }
293 else
294 {
295 stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
296 stream_putl (stream, nexthop->ifindex);
297 }
298 }
2097cd8a 299#if 0
f390d2c7 300 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
301 stream_putc (stream, route_info->depth);
2097cd8a 302#endif
f390d2c7 303 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
304 stream_putl (stream, route_info->cost);
305
306 stream_putw_at (stream, 0, stream_get_endp (stream));
307 writen (zclient->sock, stream->data, stream_get_endp (stream));
308 }
eb5d44eb 309}
310
92365889 311static void
f390d2c7 312isis_zebra_route_del_ipv4 (struct prefix *prefix,
313 struct isis_route_info *route_info)
eb5d44eb 314{
315 struct zapi_ipv4 api;
316 struct prefix_ipv4 prefix4;
f390d2c7 317
318 if (zclient->redist[ZEBRA_ROUTE_ISIS])
319 {
320 api.type = ZEBRA_ROUTE_ISIS;
321 api.flags = 0;
322 api.message = 0;
323 prefix4.family = AF_INET;
324 prefix4.prefixlen = prefix->prefixlen;
325 prefix4.prefix = prefix->u.prefix4;
326 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
327 }
328
eb5d44eb 329 return;
330}
331
332#ifdef HAVE_IPV6
333void
334isis_zebra_route_add_ipv6 (struct prefix *prefix,
f390d2c7 335 struct isis_route_info *route_info)
eb5d44eb 336{
337 struct zapi_ipv6 api;
338 struct in6_addr **nexthop_list;
339 unsigned int *ifindex_list;
340 struct isis_nexthop6 *nexthop6;
341 int i, size;
342 struct listnode *node;
343 struct prefix_ipv6 prefix6;
344
345 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
346 return;
f390d2c7 347
eb5d44eb 348 api.type = ZEBRA_ROUTE_ISIS;
349 api.flags = 0;
350 api.message = 0;
351 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
352 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
353 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
354 api.metric = route_info->cost;
355#if 0
356 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
357 api.distance = route_info->depth;
358#endif
359 api.nexthop_num = listcount (route_info->nexthops6);
360 api.ifindex_num = listcount (route_info->nexthops6);
f390d2c7 361
eb5d44eb 362 /* allocate memory for nexthop_list */
363 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
364 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
f390d2c7 365 if (!nexthop_list)
366 {
367 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
368 return;
369 }
370
eb5d44eb 371 /* allocate memory for ifindex_list */
372 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
373 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
f390d2c7 374 if (!ifindex_list)
375 {
376 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
377 XFREE (MTYPE_ISIS_TMP, nexthop_list);
378 return;
379 }
380
eb5d44eb 381 /* for each nexthop */
382 i = 0;
f390d2c7 383 for (node = listhead (route_info->nexthops6); node; nextnode (node))
384 {
385 nexthop6 = getdata (node);
386
387 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
388 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
389 {
390 api.nexthop_num--;
391 api.ifindex_num--;
392 continue;
393 }
394
395 nexthop_list[i] = &nexthop6->ip6;
396 ifindex_list[i] = nexthop6->ifindex;
397 i++;
eb5d44eb 398 }
f390d2c7 399
eb5d44eb 400 api.nexthop = nexthop_list;
401 api.ifindex = ifindex_list;
f390d2c7 402
403 if (api.nexthop_num && api.ifindex_num)
404 {
405 prefix6.family = AF_INET6;
406 prefix6.prefixlen = prefix->prefixlen;
407 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
408 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
409 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
410 }
411
eb5d44eb 412 XFREE (MTYPE_ISIS_TMP, nexthop_list);
413 XFREE (MTYPE_ISIS_TMP, ifindex_list);
f390d2c7 414
eb5d44eb 415 return;
416}
417
92365889 418static void
f390d2c7 419isis_zebra_route_del_ipv6 (struct prefix *prefix,
420 struct isis_route_info *route_info)
eb5d44eb 421{
422 struct zapi_ipv6 api;
423 struct in6_addr **nexthop_list;
424 unsigned int *ifindex_list;
425 struct isis_nexthop6 *nexthop6;
426 int i, size;
427 struct listnode *node;
428 struct prefix_ipv6 prefix6;
429
430 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
431 return;
f390d2c7 432
eb5d44eb 433 api.type = ZEBRA_ROUTE_ISIS;
434 api.flags = 0;
435 api.message = 0;
436 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
437 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
438 api.nexthop_num = listcount (route_info->nexthops6);
439 api.ifindex_num = listcount (route_info->nexthops6);
f390d2c7 440
eb5d44eb 441 /* allocate memory for nexthop_list */
442 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
443 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
f390d2c7 444 if (!nexthop_list)
445 {
446 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
447 return;
448 }
449
eb5d44eb 450 /* allocate memory for ifindex_list */
451 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
452 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
f390d2c7 453 if (!ifindex_list)
454 {
455 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
456 XFREE (MTYPE_ISIS_TMP, nexthop_list);
457 return;
458 }
459
eb5d44eb 460 /* for each nexthop */
461 i = 0;
f390d2c7 462 for (node = listhead (route_info->nexthops6); node; nextnode (node))
463 {
464 nexthop6 = getdata (node);
465
466 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
467 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
468 {
469 api.nexthop_num--;
470 api.ifindex_num--;
471 continue;
472 }
473
474 nexthop_list[i] = &nexthop6->ip6;
475 ifindex_list[i] = nexthop6->ifindex;
476 i++;
eb5d44eb 477 }
f390d2c7 478
eb5d44eb 479 api.nexthop = nexthop_list;
480 api.ifindex = ifindex_list;
f390d2c7 481
482 if (api.nexthop_num && api.ifindex_num)
483 {
484 prefix6.family = AF_INET6;
485 prefix6.prefixlen = prefix->prefixlen;
486 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
487 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
488 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
489 }
490
eb5d44eb 491 XFREE (MTYPE_ISIS_TMP, nexthop_list);
f390d2c7 492 XFREE (MTYPE_ISIS_TMP, ifindex_list);
eb5d44eb 493}
494
eb5d44eb 495#endif /* HAVE_IPV6 */
496
eb5d44eb 497void
498isis_zebra_route_update (struct prefix *prefix,
f390d2c7 499 struct isis_route_info *route_info)
eb5d44eb 500{
501 if (zclient->sock < 0)
502 return;
503
504 if (!zclient->redist[ZEBRA_ROUTE_ISIS])
505 return;
506
f390d2c7 507 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
508 {
509 if (prefix->family == AF_INET)
510 isis_zebra_route_add_ipv4 (prefix, route_info);
eb5d44eb 511#ifdef HAVE_IPV6
f390d2c7 512 else if (prefix->family == AF_INET6)
513 isis_zebra_route_add_ipv6 (prefix, route_info);
eb5d44eb 514#endif /* HAVE_IPV6 */
f390d2c7 515 }
516 else
517 {
518 if (prefix->family == AF_INET)
519 isis_zebra_route_del_ipv4 (prefix, route_info);
eb5d44eb 520#ifdef HAVE_IPV6
f390d2c7 521 else if (prefix->family == AF_INET6)
522 isis_zebra_route_del_ipv6 (prefix, route_info);
eb5d44eb 523#endif /* HAVE_IPV6 */
f390d2c7 524 }
eb5d44eb 525 return;
526}
527
92365889 528static int
f390d2c7 529isis_zebra_read_ipv4 (int command, struct zclient *zclient,
eb5d44eb 530 zebra_size_t length)
531{
532 struct stream *stream;
533 struct zapi_ipv4 api;
534 struct prefix_ipv4 p;
535 unsigned long ifindex;
536 struct in_addr nexthop;
537
538 stream = zclient->ibuf;
539 memset (&p, 0, sizeof (struct prefix_ipv4));
540 ifindex = 0;
541
f390d2c7 542 api.type = stream_getc (stream);
543 api.flags = stream_getc (stream);
eb5d44eb 544 api.message = stream_getc (stream);
545
546 p.family = AF_INET;
547 p.prefixlen = stream_getc (stream);
548 stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
f390d2c7 549
550 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
551 {
eb5d44eb 552 api.nexthop_num = stream_getc (stream);
553 nexthop.s_addr = stream_get_ipv4 (stream);
f390d2c7 554 }
555 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
556 {
557 api.ifindex_num = stream_getc (stream);
558 ifindex = stream_getl (stream);
559 }
eb5d44eb 560 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
561 api.distance = stream_getc (stream);
562 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
563 api.metric = stream_getl (stream);
564 else
565 api.metric = 0;
f390d2c7 566
567 if (command == ZEBRA_IPV4_ROUTE_ADD)
568 {
529d65b3 569 zlog_debug ("IPv4 Route add from Z");
f390d2c7 570 }
eb5d44eb 571
572 return 0;
573}
574
92365889 575static int
f390d2c7 576isis_zebra_read_ipv6 (int command, struct zclient *zclient,
eb5d44eb 577 zebra_size_t length)
578{
eb5d44eb 579 return 0;
580}
581
582#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
583T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
584
585int
586isis_distribute_list_update (int routetype)
587{
588 return 0;
589}
590
92365889 591#if 0 /* Not yet. */
592static int
f390d2c7 593isis_redistribute_default_set (int routetype, int metric_type,
594 int metric_value)
eb5d44eb 595{
596 return 0;
597}
92365889 598#endif /* 0 */
eb5d44eb 599
eb5d44eb 600void
601isis_zebra_init ()
602{
eb5d44eb 603 zclient = zclient_new ();
604 zclient_init (zclient, ZEBRA_ROUTE_ISIS);
18a6dce6 605 zclient->router_id_update = isis_router_id_update_zebra;
eb5d44eb 606 zclient->interface_add = isis_zebra_if_add;
607 zclient->interface_delete = isis_zebra_if_del;
608 zclient->interface_up = isis_zebra_if_state_up;
609 zclient->interface_down = isis_zebra_if_state_down;
610 zclient->interface_address_add = isis_zebra_if_address_add;
611 zclient->interface_address_delete = isis_zebra_if_address_del;
612 zclient->ipv4_route_add = isis_zebra_read_ipv4;
613 zclient->ipv4_route_delete = isis_zebra_read_ipv4;
614#ifdef HAVE_IPV6
615 zclient->ipv6_route_add = isis_zebra_read_ipv6;
616 zclient->ipv6_route_delete = isis_zebra_read_ipv6;
617#endif /* HAVE_IPV6 */
618
619 return;
620}
621
622void
623isis_zebra_finish ()
624{
eb5d44eb 625 zclient_stop (zclient);
626 zclient_free (zclient);
627 zclient = (struct zclient *) NULL;
628
629 return;
630}