blob: 467122f6586df226badf3ca1216a2fbddf468ab7 [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"
Josh Bailey3f045a02012-03-24 08:35:20 -070039#include "isisd/isis_flags.h"
40#include "isisd/isis_misc.h"
41#include "isisd/isis_circuit.h"
42#include "isisd/isis_tlv.h"
hassoc89c05d2005-09-04 21:36:36 +000043#include "isisd/isisd.h"
jardineb5d44e2003-12-23 08:09:43 +000044#include "isisd/isis_circuit.h"
45#include "isisd/isis_csm.h"
Josh Bailey3f045a02012-03-24 08:35:20 -070046#include "isisd/isis_lsp.h"
jardineb5d44e2003-12-23 08:09:43 +000047#include "isisd/isis_route.h"
48#include "isisd/isis_zebra.h"
49
50struct zclient *zclient = NULL;
51
hasso18a6dce2004-10-03 18:18:34 +000052/* 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{
Josh Bailey3f045a02012-03-24 08:35:20 -070057 struct isis_area *area;
58 struct listnode *node;
hasso18a6dce2004-10-03 18:18:34 +000059 struct prefix router_id;
hasso18a6dce2004-10-03 18:18:34 +000060
Josh Bailey3f045a02012-03-24 08:35:20 -070061 zebra_router_id_update_read (zclient->ibuf, &router_id);
62 if (isis->router_id == router_id.u.prefix4.s_addr)
63 return 0;
hasso18a6dce2004-10-03 18:18:34 +000064
Josh Bailey3f045a02012-03-24 08:35:20 -070065 isis->router_id = router_id.u.prefix4.s_addr;
66 for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
67 if (listcount (area->area_addrs) > 0)
68 lsp_regenerate_schedule (area, area->is_type, 0);
69
hasso18a6dce2004-10-03 18:18:34 +000070 return 0;
71}
jardineb5d44e2003-12-23 08:09:43 +000072
hasso92365882005-01-18 13:53:33 +000073static int
jardineb5d44e2003-12-23 08:09:43 +000074isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
75{
76 struct interface *ifp;
77
78 ifp = zebra_interface_add_read (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +000079
hassoc89c05d2005-09-04 21:36:36 +000080 if (isis->debugs & DEBUG_ZEBRA)
81 zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
Paul Jakma41b36e92006-12-08 01:09:50 +000082 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
hassof390d2c2004-09-10 20:48:21 +000083
hassob30c5e62004-12-29 20:06:41 +000084 if (if_is_operative (ifp))
jardineb5d44e2003-12-23 08:09:43 +000085 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
hassof390d2c2004-09-10 20:48:21 +000086
jardineb5d44e2003-12-23 08:09:43 +000087 return 0;
88}
89
hasso92365882005-01-18 13:53:33 +000090static int
jardineb5d44e2003-12-23 08:09:43 +000091isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
92{
93 struct interface *ifp;
94 struct stream *s;
95
96 s = zclient->ibuf;
97 ifp = zebra_interface_state_read (s);
hassof390d2c2004-09-10 20:48:21 +000098
jardineb5d44e2003-12-23 08:09:43 +000099 if (!ifp)
100 return 0;
101
hassob30c5e62004-12-29 20:06:41 +0000102 if (if_is_operative (ifp))
jardineb5d44e2003-12-23 08:09:43 +0000103 zlog_warn ("Zebra: got delete of %s, but interface is still up",
hassof390d2c2004-09-10 20:48:21 +0000104 ifp->name);
jardineb5d44e2003-12-23 08:09:43 +0000105
hassoc89c05d2005-09-04 21:36:36 +0000106 if (isis->debugs & DEBUG_ZEBRA)
107 zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
Paul Jakma41b36e92006-12-08 01:09:50 +0000108 ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
jardineb5d44e2003-12-23 08:09:43 +0000109
Josh Bailey3f045a02012-03-24 08:35:20 -0700110 isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
ajsd2fc8892005-04-02 18:38:43 +0000111
112 /* Cannot call if_delete because we should retain the pseudo interface
113 in case there is configuration info attached to it. */
114 if_delete_retain(ifp);
hassof390d2c2004-09-10 20:48:21 +0000115
ajsd2fc8892005-04-02 18:38:43 +0000116 ifp->ifindex = IFINDEX_INTERNAL;
117
jardineb5d44e2003-12-23 08:09:43 +0000118 return 0;
119}
120
hasso92365882005-01-18 13:53:33 +0000121static int
hassof390d2c2004-09-10 20:48:21 +0000122isis_zebra_if_state_up (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000123 zebra_size_t length)
124{
125 struct interface *ifp;
hassof390d2c2004-09-10 20:48:21 +0000126
Josh Bailey3f045a02012-03-24 08:35:20 -0700127 ifp = zebra_interface_state_read (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +0000128
Josh Bailey3f045a02012-03-24 08:35:20 -0700129 if (ifp == NULL)
jardineb5d44e2003-12-23 08:09:43 +0000130 return 0;
hassof390d2c2004-09-10 20:48:21 +0000131
jardineb5d44e2003-12-23 08:09:43 +0000132 isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
hassof390d2c2004-09-10 20:48:21 +0000133
jardineb5d44e2003-12-23 08:09:43 +0000134 return 0;
135}
136
hasso92365882005-01-18 13:53:33 +0000137static int
hassof390d2c2004-09-10 20:48:21 +0000138isis_zebra_if_state_down (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000139 zebra_size_t length)
140{
141 struct interface *ifp;
Josh Bailey3f045a02012-03-24 08:35:20 -0700142 struct isis_circuit *circuit;
hassof390d2c2004-09-10 20:48:21 +0000143
Josh Bailey3f045a02012-03-24 08:35:20 -0700144 ifp = zebra_interface_state_read (zclient->ibuf);
hassof390d2c2004-09-10 20:48:21 +0000145
jardineb5d44e2003-12-23 08:09:43 +0000146 if (ifp == NULL)
147 return 0;
hassof390d2c2004-09-10 20:48:21 +0000148
Josh Bailey3f045a02012-03-24 08:35:20 -0700149 circuit = isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp),
150 ifp);
151 if (circuit)
152 SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
hassof390d2c2004-09-10 20:48:21 +0000153
jardineb5d44e2003-12-23 08:09:43 +0000154 return 0;
155}
156
hasso92365882005-01-18 13:53:33 +0000157static int
hassof390d2c2004-09-10 20:48:21 +0000158isis_zebra_if_address_add (int command, struct zclient *zclient,
159 zebra_size_t length)
jardineb5d44e2003-12-23 08:09:43 +0000160{
161 struct connected *c;
162 struct prefix *p;
hassof7c43dc2004-09-26 16:24:14 +0000163 char buf[BUFSIZ];
jardineb5d44e2003-12-23 08:09:43 +0000164
hassof390d2c2004-09-10 20:48:21 +0000165 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
166 zclient->ibuf);
167
jardineb5d44e2003-12-23 08:09:43 +0000168 if (c == NULL)
169 return 0;
hassof390d2c2004-09-10 20:48:21 +0000170
jardineb5d44e2003-12-23 08:09:43 +0000171 p = c->address;
hassof390d2c2004-09-10 20:48:21 +0000172
jardineb5d44e2003-12-23 08:09:43 +0000173 prefix2str (p, buf, BUFSIZ);
174#ifdef EXTREME_DEBUG
hassof390d2c2004-09-10 20:48:21 +0000175 if (p->family == AF_INET)
hasso529d65b2004-12-24 00:14:50 +0000176 zlog_debug ("connected IP address %s", buf);
jardineb5d44e2003-12-23 08:09:43 +0000177#ifdef HAVE_IPV6
178 if (p->family == AF_INET6)
hasso529d65b2004-12-24 00:14:50 +0000179 zlog_debug ("connected IPv6 address %s", buf);
jardineb5d44e2003-12-23 08:09:43 +0000180#endif /* HAVE_IPV6 */
181#endif /* EXTREME_DEBUG */
hassob30c5e62004-12-29 20:06:41 +0000182 if (if_is_operative (c->ifp))
183 isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
jardineb5d44e2003-12-23 08:09:43 +0000184
185 return 0;
186}
187
hasso92365882005-01-18 13:53:33 +0000188static int
hassof390d2c2004-09-10 20:48:21 +0000189isis_zebra_if_address_del (int command, struct zclient *client,
190 zebra_size_t length)
jardineb5d44e2003-12-23 08:09:43 +0000191{
192 struct connected *c;
193 struct interface *ifp;
hasso1cd80842004-10-07 20:07:40 +0000194#ifdef EXTREME_DEBUG
hassof891f442004-09-14 13:54:30 +0000195 struct prefix *p;
196 u_char buf[BUFSIZ];
hasso1cd80842004-10-07 20:07:40 +0000197#endif /* EXTREME_DEBUG */
jardineb5d44e2003-12-23 08:09:43 +0000198
hassof390d2c2004-09-10 20:48:21 +0000199 c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
200 zclient->ibuf);
201
jardineb5d44e2003-12-23 08:09:43 +0000202 if (c == NULL)
203 return 0;
hassof390d2c2004-09-10 20:48:21 +0000204
jardineb5d44e2003-12-23 08:09:43 +0000205 ifp = c->ifp;
hassof390d2c2004-09-10 20:48:21 +0000206
hassof891f442004-09-14 13:54:30 +0000207#ifdef EXTREME_DEBUG
208 p = c->address;
209 prefix2str (p, buf, BUFSIZ);
210
211 if (p->family == AF_INET)
hasso529d65b2004-12-24 00:14:50 +0000212 zlog_debug ("disconnected IP address %s", buf);
hassof891f442004-09-14 13:54:30 +0000213#ifdef HAVE_IPV6
214 if (p->family == AF_INET6)
hasso529d65b2004-12-24 00:14:50 +0000215 zlog_debug ("disconnected IPv6 address %s", buf);
hassof891f442004-09-14 13:54:30 +0000216#endif /* HAVE_IPV6 */
217#endif /* EXTREME_DEBUG */
hassof390d2c2004-09-10 20:48:21 +0000218
hassob30c5e62004-12-29 20:06:41 +0000219 if (if_is_operative (ifp))
220 isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
hassof891f442004-09-14 13:54:30 +0000221 connected_free (c);
hassof390d2c2004-09-10 20:48:21 +0000222
jardineb5d44e2003-12-23 08:09:43 +0000223 return 0;
224}
225
hasso92365882005-01-18 13:53:33 +0000226static void
hassof390d2c2004-09-10 20:48:21 +0000227isis_zebra_route_add_ipv4 (struct prefix *prefix,
228 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000229{
230 u_char message, flags;
231 int psize;
232 struct stream *stream;
233 struct isis_nexthop *nexthop;
234 struct listnode *node;
235
Josh Bailey3f045a02012-03-24 08:35:20 -0700236 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
jardineb5d44e2003-12-23 08:09:43 +0000237 return;
238
hassof390d2c2004-09-10 20:48:21 +0000239 if (zclient->redist[ZEBRA_ROUTE_ISIS])
240 {
241 message = 0;
242 flags = 0;
jardineb5d44e2003-12-23 08:09:43 +0000243
hassof390d2c2004-09-10 20:48:21 +0000244 SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
245 SET_FLAG (message, ZAPI_MESSAGE_METRIC);
hasso2097cd82003-12-23 11:51:08 +0000246#if 0
hassof390d2c2004-09-10 20:48:21 +0000247 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
hasso2097cd82003-12-23 11:51:08 +0000248#endif
hassof390d2c2004-09-10 20:48:21 +0000249
250 stream = zclient->obuf;
251 stream_reset (stream);
pauld3092e72006-01-17 17:33:46 +0000252 zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD);
hassof390d2c2004-09-10 20:48:21 +0000253 /* type */
254 stream_putc (stream, ZEBRA_ROUTE_ISIS);
255 /* flags */
256 stream_putc (stream, flags);
257 /* message */
258 stream_putc (stream, message);
259 /* prefix information */
260 psize = PSIZE (prefix->prefixlen);
261 stream_putc (stream, prefix->prefixlen);
262 stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
263
264 stream_putc (stream, listcount (route_info->nexthops));
265
266 /* Nexthop, ifindex, distance and metric information */
paul1eb8ef22005-04-07 07:30:20 +0000267 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
hassof390d2c2004-09-10 20:48:21 +0000268 {
hassof390d2c2004-09-10 20:48:21 +0000269 /* FIXME: can it be ? */
270 if (nexthop->ip.s_addr != INADDR_ANY)
271 {
272 stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
273 stream_put_in_addr (stream, &nexthop->ip);
274 }
275 else
276 {
277 stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
278 stream_putl (stream, nexthop->ifindex);
279 }
280 }
281#if 0
282 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
283 stream_putc (stream, route_info->depth);
284#endif
285 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
286 stream_putl (stream, route_info->cost);
287
288 stream_putw_at (stream, 0, stream_get_endp (stream));
ajs634f9ea2005-04-11 15:51:40 +0000289 zclient_send_message(zclient);
Josh Bailey3f045a02012-03-24 08:35:20 -0700290 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
291 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
hassof390d2c2004-09-10 20:48:21 +0000292 }
jardineb5d44e2003-12-23 08:09:43 +0000293}
294
hasso92365882005-01-18 13:53:33 +0000295static void
hassof390d2c2004-09-10 20:48:21 +0000296isis_zebra_route_del_ipv4 (struct prefix *prefix,
297 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000298{
299 struct zapi_ipv4 api;
300 struct prefix_ipv4 prefix4;
hassof390d2c2004-09-10 20:48:21 +0000301
302 if (zclient->redist[ZEBRA_ROUTE_ISIS])
303 {
304 api.type = ZEBRA_ROUTE_ISIS;
305 api.flags = 0;
306 api.message = 0;
307 prefix4.family = AF_INET;
308 prefix4.prefixlen = prefix->prefixlen;
309 prefix4.prefix = prefix->u.prefix4;
310 zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
311 }
Josh Bailey3f045a02012-03-24 08:35:20 -0700312 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
hassof390d2c2004-09-10 20:48:21 +0000313
jardineb5d44e2003-12-23 08:09:43 +0000314 return;
315}
316
317#ifdef HAVE_IPV6
318void
319isis_zebra_route_add_ipv6 (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000320 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000321{
322 struct zapi_ipv6 api;
323 struct in6_addr **nexthop_list;
324 unsigned int *ifindex_list;
325 struct isis_nexthop6 *nexthop6;
326 int i, size;
327 struct listnode *node;
328 struct prefix_ipv6 prefix6;
329
Josh Bailey3f045a02012-03-24 08:35:20 -0700330 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
jardineb5d44e2003-12-23 08:09:43 +0000331 return;
hassof390d2c2004-09-10 20:48:21 +0000332
jardineb5d44e2003-12-23 08:09:43 +0000333 api.type = ZEBRA_ROUTE_ISIS;
334 api.flags = 0;
335 api.message = 0;
336 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
337 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
338 SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
339 api.metric = route_info->cost;
340#if 0
341 SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
342 api.distance = route_info->depth;
343#endif
344 api.nexthop_num = listcount (route_info->nexthops6);
345 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000346
jardineb5d44e2003-12-23 08:09:43 +0000347 /* allocate memory for nexthop_list */
348 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
349 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000350 if (!nexthop_list)
351 {
352 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
353 return;
354 }
355
jardineb5d44e2003-12-23 08:09:43 +0000356 /* allocate memory for ifindex_list */
357 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
358 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000359 if (!ifindex_list)
360 {
361 zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
362 XFREE (MTYPE_ISIS_TMP, nexthop_list);
363 return;
364 }
365
jardineb5d44e2003-12-23 08:09:43 +0000366 /* for each nexthop */
367 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000368 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000369 {
hassof390d2c2004-09-10 20:48:21 +0000370 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
371 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
372 {
373 api.nexthop_num--;
374 api.ifindex_num--;
375 continue;
376 }
377
378 nexthop_list[i] = &nexthop6->ip6;
379 ifindex_list[i] = nexthop6->ifindex;
380 i++;
jardineb5d44e2003-12-23 08:09:43 +0000381 }
hassof390d2c2004-09-10 20:48:21 +0000382
jardineb5d44e2003-12-23 08:09:43 +0000383 api.nexthop = nexthop_list;
384 api.ifindex = ifindex_list;
hassof390d2c2004-09-10 20:48:21 +0000385
386 if (api.nexthop_num && api.ifindex_num)
387 {
388 prefix6.family = AF_INET6;
389 prefix6.prefixlen = prefix->prefixlen;
390 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
391 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
Josh Bailey3f045a02012-03-24 08:35:20 -0700392 SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
393 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
hassof390d2c2004-09-10 20:48:21 +0000394 }
395
jardineb5d44e2003-12-23 08:09:43 +0000396 XFREE (MTYPE_ISIS_TMP, nexthop_list);
397 XFREE (MTYPE_ISIS_TMP, ifindex_list);
hassof390d2c2004-09-10 20:48:21 +0000398
jardineb5d44e2003-12-23 08:09:43 +0000399 return;
400}
401
hasso92365882005-01-18 13:53:33 +0000402static void
hassof390d2c2004-09-10 20:48:21 +0000403isis_zebra_route_del_ipv6 (struct prefix *prefix,
404 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000405{
406 struct zapi_ipv6 api;
407 struct in6_addr **nexthop_list;
408 unsigned int *ifindex_list;
409 struct isis_nexthop6 *nexthop6;
410 int i, size;
411 struct listnode *node;
412 struct prefix_ipv6 prefix6;
413
Josh Bailey3f045a02012-03-24 08:35:20 -0700414 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
jardineb5d44e2003-12-23 08:09:43 +0000415 return;
hassof390d2c2004-09-10 20:48:21 +0000416
jardineb5d44e2003-12-23 08:09:43 +0000417 api.type = ZEBRA_ROUTE_ISIS;
418 api.flags = 0;
419 api.message = 0;
420 SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
421 SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
422 api.nexthop_num = listcount (route_info->nexthops6);
423 api.ifindex_num = listcount (route_info->nexthops6);
hassof390d2c2004-09-10 20:48:21 +0000424
jardineb5d44e2003-12-23 08:09:43 +0000425 /* allocate memory for nexthop_list */
426 size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
427 nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000428 if (!nexthop_list)
429 {
430 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
431 return;
432 }
433
jardineb5d44e2003-12-23 08:09:43 +0000434 /* allocate memory for ifindex_list */
435 size = sizeof (unsigned int) * listcount (route_info->nexthops6);
436 ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
hassof390d2c2004-09-10 20:48:21 +0000437 if (!ifindex_list)
438 {
439 zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
440 XFREE (MTYPE_ISIS_TMP, nexthop_list);
441 return;
442 }
443
jardineb5d44e2003-12-23 08:09:43 +0000444 /* for each nexthop */
445 i = 0;
paul1eb8ef22005-04-07 07:30:20 +0000446 for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
hassof390d2c2004-09-10 20:48:21 +0000447 {
hassof390d2c2004-09-10 20:48:21 +0000448 if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
449 !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
450 {
451 api.nexthop_num--;
452 api.ifindex_num--;
453 continue;
454 }
455
456 nexthop_list[i] = &nexthop6->ip6;
457 ifindex_list[i] = nexthop6->ifindex;
458 i++;
jardineb5d44e2003-12-23 08:09:43 +0000459 }
hassof390d2c2004-09-10 20:48:21 +0000460
jardineb5d44e2003-12-23 08:09:43 +0000461 api.nexthop = nexthop_list;
462 api.ifindex = ifindex_list;
jardineb5d44e2003-12-23 08:09:43 +0000463
hassof390d2c2004-09-10 20:48:21 +0000464 if (api.nexthop_num && api.ifindex_num)
465 {
466 prefix6.family = AF_INET6;
467 prefix6.prefixlen = prefix->prefixlen;
468 memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
469 zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
Josh Bailey3f045a02012-03-24 08:35:20 -0700470 UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
hassof390d2c2004-09-10 20:48:21 +0000471 }
472
473 XFREE (MTYPE_ISIS_TMP, nexthop_list);
474 XFREE (MTYPE_ISIS_TMP, ifindex_list);
475}
jardineb5d44e2003-12-23 08:09:43 +0000476
477#endif /* HAVE_IPV6 */
478
jardineb5d44e2003-12-23 08:09:43 +0000479void
480isis_zebra_route_update (struct prefix *prefix,
hassof390d2c2004-09-10 20:48:21 +0000481 struct isis_route_info *route_info)
jardineb5d44e2003-12-23 08:09:43 +0000482{
483 if (zclient->sock < 0)
484 return;
485
486 if (!zclient->redist[ZEBRA_ROUTE_ISIS])
487 return;
488
hassof390d2c2004-09-10 20:48:21 +0000489 if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
490 {
491 if (prefix->family == AF_INET)
492 isis_zebra_route_add_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000493#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000494 else if (prefix->family == AF_INET6)
495 isis_zebra_route_add_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000496#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000497 }
498 else
499 {
500 if (prefix->family == AF_INET)
501 isis_zebra_route_del_ipv4 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000502#ifdef HAVE_IPV6
hassof390d2c2004-09-10 20:48:21 +0000503 else if (prefix->family == AF_INET6)
504 isis_zebra_route_del_ipv6 (prefix, route_info);
jardineb5d44e2003-12-23 08:09:43 +0000505#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000506 }
jardineb5d44e2003-12-23 08:09:43 +0000507 return;
508}
509
hasso92365882005-01-18 13:53:33 +0000510static int
hassof390d2c2004-09-10 20:48:21 +0000511isis_zebra_read_ipv4 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000512 zebra_size_t length)
513{
514 struct stream *stream;
515 struct zapi_ipv4 api;
516 struct prefix_ipv4 p;
517 unsigned long ifindex;
518 struct in_addr nexthop;
519
520 stream = zclient->ibuf;
521 memset (&p, 0, sizeof (struct prefix_ipv4));
522 ifindex = 0;
523
hassof390d2c2004-09-10 20:48:21 +0000524 api.type = stream_getc (stream);
525 api.flags = stream_getc (stream);
jardineb5d44e2003-12-23 08:09:43 +0000526 api.message = stream_getc (stream);
527
528 p.family = AF_INET;
529 p.prefixlen = stream_getc (stream);
530 stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
hassof390d2c2004-09-10 20:48:21 +0000531
532 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
533 {
jardineb5d44e2003-12-23 08:09:43 +0000534 api.nexthop_num = stream_getc (stream);
535 nexthop.s_addr = stream_get_ipv4 (stream);
hassof390d2c2004-09-10 20:48:21 +0000536 }
537 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
538 {
539 api.ifindex_num = stream_getc (stream);
540 ifindex = stream_getl (stream);
541 }
jardineb5d44e2003-12-23 08:09:43 +0000542 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
543 api.distance = stream_getc (stream);
544 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
545 api.metric = stream_getl (stream);
546 else
547 api.metric = 0;
hassof390d2c2004-09-10 20:48:21 +0000548
549 if (command == ZEBRA_IPV4_ROUTE_ADD)
550 {
hassoc89c05d2005-09-04 21:36:36 +0000551 if (isis->debugs & DEBUG_ZEBRA)
552 zlog_debug ("IPv4 Route add from Z");
hassof390d2c2004-09-10 20:48:21 +0000553 }
jardineb5d44e2003-12-23 08:09:43 +0000554
555 return 0;
556}
557
Paul Jakma41b36e92006-12-08 01:09:50 +0000558#ifdef HAVE_IPV6
hasso92365882005-01-18 13:53:33 +0000559static int
hassof390d2c2004-09-10 20:48:21 +0000560isis_zebra_read_ipv6 (int command, struct zclient *zclient,
jardineb5d44e2003-12-23 08:09:43 +0000561 zebra_size_t length)
562{
jardineb5d44e2003-12-23 08:09:43 +0000563 return 0;
564}
Paul Jakma41b36e92006-12-08 01:09:50 +0000565#endif
jardineb5d44e2003-12-23 08:09:43 +0000566
567#define ISIS_TYPE_IS_REDISTRIBUTED(T) \
568T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type]
569
570int
571isis_distribute_list_update (int routetype)
572{
573 return 0;
574}
575
hasso92365882005-01-18 13:53:33 +0000576#if 0 /* Not yet. */
577static int
hassof390d2c2004-09-10 20:48:21 +0000578isis_redistribute_default_set (int routetype, int metric_type,
579 int metric_value)
jardineb5d44e2003-12-23 08:09:43 +0000580{
581 return 0;
582}
hasso92365882005-01-18 13:53:33 +0000583#endif /* 0 */
jardineb5d44e2003-12-23 08:09:43 +0000584
jardineb5d44e2003-12-23 08:09:43 +0000585void
586isis_zebra_init ()
587{
jardineb5d44e2003-12-23 08:09:43 +0000588 zclient = zclient_new ();
589 zclient_init (zclient, ZEBRA_ROUTE_ISIS);
hasso18a6dce2004-10-03 18:18:34 +0000590 zclient->router_id_update = isis_router_id_update_zebra;
jardineb5d44e2003-12-23 08:09:43 +0000591 zclient->interface_add = isis_zebra_if_add;
592 zclient->interface_delete = isis_zebra_if_del;
593 zclient->interface_up = isis_zebra_if_state_up;
594 zclient->interface_down = isis_zebra_if_state_down;
595 zclient->interface_address_add = isis_zebra_if_address_add;
596 zclient->interface_address_delete = isis_zebra_if_address_del;
597 zclient->ipv4_route_add = isis_zebra_read_ipv4;
598 zclient->ipv4_route_delete = isis_zebra_read_ipv4;
599#ifdef HAVE_IPV6
600 zclient->ipv6_route_add = isis_zebra_read_ipv6;
601 zclient->ipv6_route_delete = isis_zebra_read_ipv6;
602#endif /* HAVE_IPV6 */
603
604 return;
605}