blob: 9ee5ffc5d22ea07a8cc5cdfab13c1114f0820a13 [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",
Paul Jakma41b36e92006-12-08 01:09:50 +000075 ifp->name, ifp->ifindex, (long)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",
Paul Jakma41b36e92006-12-08 01:09:50 +0000101 ifp->name, ifp->ifindex, (long)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);
pauld3092e72006-01-17 17:33:46 +0000270 zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD);
hassof390d2c2004-09-10 20:48:21 +0000271 /* type */
272 stream_putc (stream, ZEBRA_ROUTE_ISIS);
273 /* flags */
274 stream_putc (stream, flags);
275 /* message */
276 stream_putc (stream, message);
277 /* prefix information */
278 psize = PSIZE (prefix->prefixlen);
279 stream_putc (stream, prefix->prefixlen);
280 stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
281
282 stream_putc (stream, listcount (route_info->nexthops));
283
284 /* Nexthop, ifindex, distance and metric information */
paul1eb8ef22005-04-07 07:30:20 +0000285 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
hassof390d2c2004-09-10 20:48:21 +0000286 {
hassof390d2c2004-09-10 20:48:21 +0000287 /* 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));
ajs634f9ea2005-04-11 15:51:40 +0000307 zclient_send_message(zclient);
hassofac1f7c2005-09-26 18:26:26 +0000308 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
hassof390d2c2004-09-10 20:48:21 +0000309 }
jardineb5d44e2003-12-23 08:09:43 +0000310}
311
hasso92365882005-01-18 13:53:33 +0000312static void
hassof390d2c2004-09-10 20:48:21 +0000313isis_zebra_route_del_ipv4 (struct prefix *prefix,
314 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000315{
316 struct zapi_ipv4 api;
317 struct prefix_ipv4 prefix4;
hassof390d2c2004-09-10 20:48:21 +0000318
319 if (zclient->redist[ZEBRA_ROUTE_ISIS])
320 {
321 api.type = ZEBRA_ROUTE_ISIS;
322 api.flags = 0;
323 api.message = 0;
324 prefix4.family = AF_INET;
325 prefix4.prefixlen = prefix->prefixlen;
326 prefix4.prefix = prefix->u.prefix4;
327 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
328 }
hassofac1f7c2005-09-26 18:26:26 +0000329 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
hassof390d2c2004-09-10 20:48:21 +0000330
jardineb5d44e2003-12-23 08:09:43 +0000331 return;
332}
333
334#ifdef HAVE_IPV6
335void
336isis_zebra_route_add_ipv6 (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000337 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000338{
339 struct zapi_ipv6 api;
340 struct in6_addr **nexthop_list;
341 unsigned int *ifindex_list;
342 struct isis_nexthop6 *nexthop6;
343 int i, size;
344 struct listnode *node;
345 struct prefix_ipv6 prefix6;
346
347 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
348 return;
hassof390d2c2004-09-10 20:48:21 +0000349
jardineb5d44e2003-12-23 08:09:43 +0000350 api.type = ZEBRA_ROUTE_ISIS;
351 api.flags = 0;
352 api.message = 0;
353 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
354 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
355 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
356 api.metric = route_info->cost;
357#if 0
358 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
359 api.distance = route_info->depth;
360#endif
361 api.nexthop_num = listcount (route_info->nexthops6);
362 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000363
jardineb5d44e2003-12-23 08:09:43 +0000364 /* allocate memory for nexthop_list */
365 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
366 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000367 if (!nexthop_list)
368 {
369 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
370 return;
371 }
372
jardineb5d44e2003-12-23 08:09:43 +0000373 /* allocate memory for ifindex_list */
374 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
375 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000376 if (!ifindex_list)
377 {
378 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
379 XFREE (MTYPE_ISIS_TMP, nexthop_list);
380 return;
381 }
382
jardineb5d44e2003-12-23 08:09:43 +0000383 /* for each nexthop */
384 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000385 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000386 {
hassof390d2c2004-09-10 20:48:21 +0000387 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;
paul1eb8ef22005-04-07 07:30:20 +0000462 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000463 {
hassof390d2c2004-09-10 20:48:21 +0000464 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
465 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
466 {
467 api.nexthop_num--;
468 api.ifindex_num--;
469 continue;
470 }
471
472 nexthop_list[i] = &nexthop6->ip6;
473 ifindex_list[i] = nexthop6->ifindex;
474 i++;
jardineb5d44e2003-12-23 08:09:43 +0000475 }
hassof390d2c2004-09-10 20:48:21 +0000476
jardineb5d44e2003-12-23 08:09:43 +0000477 api.nexthop = nexthop_list;
478 api.ifindex = ifindex_list;
jardineb5d44e2003-12-23 08:09:43 +0000479
hassof390d2c2004-09-10 20:48:21 +0000480 if (api.nexthop_num && api.ifindex_num)
481 {
482 prefix6.family = AF_INET6;
483 prefix6.prefixlen = prefix->prefixlen;
484 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
485 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
486 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
487 }
488
489 XFREE (MTYPE_ISIS_TMP, nexthop_list);
490 XFREE (MTYPE_ISIS_TMP, ifindex_list);
491}
jardineb5d44e2003-12-23 08:09:43 +0000492
493#endif /* HAVE_IPV6 */
494
jardineb5d44e2003-12-23 08:09:43 +0000495void
496isis_zebra_route_update (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000497 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000498{
499 if (zclient->sock < 0)
500 return;
501
502 if (!zclient->redist[ZEBRA_ROUTE_ISIS])
503 return;
504
hassof390d2c2004-09-10 20:48:21 +0000505 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
506 {
507 if (prefix->family == AF_INET)
508 isis_zebra_route_add_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000509#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000510 else if (prefix->family == AF_INET6)
511 isis_zebra_route_add_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000512#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000513 }
514 else
515 {
516 if (prefix->family == AF_INET)
517 isis_zebra_route_del_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000518#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000519 else if (prefix->family == AF_INET6)
520 isis_zebra_route_del_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000521#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000522 }
jardineb5d44e2003-12-23 08:09:43 +0000523 return;
524}
525
hasso92365882005-01-18 13:53:33 +0000526static int
hassof390d2c2004-09-10 20:48:21 +0000527isis_zebra_read_ipv4 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000528 zebra_size_t length)
529{
530 struct stream *stream;
531 struct zapi_ipv4 api;
532 struct prefix_ipv4 p;
533 unsigned long ifindex;
534 struct in_addr nexthop;
535
536 stream = zclient->ibuf;
537 memset (&p, 0, sizeof (struct prefix_ipv4));
538 ifindex = 0;
539
hassof390d2c2004-09-10 20:48:21 +0000540 api.type = stream_getc (stream);
541 api.flags = stream_getc (stream);
jardineb5d44e2003-12-23 08:09:43 +0000542 api.message = stream_getc (stream);
543
544 p.family = AF_INET;
545 p.prefixlen = stream_getc (stream);
546 stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
hassof390d2c2004-09-10 20:48:21 +0000547
548 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
549 {
jardineb5d44e2003-12-23 08:09:43 +0000550 api.nexthop_num = stream_getc (stream);
551 nexthop.s_addr = stream_get_ipv4 (stream);
hassof390d2c2004-09-10 20:48:21 +0000552 }
553 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
554 {
555 api.ifindex_num = stream_getc (stream);
556 ifindex = stream_getl (stream);
557 }
jardineb5d44e2003-12-23 08:09:43 +0000558 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
559 api.distance = stream_getc (stream);
560 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
561 api.metric = stream_getl (stream);
562 else
563 api.metric = 0;
hassof390d2c2004-09-10 20:48:21 +0000564
565 if (command == ZEBRA_IPV4_ROUTE_ADD)
566 {
hassoc89c05d2005-09-04 21:36:36 +0000567 if (isis->debugs & DEBUG_ZEBRA)
568 zlog_debug ("IPv4 Route add from Z");
hassof390d2c2004-09-10 20:48:21 +0000569 }
jardineb5d44e2003-12-23 08:09:43 +0000570
571 return 0;
572}
573
Paul Jakma41b36e92006-12-08 01:09:50 +0000574#ifdef HAVE_IPV6
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}
Paul Jakma41b36e92006-12-08 01:09:50 +0000581#endif
jardineb5d44e2003-12-23 08:09:43 +0000582
583#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
584T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
585
586int
587isis_distribute_list_update (int routetype)
588{
589 return 0;
590}
591
hasso92365882005-01-18 13:53:33 +0000592#if 0 /* Not yet. */
593static int
hassof390d2c2004-09-10 20:48:21 +0000594isis_redistribute_default_set (int routetype, int metric_type,
595 int metric_value)
jardineb5d44e2003-12-23 08:09:43 +0000596{
597 return 0;
598}
hasso92365882005-01-18 13:53:33 +0000599#endif /* 0 */
jardineb5d44e2003-12-23 08:09:43 +0000600
jardineb5d44e2003-12-23 08:09:43 +0000601void
602isis_zebra_init ()
603{
jardineb5d44e2003-12-23 08:09:43 +0000604 zclient = zclient_new ();
605 zclient_init (zclient, ZEBRA_ROUTE_ISIS);
hasso18a6dce2004-10-03 18:18:34 +0000606 zclient->router_id_update = isis_router_id_update_zebra;
jardineb5d44e2003-12-23 08:09:43 +0000607 zclient->interface_add = isis_zebra_if_add;
608 zclient->interface_delete = isis_zebra_if_del;
609 zclient->interface_up = isis_zebra_if_state_up;
610 zclient->interface_down = isis_zebra_if_state_down;
611 zclient->interface_address_add = isis_zebra_if_address_add;
612 zclient->interface_address_delete = isis_zebra_if_address_del;
613 zclient->ipv4_route_add = isis_zebra_read_ipv4;
614 zclient->ipv4_route_delete = isis_zebra_read_ipv4;
615#ifdef HAVE_IPV6
616 zclient->ipv6_route_add = isis_zebra_read_ipv6;
617 zclient->ipv6_route_delete = isis_zebra_read_ipv6;
618#endif /* HAVE_IPV6 */
619
620 return;
621}