if_rmap.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /* route-map for interface.
  2. * Copyright (C) 1999 Kunihiro Ishiguro
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "hash.h"
  23. #include "command.h"
  24. #include "memory.h"
  25. #include "if.h"
  26. #include "if_rmap.h"
  27. struct hash *ifrmaphash;
  28. /* Hook functions. */
  29. static void (*if_rmap_add_hook) (struct if_rmap *) = NULL;
  30. static void (*if_rmap_delete_hook) (struct if_rmap *) = NULL;
  31. static struct if_rmap *
  32. if_rmap_new (void)
  33. {
  34. struct if_rmap *new;
  35. new = XCALLOC (MTYPE_IF_RMAP, sizeof (struct if_rmap));
  36. return new;
  37. }
  38. static void
  39. if_rmap_free (struct if_rmap *if_rmap)
  40. {
  41. if (if_rmap->ifname)
  42. XFREE (MTYPE_IF_RMAP_NAME, if_rmap->ifname);
  43. if (if_rmap->routemap[IF_RMAP_IN])
  44. XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
  45. if (if_rmap->routemap[IF_RMAP_OUT])
  46. XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
  47. XFREE (MTYPE_IF_RMAP, if_rmap);
  48. }
  49. struct if_rmap *
  50. if_rmap_lookup (const char *ifname)
  51. {
  52. struct if_rmap key;
  53. struct if_rmap *if_rmap;
  54. /* temporary copy */
  55. key.ifname = (char *)ifname;
  56. if_rmap = hash_lookup (ifrmaphash, &key);
  57. return if_rmap;
  58. }
  59. void
  60. if_rmap_hook_add (void (*func) (struct if_rmap *))
  61. {
  62. if_rmap_add_hook = func;
  63. }
  64. void
  65. if_rmap_hook_delete (void (*func) (struct if_rmap *))
  66. {
  67. if_rmap_delete_hook = func;
  68. }
  69. static void *
  70. if_rmap_hash_alloc (void *arg)
  71. {
  72. struct if_rmap *ifarg = arg;
  73. struct if_rmap *if_rmap;
  74. if_rmap = if_rmap_new ();
  75. if_rmap->ifname = XSTRDUP (MTYPE_IF_RMAP_NAME, ifarg->ifname);
  76. return if_rmap;
  77. }
  78. static struct if_rmap *
  79. if_rmap_get (const char *ifname)
  80. {
  81. struct if_rmap key;
  82. /* temporary copy */
  83. key.ifname = (char *)ifname;
  84. return (struct if_rmap *) hash_get (ifrmaphash, &key, if_rmap_hash_alloc);
  85. }
  86. static unsigned int
  87. if_rmap_hash_make (void *data)
  88. {
  89. const struct if_rmap *if_rmap = data;
  90. return string_hash_make (if_rmap->ifname);
  91. }
  92. static int
  93. if_rmap_hash_cmp (const void *arg1, const void* arg2)
  94. {
  95. const struct if_rmap *if_rmap1 = arg1;
  96. const struct if_rmap *if_rmap2 = arg2;
  97. return strcmp (if_rmap1->ifname, if_rmap2->ifname) == 0;
  98. }
  99. static struct if_rmap *
  100. if_rmap_set (const char *ifname, enum if_rmap_type type,
  101. const char *routemap_name)
  102. {
  103. struct if_rmap *if_rmap;
  104. if_rmap = if_rmap_get (ifname);
  105. if (type == IF_RMAP_IN)
  106. {
  107. if (if_rmap->routemap[IF_RMAP_IN])
  108. XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
  109. if_rmap->routemap[IF_RMAP_IN]
  110. = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name);
  111. }
  112. if (type == IF_RMAP_OUT)
  113. {
  114. if (if_rmap->routemap[IF_RMAP_OUT])
  115. XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
  116. if_rmap->routemap[IF_RMAP_OUT]
  117. = XSTRDUP (MTYPE_IF_RMAP_NAME, routemap_name);
  118. }
  119. if (if_rmap_add_hook)
  120. (*if_rmap_add_hook) (if_rmap);
  121. return if_rmap;
  122. }
  123. static int
  124. if_rmap_unset (const char *ifname, enum if_rmap_type type,
  125. const char *routemap_name)
  126. {
  127. struct if_rmap *if_rmap;
  128. if_rmap = if_rmap_lookup (ifname);
  129. if (!if_rmap)
  130. return 0;
  131. if (type == IF_RMAP_IN)
  132. {
  133. if (!if_rmap->routemap[IF_RMAP_IN])
  134. return 0;
  135. if (strcmp (if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0)
  136. return 0;
  137. XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
  138. if_rmap->routemap[IF_RMAP_IN] = NULL;
  139. }
  140. if (type == IF_RMAP_OUT)
  141. {
  142. if (!if_rmap->routemap[IF_RMAP_OUT])
  143. return 0;
  144. if (strcmp (if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0)
  145. return 0;
  146. XFREE (MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
  147. if_rmap->routemap[IF_RMAP_OUT] = NULL;
  148. }
  149. if (if_rmap_delete_hook)
  150. (*if_rmap_delete_hook) (if_rmap);
  151. if (if_rmap->routemap[IF_RMAP_IN] == NULL &&
  152. if_rmap->routemap[IF_RMAP_OUT] == NULL)
  153. {
  154. hash_release (ifrmaphash, if_rmap);
  155. if_rmap_free (if_rmap);
  156. }
  157. return 1;
  158. }
  159. DEFUN (if_rmap,
  160. if_rmap_cmd,
  161. "route-map RMAP_NAME (in|out) IFNAME",
  162. "Route map set\n"
  163. "Route map name\n"
  164. "Route map set for input filtering\n"
  165. "Route map set for output filtering\n"
  166. "Route map interface name\n")
  167. {
  168. enum if_rmap_type type;
  169. if (strncmp (argv[1], "i", 1) == 0)
  170. type = IF_RMAP_IN;
  171. else if (strncmp (argv[1], "o", 1) == 0)
  172. type = IF_RMAP_OUT;
  173. else
  174. {
  175. vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
  176. return CMD_WARNING;
  177. }
  178. if_rmap_set (argv[2], type, argv[0]);
  179. return CMD_SUCCESS;
  180. }
  181. ALIAS (if_rmap,
  182. if_ipv6_rmap_cmd,
  183. "route-map RMAP_NAME (in|out) IFNAME",
  184. "Route map set\n"
  185. "Route map name\n"
  186. "Route map set for input filtering\n"
  187. "Route map set for output filtering\n"
  188. "Route map interface name\n")
  189. DEFUN (no_if_rmap,
  190. no_if_rmap_cmd,
  191. "no route-map ROUTEMAP_NAME (in|out) IFNAME",
  192. NO_STR
  193. "Route map unset\n"
  194. "Route map name\n"
  195. "Route map for input filtering\n"
  196. "Route map for output filtering\n"
  197. "Route map interface name\n")
  198. {
  199. int ret;
  200. enum if_rmap_type type;
  201. if (strncmp (argv[1], "i", 1) == 0)
  202. type = IF_RMAP_IN;
  203. else if (strncmp (argv[1], "o", 1) == 0)
  204. type = IF_RMAP_OUT;
  205. else
  206. {
  207. vty_out (vty, "route-map direction must be [in|out]%s", VTY_NEWLINE);
  208. return CMD_WARNING;
  209. }
  210. ret = if_rmap_unset (argv[2], type, argv[0]);
  211. if (! ret)
  212. {
  213. vty_out (vty, "route-map doesn't exist%s", VTY_NEWLINE);
  214. return CMD_WARNING;
  215. }
  216. return CMD_SUCCESS;
  217. }
  218. ALIAS (no_if_rmap,
  219. no_if_ipv6_rmap_cmd,
  220. "no route-map ROUTEMAP_NAME (in|out) IFNAME",
  221. NO_STR
  222. "Route map unset\n"
  223. "Route map name\n"
  224. "Route map for input filtering\n"
  225. "Route map for output filtering\n"
  226. "Route map interface name\n")
  227. /* Configuration write function. */
  228. int
  229. config_write_if_rmap (struct vty *vty)
  230. {
  231. unsigned int i;
  232. struct hash_backet *mp;
  233. int write = 0;
  234. for (i = 0; i < ifrmaphash->size; i++)
  235. for (mp = ifrmaphash->index[i]; mp; mp = mp->next)
  236. {
  237. struct if_rmap *if_rmap;
  238. if_rmap = mp->data;
  239. if (if_rmap->routemap[IF_RMAP_IN])
  240. {
  241. vty_out (vty, " route-map %s in %s%s",
  242. if_rmap->routemap[IF_RMAP_IN],
  243. if_rmap->ifname,
  244. VTY_NEWLINE);
  245. write++;
  246. }
  247. if (if_rmap->routemap[IF_RMAP_OUT])
  248. {
  249. vty_out (vty, " route-map %s out %s%s",
  250. if_rmap->routemap[IF_RMAP_OUT],
  251. if_rmap->ifname,
  252. VTY_NEWLINE);
  253. write++;
  254. }
  255. }
  256. return write;
  257. }
  258. void
  259. if_rmap_reset ()
  260. {
  261. hash_clean (ifrmaphash, (void (*) (void *)) if_rmap_free);
  262. }
  263. void
  264. if_rmap_init (int node)
  265. {
  266. ifrmaphash = hash_create (if_rmap_hash_make, if_rmap_hash_cmp);
  267. if (node == RIPNG_NODE) {
  268. install_element (RIPNG_NODE, &if_ipv6_rmap_cmd);
  269. install_element (RIPNG_NODE, &no_if_ipv6_rmap_cmd);
  270. } else if (node == RIP_NODE) {
  271. install_element (RIP_NODE, &if_rmap_cmd);
  272. install_element (RIP_NODE, &no_if_rmap_cmd);
  273. }
  274. }