blob: a385e6b5c94fd9e74b791fb201ec9daac8a9b216 [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);
hassof390d2c2004-09-10 20:48:21 +0000311 }
jardineb5d44e2003-12-23 08:09:43 +0000312}
313
hasso92365882005-01-18 13:53:33 +0000314static void
hassof390d2c2004-09-10 20:48:21 +0000315isis_zebra_route_del_ipv4 (struct prefix *prefix,
316 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000317{
318 struct zapi_ipv4 api;
319 struct prefix_ipv4 prefix4;
hassof390d2c2004-09-10 20:48:21 +0000320
321 if (zclient->redist[ZEBRA_ROUTE_ISIS])
322 {
323 api.type = ZEBRA_ROUTE_ISIS;
324 api.flags = 0;
325 api.message = 0;
326 prefix4.family = AF_INET;
327 prefix4.prefixlen = prefix->prefixlen;
328 prefix4.prefix = prefix->u.prefix4;
329 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
330 }
331
jardineb5d44e2003-12-23 08:09:43 +0000332 return;
333}
334
335#ifdef HAVE_IPV6
336void
337isis_zebra_route_add_ipv6 (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000338 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000339{
340 struct zapi_ipv6 api;
341 struct in6_addr **nexthop_list;
342 unsigned int *ifindex_list;
343 struct isis_nexthop6 *nexthop6;
344 int i, size;
345 struct listnode *node;
346 struct prefix_ipv6 prefix6;
347
348 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
349 return;
hassof390d2c2004-09-10 20:48:21 +0000350
jardineb5d44e2003-12-23 08:09:43 +0000351 api.type = ZEBRA_ROUTE_ISIS;
352 api.flags = 0;
353 api.message = 0;
354 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
355 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
356 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
357 api.metric = route_info->cost;
358#if 0
359 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
360 api.distance = route_info->depth;
361#endif
362 api.nexthop_num = listcount (route_info->nexthops6);
363 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000364
jardineb5d44e2003-12-23 08:09:43 +0000365 /* allocate memory for nexthop_list */
366 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
367 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000368 if (!nexthop_list)
369 {
370 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
371 return;
372 }
373
jardineb5d44e2003-12-23 08:09:43 +0000374 /* allocate memory for ifindex_list */
375 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
376 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000377 if (!ifindex_list)
378 {
379 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
380 XFREE (MTYPE_ISIS_TMP, nexthop_list);
381 return;
382 }
383
jardineb5d44e2003-12-23 08:09:43 +0000384 /* for each nexthop */
385 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000386 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000387 {
hassof390d2c2004-09-10 20:48:21 +0000388 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
389 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
390 {
391 api.nexthop_num--;
392 api.ifindex_num--;
393 continue;
394 }
395
396 nexthop_list[i] = &nexthop6->ip6;
397 ifindex_list[i] = nexthop6->ifindex;
398 i++;
jardineb5d44e2003-12-23 08:09:43 +0000399 }
hassof390d2c2004-09-10 20:48:21 +0000400
jardineb5d44e2003-12-23 08:09:43 +0000401 api.nexthop = nexthop_list;
402 api.ifindex = ifindex_list;
hassof390d2c2004-09-10 20:48:21 +0000403
404 if (api.nexthop_num && api.ifindex_num)
405 {
406 prefix6.family = AF_INET6;
407 prefix6.prefixlen = prefix->prefixlen;
408 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
409 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
410 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
411 }
412
jardineb5d44e2003-12-23 08:09:43 +0000413 XFREE (MTYPE_ISIS_TMP, nexthop_list);
414 XFREE (MTYPE_ISIS_TMP, ifindex_list);
hassof390d2c2004-09-10 20:48:21 +0000415
jardineb5d44e2003-12-23 08:09:43 +0000416 return;
417}
418
hasso92365882005-01-18 13:53:33 +0000419static void
hassof390d2c2004-09-10 20:48:21 +0000420isis_zebra_route_del_ipv6 (struct prefix *prefix,
421 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000422{
423 struct zapi_ipv6 api;
424 struct in6_addr **nexthop_list;
425 unsigned int *ifindex_list;
426 struct isis_nexthop6 *nexthop6;
427 int i, size;
428 struct listnode *node;
429 struct prefix_ipv6 prefix6;
430
431 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
432 return;
hassof390d2c2004-09-10 20:48:21 +0000433
jardineb5d44e2003-12-23 08:09:43 +0000434 api.type = ZEBRA_ROUTE_ISIS;
435 api.flags = 0;
436 api.message = 0;
437 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
438 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
439 api.nexthop_num = listcount (route_info->nexthops6);
440 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000441
jardineb5d44e2003-12-23 08:09:43 +0000442 /* allocate memory for nexthop_list */
443 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
444 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000445 if (!nexthop_list)
446 {
447 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
448 return;
449 }
450
jardineb5d44e2003-12-23 08:09:43 +0000451 /* allocate memory for ifindex_list */
452 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
453 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000454 if (!ifindex_list)
455 {
456 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
457 XFREE (MTYPE_ISIS_TMP, nexthop_list);
458 return;
459 }
460
jardineb5d44e2003-12-23 08:09:43 +0000461 /* for each nexthop */
462 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000463 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000464 {
hassof390d2c2004-09-10 20:48:21 +0000465 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
466 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
467 {
468 api.nexthop_num--;
469 api.ifindex_num--;
470 continue;
471 }
472
473 nexthop_list[i] = &nexthop6->ip6;
474 ifindex_list[i] = nexthop6->ifindex;
475 i++;
jardineb5d44e2003-12-23 08:09:43 +0000476 }
hassof390d2c2004-09-10 20:48:21 +0000477
jardineb5d44e2003-12-23 08:09:43 +0000478 api.nexthop = nexthop_list;
479 api.ifindex = ifindex_list;
jardineb5d44e2003-12-23 08:09:43 +0000480
hassof390d2c2004-09-10 20:48:21 +0000481 if (api.nexthop_num && api.ifindex_num)
482 {
483 prefix6.family = AF_INET6;
484 prefix6.prefixlen = prefix->prefixlen;
485 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
486 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
487 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
488 }
489
490 XFREE (MTYPE_ISIS_TMP, nexthop_list);
491 XFREE (MTYPE_ISIS_TMP, ifindex_list);
492}
jardineb5d44e2003-12-23 08:09:43 +0000493
494#endif /* HAVE_IPV6 */
495
jardineb5d44e2003-12-23 08:09:43 +0000496void
497isis_zebra_route_update (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000498 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000499{
500 if (zclient->sock < 0)
501 return;
502
503 if (!zclient->redist[ZEBRA_ROUTE_ISIS])
504 return;
505
hassof390d2c2004-09-10 20:48:21 +0000506 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
507 {
508 if (prefix->family == AF_INET)
509 isis_zebra_route_add_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000510#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000511 else if (prefix->family == AF_INET6)
512 isis_zebra_route_add_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000513#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000514 }
515 else
516 {
517 if (prefix->family == AF_INET)
518 isis_zebra_route_del_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000519#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000520 else if (prefix->family == AF_INET6)
521 isis_zebra_route_del_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000522#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000523 }
jardineb5d44e2003-12-23 08:09:43 +0000524 return;
525}
526
hasso92365882005-01-18 13:53:33 +0000527static int
hassof390d2c2004-09-10 20:48:21 +0000528isis_zebra_read_ipv4 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000529 zebra_size_t length)
530{
531 struct stream *stream;
532 struct zapi_ipv4 api;
533 struct prefix_ipv4 p;
534 unsigned long ifindex;
535 struct in_addr nexthop;
536
537 stream = zclient->ibuf;
538 memset (&p, 0, sizeof (struct prefix_ipv4));
539 ifindex = 0;
540
hassof390d2c2004-09-10 20:48:21 +0000541 api.type = stream_getc (stream);
542 api.flags = stream_getc (stream);
jardineb5d44e2003-12-23 08:09:43 +0000543 api.message = stream_getc (stream);
544
545 p.family = AF_INET;
546 p.prefixlen = stream_getc (stream);
547 stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
hassof390d2c2004-09-10 20:48:21 +0000548
549 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
550 {
jardineb5d44e2003-12-23 08:09:43 +0000551 api.nexthop_num = stream_getc (stream);
552 nexthop.s_addr = stream_get_ipv4 (stream);
hassof390d2c2004-09-10 20:48:21 +0000553 }
554 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
555 {
556 api.ifindex_num = stream_getc (stream);
557 ifindex = stream_getl (stream);
558 }
jardineb5d44e2003-12-23 08:09:43 +0000559 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
560 api.distance = stream_getc (stream);
561 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
562 api.metric = stream_getl (stream);
563 else
564 api.metric = 0;
hassof390d2c2004-09-10 20:48:21 +0000565
566 if (command == ZEBRA_IPV4_ROUTE_ADD)
567 {
hassoc89c05d2005-09-04 21:36:36 +0000568 if (isis->debugs & DEBUG_ZEBRA)
569 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}