isis_zebra.c 19 KB

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