blob: 40743b295c6a1222dbe83fe1fdab2cfebd133532 [file] [log] [blame]
jardineb5d44e2003-12-23 08:09:43 +00001/*
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>
jardineb5d44e2003-12-23 08:09:43 +000024
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;
hasso18a6dce2004-10-03 18:18:34 +000046struct in_addr router_id_zebra;
47
48/* Router-id update message from zebra. */
hasso92365882005-01-18 13:53:33 +000049static int
hasso18a6dce2004-10-03 18:18:34 +000050isis_router_id_update_zebra (int command, struct zclient *zclient,
51 zebra_size_t length)
52{
53 struct prefix router_id;
hasso18a6dce2004-10-03 18:18:34 +000054
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}
jardineb5d44e2003-12-23 08:09:43 +000061
hasso92365882005-01-18 13:53:33 +000062static int
jardineb5d44e2003-12-23 08:09:43 +000063isis_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);
hassof390d2c2004-09-10 20:48:21 +000068
jardineb5d44e2003-12-23 08:09:43 +000069
hasso529d65b2004-12-24 00:14:50 +000070 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);
hassof390d2c2004-09-10 20:48:21 +000072
hassob30c5e62004-12-29 20:06:41 +000073 if (if_is_operative (ifp))
jardineb5d44e2003-12-23 08:09:43 +000074 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
hassof390d2c2004-09-10 20:48:21 +000075
jardineb5d44e2003-12-23 08:09:43 +000076 return 0;
77}
78
hasso92365882005-01-18 13:53:33 +000079static int
jardineb5d44e2003-12-23 08:09:43 +000080isis_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);
hassof390d2c2004-09-10 20:48:21 +000087
jardineb5d44e2003-12-23 08:09:43 +000088 if (!ifp)
89 return 0;
90
hassob30c5e62004-12-29 20:06:41 +000091 if (if_is_operative (ifp))
jardineb5d44e2003-12-23 08:09:43 +000092 zlog_warn ("Zebra: got delete of %s, but interface is still up",
hassof390d2c2004-09-10 20:48:21 +000093 ifp->name);
jardineb5d44e2003-12-23 08:09:43 +000094
hasso529d65b2004-12-24 00:14:50 +000095 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);
jardineb5d44e2003-12-23 08:09:43 +000097
98 if_delete (ifp);
hassof390d2c2004-09-10 20:48:21 +000099
jardineb5d44e2003-12-23 08:09:43 +0000100 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
101
102 return 0;
103}
104
hasso92365882005-01-18 13:53:33 +0000105static struct interface *
jardineb5d44e2003-12-23 08:09:43 +0000106zebra_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. */
hassof7c43dc2004-09-26 16:24:14 +0000115 ifp = if_lookup_by_name ((char *) ifname_tmp);
jardineb5d44e2003-12-23 08:09:43 +0000116
117 /* If such interface does not exist, indicate an error */
118 if (!ifp)
119 return NULL;
120
121 return ifp;
122}
123
hasso92365882005-01-18 13:53:33 +0000124static int
hassof390d2c2004-09-10 20:48:21 +0000125isis_zebra_if_state_up (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000126 zebra_size_t length)
127{
128 struct interface *ifp;
hassof390d2c2004-09-10 20:48:21 +0000129
jardineb5d44e2003-12-23 08:09:43 +0000130 ifp = zebra_interface_if_lookup (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +0000131
jardineb5d44e2003-12-23 08:09:43 +0000132 if (!ifp)
133 return 0;
hassof390d2c2004-09-10 20:48:21 +0000134
hassob30c5e62004-12-29 20:06:41 +0000135 if (if_is_operative (ifp))
hassof390d2c2004-09-10 20:48:21 +0000136 {
137 zebra_interface_if_set_value (zclient->ibuf, ifp);
hasso46606872004-12-29 19:34:22 +0000138 /* 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 */
hassof390d2c2004-09-10 20:48:21 +0000141 isis_circuit_update_params (circuit_scan_by_ifp (ifp), ifp);
142 return 0;
143 }
144
jardineb5d44e2003-12-23 08:09:43 +0000145 zebra_interface_if_set_value (zclient->ibuf, ifp);
146 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
hassof390d2c2004-09-10 20:48:21 +0000147
jardineb5d44e2003-12-23 08:09:43 +0000148 return 0;
149}
150
hasso92365882005-01-18 13:53:33 +0000151static int
hassof390d2c2004-09-10 20:48:21 +0000152isis_zebra_if_state_down (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000153 zebra_size_t length)
154{
155 struct interface *ifp;
hassof390d2c2004-09-10 20:48:21 +0000156
jardineb5d44e2003-12-23 08:09:43 +0000157 ifp = zebra_interface_if_lookup (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +0000158
jardineb5d44e2003-12-23 08:09:43 +0000159 if (ifp == NULL)
160 return 0;
hassof390d2c2004-09-10 20:48:21 +0000161
hassob30c5e62004-12-29 20:06:41 +0000162 if (if_is_operative (ifp))
hassof390d2c2004-09-10 20:48:21 +0000163 {
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
jardineb5d44e2003-12-23 08:09:43 +0000168 return 0;
169}
170
hasso92365882005-01-18 13:53:33 +0000171static int
hassof390d2c2004-09-10 20:48:21 +0000172isis_zebra_if_address_add (int command, struct zclient *zclient,
173 zebra_size_t length)
jardineb5d44e2003-12-23 08:09:43 +0000174{
175 struct connected *c;
176 struct prefix *p;
hassof7c43dc2004-09-26 16:24:14 +0000177 char buf[BUFSIZ];
jardineb5d44e2003-12-23 08:09:43 +0000178
hassof390d2c2004-09-10 20:48:21 +0000179 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
180 zclient->ibuf);
181
jardineb5d44e2003-12-23 08:09:43 +0000182 if (c == NULL)
183 return 0;
hassof390d2c2004-09-10 20:48:21 +0000184
jardineb5d44e2003-12-23 08:09:43 +0000185 p = c->address;
hassof390d2c2004-09-10 20:48:21 +0000186
jardineb5d44e2003-12-23 08:09:43 +0000187 prefix2str (p, buf, BUFSIZ);
188#ifdef EXTREME_DEBUG
hassof390d2c2004-09-10 20:48:21 +0000189 if (p->family == AF_INET)
hasso529d65b2004-12-24 00:14:50 +0000190 zlog_debug ("connected IP address %s", buf);
jardineb5d44e2003-12-23 08:09:43 +0000191#ifdef HAVE_IPV6
192 if (p->family == AF_INET6)
hasso529d65b2004-12-24 00:14:50 +0000193 zlog_debug ("connected IPv6 address %s", buf);
jardineb5d44e2003-12-23 08:09:43 +0000194#endif /* HAVE_IPV6 */
195#endif /* EXTREME_DEBUG */
hassob30c5e62004-12-29 20:06:41 +0000196 if (if_is_operative (c->ifp))
197 isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
jardineb5d44e2003-12-23 08:09:43 +0000198
199 return 0;
200}
201
hasso92365882005-01-18 13:53:33 +0000202static int
hassof390d2c2004-09-10 20:48:21 +0000203isis_zebra_if_address_del (int command, struct zclient *client,
204 zebra_size_t length)
jardineb5d44e2003-12-23 08:09:43 +0000205{
206 struct connected *c;
207 struct interface *ifp;
hasso1cd80842004-10-07 20:07:40 +0000208#ifdef EXTREME_DEBUG
hassof891f442004-09-14 13:54:30 +0000209 struct prefix *p;
210 u_char buf[BUFSIZ];
hasso1cd80842004-10-07 20:07:40 +0000211#endif /* EXTREME_DEBUG */
jardineb5d44e2003-12-23 08:09:43 +0000212
hassof390d2c2004-09-10 20:48:21 +0000213 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
214 zclient->ibuf);
215
jardineb5d44e2003-12-23 08:09:43 +0000216 if (c == NULL)
217 return 0;
hassof390d2c2004-09-10 20:48:21 +0000218
jardineb5d44e2003-12-23 08:09:43 +0000219 ifp = c->ifp;
hassof390d2c2004-09-10 20:48:21 +0000220
hassof891f442004-09-14 13:54:30 +0000221#ifdef EXTREME_DEBUG
222 p = c->address;
223 prefix2str (p, buf, BUFSIZ);
224
225 if (p->family == AF_INET)
hasso529d65b2004-12-24 00:14:50 +0000226 zlog_debug ("disconnected IP address %s", buf);
hassof891f442004-09-14 13:54:30 +0000227#ifdef HAVE_IPV6
228 if (p->family == AF_INET6)
hasso529d65b2004-12-24 00:14:50 +0000229 zlog_debug ("disconnected IPv6 address %s", buf);
hassof891f442004-09-14 13:54:30 +0000230#endif /* HAVE_IPV6 */
231#endif /* EXTREME_DEBUG */
hassof390d2c2004-09-10 20:48:21 +0000232
hassob30c5e62004-12-29 20:06:41 +0000233 if (if_is_operative (ifp))
234 isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
hassof891f442004-09-14 13:54:30 +0000235 connected_free (c);
hassof390d2c2004-09-10 20:48:21 +0000236
jardineb5d44e2003-12-23 08:09:43 +0000237 return 0;
238}
239
hasso92365882005-01-18 13:53:33 +0000240static void
hassof390d2c2004-09-10 20:48:21 +0000241isis_zebra_route_add_ipv4 (struct prefix *prefix,
242 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000243{
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
hassof390d2c2004-09-10 20:48:21 +0000253 if (zclient->redist[ZEBRA_ROUTE_ISIS])
254 {
255 message = 0;
256 flags = 0;
jardineb5d44e2003-12-23 08:09:43 +0000257
hassof390d2c2004-09-10 20:48:21 +0000258 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
259 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
hasso2097cd82003-12-23 11:51:08 +0000260#if 0
hassof390d2c2004-09-10 20:48:21 +0000261 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
hasso2097cd82003-12-23 11:51:08 +0000262#endif
hassof390d2c2004-09-10 20:48:21 +0000263
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 }
299#if 0
300 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
301 stream_putc (stream, route_info->depth);
302#endif
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 }
jardineb5d44e2003-12-23 08:09:43 +0000309}
310
hasso92365882005-01-18 13:53:33 +0000311static void
hassof390d2c2004-09-10 20:48:21 +0000312isis_zebra_route_del_ipv4 (struct prefix *prefix,
313 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000314{
315 struct zapi_ipv4 api;
316 struct prefix_ipv4 prefix4;
hassof390d2c2004-09-10 20:48:21 +0000317
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
jardineb5d44e2003-12-23 08:09:43 +0000329 return;
330}
331
332#ifdef HAVE_IPV6
333void
334isis_zebra_route_add_ipv6 (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000335 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000336{
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;
hassof390d2c2004-09-10 20:48:21 +0000347
jardineb5d44e2003-12-23 08:09:43 +0000348 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);
hassof390d2c2004-09-10 20:48:21 +0000361
jardineb5d44e2003-12-23 08:09:43 +0000362 /* 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);
hassof390d2c2004-09-10 20:48:21 +0000365 if (!nexthop_list)
366 {
367 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
368 return;
369 }
370
jardineb5d44e2003-12-23 08:09:43 +0000371 /* allocate memory for ifindex_list */
372 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
373 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000374 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
jardineb5d44e2003-12-23 08:09:43 +0000381 /* for each nexthop */
382 i = 0;
hassof390d2c2004-09-10 20:48:21 +0000383 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++;
jardineb5d44e2003-12-23 08:09:43 +0000398 }
hassof390d2c2004-09-10 20:48:21 +0000399
jardineb5d44e2003-12-23 08:09:43 +0000400 api.nexthop = nexthop_list;
401 api.ifindex = ifindex_list;
hassof390d2c2004-09-10 20:48:21 +0000402
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
jardineb5d44e2003-12-23 08:09:43 +0000412 XFREE (MTYPE_ISIS_TMP, nexthop_list);
413 XFREE (MTYPE_ISIS_TMP, ifindex_list);
hassof390d2c2004-09-10 20:48:21 +0000414
jardineb5d44e2003-12-23 08:09:43 +0000415 return;
416}
417
hasso92365882005-01-18 13:53:33 +0000418static void
hassof390d2c2004-09-10 20:48:21 +0000419isis_zebra_route_del_ipv6 (struct prefix *prefix,
420 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000421{
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;
hassof390d2c2004-09-10 20:48:21 +0000432
jardineb5d44e2003-12-23 08:09:43 +0000433 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);
hassof390d2c2004-09-10 20:48:21 +0000440
jardineb5d44e2003-12-23 08:09:43 +0000441 /* 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);
hassof390d2c2004-09-10 20:48:21 +0000444 if (!nexthop_list)
445 {
446 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
447 return;
448 }
449
jardineb5d44e2003-12-23 08:09:43 +0000450 /* allocate memory for ifindex_list */
451 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
452 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000453 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
jardineb5d44e2003-12-23 08:09:43 +0000460 /* for each nexthop */
461 i = 0;
hassof390d2c2004-09-10 20:48:21 +0000462 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++;
jardineb5d44e2003-12-23 08:09:43 +0000477 }
hassof390d2c2004-09-10 20:48:21 +0000478
jardineb5d44e2003-12-23 08:09:43 +0000479 api.nexthop = nexthop_list;
480 api.ifindex = ifindex_list;
jardineb5d44e2003-12-23 08:09:43 +0000481
hassof390d2c2004-09-10 20:48:21 +0000482 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
491 XFREE (MTYPE_ISIS_TMP, nexthop_list);
492 XFREE (MTYPE_ISIS_TMP, ifindex_list);
493}
jardineb5d44e2003-12-23 08:09:43 +0000494
495#endif /* HAVE_IPV6 */
496
jardineb5d44e2003-12-23 08:09:43 +0000497void
498isis_zebra_route_update (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000499 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000500{
501 if (zclient->sock < 0)
502 return;
503
504 if (!zclient->redist[ZEBRA_ROUTE_ISIS])
505 return;
506
hassof390d2c2004-09-10 20:48:21 +0000507 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);
jardineb5d44e2003-12-23 08:09:43 +0000511#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000512 else if (prefix->family == AF_INET6)
513 isis_zebra_route_add_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000514#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000515 }
516 else
517 {
518 if (prefix->family == AF_INET)
519 isis_zebra_route_del_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000520#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000521 else if (prefix->family == AF_INET6)
522 isis_zebra_route_del_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000523#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000524 }
jardineb5d44e2003-12-23 08:09:43 +0000525 return;
526}
527
hasso92365882005-01-18 13:53:33 +0000528static int
hassof390d2c2004-09-10 20:48:21 +0000529isis_zebra_read_ipv4 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000530 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
hassof390d2c2004-09-10 20:48:21 +0000542 api.type = stream_getc (stream);
543 api.flags = stream_getc (stream);
jardineb5d44e2003-12-23 08:09:43 +0000544 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));
hassof390d2c2004-09-10 20:48:21 +0000549
550 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
551 {
jardineb5d44e2003-12-23 08:09:43 +0000552 api.nexthop_num = stream_getc (stream);
553 nexthop.s_addr = stream_get_ipv4 (stream);
hassof390d2c2004-09-10 20:48:21 +0000554 }
555 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
556 {
557 api.ifindex_num = stream_getc (stream);
558 ifindex = stream_getl (stream);
559 }
jardineb5d44e2003-12-23 08:09:43 +0000560 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;
hassof390d2c2004-09-10 20:48:21 +0000566
567 if (command == ZEBRA_IPV4_ROUTE_ADD)
568 {
hasso529d65b2004-12-24 00:14:50 +0000569 zlog_debug ("IPv4 Route add from Z");
hassof390d2c2004-09-10 20:48:21 +0000570 }
jardineb5d44e2003-12-23 08:09:43 +0000571
572 return 0;
573}
574
hasso92365882005-01-18 13:53:33 +0000575static int
hassof390d2c2004-09-10 20:48:21 +0000576isis_zebra_read_ipv6 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000577 zebra_size_t length)
578{
jardineb5d44e2003-12-23 08:09:43 +0000579 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
hasso92365882005-01-18 13:53:33 +0000591#if 0 /* Not yet. */
592static int
hassof390d2c2004-09-10 20:48:21 +0000593isis_redistribute_default_set (int routetype, int metric_type,
594 int metric_value)
jardineb5d44e2003-12-23 08:09:43 +0000595{
596 return 0;
597}
hasso92365882005-01-18 13:53:33 +0000598#endif /* 0 */
jardineb5d44e2003-12-23 08:09:43 +0000599
jardineb5d44e2003-12-23 08:09:43 +0000600void
601isis_zebra_init ()
602{
jardineb5d44e2003-12-23 08:09:43 +0000603 zclient = zclient_new ();
604 zclient_init (zclient, ZEBRA_ROUTE_ISIS);
hasso18a6dce2004-10-03 18:18:34 +0000605 zclient->router_id_update = isis_router_id_update_zebra;
jardineb5d44e2003-12-23 08:09:43 +0000606 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{
jardineb5d44e2003-12-23 08:09:43 +0000625 zclient_stop (zclient);
626 zclient_free (zclient);
627 zclient = (struct zclient *) NULL;
628
629 return;
630}