isis_zebra.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /*
  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. * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public Licenseas published by the Free
  11. * Software Foundation; either version 2 of the License, or (at your option)
  12. * any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,but WITHOUT
  15. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  17. * more details.
  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. #include <zebra.h>
  23. #include "thread.h"
  24. #include "command.h"
  25. #include "memory.h"
  26. #include "log.h"
  27. #include "if.h"
  28. #include "network.h"
  29. #include "prefix.h"
  30. #include "zclient.h"
  31. #include "stream.h"
  32. #include "linklist.h"
  33. #include "vrf.h"
  34. #include "isisd/dict.h"
  35. #include "isisd/isis_constants.h"
  36. #include "isisd/isis_common.h"
  37. #include "isisd/isis_flags.h"
  38. #include "isisd/isis_misc.h"
  39. #include "isisd/isis_circuit.h"
  40. #include "isisd/isis_tlv.h"
  41. #include "isisd/isisd.h"
  42. #include "isisd/isis_circuit.h"
  43. #include "isisd/isis_csm.h"
  44. #include "isisd/isis_lsp.h"
  45. #include "isisd/isis_route.h"
  46. #include "isisd/isis_zebra.h"
  47. struct zclient *zclient = NULL;
  48. /* Router-id update message from zebra. */
  49. static int
  50. isis_router_id_update_zebra (int command, struct zclient *zclient,
  51. zebra_size_t length, vrf_id_t vrf_id)
  52. {
  53. struct isis_area *area;
  54. struct listnode *node;
  55. struct prefix router_id;
  56. zebra_router_id_update_read (zclient->ibuf, &router_id);
  57. if (isis->router_id == router_id.u.prefix4.s_addr)
  58. return 0;
  59. isis->router_id = router_id.u.prefix4.s_addr;
  60. for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area))
  61. if (listcount (area->area_addrs) > 0)
  62. lsp_regenerate_schedule (area, area->is_type, 0);
  63. return 0;
  64. }
  65. static int
  66. isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length,
  67. vrf_id_t vrf_id)
  68. {
  69. struct interface *ifp;
  70. ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
  71. if (isis->debugs & DEBUG_ZEBRA)
  72. zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
  73. ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
  74. if (if_is_operative (ifp))
  75. isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
  76. return 0;
  77. }
  78. static int
  79. isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length,
  80. vrf_id_t vrf_id)
  81. {
  82. struct interface *ifp;
  83. struct stream *s;
  84. s = zclient->ibuf;
  85. ifp = zebra_interface_state_read (s, vrf_id);
  86. if (!ifp)
  87. return 0;
  88. if (if_is_operative (ifp))
  89. zlog_warn ("Zebra: got delete of %s, but interface is still up",
  90. ifp->name);
  91. if (isis->debugs & DEBUG_ZEBRA)
  92. zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
  93. ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu);
  94. isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
  95. /* Cannot call if_delete because we should retain the pseudo interface
  96. in case there is configuration info attached to it. */
  97. if_delete_retain(ifp);
  98. ifp->ifindex = IFINDEX_INTERNAL;
  99. return 0;
  100. }
  101. static int
  102. isis_zebra_if_state_up (int command, struct zclient *zclient,
  103. zebra_size_t length, vrf_id_t vrf_id)
  104. {
  105. struct interface *ifp;
  106. ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
  107. if (ifp == NULL)
  108. return 0;
  109. isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
  110. return 0;
  111. }
  112. static int
  113. isis_zebra_if_state_down (int command, struct zclient *zclient,
  114. zebra_size_t length, vrf_id_t vrf_id)
  115. {
  116. struct interface *ifp;
  117. struct isis_circuit *circuit;
  118. ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
  119. if (ifp == NULL)
  120. return 0;
  121. circuit = isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp),
  122. ifp);
  123. if (circuit)
  124. SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
  125. return 0;
  126. }
  127. static int
  128. isis_zebra_if_address_add (int command, struct zclient *zclient,
  129. zebra_size_t length, vrf_id_t vrf_id)
  130. {
  131. struct connected *c;
  132. struct prefix *p;
  133. char buf[BUFSIZ];
  134. c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
  135. zclient->ibuf, vrf_id);
  136. if (c == NULL)
  137. return 0;
  138. p = c->address;
  139. prefix2str (p, buf, BUFSIZ);
  140. #ifdef EXTREME_DEBUG
  141. if (p->family == AF_INET)
  142. zlog_debug ("connected IP address %s", buf);
  143. #ifdef HAVE_IPV6
  144. if (p->family == AF_INET6)
  145. zlog_debug ("connected IPv6 address %s", buf);
  146. #endif /* HAVE_IPV6 */
  147. #endif /* EXTREME_DEBUG */
  148. if (if_is_operative (c->ifp))
  149. isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
  150. return 0;
  151. }
  152. static int
  153. isis_zebra_if_address_del (int command, struct zclient *client,
  154. zebra_size_t length, vrf_id_t vrf_id)
  155. {
  156. struct connected *c;
  157. struct interface *ifp;
  158. #ifdef EXTREME_DEBUG
  159. struct prefix *p;
  160. u_char buf[BUFSIZ];
  161. #endif /* EXTREME_DEBUG */
  162. c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
  163. zclient->ibuf, vrf_id);
  164. if (c == NULL)
  165. return 0;
  166. ifp = c->ifp;
  167. #ifdef EXTREME_DEBUG
  168. p = c->address;
  169. prefix2str (p, buf, BUFSIZ);
  170. if (p->family == AF_INET)
  171. zlog_debug ("disconnected IP address %s", buf);
  172. #ifdef HAVE_IPV6
  173. if (p->family == AF_INET6)
  174. zlog_debug ("disconnected IPv6 address %s", buf);
  175. #endif /* HAVE_IPV6 */
  176. #endif /* EXTREME_DEBUG */
  177. if (if_is_operative (ifp))
  178. isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
  179. connected_free (c);
  180. return 0;
  181. }
  182. static void
  183. isis_zebra_route_add_ipv4 (struct prefix *prefix,
  184. struct isis_route_info *route_info)
  185. {
  186. u_char message, flags;
  187. int psize;
  188. struct stream *stream;
  189. struct isis_nexthop *nexthop;
  190. struct listnode *node;
  191. if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
  192. return;
  193. if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
  194. {
  195. message = 0;
  196. flags = 0;
  197. SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
  198. SET_FLAG (message, ZAPI_MESSAGE_METRIC);
  199. #if 0
  200. SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
  201. #endif
  202. stream = zclient->obuf;
  203. stream_reset (stream);
  204. zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT);
  205. /* type */
  206. stream_putc (stream, ZEBRA_ROUTE_ISIS);
  207. /* flags */
  208. stream_putc (stream, flags);
  209. /* message */
  210. stream_putc (stream, message);
  211. /* SAFI */
  212. stream_putw (stream, SAFI_UNICAST);
  213. /* prefix information */
  214. psize = PSIZE (prefix->prefixlen);
  215. stream_putc (stream, prefix->prefixlen);
  216. stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
  217. stream_putc (stream, listcount (route_info->nexthops));
  218. /* Nexthop, ifindex, distance and metric information */
  219. for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop))
  220. {
  221. /* FIXME: can it be ? */
  222. if (nexthop->ip.s_addr != INADDR_ANY)
  223. {
  224. stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
  225. stream_put_in_addr (stream, &nexthop->ip);
  226. }
  227. else
  228. {
  229. stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
  230. stream_putl (stream, nexthop->ifindex);
  231. }
  232. }
  233. #if 0
  234. if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
  235. stream_putc (stream, route_info->depth);
  236. #endif
  237. if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
  238. stream_putl (stream, route_info->cost);
  239. stream_putw_at (stream, 0, stream_get_endp (stream));
  240. zclient_send_message(zclient);
  241. SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  242. UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
  243. }
  244. }
  245. static void
  246. isis_zebra_route_del_ipv4 (struct prefix *prefix,
  247. struct isis_route_info *route_info)
  248. {
  249. struct zapi_ipv4 api;
  250. struct prefix_ipv4 prefix4;
  251. if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
  252. {
  253. api.vrf_id = VRF_DEFAULT;
  254. api.type = ZEBRA_ROUTE_ISIS;
  255. api.flags = 0;
  256. api.message = 0;
  257. api.safi = SAFI_UNICAST;
  258. prefix4.family = AF_INET;
  259. prefix4.prefixlen = prefix->prefixlen;
  260. prefix4.prefix = prefix->u.prefix4;
  261. zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
  262. }
  263. UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  264. return;
  265. }
  266. #ifdef HAVE_IPV6
  267. static void
  268. isis_zebra_route_add_ipv6 (struct prefix *prefix,
  269. struct isis_route_info *route_info)
  270. {
  271. struct zapi_ipv6 api;
  272. struct in6_addr **nexthop_list;
  273. ifindex_t *ifindex_list;
  274. struct isis_nexthop6 *nexthop6;
  275. int i, size;
  276. struct listnode *node;
  277. struct prefix_ipv6 prefix6;
  278. if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
  279. return;
  280. api.vrf_id = VRF_DEFAULT;
  281. api.type = ZEBRA_ROUTE_ISIS;
  282. api.flags = 0;
  283. api.message = 0;
  284. api.safi = SAFI_UNICAST;
  285. SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  286. SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  287. SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
  288. api.metric = route_info->cost;
  289. #if 0
  290. SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
  291. api.distance = route_info->depth;
  292. #endif
  293. api.nexthop_num = listcount (route_info->nexthops6);
  294. api.ifindex_num = listcount (route_info->nexthops6);
  295. /* allocate memory for nexthop_list */
  296. size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
  297. nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
  298. if (!nexthop_list)
  299. {
  300. zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
  301. return;
  302. }
  303. /* allocate memory for ifindex_list */
  304. size = sizeof (unsigned int) * listcount (route_info->nexthops6);
  305. ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
  306. if (!ifindex_list)
  307. {
  308. zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
  309. XFREE (MTYPE_ISIS_TMP, nexthop_list);
  310. return;
  311. }
  312. /* for each nexthop */
  313. i = 0;
  314. for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
  315. {
  316. if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
  317. !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
  318. {
  319. api.nexthop_num--;
  320. api.ifindex_num--;
  321. continue;
  322. }
  323. nexthop_list[i] = &nexthop6->ip6;
  324. ifindex_list[i] = nexthop6->ifindex;
  325. i++;
  326. }
  327. api.nexthop = nexthop_list;
  328. api.ifindex = ifindex_list;
  329. if (api.nexthop_num && api.ifindex_num)
  330. {
  331. prefix6.family = AF_INET6;
  332. prefix6.prefixlen = prefix->prefixlen;
  333. memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
  334. zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
  335. SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  336. UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
  337. }
  338. XFREE (MTYPE_ISIS_TMP, nexthop_list);
  339. XFREE (MTYPE_ISIS_TMP, ifindex_list);
  340. return;
  341. }
  342. static void
  343. isis_zebra_route_del_ipv6 (struct prefix *prefix,
  344. struct isis_route_info *route_info)
  345. {
  346. struct zapi_ipv6 api;
  347. struct in6_addr **nexthop_list;
  348. ifindex_t *ifindex_list;
  349. struct isis_nexthop6 *nexthop6;
  350. int i, size;
  351. struct listnode *node;
  352. struct prefix_ipv6 prefix6;
  353. if (!CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
  354. return;
  355. api.vrf_id = VRF_DEFAULT;
  356. api.type = ZEBRA_ROUTE_ISIS;
  357. api.flags = 0;
  358. api.message = 0;
  359. api.safi = SAFI_UNICAST;
  360. SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  361. SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  362. api.nexthop_num = listcount (route_info->nexthops6);
  363. api.ifindex_num = listcount (route_info->nexthops6);
  364. /* 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);
  367. if (!nexthop_list)
  368. {
  369. zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
  370. return;
  371. }
  372. /* allocate memory for ifindex_list */
  373. size = sizeof (unsigned int) * listcount (route_info->nexthops6);
  374. ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
  375. if (!ifindex_list)
  376. {
  377. zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
  378. XFREE (MTYPE_ISIS_TMP, nexthop_list);
  379. return;
  380. }
  381. /* for each nexthop */
  382. i = 0;
  383. for (ALL_LIST_ELEMENTS_RO (route_info->nexthops6, node, nexthop6))
  384. {
  385. if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
  386. !IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
  387. {
  388. api.nexthop_num--;
  389. api.ifindex_num--;
  390. continue;
  391. }
  392. nexthop_list[i] = &nexthop6->ip6;
  393. ifindex_list[i] = nexthop6->ifindex;
  394. i++;
  395. }
  396. api.nexthop = nexthop_list;
  397. api.ifindex = ifindex_list;
  398. if (api.nexthop_num && api.ifindex_num)
  399. {
  400. prefix6.family = AF_INET6;
  401. prefix6.prefixlen = prefix->prefixlen;
  402. memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
  403. zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
  404. UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
  405. }
  406. XFREE (MTYPE_ISIS_TMP, nexthop_list);
  407. XFREE (MTYPE_ISIS_TMP, ifindex_list);
  408. }
  409. #endif /* HAVE_IPV6 */
  410. void
  411. isis_zebra_route_update (struct prefix *prefix,
  412. struct isis_route_info *route_info)
  413. {
  414. if (zclient->sock < 0)
  415. return;
  416. if (!vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT))
  417. return;
  418. if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
  419. {
  420. if (prefix->family == AF_INET)
  421. isis_zebra_route_add_ipv4 (prefix, route_info);
  422. #ifdef HAVE_IPV6
  423. else if (prefix->family == AF_INET6)
  424. isis_zebra_route_add_ipv6 (prefix, route_info);
  425. #endif /* HAVE_IPV6 */
  426. }
  427. else
  428. {
  429. if (prefix->family == AF_INET)
  430. isis_zebra_route_del_ipv4 (prefix, route_info);
  431. #ifdef HAVE_IPV6
  432. else if (prefix->family == AF_INET6)
  433. isis_zebra_route_del_ipv6 (prefix, route_info);
  434. #endif /* HAVE_IPV6 */
  435. }
  436. return;
  437. }
  438. static int
  439. isis_zebra_read_ipv4 (int command, struct zclient *zclient,
  440. zebra_size_t length, vrf_id_t vrf_id)
  441. {
  442. struct stream *stream;
  443. struct zapi_ipv4 api;
  444. struct prefix_ipv4 p;
  445. struct prefix *p_generic = (struct prefix*)&p;
  446. unsigned long ifindex __attribute__ ((unused));
  447. struct in_addr nexthop __attribute__ ((unused));
  448. stream = zclient->ibuf;
  449. memset(&api, 0, sizeof(api));
  450. memset (&p, 0, sizeof (struct prefix_ipv4));
  451. memset(&nexthop, 0, sizeof(nexthop));
  452. ifindex = 0;
  453. api.type = stream_getc (stream);
  454. api.flags = stream_getc (stream);
  455. api.message = stream_getc (stream);
  456. p.family = AF_INET;
  457. p.prefixlen = stream_getc (stream);
  458. stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
  459. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
  460. {
  461. api.nexthop_num = stream_getc (stream);
  462. nexthop.s_addr = stream_get_ipv4 (stream);
  463. }
  464. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
  465. {
  466. api.ifindex_num = stream_getc (stream);
  467. ifindex = stream_getl (stream);
  468. }
  469. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
  470. api.distance = stream_getc (stream);
  471. if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
  472. api.metric = stream_getl (stream);
  473. /*
  474. * Avoid advertising a false default reachability. (A default
  475. * route installed by IS-IS gets redistributed from zebra back
  476. * into IS-IS causing us to start advertising default reachabity
  477. * without this check)
  478. */
  479. if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
  480. command = ZEBRA_IPV4_ROUTE_DELETE;
  481. if (command == ZEBRA_IPV4_ROUTE_ADD)
  482. isis_redist_add(api.type, p_generic, api.distance, api.metric);
  483. else
  484. isis_redist_delete(api.type, p_generic);
  485. return 0;
  486. }
  487. static int
  488. isis_zebra_read_ipv6 (int command, struct zclient *zclient,
  489. zebra_size_t length, vrf_id_t vrf_id)
  490. {
  491. struct stream *stream;
  492. struct zapi_ipv6 api;
  493. struct prefix_ipv6 p;
  494. struct prefix *p_generic = (struct prefix*)&p;
  495. struct in6_addr nexthop;
  496. unsigned long ifindex __attribute__((unused));
  497. stream = zclient->ibuf;
  498. memset(&api, 0, sizeof(api));
  499. memset(&p, 0, sizeof(struct prefix_ipv6));
  500. memset(&nexthop, 0, sizeof(nexthop));
  501. ifindex = 0;
  502. api.type = stream_getc(stream);
  503. api.flags = stream_getc(stream);
  504. api.message = stream_getc(stream);
  505. p.family = AF_INET6;
  506. p.prefixlen = stream_getc(stream);
  507. stream_get(&p.prefix, stream, PSIZE(p.prefixlen));
  508. if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP))
  509. {
  510. api.nexthop_num = stream_getc(stream); /* this is always 1 */
  511. stream_get(&nexthop, stream, sizeof(nexthop));
  512. }
  513. if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX))
  514. {
  515. api.ifindex_num = stream_getc(stream);
  516. ifindex = stream_getl(stream);
  517. }
  518. if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
  519. api.distance = stream_getc(stream);
  520. if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC))
  521. api.metric = stream_getl(stream);
  522. /*
  523. * Avoid advertising a false default reachability. (A default
  524. * route installed by IS-IS gets redistributed from zebra back
  525. * into IS-IS causing us to start advertising default reachabity
  526. * without this check)
  527. */
  528. if (p.prefixlen == 0 && api.type == ZEBRA_ROUTE_ISIS)
  529. command = ZEBRA_IPV6_ROUTE_DELETE;
  530. if (command == ZEBRA_IPV6_ROUTE_ADD)
  531. isis_redist_add(api.type, p_generic, api.distance, api.metric);
  532. else
  533. isis_redist_delete(api.type, p_generic);
  534. return 0;
  535. }
  536. int
  537. isis_distribute_list_update (int routetype)
  538. {
  539. return 0;
  540. }
  541. void
  542. isis_zebra_redistribute_set(int type)
  543. {
  544. if (type == DEFAULT_ROUTE)
  545. zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, VRF_DEFAULT);
  546. else
  547. zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, type, VRF_DEFAULT);
  548. }
  549. void
  550. isis_zebra_redistribute_unset(int type)
  551. {
  552. if (type == DEFAULT_ROUTE)
  553. zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, VRF_DEFAULT);
  554. else
  555. zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, type, VRF_DEFAULT);
  556. }
  557. static void
  558. isis_zebra_connected (struct zclient *zclient)
  559. {
  560. zclient_send_requests (zclient, VRF_DEFAULT);
  561. }
  562. void
  563. isis_zebra_init (struct thread_master *master)
  564. {
  565. zclient = zclient_new (master);
  566. zclient_init (zclient, ZEBRA_ROUTE_ISIS);
  567. zclient->zebra_connected = isis_zebra_connected;
  568. zclient->router_id_update = isis_router_id_update_zebra;
  569. zclient->interface_add = isis_zebra_if_add;
  570. zclient->interface_delete = isis_zebra_if_del;
  571. zclient->interface_up = isis_zebra_if_state_up;
  572. zclient->interface_down = isis_zebra_if_state_down;
  573. zclient->interface_address_add = isis_zebra_if_address_add;
  574. zclient->interface_address_delete = isis_zebra_if_address_del;
  575. zclient->ipv4_route_add = isis_zebra_read_ipv4;
  576. zclient->ipv4_route_delete = isis_zebra_read_ipv4;
  577. #ifdef HAVE_IPV6
  578. zclient->ipv6_route_add = isis_zebra_read_ipv6;
  579. zclient->ipv6_route_delete = isis_zebra_read_ipv6;
  580. #endif /* HAVE_IPV6 */
  581. return;
  582. }