blob: d5ccef9ea0947eacb9e90203ec8b2ac887099fb9 [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);
Denis Ovsienkob4e45f62011-12-05 16:35:14 +0400277 /* SAFI */
278 stream_putw (stream, SAFI_UNICAST);
hassof390d2c2004-09-10 20:48:21 +0000279 /* prefix information */
280 psize = PSIZE (prefix->prefixlen);
281 stream_putc (stream, prefix->prefixlen);
282 stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
283
284 stream_putc (stream, listcount (route_info->nexthops));
285
286 /* Nexthop, ifindex, distance and metric information */
paul1eb8ef22005-04-07 07:30:20 +0000287 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
hassof390d2c2004-09-10 20:48:21 +0000288 {
hassof390d2c2004-09-10 20:48:21 +0000289 /* FIXME: can it be ? */
290 if (nexthop->ip.s_addr != INADDR_ANY)
291 {
292 stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
293 stream_put_in_addr (stream, &nexthop->ip);
294 }
295 else
296 {
297 stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
298 stream_putl (stream, nexthop->ifindex);
299 }
300 }
301#if 0
302 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
303 stream_putc (stream, route_info->depth);
304#endif
305 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
306 stream_putl (stream, route_info->cost);
307
308 stream_putw_at (stream, 0, stream_get_endp (stream));
ajs634f9ea2005-04-11 15:51:40 +0000309 zclient_send_message(zclient);
hassofac1f7c2005-09-26 18:26:26 +0000310 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
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;
Denis Ovsienkob4e45f62011-12-05 16:35:14 +0400326 api.safi = SAFI_UNICAST;
hassof390d2c2004-09-10 20:48:21 +0000327 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;
Denis Ovsienkob4e45f62011-12-05 16:35:14 +0400356 api.safi = SAFI_UNICAST;
jardineb5d44e2003-12-23 08:09:43 +0000357 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
358 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
359 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
360 api.metric = route_info->cost;
361#if 0
362 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
363 api.distance = route_info->depth;
364#endif
365 api.nexthop_num = listcount (route_info->nexthops6);
366 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000367
jardineb5d44e2003-12-23 08:09:43 +0000368 /* allocate memory for nexthop_list */
369 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
370 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000371 if (!nexthop_list)
372 {
373 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
374 return;
375 }
376
jardineb5d44e2003-12-23 08:09:43 +0000377 /* allocate memory for ifindex_list */
378 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
379 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000380 if (!ifindex_list)
381 {
382 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
383 XFREE (MTYPE_ISIS_TMP, nexthop_list);
384 return;
385 }
386
jardineb5d44e2003-12-23 08:09:43 +0000387 /* for each nexthop */
388 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000389 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000390 {
hassof390d2c2004-09-10 20:48:21 +0000391 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
392 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
393 {
394 api.nexthop_num--;
395 api.ifindex_num--;
396 continue;
397 }
398
399 nexthop_list[i] = &nexthop6->ip6;
400 ifindex_list[i] = nexthop6->ifindex;
401 i++;
jardineb5d44e2003-12-23 08:09:43 +0000402 }
hassof390d2c2004-09-10 20:48:21 +0000403
jardineb5d44e2003-12-23 08:09:43 +0000404 api.nexthop = nexthop_list;
405 api.ifindex = ifindex_list;
hassof390d2c2004-09-10 20:48:21 +0000406
407 if (api.nexthop_num && api.ifindex_num)
408 {
409 prefix6.family = AF_INET6;
410 prefix6.prefixlen = prefix->prefixlen;
411 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
412 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
413 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
414 }
415
jardineb5d44e2003-12-23 08:09:43 +0000416 XFREE (MTYPE_ISIS_TMP, nexthop_list);
417 XFREE (MTYPE_ISIS_TMP, ifindex_list);
hassof390d2c2004-09-10 20:48:21 +0000418
jardineb5d44e2003-12-23 08:09:43 +0000419 return;
420}
421
hasso92365882005-01-18 13:53:33 +0000422static void
hassof390d2c2004-09-10 20:48:21 +0000423isis_zebra_route_del_ipv6 (struct prefix *prefix,
424 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000425{
426 struct zapi_ipv6 api;
427 struct in6_addr **nexthop_list;
428 unsigned int *ifindex_list;
429 struct isis_nexthop6 *nexthop6;
430 int i, size;
431 struct listnode *node;
432 struct prefix_ipv6 prefix6;
433
434 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
435 return;
hassof390d2c2004-09-10 20:48:21 +0000436
jardineb5d44e2003-12-23 08:09:43 +0000437 api.type = ZEBRA_ROUTE_ISIS;
438 api.flags = 0;
439 api.message = 0;
Denis Ovsienkob4e45f62011-12-05 16:35:14 +0400440 api.safi = SAFI_UNICAST;
jardineb5d44e2003-12-23 08:09:43 +0000441 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
442 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
443 api.nexthop_num = listcount (route_info->nexthops6);
444 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000445
jardineb5d44e2003-12-23 08:09:43 +0000446 /* allocate memory for nexthop_list */
447 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
448 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000449 if (!nexthop_list)
450 {
451 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
452 return;
453 }
454
jardineb5d44e2003-12-23 08:09:43 +0000455 /* allocate memory for ifindex_list */
456 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
457 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000458 if (!ifindex_list)
459 {
460 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
461 XFREE (MTYPE_ISIS_TMP, nexthop_list);
462 return;
463 }
464
jardineb5d44e2003-12-23 08:09:43 +0000465 /* for each nexthop */
466 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000467 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000468 {
hassof390d2c2004-09-10 20:48:21 +0000469 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
470 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
471 {
472 api.nexthop_num--;
473 api.ifindex_num--;
474 continue;
475 }
476
477 nexthop_list[i] = &nexthop6->ip6;
478 ifindex_list[i] = nexthop6->ifindex;
479 i++;
jardineb5d44e2003-12-23 08:09:43 +0000480 }
hassof390d2c2004-09-10 20:48:21 +0000481
jardineb5d44e2003-12-23 08:09:43 +0000482 api.nexthop = nexthop_list;
483 api.ifindex = ifindex_list;
jardineb5d44e2003-12-23 08:09:43 +0000484
hassof390d2c2004-09-10 20:48:21 +0000485 if (api.nexthop_num && api.ifindex_num)
486 {
487 prefix6.family = AF_INET6;
488 prefix6.prefixlen = prefix->prefixlen;
489 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
490 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
491 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
492 }
493
494 XFREE (MTYPE_ISIS_TMP, nexthop_list);
495 XFREE (MTYPE_ISIS_TMP, ifindex_list);
496}
jardineb5d44e2003-12-23 08:09:43 +0000497
498#endif /* HAVE_IPV6 */
499
jardineb5d44e2003-12-23 08:09:43 +0000500void
501isis_zebra_route_update (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000502 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000503{
504 if (zclient->sock < 0)
505 return;
506
507 if (!zclient->redist[ZEBRA_ROUTE_ISIS])
508 return;
509
hassof390d2c2004-09-10 20:48:21 +0000510 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
511 {
512 if (prefix->family == AF_INET)
513 isis_zebra_route_add_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000514#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000515 else if (prefix->family == AF_INET6)
516 isis_zebra_route_add_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000517#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000518 }
519 else
520 {
521 if (prefix->family == AF_INET)
522 isis_zebra_route_del_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000523#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000524 else if (prefix->family == AF_INET6)
525 isis_zebra_route_del_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000526#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000527 }
jardineb5d44e2003-12-23 08:09:43 +0000528 return;
529}
530
hasso92365882005-01-18 13:53:33 +0000531static int
hassof390d2c2004-09-10 20:48:21 +0000532isis_zebra_read_ipv4 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000533 zebra_size_t length)
534{
535 struct stream *stream;
536 struct zapi_ipv4 api;
537 struct prefix_ipv4 p;
538 unsigned long ifindex;
539 struct in_addr nexthop;
540
541 stream = zclient->ibuf;
542 memset (&p, 0, sizeof (struct prefix_ipv4));
543 ifindex = 0;
544
hassof390d2c2004-09-10 20:48:21 +0000545 api.type = stream_getc (stream);
546 api.flags = stream_getc (stream);
jardineb5d44e2003-12-23 08:09:43 +0000547 api.message = stream_getc (stream);
548
549 p.family = AF_INET;
550 p.prefixlen = stream_getc (stream);
551 stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
hassof390d2c2004-09-10 20:48:21 +0000552
553 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
554 {
jardineb5d44e2003-12-23 08:09:43 +0000555 api.nexthop_num = stream_getc (stream);
556 nexthop.s_addr = stream_get_ipv4 (stream);
hassof390d2c2004-09-10 20:48:21 +0000557 }
558 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
559 {
560 api.ifindex_num = stream_getc (stream);
561 ifindex = stream_getl (stream);
562 }
jardineb5d44e2003-12-23 08:09:43 +0000563 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
564 api.distance = stream_getc (stream);
565 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
566 api.metric = stream_getl (stream);
567 else
568 api.metric = 0;
hassof390d2c2004-09-10 20:48:21 +0000569
570 if (command == ZEBRA_IPV4_ROUTE_ADD)
571 {
hassoc89c05d2005-09-04 21:36:36 +0000572 if (isis->debugs & DEBUG_ZEBRA)
573 zlog_debug ("IPv4 Route add from Z");
hassof390d2c2004-09-10 20:48:21 +0000574 }
jardineb5d44e2003-12-23 08:09:43 +0000575
576 return 0;
577}
578
Paul Jakma41b36e92006-12-08 01:09:50 +0000579#ifdef HAVE_IPV6
hasso92365882005-01-18 13:53:33 +0000580static int
hassof390d2c2004-09-10 20:48:21 +0000581isis_zebra_read_ipv6 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000582 zebra_size_t length)
583{
jardineb5d44e2003-12-23 08:09:43 +0000584 return 0;
585}
Paul Jakma41b36e92006-12-08 01:09:50 +0000586#endif
jardineb5d44e2003-12-23 08:09:43 +0000587
588#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
589T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
590
591int
592isis_distribute_list_update (int routetype)
593{
594 return 0;
595}
596
hasso92365882005-01-18 13:53:33 +0000597#if 0 /* Not yet. */
598static int
hassof390d2c2004-09-10 20:48:21 +0000599isis_redistribute_default_set (int routetype, int metric_type,
600 int metric_value)
jardineb5d44e2003-12-23 08:09:43 +0000601{
602 return 0;
603}
hasso92365882005-01-18 13:53:33 +0000604#endif /* 0 */
jardineb5d44e2003-12-23 08:09:43 +0000605
jardineb5d44e2003-12-23 08:09:43 +0000606void
607isis_zebra_init ()
608{
jardineb5d44e2003-12-23 08:09:43 +0000609 zclient = zclient_new ();
610 zclient_init (zclient, ZEBRA_ROUTE_ISIS);
hasso18a6dce2004-10-03 18:18:34 +0000611 zclient->router_id_update = isis_router_id_update_zebra;
jardineb5d44e2003-12-23 08:09:43 +0000612 zclient->interface_add = isis_zebra_if_add;
613 zclient->interface_delete = isis_zebra_if_del;
614 zclient->interface_up = isis_zebra_if_state_up;
615 zclient->interface_down = isis_zebra_if_state_down;
616 zclient->interface_address_add = isis_zebra_if_address_add;
617 zclient->interface_address_delete = isis_zebra_if_address_del;
618 zclient->ipv4_route_add = isis_zebra_read_ipv4;
619 zclient->ipv4_route_delete = isis_zebra_read_ipv4;
620#ifdef HAVE_IPV6
621 zclient->ipv6_route_add = isis_zebra_read_ipv6;
622 zclient->ipv6_route_delete = isis_zebra_read_ipv6;
623#endif /* HAVE_IPV6 */
624
625 return;
626}