]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_zebra.c
isisd: add support to import routes from other protocols
[mirror_frr.git] / isisd / isis_zebra.c
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 * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public Licenseas published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #include <zebra.h>
25
26 #include "thread.h"
27 #include "command.h"
28 #include "memory.h"
29 #include "log.h"
30 #include "if.h"
31 #include "network.h"
32 #include "prefix.h"
33 #include "zclient.h"
34 #include "stream.h"
35 #include "linklist.h"
36 #include "nexthop.h"
37 #include "vrf.h"
38
39 #include "isisd/dict.h"
40 #include "isisd/isis_constants.h"
41 #include "isisd/isis_common.h"
42 #include "isisd/isis_flags.h"
43 #include "isisd/isis_misc.h"
44 #include "isisd/isis_circuit.h"
45 #include "isisd/isis_tlv.h"
46 #include "isisd/isisd.h"
47 #include "isisd/isis_circuit.h"
48 #include "isisd/isis_csm.h"
49 #include "isisd/isis_lsp.h"
50 #include "isisd/isis_route.h"
51 #include "isisd/isis_zebra.h"
52
53 struct zclient *zclient = NULL;
54
55 /* Router-id update message from zebra. */
56 static int
57 isis_router_id_update_zebra (int command, struct zclient *zclient,
58 zebra_size_t length, vrf_id_t vrf_id)
59 {
60 struct isis_area *area;
61 struct listnode *node;
62 struct prefix router_id;
63
64 zebra_router_id_update_read (zclient->ibuf, &router_id);
65 if (isis->router_id == router_id.u.prefix4.s_addr)
66 return 0;
67
68 isis->router_id = router_id.u.prefix4.s_addr;
69 for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
70 if (listcount (area->area_addrs) > 0)
71 lsp_regenerate_schedule (area, area->is_type, 0);
72
73 return 0;
74 }
75
76 static int
77 isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length,
78 vrf_id_t vrf_id)
79 {
80 struct interface *ifp;
81
82 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
83
84 if (isis->debugs & DEBUG_ZEBRA)
85 zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
86 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
87
88 if (if_is_operative (ifp))
89 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
90
91 return 0;
92 }
93
94 static int
95 isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length,
96 vrf_id_t vrf_id)
97 {
98 struct interface *ifp;
99 struct stream *s;
100
101 s = zclient->ibuf;
102 ifp = zebra_interface_state_read (s, vrf_id);
103
104 if (!ifp)
105 return 0;
106
107 if (if_is_operative (ifp))
108 zlog_warn ("Zebra: got delete of %s, but interface is still up",
109 ifp->name);
110
111 if (isis->debugs & DEBUG_ZEBRA)
112 zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
113 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
114
115 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
116
117 /* Cannot call if_delete because we should retain the pseudo interface
118 in case there is configuration info attached to it. */
119 if_delete_retain(ifp);
120
121 ifp->ifindex = IFINDEX_DELETED;
122
123 return 0;
124 }
125
126 static int
127 isis_zebra_if_state_up (int command, struct zclient *zclient,
128 zebra_size_t length, vrf_id_t vrf_id)
129 {
130 struct interface *ifp;
131
132 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
133
134 if (ifp == NULL)
135 return 0;
136
137 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
138
139 return 0;
140 }
141
142 static int
143 isis_zebra_if_state_down (int command, struct zclient *zclient,
144 zebra_size_t length, vrf_id_t vrf_id)
145 {
146 struct interface *ifp;
147 struct isis_circuit *circuit;
148
149 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
150
151 if (ifp == NULL)
152 return 0;
153
154 circuit = isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp),
155 ifp);
156 if (circuit)
157 SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
158
159 return 0;
160 }
161
162 static int
163 isis_zebra_if_address_add (int command, struct zclient *zclient,
164 zebra_size_t length, vrf_id_t vrf_id)
165 {
166 struct connected *c;
167 struct prefix *p;
168 char buf[PREFIX2STR_BUFFER];
169
170 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
171 zclient->ibuf, vrf_id);
172
173 if (c == NULL)
174 return 0;
175
176 p = c->address;
177
178 prefix2str (p, buf, sizeof (buf));
179 #ifdef EXTREME_DEBUG
180 if (p->family == AF_INET)
181 zlog_debug ("connected IP address %s", buf);
182 #ifdef HAVE_IPV6
183 if (p->family == AF_INET6)
184 zlog_debug ("connected IPv6 address %s", buf);
185 #endif /* HAVE_IPV6 */
186 #endif /* EXTREME_DEBUG */
187 if (if_is_operative (c->ifp))
188 isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
189
190 return 0;
191 }
192
193 static int
194 isis_zebra_if_address_del (int command, struct zclient *client,
195 zebra_size_t length, vrf_id_t vrf_id)
196 {
197 struct connected *c;
198 struct interface *ifp;
199 #ifdef EXTREME_DEBUG
200 struct prefix *p;
201 char buf[PREFIX2STR_BUFFER];
202 #endif /* EXTREME_DEBUG */
203
204 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
205 zclient->ibuf, vrf_id);
206
207 if (c == NULL)
208 return 0;
209
210 ifp = c->ifp;
211
212 #ifdef EXTREME_DEBUG
213 p = c->address;
214 prefix2str (p, buf, sizeof (buf));
215
216 if (p->family == AF_INET)
217 zlog_debug ("disconnected IP address %s", buf);
218 #ifdef HAVE_IPV6
219 if (p->family == AF_INET6)
220 zlog_debug ("disconnected IPv6 address %s", buf);
221 #endif /* HAVE_IPV6 */
222 #endif /* EXTREME_DEBUG */
223
224 if (if_is_operative (ifp))
225 isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
226 connected_free (c);
227
228 return 0;
229 }
230
231 static void
232 isis_zebra_route_add_ipv4 (struct prefix *prefix,
233 struct isis_route_info *route_info)
234 {
235 u_char message, flags;
236 int psize;
237 struct stream *stream;
238 struct isis_nexthop *nexthop;
239 struct listnode *node;
240
241 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
242 return;
243
244 if (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
245 {
246 message = 0;
247 flags = 0;
248
249 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
250 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
251 #if 0
252 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
253 #endif
254
255 stream = zclient->obuf;
256 stream_reset (stream);
257 zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
258 /* type */
259 stream_putc (stream, ZEBRA_ROUTE_ISIS);
260 /* instance */
261 stream_putw (stream, 0);
262 /* flags */
263 stream_putc (stream, flags);
264 /* message */
265 stream_putc (stream, message);
266 /* SAFI */
267 stream_putw (stream, SAFI_UNICAST);
268 /* prefix information */
269 psize = PSIZE (prefix->prefixlen);
270 stream_putc (stream, prefix->prefixlen);
271 stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
272
273 stream_putc (stream, listcount (route_info->nexthops));
274
275 /* Nexthop, ifindex, distance and metric information */
276 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
277 {
278 /* FIXME: can it be ? */
279 if (nexthop->ip.s_addr != INADDR_ANY)
280 {
281 stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
282 stream_put_in_addr (stream, &nexthop->ip);
283 }
284 else
285 {
286 stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
287 stream_putl (stream, nexthop->ifindex);
288 }
289 }
290 #if 0
291 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
292 stream_putc (stream, route_info->depth);
293 #endif
294 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
295 stream_putl (stream, route_info->cost);
296
297 stream_putw_at (stream, 0, stream_get_endp (stream));
298 zclient_send_message(zclient);
299 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
300 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
301 }
302 }
303
304 static void
305 isis_zebra_route_del_ipv4 (struct prefix *prefix,
306 struct isis_route_info *route_info)
307 {
308 struct zapi_ipv4 api;
309 struct prefix_ipv4 prefix4;
310
311 if (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
312 {
313 api.vrf_id = VRF_DEFAULT;
314 api.type = ZEBRA_ROUTE_ISIS;
315 api.instance = 0;
316 api.flags = 0;
317 api.message = 0;
318 api.safi = SAFI_UNICAST;
319 prefix4.family = AF_INET;
320 prefix4.prefixlen = prefix->prefixlen;
321 prefix4.prefix = prefix->u.prefix4;
322 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
323 }
324 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
325
326 return;
327 }
328
329 #ifdef HAVE_IPV6
330 static void
331 isis_zebra_route_add_ipv6 (struct prefix *prefix,
332 struct isis_route_info *route_info)
333 {
334 struct zapi_ipv6 api;
335 struct in6_addr **nexthop_list;
336 unsigned int *ifindex_list;
337 struct isis_nexthop6 *nexthop6;
338 int i, size;
339 struct listnode *node;
340 struct prefix_ipv6 prefix6;
341
342 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
343 return;
344
345 api.vrf_id = VRF_DEFAULT;
346 api.type = ZEBRA_ROUTE_ISIS;
347 api.instance = 0;
348 api.flags = 0;
349 api.message = 0;
350 api.safi = SAFI_UNICAST;
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);
361
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);
365 if (!nexthop_list)
366 {
367 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
368 return;
369 }
370
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);
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
381 /* for each nexthop */
382 i = 0;
383 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
384 {
385 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
386 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
387 {
388 api.nexthop_num--;
389 api.ifindex_num--;
390 continue;
391 }
392
393 nexthop_list[i] = &nexthop6->ip6;
394 ifindex_list[i] = nexthop6->ifindex;
395 i++;
396 }
397
398 api.nexthop = nexthop_list;
399 api.ifindex = ifindex_list;
400
401 if (api.nexthop_num && api.ifindex_num)
402 {
403 prefix6.family = AF_INET6;
404 prefix6.prefixlen = prefix->prefixlen;
405 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
406 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
407 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
408 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
409 }
410
411 XFREE (MTYPE_ISIS_TMP, nexthop_list);
412 XFREE (MTYPE_ISIS_TMP, ifindex_list);
413
414 return;
415 }
416
417 static void
418 isis_zebra_route_del_ipv6 (struct prefix *prefix,
419 struct isis_route_info *route_info)
420 {
421 struct zapi_ipv6 api;
422 struct in6_addr **nexthop_list;
423 unsigned int *ifindex_list;
424 struct isis_nexthop6 *nexthop6;
425 int i, size;
426 struct listnode *node;
427 struct prefix_ipv6 prefix6;
428
429 if (!CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
430 return;
431
432 api.vrf_id = VRF_DEFAULT;
433 api.type = ZEBRA_ROUTE_ISIS;
434 api.instance = 0;
435 api.flags = 0;
436 api.message = 0;
437 api.safi = SAFI_UNICAST;
438 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
439 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
440 api.nexthop_num = listcount (route_info->nexthops6);
441 api.ifindex_num = listcount (route_info->nexthops6);
442
443 /* allocate memory for nexthop_list */
444 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
445 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
446 if (!nexthop_list)
447 {
448 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
449 return;
450 }
451
452 /* allocate memory for ifindex_list */
453 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
454 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
455 if (!ifindex_list)
456 {
457 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
458 XFREE (MTYPE_ISIS_TMP, nexthop_list);
459 return;
460 }
461
462 /* for each nexthop */
463 i = 0;
464 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
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++;
477 }
478
479 api.nexthop = nexthop_list;
480 api.ifindex = ifindex_list;
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_SYNCED);
489 }
490
491 XFREE (MTYPE_ISIS_TMP, nexthop_list);
492 XFREE (MTYPE_ISIS_TMP, ifindex_list);
493 }
494
495 #endif /* HAVE_IPV6 */
496
497 void
498 isis_zebra_route_update (struct prefix *prefix,
499 struct isis_route_info *route_info)
500 {
501 if (zclient->sock < 0)
502 return;
503
504 if ((prefix->family == AF_INET && !vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) ||
505 (prefix->family == AF_INET6 && !vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_ISIS], VRF_DEFAULT)))
506 return;
507
508 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
509 {
510 if (prefix->family == AF_INET)
511 isis_zebra_route_add_ipv4 (prefix, route_info);
512 #ifdef HAVE_IPV6
513 else if (prefix->family == AF_INET6)
514 isis_zebra_route_add_ipv6 (prefix, route_info);
515 #endif /* HAVE_IPV6 */
516 }
517 else
518 {
519 if (prefix->family == AF_INET)
520 isis_zebra_route_del_ipv4 (prefix, route_info);
521 #ifdef HAVE_IPV6
522 else if (prefix->family == AF_INET6)
523 isis_zebra_route_del_ipv6 (prefix, route_info);
524 #endif /* HAVE_IPV6 */
525 }
526 return;
527 }
528
529 static int
530 isis_zebra_read_ipv4 (int command, struct zclient *zclient,
531 zebra_size_t length, vrf_id_t vrf_id)
532 {
533 struct stream *stream;
534 struct zapi_ipv4 api;
535 struct prefix_ipv4 p;
536 struct prefix *p_generic = (struct prefix*)&p;
537
538 stream = zclient->ibuf;
539 memset(&api, 0, sizeof(api));
540 memset (&p, 0, sizeof (struct prefix_ipv4));
541
542 api.type = stream_getc (stream);
543 api.instance = stream_getw (stream);
544 api.flags = stream_getc (stream);
545 api.message = stream_getc (stream);
546
547 p.family = AF_INET;
548 p.prefixlen = stream_getc (stream);
549 stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
550
551 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
552 {
553 api.nexthop_num = stream_getc (stream);
554 (void)stream_get_ipv4 (stream);
555 }
556 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
557 {
558 api.ifindex_num = stream_getc (stream);
559 stream_getl (stream);
560 }
561 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
562 api.distance = stream_getc (stream);
563 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
564 api.metric = stream_getl (stream);
565
566 /*
567 * Avoid advertising a false default reachability. (A default
568 * route installed by IS-IS gets redistributed from zebra back
569 * into IS-IS causing us to start advertising default reachabity
570 * without this check)
571 */
572 if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
573 command = ZEBRA_IPV4_ROUTE_DELETE;
574
575 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
576 isis_redist_add(api.type, p_generic, api.distance, api.metric);
577 else
578 isis_redist_delete(api.type, p_generic);
579
580 return 0;
581 }
582
583 static int
584 isis_zebra_read_ipv6 (int command, struct zclient *zclient,
585 zebra_size_t length, vrf_id_t vrf_id)
586 {
587 struct stream *stream;
588 struct zapi_ipv6 api;
589 struct prefix_ipv6 p;
590 struct prefix *p_generic = (struct prefix*)&p;
591 struct in6_addr nexthop;
592 unsigned long ifindex __attribute__((unused));
593
594 stream = zclient->ibuf;
595 memset(&api, 0, sizeof(api));
596 memset(&p, 0, sizeof(struct prefix_ipv6));
597 memset(&nexthop, 0, sizeof(nexthop));
598 ifindex = 0;
599
600 api.type = stream_getc(stream);
601 api.flags = stream_getc(stream);
602 api.message = stream_getc(stream);
603
604 p.family = AF_INET6;
605 p.prefixlen = stream_getc(stream);
606 stream_get(&p.prefix, stream, PSIZE(p.prefixlen));
607
608 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP))
609 {
610 api.nexthop_num = stream_getc(stream); /* this is always 1 */
611 stream_get(&nexthop, stream, sizeof(nexthop));
612 }
613 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX))
614 {
615 api.ifindex_num = stream_getc(stream);
616 ifindex = stream_getl(stream);
617 }
618 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
619 api.distance = stream_getc(stream);
620 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
621 api.metric = stream_getl(stream);
622
623 /*
624 * Avoid advertising a false default reachability. (A default
625 * route installed by IS-IS gets redistributed from zebra back
626 * into IS-IS causing us to start advertising default reachabity
627 * without this check)
628 */
629 if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
630 command = ZEBRA_IPV6_ROUTE_DELETE;
631
632 if (command == ZEBRA_IPV6_ROUTE_ADD)
633 isis_redist_add(api.type, p_generic, api.distance, api.metric);
634 else
635 isis_redist_delete(api.type, p_generic);
636
637 return 0;
638 }
639
640 int
641 isis_distribute_list_update (int routetype)
642 {
643 return 0;
644 }
645
646 void
647 isis_zebra_redistribute_set(int type)
648 {
649 if (type == DEFAULT_ROUTE)
650 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, VRF_DEFAULT);
651 else
652 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0, VRF_DEFAULT);
653 }
654
655 void
656 isis_zebra_redistribute_unset(int type)
657 {
658 if (type == DEFAULT_ROUTE)
659 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, VRF_DEFAULT);
660 else
661 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
662 }
663
664 static void
665 isis_zebra_connected (struct zclient *zclient)
666 {
667 zclient_send_reg_requests (zclient, VRF_DEFAULT);
668 }
669
670 void
671 isis_zebra_init (struct thread_master *master)
672 {
673 zclient = zclient_new (master);
674 zclient_init (zclient, ZEBRA_ROUTE_ISIS, 0);
675 zclient->zebra_connected = isis_zebra_connected;
676 zclient->router_id_update = isis_router_id_update_zebra;
677 zclient->interface_add = isis_zebra_if_add;
678 zclient->interface_delete = isis_zebra_if_del;
679 zclient->interface_up = isis_zebra_if_state_up;
680 zclient->interface_down = isis_zebra_if_state_down;
681 zclient->interface_address_add = isis_zebra_if_address_add;
682 zclient->interface_address_delete = isis_zebra_if_address_del;
683 zclient->ipv4_route_add = isis_zebra_read_ipv4;
684 zclient->ipv4_route_delete = isis_zebra_read_ipv4;
685 zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4;
686 zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4;
687 #ifdef HAVE_IPV6
688 zclient->ipv6_route_add = isis_zebra_read_ipv6;
689 zclient->ipv6_route_delete = isis_zebra_read_ipv6;
690 zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6;
691 zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6;
692 #endif /* HAVE_IPV6 */
693
694 return;
695 }