]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_zebra.c
Add user `frr` into group `frrvty`
[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 #include "isisd/isis_te.h"
53
54 struct zclient *zclient = NULL;
55
56 /* Router-id update message from zebra. */
57 static int
58 isis_router_id_update_zebra (int command, struct zclient *zclient,
59 zebra_size_t length, vrf_id_t vrf_id)
60 {
61 struct isis_area *area;
62 struct listnode *node;
63 struct prefix router_id;
64
65 /*
66 * If ISIS TE is enable, TE Router ID is set through specific command.
67 * See mpls_te_router_addr() command in isis_te.c
68 */
69 if (IS_MPLS_TE(isisMplsTE))
70 return 0;
71
72 zebra_router_id_update_read (zclient->ibuf, &router_id);
73 if (isis->router_id == router_id.u.prefix4.s_addr)
74 return 0;
75
76 isis->router_id = router_id.u.prefix4.s_addr;
77 for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
78 if (listcount (area->area_addrs) > 0)
79 lsp_regenerate_schedule (area, area->is_type, 0);
80
81 return 0;
82 }
83
84 static int
85 isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length,
86 vrf_id_t vrf_id)
87 {
88 struct interface *ifp;
89
90 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
91
92 if (isis->debugs & DEBUG_ZEBRA)
93 zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
94 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
95
96 if (if_is_operative (ifp))
97 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
98
99 return 0;
100 }
101
102 static int
103 isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length,
104 vrf_id_t vrf_id)
105 {
106 struct interface *ifp;
107 struct stream *s;
108
109 s = zclient->ibuf;
110 ifp = zebra_interface_state_read (s, vrf_id);
111
112 if (!ifp)
113 return 0;
114
115 if (if_is_operative (ifp))
116 zlog_warn ("Zebra: got delete of %s, but interface is still up",
117 ifp->name);
118
119 if (isis->debugs & DEBUG_ZEBRA)
120 zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
121 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
122
123 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
124
125 /* Cannot call if_delete because we should retain the pseudo interface
126 in case there is configuration info attached to it. */
127 if_delete_retain(ifp);
128
129 ifp->ifindex = IFINDEX_DELETED;
130
131 return 0;
132 }
133
134 static int
135 isis_zebra_if_state_up (int command, struct zclient *zclient,
136 zebra_size_t length, vrf_id_t vrf_id)
137 {
138 struct interface *ifp;
139
140 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
141
142 if (ifp == NULL)
143 return 0;
144
145 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
146
147 return 0;
148 }
149
150 static int
151 isis_zebra_if_state_down (int command, struct zclient *zclient,
152 zebra_size_t length, vrf_id_t vrf_id)
153 {
154 struct interface *ifp;
155 struct isis_circuit *circuit;
156
157 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
158
159 if (ifp == NULL)
160 return 0;
161
162 circuit = isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp),
163 ifp);
164 if (circuit)
165 SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
166
167 return 0;
168 }
169
170 static int
171 isis_zebra_if_address_add (int command, struct zclient *zclient,
172 zebra_size_t length, vrf_id_t vrf_id)
173 {
174 struct connected *c;
175 struct prefix *p;
176 char buf[PREFIX2STR_BUFFER];
177
178 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
179 zclient->ibuf, vrf_id);
180
181 if (c == NULL)
182 return 0;
183
184 p = c->address;
185
186 prefix2str (p, buf, sizeof (buf));
187 #ifdef EXTREME_DEBUG
188 if (p->family == AF_INET)
189 zlog_debug ("connected IP address %s", buf);
190 #ifdef HAVE_IPV6
191 if (p->family == AF_INET6)
192 zlog_debug ("connected IPv6 address %s", buf);
193 #endif /* HAVE_IPV6 */
194 #endif /* EXTREME_DEBUG */
195 if (if_is_operative (c->ifp))
196 isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
197
198 return 0;
199 }
200
201 static int
202 isis_zebra_if_address_del (int command, struct zclient *client,
203 zebra_size_t length, vrf_id_t vrf_id)
204 {
205 struct connected *c;
206 struct interface *ifp;
207 #ifdef EXTREME_DEBUG
208 struct prefix *p;
209 char buf[PREFIX2STR_BUFFER];
210 #endif /* EXTREME_DEBUG */
211
212 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
213 zclient->ibuf, vrf_id);
214
215 if (c == NULL)
216 return 0;
217
218 ifp = c->ifp;
219
220 #ifdef EXTREME_DEBUG
221 p = c->address;
222 prefix2str (p, buf, sizeof (buf));
223
224 if (p->family == AF_INET)
225 zlog_debug ("disconnected IP address %s", buf);
226 #ifdef HAVE_IPV6
227 if (p->family == AF_INET6)
228 zlog_debug ("disconnected IPv6 address %s", buf);
229 #endif /* HAVE_IPV6 */
230 #endif /* EXTREME_DEBUG */
231
232 if (if_is_operative (ifp))
233 isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
234 connected_free (c);
235
236 return 0;
237 }
238
239 static int
240 isis_zebra_link_params (int command, struct zclient *zclient,
241 zebra_size_t length)
242 {
243 struct interface *ifp;
244
245 ifp = zebra_interface_link_params_read (zclient->ibuf);
246
247 if (ifp == NULL)
248 return 0;
249
250 /* Update TE TLV */
251 isis_mpls_te_update(ifp);
252
253 return 0;
254 }
255
256 static void
257 isis_zebra_route_add_ipv4 (struct prefix *prefix,
258 struct isis_route_info *route_info)
259 {
260 u_char message;
261 u_int32_t flags;
262 int psize;
263 struct stream *stream;
264 struct isis_nexthop *nexthop;
265 struct listnode *node;
266
267 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
268 return;
269
270 if (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
271 {
272 message = 0;
273 flags = 0;
274
275 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
276 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
277 #if 0
278 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
279 #endif
280
281 stream = zclient->obuf;
282 stream_reset (stream);
283 zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
284 /* type */
285 stream_putc (stream, ZEBRA_ROUTE_ISIS);
286 /* instance */
287 stream_putw (stream, 0);
288 /* flags */
289 stream_putl (stream, flags);
290 /* message */
291 stream_putc (stream, message);
292 /* SAFI */
293 stream_putw (stream, SAFI_UNICAST);
294 /* prefix information */
295 psize = PSIZE (prefix->prefixlen);
296 stream_putc (stream, prefix->prefixlen);
297 stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
298
299 stream_putc (stream, listcount (route_info->nexthops));
300
301 /* Nexthop, ifindex, distance and metric information */
302 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
303 {
304 /* FIXME: can it be ? */
305 if (nexthop->ip.s_addr != INADDR_ANY)
306 {
307 stream_putc (stream, NEXTHOP_TYPE_IPV4);
308 stream_put_in_addr (stream, &nexthop->ip);
309 }
310 else
311 {
312 stream_putc (stream, NEXTHOP_TYPE_IFINDEX);
313 stream_putl (stream, nexthop->ifindex);
314 }
315 }
316 #if 0
317 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
318 stream_putc (stream, route_info->depth);
319 #endif
320 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
321 stream_putl (stream, route_info->cost);
322
323 stream_putw_at (stream, 0, stream_get_endp (stream));
324 zclient_send_message(zclient);
325 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
326 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
327 }
328 }
329
330 static void
331 isis_zebra_route_del_ipv4 (struct prefix *prefix,
332 struct isis_route_info *route_info)
333 {
334 struct zapi_ipv4 api;
335 struct prefix_ipv4 prefix4;
336
337 if (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
338 {
339 api.vrf_id = VRF_DEFAULT;
340 api.type = ZEBRA_ROUTE_ISIS;
341 api.instance = 0;
342 api.flags = 0;
343 api.message = 0;
344 api.safi = SAFI_UNICAST;
345 prefix4.family = AF_INET;
346 prefix4.prefixlen = prefix->prefixlen;
347 prefix4.prefix = prefix->u.prefix4;
348 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
349 }
350 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
351
352 return;
353 }
354
355 #ifdef HAVE_IPV6
356 static void
357 isis_zebra_route_add_ipv6 (struct prefix *prefix,
358 struct isis_route_info *route_info)
359 {
360 struct zapi_ipv6 api;
361 struct in6_addr **nexthop_list;
362 ifindex_t *ifindex_list;
363 struct isis_nexthop6 *nexthop6;
364 int i, size;
365 struct listnode *node;
366 struct prefix_ipv6 prefix6;
367
368 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
369 return;
370
371 api.vrf_id = VRF_DEFAULT;
372 api.type = ZEBRA_ROUTE_ISIS;
373 api.instance = 0;
374 api.flags = 0;
375 api.message = 0;
376 api.safi = SAFI_UNICAST;
377 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
378 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
379 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
380 api.metric = route_info->cost;
381 #if 0
382 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
383 api.distance = route_info->depth;
384 #endif
385 api.nexthop_num = listcount (route_info->nexthops6);
386 api.ifindex_num = listcount (route_info->nexthops6);
387
388 /* allocate memory for nexthop_list */
389 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
390 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
391 if (!nexthop_list)
392 {
393 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
394 return;
395 }
396
397 /* allocate memory for ifindex_list */
398 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
399 ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
400 if (!ifindex_list)
401 {
402 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
403 XFREE (MTYPE_ISIS_TMP, nexthop_list);
404 return;
405 }
406
407 /* for each nexthop */
408 i = 0;
409 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
410 {
411 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
412 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
413 {
414 api.nexthop_num--;
415 api.ifindex_num--;
416 continue;
417 }
418
419 nexthop_list[i] = &nexthop6->ip6;
420 ifindex_list[i] = nexthop6->ifindex;
421 i++;
422 }
423
424 api.nexthop = nexthop_list;
425 api.ifindex = ifindex_list;
426
427 if (api.nexthop_num && api.ifindex_num)
428 {
429 prefix6.family = AF_INET6;
430 prefix6.prefixlen = prefix->prefixlen;
431 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
432 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
433 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
434 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
435 }
436
437 XFREE (MTYPE_ISIS_TMP, nexthop_list);
438 XFREE (MTYPE_ISIS_TMP, ifindex_list);
439
440 return;
441 }
442
443 static void
444 isis_zebra_route_del_ipv6 (struct prefix *prefix,
445 struct isis_route_info *route_info)
446 {
447 struct zapi_ipv6 api;
448 struct in6_addr **nexthop_list;
449 ifindex_t *ifindex_list;
450 struct isis_nexthop6 *nexthop6;
451 int i, size;
452 struct listnode *node;
453 struct prefix_ipv6 prefix6;
454
455 if (!CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
456 return;
457
458 api.vrf_id = VRF_DEFAULT;
459 api.type = ZEBRA_ROUTE_ISIS;
460 api.instance = 0;
461 api.flags = 0;
462 api.message = 0;
463 api.safi = SAFI_UNICAST;
464 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
465 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
466 api.nexthop_num = listcount (route_info->nexthops6);
467 api.ifindex_num = listcount (route_info->nexthops6);
468
469 /* allocate memory for nexthop_list */
470 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
471 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
472 if (!nexthop_list)
473 {
474 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
475 return;
476 }
477
478 /* allocate memory for ifindex_list */
479 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
480 ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
481 if (!ifindex_list)
482 {
483 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
484 XFREE (MTYPE_ISIS_TMP, nexthop_list);
485 return;
486 }
487
488 /* for each nexthop */
489 i = 0;
490 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
491 {
492 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
493 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
494 {
495 api.nexthop_num--;
496 api.ifindex_num--;
497 continue;
498 }
499
500 nexthop_list[i] = &nexthop6->ip6;
501 ifindex_list[i] = nexthop6->ifindex;
502 i++;
503 }
504
505 api.nexthop = nexthop_list;
506 api.ifindex = ifindex_list;
507
508 if (api.nexthop_num && api.ifindex_num)
509 {
510 prefix6.family = AF_INET6;
511 prefix6.prefixlen = prefix->prefixlen;
512 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
513 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
514 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
515 }
516
517 XFREE (MTYPE_ISIS_TMP, nexthop_list);
518 XFREE (MTYPE_ISIS_TMP, ifindex_list);
519 }
520
521 #endif /* HAVE_IPV6 */
522
523 void
524 isis_zebra_route_update (struct prefix *prefix,
525 struct isis_route_info *route_info)
526 {
527 if (zclient->sock < 0)
528 return;
529
530 if ((prefix->family == AF_INET && !vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) ||
531 (prefix->family == AF_INET6 && !vrf_bitmap_check (zclient->redist[AFI_IP6][ZEBRA_ROUTE_ISIS], VRF_DEFAULT)))
532 return;
533
534 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
535 {
536 if (prefix->family == AF_INET)
537 isis_zebra_route_add_ipv4 (prefix, route_info);
538 #ifdef HAVE_IPV6
539 else if (prefix->family == AF_INET6)
540 isis_zebra_route_add_ipv6 (prefix, route_info);
541 #endif /* HAVE_IPV6 */
542 }
543 else
544 {
545 if (prefix->family == AF_INET)
546 isis_zebra_route_del_ipv4 (prefix, route_info);
547 #ifdef HAVE_IPV6
548 else if (prefix->family == AF_INET6)
549 isis_zebra_route_del_ipv6 (prefix, route_info);
550 #endif /* HAVE_IPV6 */
551 }
552 return;
553 }
554
555 static int
556 isis_zebra_read_ipv4 (int command, struct zclient *zclient,
557 zebra_size_t length, vrf_id_t vrf_id)
558 {
559 struct stream *stream;
560 struct zapi_ipv4 api;
561 struct prefix_ipv4 p;
562 struct prefix *p_generic = (struct prefix*)&p;
563
564 stream = zclient->ibuf;
565 memset(&api, 0, sizeof(api));
566 memset (&p, 0, sizeof (struct prefix_ipv4));
567
568 api.type = stream_getc (stream);
569 api.instance = stream_getw (stream);
570 api.flags = stream_getl (stream);
571 api.message = stream_getc (stream);
572
573 p.family = AF_INET;
574 p.prefixlen = MIN(IPV4_MAX_PREFIXLEN, stream_getc (stream));
575 stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
576
577 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
578 {
579 api.nexthop_num = stream_getc (stream);
580 (void)stream_get_ipv4 (stream);
581 }
582 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
583 {
584 api.ifindex_num = stream_getc (stream);
585 stream_getl (stream);
586 }
587 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
588 api.distance = stream_getc (stream);
589 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
590 api.metric = stream_getl (stream);
591
592 /*
593 * Avoid advertising a false default reachability. (A default
594 * route installed by IS-IS gets redistributed from zebra back
595 * into IS-IS causing us to start advertising default reachabity
596 * without this check)
597 */
598 if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
599 command = ZEBRA_IPV4_ROUTE_DELETE;
600
601 if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD)
602 isis_redist_add(api.type, p_generic, api.distance, api.metric);
603 else
604 isis_redist_delete(api.type, p_generic);
605
606 return 0;
607 }
608
609 static int
610 isis_zebra_read_ipv6 (int command, struct zclient *zclient,
611 zebra_size_t length, vrf_id_t vrf_id)
612 {
613 struct stream *stream;
614 struct zapi_ipv6 api;
615 struct prefix_ipv6 p;
616 struct prefix *p_generic = (struct prefix*)&p;
617 struct in6_addr nexthop;
618 unsigned long ifindex __attribute__((unused));
619
620 stream = zclient->ibuf;
621 memset(&api, 0, sizeof(api));
622 memset(&p, 0, sizeof(struct prefix_ipv6));
623 memset(&nexthop, 0, sizeof(nexthop));
624 ifindex = 0;
625
626 api.type = stream_getc(stream);
627 api.flags = stream_getl(stream);
628 api.message = stream_getc(stream);
629
630 p.family = AF_INET6;
631 p.prefixlen = stream_getc(stream);
632 stream_get(&p.prefix, stream, PSIZE(p.prefixlen));
633
634 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP))
635 {
636 api.nexthop_num = stream_getc(stream); /* this is always 1 */
637 stream_get(&nexthop, stream, sizeof(nexthop));
638 }
639 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX))
640 {
641 api.ifindex_num = stream_getc(stream);
642 ifindex = stream_getl(stream);
643 }
644 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
645 api.distance = stream_getc(stream);
646 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
647 api.metric = stream_getl(stream);
648
649 /*
650 * Avoid advertising a false default reachability. (A default
651 * route installed by IS-IS gets redistributed from zebra back
652 * into IS-IS causing us to start advertising default reachabity
653 * without this check)
654 */
655 if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
656 command = ZEBRA_IPV6_ROUTE_DELETE;
657
658 if (command == ZEBRA_IPV6_ROUTE_ADD)
659 isis_redist_add(api.type, p_generic, api.distance, api.metric);
660 else
661 isis_redist_delete(api.type, p_generic);
662
663 return 0;
664 }
665
666 int
667 isis_distribute_list_update (int routetype)
668 {
669 return 0;
670 }
671
672 void
673 isis_zebra_redistribute_set(int type)
674 {
675 if (type == DEFAULT_ROUTE)
676 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, VRF_DEFAULT);
677 else
678 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0, VRF_DEFAULT);
679 }
680
681 void
682 isis_zebra_redistribute_unset(int type)
683 {
684 if (type == DEFAULT_ROUTE)
685 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, VRF_DEFAULT);
686 else
687 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
688 }
689
690 static void
691 isis_zebra_connected (struct zclient *zclient)
692 {
693 zclient_send_reg_requests (zclient, VRF_DEFAULT);
694 }
695
696 void
697 isis_zebra_init (struct thread_master *master)
698 {
699 zclient = zclient_new (master);
700 zclient_init (zclient, ZEBRA_ROUTE_ISIS, 0);
701 zclient->zebra_connected = isis_zebra_connected;
702 zclient->router_id_update = isis_router_id_update_zebra;
703 zclient->interface_add = isis_zebra_if_add;
704 zclient->interface_delete = isis_zebra_if_del;
705 zclient->interface_up = isis_zebra_if_state_up;
706 zclient->interface_down = isis_zebra_if_state_down;
707 zclient->interface_address_add = isis_zebra_if_address_add;
708 zclient->interface_address_delete = isis_zebra_if_address_del;
709 zclient->interface_link_params = isis_zebra_link_params;
710 zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4;
711 zclient->redistribute_route_ipv4_del = isis_zebra_read_ipv4;
712 #ifdef HAVE_IPV6
713 zclient->redistribute_route_ipv6_add = isis_zebra_read_ipv6;
714 zclient->redistribute_route_ipv6_del = isis_zebra_read_ipv6;
715 #endif /* HAVE_IPV6 */
716
717 return;
718 }