blob: aff6a716573e897fb8ad7e9ad718b9353b4fdfaf [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
hassoc89c05d2005-09-04 21:36:36 +000036#include "isisd/dict.h"
jardineb5d44e2003-12-23 08:09:43 +000037#include "isisd/isis_constants.h"
38#include "isisd/isis_common.h"
hassoc89c05d2005-09-04 21:36:36 +000039#include "isisd/isisd.h"
jardineb5d44e2003-12-23 08:09:43 +000040#include "isisd/isis_circuit.h"
41#include "isisd/isis_csm.h"
42#include "isisd/isis_route.h"
43#include "isisd/isis_zebra.h"
44
45struct zclient *zclient = NULL;
46
47extern struct thread_master *master;
hassoc89c05d2005-09-04 21:36:36 +000048extern struct isis *isis;
49
hasso18a6dce2004-10-03 18:18:34 +000050struct in_addr router_id_zebra;
51
52/* Router-id update message from zebra. */
hasso92365882005-01-18 13:53:33 +000053static int
hasso18a6dce2004-10-03 18:18:34 +000054isis_router_id_update_zebra (int command, struct zclient *zclient,
55 zebra_size_t length)
56{
57 struct prefix router_id;
hasso18a6dce2004-10-03 18:18:34 +000058
59 zebra_router_id_update_read (zclient->ibuf,&router_id);
60 router_id_zebra = router_id.u.prefix4;
61
62 /* FIXME: Do we react somehow? */
63 return 0;
64}
jardineb5d44e2003-12-23 08:09:43 +000065
hasso92365882005-01-18 13:53:33 +000066static int
jardineb5d44e2003-12-23 08:09:43 +000067isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
68{
69 struct interface *ifp;
70
71 ifp = zebra_interface_add_read (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +000072
hassoc89c05d2005-09-04 21:36:36 +000073 if (isis->debugs & DEBUG_ZEBRA)
74 zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
75 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
hassof390d2c2004-09-10 20:48:21 +000076
hassob30c5e62004-12-29 20:06:41 +000077 if (if_is_operative (ifp))
jardineb5d44e2003-12-23 08:09:43 +000078 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
hassof390d2c2004-09-10 20:48:21 +000079
jardineb5d44e2003-12-23 08:09:43 +000080 return 0;
81}
82
hasso92365882005-01-18 13:53:33 +000083static int
jardineb5d44e2003-12-23 08:09:43 +000084isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
85{
86 struct interface *ifp;
87 struct stream *s;
88
89 s = zclient->ibuf;
90 ifp = zebra_interface_state_read (s);
hassof390d2c2004-09-10 20:48:21 +000091
jardineb5d44e2003-12-23 08:09:43 +000092 if (!ifp)
93 return 0;
94
hassob30c5e62004-12-29 20:06:41 +000095 if (if_is_operative (ifp))
jardineb5d44e2003-12-23 08:09:43 +000096 zlog_warn ("Zebra: got delete of %s, but interface is still up",
hassof390d2c2004-09-10 20:48:21 +000097 ifp->name);
jardineb5d44e2003-12-23 08:09:43 +000098
hassoc89c05d2005-09-04 21:36:36 +000099 if (isis->debugs & DEBUG_ZEBRA)
100 zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
101 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
jardineb5d44e2003-12-23 08:09:43 +0000102
ajsd2fc8892005-04-02 18:38:43 +0000103
104 /* Cannot call if_delete because we should retain the pseudo interface
105 in case there is configuration info attached to it. */
106 if_delete_retain(ifp);
hassof390d2c2004-09-10 20:48:21 +0000107
jardineb5d44e2003-12-23 08:09:43 +0000108 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
109
ajsd2fc8892005-04-02 18:38:43 +0000110 ifp->ifindex = IFINDEX_INTERNAL;
111
jardineb5d44e2003-12-23 08:09:43 +0000112 return 0;
113}
114
hasso92365882005-01-18 13:53:33 +0000115static struct interface *
jardineb5d44e2003-12-23 08:09:43 +0000116zebra_interface_if_lookup (struct stream *s)
117{
ajsbd88bf42005-04-02 23:09:52 +0000118 char ifname_tmp[INTERFACE_NAMSIZ];
jardineb5d44e2003-12-23 08:09:43 +0000119
120 /* Read interface name. */
121 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
122
ajsd2fc8892005-04-02 18:38:43 +0000123 /* And look it up. */
ajsbd88bf42005-04-02 23:09:52 +0000124 return if_lookup_by_name_len(ifname_tmp,
125 strnlen(ifname_tmp, INTERFACE_NAMSIZ));
jardineb5d44e2003-12-23 08:09:43 +0000126}
127
hasso92365882005-01-18 13:53:33 +0000128static int
hassof390d2c2004-09-10 20:48:21 +0000129isis_zebra_if_state_up (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000130 zebra_size_t length)
131{
132 struct interface *ifp;
hassof390d2c2004-09-10 20:48:21 +0000133
jardineb5d44e2003-12-23 08:09:43 +0000134 ifp = zebra_interface_if_lookup (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +0000135
jardineb5d44e2003-12-23 08:09:43 +0000136 if (!ifp)
137 return 0;
hassof390d2c2004-09-10 20:48:21 +0000138
hassob30c5e62004-12-29 20:06:41 +0000139 if (if_is_operative (ifp))
hassof390d2c2004-09-10 20:48:21 +0000140 {
141 zebra_interface_if_set_value (zclient->ibuf, ifp);
hasso46606872004-12-29 19:34:22 +0000142 /* HT: This is wrong actually. We can't assume that circuit exist
143 * if we delete circuit during if_state_down event. Needs rethink.
144 * TODO */
hassof390d2c2004-09-10 20:48:21 +0000145 isis_circuit_update_params (circuit_scan_by_ifp (ifp), ifp);
146 return 0;
147 }
148
jardineb5d44e2003-12-23 08:09:43 +0000149 zebra_interface_if_set_value (zclient->ibuf, ifp);
150 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
hassof390d2c2004-09-10 20:48:21 +0000151
jardineb5d44e2003-12-23 08:09:43 +0000152 return 0;
153}
154
hasso92365882005-01-18 13:53:33 +0000155static int
hassof390d2c2004-09-10 20:48:21 +0000156isis_zebra_if_state_down (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000157 zebra_size_t length)
158{
159 struct interface *ifp;
hassof390d2c2004-09-10 20:48:21 +0000160
jardineb5d44e2003-12-23 08:09:43 +0000161 ifp = zebra_interface_if_lookup (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +0000162
jardineb5d44e2003-12-23 08:09:43 +0000163 if (ifp == NULL)
164 return 0;
hassof390d2c2004-09-10 20:48:21 +0000165
hassob30c5e62004-12-29 20:06:41 +0000166 if (if_is_operative (ifp))
hassof390d2c2004-09-10 20:48:21 +0000167 {
168 zebra_interface_if_set_value (zclient->ibuf, ifp);
169 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
170 }
171
jardineb5d44e2003-12-23 08:09:43 +0000172 return 0;
173}
174
hasso92365882005-01-18 13:53:33 +0000175static int
hassof390d2c2004-09-10 20:48:21 +0000176isis_zebra_if_address_add (int command, struct zclient *zclient,
177 zebra_size_t length)
jardineb5d44e2003-12-23 08:09:43 +0000178{
179 struct connected *c;
180 struct prefix *p;
hassof7c43dc2004-09-26 16:24:14 +0000181 char buf[BUFSIZ];
jardineb5d44e2003-12-23 08:09:43 +0000182
hassof390d2c2004-09-10 20:48:21 +0000183 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
184 zclient->ibuf);
185
jardineb5d44e2003-12-23 08:09:43 +0000186 if (c == NULL)
187 return 0;
hassof390d2c2004-09-10 20:48:21 +0000188
jardineb5d44e2003-12-23 08:09:43 +0000189 p = c->address;
hassof390d2c2004-09-10 20:48:21 +0000190
jardineb5d44e2003-12-23 08:09:43 +0000191 prefix2str (p, buf, BUFSIZ);
192#ifdef EXTREME_DEBUG
hassof390d2c2004-09-10 20:48:21 +0000193 if (p->family == AF_INET)
hasso529d65b2004-12-24 00:14:50 +0000194 zlog_debug ("connected IP address %s", buf);
jardineb5d44e2003-12-23 08:09:43 +0000195#ifdef HAVE_IPV6
196 if (p->family == AF_INET6)
hasso529d65b2004-12-24 00:14:50 +0000197 zlog_debug ("connected IPv6 address %s", buf);
jardineb5d44e2003-12-23 08:09:43 +0000198#endif /* HAVE_IPV6 */
199#endif /* EXTREME_DEBUG */
hassob30c5e62004-12-29 20:06:41 +0000200 if (if_is_operative (c->ifp))
201 isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
jardineb5d44e2003-12-23 08:09:43 +0000202
203 return 0;
204}
205
hasso92365882005-01-18 13:53:33 +0000206static int
hassof390d2c2004-09-10 20:48:21 +0000207isis_zebra_if_address_del (int command, struct zclient *client,
208 zebra_size_t length)
jardineb5d44e2003-12-23 08:09:43 +0000209{
210 struct connected *c;
211 struct interface *ifp;
hasso1cd80842004-10-07 20:07:40 +0000212#ifdef EXTREME_DEBUG
hassof891f442004-09-14 13:54:30 +0000213 struct prefix *p;
214 u_char buf[BUFSIZ];
hasso1cd80842004-10-07 20:07:40 +0000215#endif /* EXTREME_DEBUG */
jardineb5d44e2003-12-23 08:09:43 +0000216
hassof390d2c2004-09-10 20:48:21 +0000217 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
218 zclient->ibuf);
219
jardineb5d44e2003-12-23 08:09:43 +0000220 if (c == NULL)
221 return 0;
hassof390d2c2004-09-10 20:48:21 +0000222
jardineb5d44e2003-12-23 08:09:43 +0000223 ifp = c->ifp;
hassof390d2c2004-09-10 20:48:21 +0000224
hassof891f442004-09-14 13:54:30 +0000225#ifdef EXTREME_DEBUG
226 p = c->address;
227 prefix2str (p, buf, BUFSIZ);
228
229 if (p->family == AF_INET)
hasso529d65b2004-12-24 00:14:50 +0000230 zlog_debug ("disconnected IP address %s", buf);
hassof891f442004-09-14 13:54:30 +0000231#ifdef HAVE_IPV6
232 if (p->family == AF_INET6)
hasso529d65b2004-12-24 00:14:50 +0000233 zlog_debug ("disconnected IPv6 address %s", buf);
hassof891f442004-09-14 13:54:30 +0000234#endif /* HAVE_IPV6 */
235#endif /* EXTREME_DEBUG */
hassof390d2c2004-09-10 20:48:21 +0000236
hassob30c5e62004-12-29 20:06:41 +0000237 if (if_is_operative (ifp))
238 isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
hassof891f442004-09-14 13:54:30 +0000239 connected_free (c);
hassof390d2c2004-09-10 20:48:21 +0000240
jardineb5d44e2003-12-23 08:09:43 +0000241 return 0;
242}
243
hasso92365882005-01-18 13:53:33 +0000244static void
hassof390d2c2004-09-10 20:48:21 +0000245isis_zebra_route_add_ipv4 (struct prefix *prefix,
246 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000247{
248 u_char message, flags;
249 int psize;
250 struct stream *stream;
251 struct isis_nexthop *nexthop;
252 struct listnode *node;
253
254 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
255 return;
256
hassof390d2c2004-09-10 20:48:21 +0000257 if (zclient->redist[ZEBRA_ROUTE_ISIS])
258 {
259 message = 0;
260 flags = 0;
jardineb5d44e2003-12-23 08:09:43 +0000261
hassof390d2c2004-09-10 20:48:21 +0000262 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
263 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
hasso2097cd82003-12-23 11:51:08 +0000264#if 0
hassof390d2c2004-09-10 20:48:21 +0000265 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
hasso2097cd82003-12-23 11:51:08 +0000266#endif
hassof390d2c2004-09-10 20:48:21 +0000267
268 stream = zclient->obuf;
269 stream_reset (stream);
270 /* Length place holder. */
271 stream_putw (stream, 0);
272 /* command */
273 stream_putc (stream, ZEBRA_IPV4_ROUTE_ADD);
274 /* type */
275 stream_putc (stream, ZEBRA_ROUTE_ISIS);
276 /* flags */
277 stream_putc (stream, flags);
278 /* message */
279 stream_putc (stream, message);
280 /* prefix information */
281 psize = PSIZE (prefix->prefixlen);
282 stream_putc (stream, prefix->prefixlen);
283 stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
284
285 stream_putc (stream, listcount (route_info->nexthops));
286
287 /* Nexthop, ifindex, distance and metric information */
paul1eb8ef22005-04-07 07:30:20 +0000288 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
hassof390d2c2004-09-10 20:48:21 +0000289 {
hassof390d2c2004-09-10 20:48:21 +0000290 /* FIXME: can it be ? */
291 if (nexthop->ip.s_addr != INADDR_ANY)
292 {
293 stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
294 stream_put_in_addr (stream, &nexthop->ip);
295 }
296 else
297 {
298 stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
299 stream_putl (stream, nexthop->ifindex);
300 }
301 }
302#if 0
303 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
304 stream_putc (stream, route_info->depth);
305#endif
306 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
307 stream_putl (stream, route_info->cost);
308
309 stream_putw_at (stream, 0, stream_get_endp (stream));
ajs634f9ea2005-04-11 15:51:40 +0000310 zclient_send_message(zclient);
hassofac1f7c2005-09-26 18:26:26 +0000311 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
hassof390d2c2004-09-10 20:48:21 +0000312 }
jardineb5d44e2003-12-23 08:09:43 +0000313}
314
hasso92365882005-01-18 13:53:33 +0000315static void
hassof390d2c2004-09-10 20:48:21 +0000316isis_zebra_route_del_ipv4 (struct prefix *prefix,
317 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000318{
319 struct zapi_ipv4 api;
320 struct prefix_ipv4 prefix4;
hassof390d2c2004-09-10 20:48:21 +0000321
322 if (zclient->redist[ZEBRA_ROUTE_ISIS])
323 {
324 api.type = ZEBRA_ROUTE_ISIS;
325 api.flags = 0;
326 api.message = 0;
327 prefix4.family = AF_INET;
328 prefix4.prefixlen = prefix->prefixlen;
329 prefix4.prefix = prefix->u.prefix4;
330 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
331 }
hassofac1f7c2005-09-26 18:26:26 +0000332 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
hassof390d2c2004-09-10 20:48:21 +0000333
jardineb5d44e2003-12-23 08:09:43 +0000334 return;
335}
336
337#ifdef HAVE_IPV6
338void
339isis_zebra_route_add_ipv6 (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000340 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000341{
342 struct zapi_ipv6 api;
343 struct in6_addr **nexthop_list;
344 unsigned int *ifindex_list;
345 struct isis_nexthop6 *nexthop6;
346 int i, size;
347 struct listnode *node;
348 struct prefix_ipv6 prefix6;
349
350 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
351 return;
hassof390d2c2004-09-10 20:48:21 +0000352
jardineb5d44e2003-12-23 08:09:43 +0000353 api.type = ZEBRA_ROUTE_ISIS;
354 api.flags = 0;
355 api.message = 0;
356 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
357 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
358 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
359 api.metric = route_info->cost;
360#if 0
361 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
362 api.distance = route_info->depth;
363#endif
364 api.nexthop_num = listcount (route_info->nexthops6);
365 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000366
jardineb5d44e2003-12-23 08:09:43 +0000367 /* allocate memory for nexthop_list */
368 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
369 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000370 if (!nexthop_list)
371 {
372 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
373 return;
374 }
375
jardineb5d44e2003-12-23 08:09:43 +0000376 /* allocate memory for ifindex_list */
377 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
378 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000379 if (!ifindex_list)
380 {
381 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
382 XFREE (MTYPE_ISIS_TMP, nexthop_list);
383 return;
384 }
385
jardineb5d44e2003-12-23 08:09:43 +0000386 /* for each nexthop */
387 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000388 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000389 {
hassof390d2c2004-09-10 20:48:21 +0000390 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
391 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
392 {
393 api.nexthop_num--;
394 api.ifindex_num--;
395 continue;
396 }
397
398 nexthop_list[i] = &nexthop6->ip6;
399 ifindex_list[i] = nexthop6->ifindex;
400 i++;
jardineb5d44e2003-12-23 08:09:43 +0000401 }
hassof390d2c2004-09-10 20:48:21 +0000402
jardineb5d44e2003-12-23 08:09:43 +0000403 api.nexthop = nexthop_list;
404 api.ifindex = ifindex_list;
hassof390d2c2004-09-10 20:48:21 +0000405
406 if (api.nexthop_num && api.ifindex_num)
407 {
408 prefix6.family = AF_INET6;
409 prefix6.prefixlen = prefix->prefixlen;
410 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
411 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
412 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
413 }
414
jardineb5d44e2003-12-23 08:09:43 +0000415 XFREE (MTYPE_ISIS_TMP, nexthop_list);
416 XFREE (MTYPE_ISIS_TMP, ifindex_list);
hassof390d2c2004-09-10 20:48:21 +0000417
jardineb5d44e2003-12-23 08:09:43 +0000418 return;
419}
420
hasso92365882005-01-18 13:53:33 +0000421static void
hassof390d2c2004-09-10 20:48:21 +0000422isis_zebra_route_del_ipv6 (struct prefix *prefix,
423 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000424{
425 struct zapi_ipv6 api;
426 struct in6_addr **nexthop_list;
427 unsigned int *ifindex_list;
428 struct isis_nexthop6 *nexthop6;
429 int i, size;
430 struct listnode *node;
431 struct prefix_ipv6 prefix6;
432
433 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
434 return;
hassof390d2c2004-09-10 20:48:21 +0000435
jardineb5d44e2003-12-23 08:09:43 +0000436 api.type = ZEBRA_ROUTE_ISIS;
437 api.flags = 0;
438 api.message = 0;
439 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
440 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
441 api.nexthop_num = listcount (route_info->nexthops6);
442 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000443
jardineb5d44e2003-12-23 08:09:43 +0000444 /* allocate memory for nexthop_list */
445 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
446 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000447 if (!nexthop_list)
448 {
449 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
450 return;
451 }
452
jardineb5d44e2003-12-23 08:09:43 +0000453 /* allocate memory for ifindex_list */
454 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
455 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000456 if (!ifindex_list)
457 {
458 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
459 XFREE (MTYPE_ISIS_TMP, nexthop_list);
460 return;
461 }
462
jardineb5d44e2003-12-23 08:09:43 +0000463 /* for each nexthop */
464 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000465 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000466 {
hassof390d2c2004-09-10 20:48:21 +0000467 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
468 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
469 {
470 api.nexthop_num--;
471 api.ifindex_num--;
472 continue;
473 }
474
475 nexthop_list[i] = &nexthop6->ip6;
476 ifindex_list[i] = nexthop6->ifindex;
477 i++;
jardineb5d44e2003-12-23 08:09:43 +0000478 }
hassof390d2c2004-09-10 20:48:21 +0000479
jardineb5d44e2003-12-23 08:09:43 +0000480 api.nexthop = nexthop_list;
481 api.ifindex = ifindex_list;
jardineb5d44e2003-12-23 08:09:43 +0000482
hassof390d2c2004-09-10 20:48:21 +0000483 if (api.nexthop_num && api.ifindex_num)
484 {
485 prefix6.family = AF_INET6;
486 prefix6.prefixlen = prefix->prefixlen;
487 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
488 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
489 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
490 }
491
492 XFREE (MTYPE_ISIS_TMP, nexthop_list);
493 XFREE (MTYPE_ISIS_TMP, ifindex_list);
494}
jardineb5d44e2003-12-23 08:09:43 +0000495
496#endif /* HAVE_IPV6 */
497
jardineb5d44e2003-12-23 08:09:43 +0000498void
499isis_zebra_route_update (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000500 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000501{
502 if (zclient->sock < 0)
503 return;
504
505 if (!zclient->redist[ZEBRA_ROUTE_ISIS])
506 return;
507
hassof390d2c2004-09-10 20:48:21 +0000508 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);
jardineb5d44e2003-12-23 08:09:43 +0000512#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000513 else if (prefix->family == AF_INET6)
514 isis_zebra_route_add_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000515#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000516 }
517 else
518 {
519 if (prefix->family == AF_INET)
520 isis_zebra_route_del_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000521#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000522 else if (prefix->family == AF_INET6)
523 isis_zebra_route_del_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000524#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000525 }
jardineb5d44e2003-12-23 08:09:43 +0000526 return;
527}
528
hasso92365882005-01-18 13:53:33 +0000529static int
hassof390d2c2004-09-10 20:48:21 +0000530isis_zebra_read_ipv4 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000531 zebra_size_t length)
532{
533 struct stream *stream;
534 struct zapi_ipv4 api;
535 struct prefix_ipv4 p;
536 unsigned long ifindex;
537 struct in_addr nexthop;
538
539 stream = zclient->ibuf;
540 memset (&p, 0, sizeof (struct prefix_ipv4));
541 ifindex = 0;
542
hassof390d2c2004-09-10 20:48:21 +0000543 api.type = stream_getc (stream);
544 api.flags = stream_getc (stream);
jardineb5d44e2003-12-23 08:09:43 +0000545 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));
hassof390d2c2004-09-10 20:48:21 +0000550
551 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
552 {
jardineb5d44e2003-12-23 08:09:43 +0000553 api.nexthop_num = stream_getc (stream);
554 nexthop.s_addr = stream_get_ipv4 (stream);
hassof390d2c2004-09-10 20:48:21 +0000555 }
556 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
557 {
558 api.ifindex_num = stream_getc (stream);
559 ifindex = stream_getl (stream);
560 }
jardineb5d44e2003-12-23 08:09:43 +0000561 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 else
566 api.metric = 0;
hassof390d2c2004-09-10 20:48:21 +0000567
568 if (command == ZEBRA_IPV4_ROUTE_ADD)
569 {
hassoc89c05d2005-09-04 21:36:36 +0000570 if (isis->debugs & DEBUG_ZEBRA)
571 zlog_debug ("IPv4 Route add from Z");
hassof390d2c2004-09-10 20:48:21 +0000572 }
jardineb5d44e2003-12-23 08:09:43 +0000573
574 return 0;
575}
576
hasso92365882005-01-18 13:53:33 +0000577static int
hassof390d2c2004-09-10 20:48:21 +0000578isis_zebra_read_ipv6 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000579 zebra_size_t length)
580{
jardineb5d44e2003-12-23 08:09:43 +0000581 return 0;
582}
583
584#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
585T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
586
587int
588isis_distribute_list_update (int routetype)
589{
590 return 0;
591}
592
hasso92365882005-01-18 13:53:33 +0000593#if 0 /* Not yet. */
594static int
hassof390d2c2004-09-10 20:48:21 +0000595isis_redistribute_default_set (int routetype, int metric_type,
596 int metric_value)
jardineb5d44e2003-12-23 08:09:43 +0000597{
598 return 0;
599}
hasso92365882005-01-18 13:53:33 +0000600#endif /* 0 */
jardineb5d44e2003-12-23 08:09:43 +0000601
jardineb5d44e2003-12-23 08:09:43 +0000602void
603isis_zebra_init ()
604{
jardineb5d44e2003-12-23 08:09:43 +0000605 zclient = zclient_new ();
606 zclient_init (zclient, ZEBRA_ROUTE_ISIS);
hasso18a6dce2004-10-03 18:18:34 +0000607 zclient->router_id_update = isis_router_id_update_zebra;
jardineb5d44e2003-12-23 08:09:43 +0000608 zclient->interface_add = isis_zebra_if_add;
609 zclient->interface_delete = isis_zebra_if_del;
610 zclient->interface_up = isis_zebra_if_state_up;
611 zclient->interface_down = isis_zebra_if_state_down;
612 zclient->interface_address_add = isis_zebra_if_address_add;
613 zclient->interface_address_delete = isis_zebra_if_address_del;
614 zclient->ipv4_route_add = isis_zebra_read_ipv4;
615 zclient->ipv4_route_delete = isis_zebra_read_ipv4;
616#ifdef HAVE_IPV6
617 zclient->ipv6_route_add = isis_zebra_read_ipv6;
618 zclient->ipv6_route_delete = isis_zebra_read_ipv6;
619#endif /* HAVE_IPV6 */
620
621 return;
622}