router-id.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * Router ID for zebra daemon.
  3. *
  4. * Copyright (C) 2004 James R. Leu
  5. *
  6. * This file is part of Quagga routing suite.
  7. *
  8. * Quagga is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2, or (at your option) any
  11. * later version.
  12. *
  13. * Quagga is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  20. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  21. * 02111-1307, USA.
  22. */
  23. #include <zebra.h>
  24. #include "if.h"
  25. #include "vty.h"
  26. #include "sockunion.h"
  27. #include "prefix.h"
  28. #include "stream.h"
  29. #include "command.h"
  30. #include "memory.h"
  31. #include "ioctl.h"
  32. #include "connected.h"
  33. #include "network.h"
  34. #include "log.h"
  35. #include "table.h"
  36. #include "rib.h"
  37. #include "vrf.h"
  38. #include "zebra/zserv.h"
  39. #include "zebra/router-id.h"
  40. #include "zebra/redistribute.h"
  41. /* master zebra server structure */
  42. extern struct zebra_t zebrad;
  43. static struct connected *
  44. router_id_find_node (struct list *l, struct connected *ifc)
  45. {
  46. struct listnode *node;
  47. struct connected *c;
  48. for (ALL_LIST_ELEMENTS_RO (l, node, c))
  49. if (prefix_same (ifc->address, c->address))
  50. return c;
  51. return NULL;
  52. }
  53. static int
  54. router_id_bad_address (struct connected *ifc)
  55. {
  56. if (ifc->address->family != AF_INET)
  57. return 1;
  58. /* non-redistributable addresses shouldn't be used for RIDs either */
  59. if (!zebra_check_addr (ifc->address))
  60. return 1;
  61. return 0;
  62. }
  63. void
  64. router_id_get (struct prefix *p, vrf_id_t vrf_id)
  65. {
  66. struct listnode *node;
  67. struct connected *c;
  68. struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
  69. p->u.prefix4.s_addr = 0;
  70. p->family = AF_INET;
  71. p->prefixlen = 32;
  72. if (zvrf->rid_user_assigned.u.prefix4.s_addr)
  73. p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
  74. else if (!list_isempty (zvrf->rid_lo_sorted_list))
  75. {
  76. node = listtail (zvrf->rid_lo_sorted_list);
  77. c = listgetdata (node);
  78. p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
  79. }
  80. else if (!list_isempty (zvrf->rid_all_sorted_list))
  81. {
  82. node = listtail (zvrf->rid_all_sorted_list);
  83. c = listgetdata (node);
  84. p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
  85. }
  86. }
  87. static void
  88. router_id_set (struct prefix *p, vrf_id_t vrf_id)
  89. {
  90. struct prefix p2;
  91. struct listnode *node;
  92. struct zserv *client;
  93. struct zebra_vrf *zvrf;
  94. if (p->u.prefix4.s_addr == 0) /* unset */
  95. {
  96. zvrf = vrf_info_lookup (vrf_id);
  97. if (! zvrf)
  98. return;
  99. }
  100. else /* set */
  101. zvrf = vrf_info_get (vrf_id);
  102. zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
  103. router_id_get (&p2, vrf_id);
  104. for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
  105. zsend_router_id_update (client, &p2, vrf_id);
  106. }
  107. void
  108. router_id_add_address (struct connected *ifc)
  109. {
  110. struct list *l = NULL;
  111. struct listnode *node;
  112. struct prefix before;
  113. struct prefix after;
  114. struct zserv *client;
  115. struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
  116. if (router_id_bad_address (ifc))
  117. return;
  118. router_id_get (&before, zvrf->vrf_id);
  119. if (!strncmp (ifc->ifp->name, "lo", 2)
  120. || !strncmp (ifc->ifp->name, "dummy", 5))
  121. l = zvrf->rid_lo_sorted_list;
  122. else
  123. l = zvrf->rid_all_sorted_list;
  124. if (!router_id_find_node (l, ifc))
  125. listnode_add_sort (l, ifc);
  126. router_id_get (&after, zvrf->vrf_id);
  127. if (prefix_same (&before, &after))
  128. return;
  129. for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
  130. zsend_router_id_update (client, &after, zvrf->vrf_id);
  131. }
  132. void
  133. router_id_del_address (struct connected *ifc)
  134. {
  135. struct connected *c;
  136. struct list *l;
  137. struct prefix after;
  138. struct prefix before;
  139. struct listnode *node;
  140. struct zserv *client;
  141. struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
  142. if (router_id_bad_address (ifc))
  143. return;
  144. router_id_get (&before, zvrf->vrf_id);
  145. if (!strncmp (ifc->ifp->name, "lo", 2)
  146. || !strncmp (ifc->ifp->name, "dummy", 5))
  147. l = zvrf->rid_lo_sorted_list;
  148. else
  149. l = zvrf->rid_all_sorted_list;
  150. if ((c = router_id_find_node (l, ifc)))
  151. listnode_delete (l, c);
  152. router_id_get (&after, zvrf->vrf_id);
  153. if (prefix_same (&before, &after))
  154. return;
  155. for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
  156. zsend_router_id_update (client, &after, zvrf->vrf_id);
  157. }
  158. void
  159. router_id_write (struct vty *vty)
  160. {
  161. struct zebra_vrf *zvrf;
  162. vrf_iter_t iter;
  163. for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
  164. if ((zvrf = vrf_iter2info (iter)) != NULL)
  165. if (zvrf->rid_user_assigned.u.prefix4.s_addr)
  166. {
  167. if (zvrf->vrf_id == VRF_DEFAULT)
  168. vty_out (vty, "router-id %s%s",
  169. inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
  170. VTY_NEWLINE);
  171. else
  172. vty_out (vty, "router-id %s vrf %u%s",
  173. inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
  174. zvrf->vrf_id,
  175. VTY_NEWLINE);
  176. }
  177. }
  178. DEFUN (router_id,
  179. router_id_cmd,
  180. "router-id A.B.C.D",
  181. "Manually set the router-id\n"
  182. "IP address to use for router-id\n")
  183. {
  184. struct prefix rid;
  185. vrf_id_t vrf_id = VRF_DEFAULT;
  186. rid.u.prefix4.s_addr = inet_addr (argv[0]);
  187. if (!rid.u.prefix4.s_addr)
  188. return CMD_WARNING;
  189. rid.prefixlen = 32;
  190. rid.family = AF_INET;
  191. if (argc > 1)
  192. VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
  193. router_id_set (&rid, vrf_id);
  194. return CMD_SUCCESS;
  195. }
  196. ALIAS (router_id,
  197. router_id_vrf_cmd,
  198. "router-id A.B.C.D " VRF_CMD_STR,
  199. "Manually set the router-id\n"
  200. "IP address to use for router-id\n"
  201. VRF_CMD_HELP_STR)
  202. DEFUN (no_router_id,
  203. no_router_id_cmd,
  204. "no router-id",
  205. NO_STR
  206. "Remove the manually configured router-id\n")
  207. {
  208. struct prefix rid;
  209. vrf_id_t vrf_id = VRF_DEFAULT;
  210. rid.u.prefix4.s_addr = 0;
  211. rid.prefixlen = 0;
  212. rid.family = AF_INET;
  213. if (argc > 0)
  214. VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
  215. router_id_set (&rid, vrf_id);
  216. return CMD_SUCCESS;
  217. }
  218. ALIAS (no_router_id,
  219. no_router_id_vrf_cmd,
  220. "no router-id " VRF_CMD_STR,
  221. NO_STR
  222. "Remove the manually configured router-id\n"
  223. VRF_CMD_HELP_STR)
  224. static int
  225. router_id_cmp (void *a, void *b)
  226. {
  227. const struct connected *ifa = (const struct connected *)a;
  228. const struct connected *ifb = (const struct connected *)b;
  229. return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr);
  230. }
  231. void
  232. router_id_cmd_init (void)
  233. {
  234. install_element (CONFIG_NODE, &router_id_cmd);
  235. install_element (CONFIG_NODE, &no_router_id_cmd);
  236. install_element (CONFIG_NODE, &router_id_vrf_cmd);
  237. install_element (CONFIG_NODE, &no_router_id_vrf_cmd);
  238. }
  239. void
  240. router_id_init (struct zebra_vrf *zvrf)
  241. {
  242. zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
  243. zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
  244. memset (zvrf->rid_all_sorted_list, 0, sizeof (zvrf->_rid_all_sorted_list));
  245. memset (zvrf->rid_lo_sorted_list, 0, sizeof (zvrf->_rid_lo_sorted_list));
  246. memset (&zvrf->rid_user_assigned, 0, sizeof (zvrf->rid_user_assigned));
  247. zvrf->rid_all_sorted_list->cmp = router_id_cmp;
  248. zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
  249. zvrf->rid_user_assigned.family = AF_INET;
  250. zvrf->rid_user_assigned.prefixlen = 32;
  251. }