distribute.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. /* Distribute list functions
  2. * Copyright (C) 1998, 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
  7. * it under the terms of the GNU General Public License as published
  8. * by the Free Software Foundation; either version 2, or (at your
  9. * option) any 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
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "hash.h"
  23. #include "if.h"
  24. #include "filter.h"
  25. #include "command.h"
  26. #include "distribute.h"
  27. #include "memory.h"
  28. /* Hash of distribute list. */
  29. struct hash *disthash;
  30. /* Hook functions. */
  31. void (*distribute_add_hook) (struct distribute *);
  32. void (*distribute_delete_hook) (struct distribute *);
  33. static struct distribute *
  34. distribute_new (void)
  35. {
  36. return XCALLOC (MTYPE_DISTRIBUTE, sizeof (struct distribute));
  37. }
  38. /* Free distribute object. */
  39. static void
  40. distribute_free (struct distribute *dist)
  41. {
  42. if (dist->ifname)
  43. XFREE (MTYPE_DISTRIBUTE_IFNAME, dist->ifname);
  44. if (dist->list[DISTRIBUTE_IN])
  45. free (dist->list[DISTRIBUTE_IN]);
  46. if (dist->list[DISTRIBUTE_OUT])
  47. free (dist->list[DISTRIBUTE_OUT]);
  48. if (dist->prefix[DISTRIBUTE_IN])
  49. free (dist->prefix[DISTRIBUTE_IN]);
  50. if (dist->prefix[DISTRIBUTE_OUT])
  51. free (dist->prefix[DISTRIBUTE_OUT]);
  52. XFREE (MTYPE_DISTRIBUTE, dist);
  53. }
  54. /* Lookup interface's distribute list. */
  55. struct distribute *
  56. distribute_lookup (const char *ifname)
  57. {
  58. struct distribute key;
  59. struct distribute *dist;
  60. /* temporary reference */
  61. key.ifname = (char *)ifname;
  62. dist = hash_lookup (disthash, &key);
  63. return dist;
  64. }
  65. void
  66. distribute_list_add_hook (void (*func) (struct distribute *))
  67. {
  68. distribute_add_hook = func;
  69. }
  70. void
  71. distribute_list_delete_hook (void (*func) (struct distribute *))
  72. {
  73. distribute_delete_hook = func;
  74. }
  75. static void *
  76. distribute_hash_alloc (struct distribute *arg)
  77. {
  78. struct distribute *dist;
  79. dist = distribute_new ();
  80. if (arg->ifname)
  81. dist->ifname = XSTRDUP (MTYPE_DISTRIBUTE_IFNAME, arg->ifname);
  82. else
  83. dist->ifname = NULL;
  84. return dist;
  85. }
  86. /* Make new distribute list and push into hash. */
  87. static struct distribute *
  88. distribute_get (const char *ifname)
  89. {
  90. struct distribute key;
  91. /* temporary reference */
  92. key.ifname = (char *)ifname;
  93. return hash_get (disthash, &key, (void * (*) (void *))distribute_hash_alloc);
  94. }
  95. static unsigned int
  96. distribute_hash_make (void *arg)
  97. {
  98. const struct distribute *dist = arg;
  99. return dist->ifname ? string_hash_make (dist->ifname) : 0;
  100. }
  101. /* If two distribute-list have same value then return 1 else return
  102. 0. This function is used by hash package. */
  103. static int
  104. distribute_cmp (const struct distribute *dist1, const struct distribute *dist2)
  105. {
  106. if (dist1->ifname && dist2->ifname)
  107. if (strcmp (dist1->ifname, dist2->ifname) == 0)
  108. return 1;
  109. if (! dist1->ifname && ! dist2->ifname)
  110. return 1;
  111. return 0;
  112. }
  113. /* Set access-list name to the distribute list. */
  114. static struct distribute *
  115. distribute_list_set (const char *ifname, enum distribute_type type,
  116. const char *alist_name)
  117. {
  118. struct distribute *dist;
  119. dist = distribute_get (ifname);
  120. if (type == DISTRIBUTE_IN)
  121. {
  122. if (dist->list[DISTRIBUTE_IN])
  123. free (dist->list[DISTRIBUTE_IN]);
  124. dist->list[DISTRIBUTE_IN] = strdup (alist_name);
  125. }
  126. if (type == DISTRIBUTE_OUT)
  127. {
  128. if (dist->list[DISTRIBUTE_OUT])
  129. free (dist->list[DISTRIBUTE_OUT]);
  130. dist->list[DISTRIBUTE_OUT] = strdup (alist_name);
  131. }
  132. /* Apply this distribute-list to the interface. */
  133. (*distribute_add_hook) (dist);
  134. return dist;
  135. }
  136. /* Unset distribute-list. If matched distribute-list exist then
  137. return 1. */
  138. static int
  139. distribute_list_unset (const char *ifname, enum distribute_type type,
  140. const char *alist_name)
  141. {
  142. struct distribute *dist;
  143. dist = distribute_lookup (ifname);
  144. if (!dist)
  145. return 0;
  146. if (type == DISTRIBUTE_IN)
  147. {
  148. if (!dist->list[DISTRIBUTE_IN])
  149. return 0;
  150. if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0)
  151. return 0;
  152. free (dist->list[DISTRIBUTE_IN]);
  153. dist->list[DISTRIBUTE_IN] = NULL;
  154. }
  155. if (type == DISTRIBUTE_OUT)
  156. {
  157. if (!dist->list[DISTRIBUTE_OUT])
  158. return 0;
  159. if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0)
  160. return 0;
  161. free (dist->list[DISTRIBUTE_OUT]);
  162. dist->list[DISTRIBUTE_OUT] = NULL;
  163. }
  164. /* Apply this distribute-list to the interface. */
  165. (*distribute_delete_hook) (dist);
  166. /* If both out and in is NULL then free distribute list. */
  167. if (dist->list[DISTRIBUTE_IN] == NULL &&
  168. dist->list[DISTRIBUTE_OUT] == NULL &&
  169. dist->prefix[DISTRIBUTE_IN] == NULL &&
  170. dist->prefix[DISTRIBUTE_OUT] == NULL)
  171. {
  172. hash_release (disthash, dist);
  173. distribute_free (dist);
  174. }
  175. return 1;
  176. }
  177. /* Set access-list name to the distribute list. */
  178. static struct distribute *
  179. distribute_list_prefix_set (const char *ifname, enum distribute_type type,
  180. const char *plist_name)
  181. {
  182. struct distribute *dist;
  183. dist = distribute_get (ifname);
  184. if (type == DISTRIBUTE_IN)
  185. {
  186. if (dist->prefix[DISTRIBUTE_IN])
  187. free (dist->prefix[DISTRIBUTE_IN]);
  188. dist->prefix[DISTRIBUTE_IN] = strdup (plist_name);
  189. }
  190. if (type == DISTRIBUTE_OUT)
  191. {
  192. if (dist->prefix[DISTRIBUTE_OUT])
  193. free (dist->prefix[DISTRIBUTE_OUT]);
  194. dist->prefix[DISTRIBUTE_OUT] = strdup (plist_name);
  195. }
  196. /* Apply this distribute-list to the interface. */
  197. (*distribute_add_hook) (dist);
  198. return dist;
  199. }
  200. /* Unset distribute-list. If matched distribute-list exist then
  201. return 1. */
  202. static int
  203. distribute_list_prefix_unset (const char *ifname, enum distribute_type type,
  204. const char *plist_name)
  205. {
  206. struct distribute *dist;
  207. dist = distribute_lookup (ifname);
  208. if (!dist)
  209. return 0;
  210. if (type == DISTRIBUTE_IN)
  211. {
  212. if (!dist->prefix[DISTRIBUTE_IN])
  213. return 0;
  214. if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0)
  215. return 0;
  216. free (dist->prefix[DISTRIBUTE_IN]);
  217. dist->prefix[DISTRIBUTE_IN] = NULL;
  218. }
  219. if (type == DISTRIBUTE_OUT)
  220. {
  221. if (!dist->prefix[DISTRIBUTE_OUT])
  222. return 0;
  223. if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0)
  224. return 0;
  225. free (dist->prefix[DISTRIBUTE_OUT]);
  226. dist->prefix[DISTRIBUTE_OUT] = NULL;
  227. }
  228. /* Apply this distribute-list to the interface. */
  229. (*distribute_delete_hook) (dist);
  230. /* If both out and in is NULL then free distribute list. */
  231. if (dist->list[DISTRIBUTE_IN] == NULL &&
  232. dist->list[DISTRIBUTE_OUT] == NULL &&
  233. dist->prefix[DISTRIBUTE_IN] == NULL &&
  234. dist->prefix[DISTRIBUTE_OUT] == NULL)
  235. {
  236. hash_release (disthash, dist);
  237. distribute_free (dist);
  238. }
  239. return 1;
  240. }
  241. DEFUN (distribute_list_all,
  242. distribute_list_all_cmd,
  243. "distribute-list WORD (in|out)",
  244. "Filter networks in routing updates\n"
  245. "Access-list name\n"
  246. "Filter incoming routing updates\n"
  247. "Filter outgoing routing updates\n")
  248. {
  249. enum distribute_type type;
  250. struct distribute *dist;
  251. /* Check of distribute list type. */
  252. if (strncmp (argv[1], "i", 1) == 0)
  253. type = DISTRIBUTE_IN;
  254. else if (strncmp (argv[1], "o", 1) == 0)
  255. type = DISTRIBUTE_OUT;
  256. else
  257. {
  258. vty_out (vty, "distribute list direction must be [in|out]%s",
  259. VTY_NEWLINE);
  260. return CMD_WARNING;
  261. }
  262. /* Get interface name corresponding distribute list. */
  263. dist = distribute_list_set (NULL, type, argv[0]);
  264. return CMD_SUCCESS;
  265. }
  266. ALIAS (distribute_list_all,
  267. ipv6_distribute_list_all_cmd,
  268. "distribute-list WORD (in|out)",
  269. "Filter networks in routing updates\n"
  270. "Access-list name\n"
  271. "Filter incoming routing updates\n"
  272. "Filter outgoing routing updates\n")
  273. DEFUN (no_distribute_list_all,
  274. no_distribute_list_all_cmd,
  275. "no distribute-list WORD (in|out)",
  276. NO_STR
  277. "Filter networks in routing updates\n"
  278. "Access-list name\n"
  279. "Filter incoming routing updates\n"
  280. "Filter outgoing routing updates\n")
  281. {
  282. int ret;
  283. enum distribute_type type;
  284. /* Check of distribute list type. */
  285. if (strncmp (argv[1], "i", 1) == 0)
  286. type = DISTRIBUTE_IN;
  287. else if (strncmp (argv[1], "o", 1) == 0)
  288. type = DISTRIBUTE_OUT;
  289. else
  290. {
  291. vty_out (vty, "distribute list direction must be [in|out]%s",
  292. VTY_NEWLINE);
  293. return CMD_WARNING;
  294. }
  295. ret = distribute_list_unset (NULL, type, argv[0]);
  296. if (! ret)
  297. {
  298. vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  299. return CMD_WARNING;
  300. }
  301. return CMD_SUCCESS;
  302. }
  303. ALIAS (no_distribute_list_all,
  304. no_ipv6_distribute_list_all_cmd,
  305. "no distribute-list WORD (in|out)",
  306. NO_STR
  307. "Filter networks in routing updates\n"
  308. "Access-list name\n"
  309. "Filter incoming routing updates\n"
  310. "Filter outgoing routing updates\n")
  311. DEFUN (distribute_list,
  312. distribute_list_cmd,
  313. "distribute-list WORD (in|out) WORD",
  314. "Filter networks in routing updates\n"
  315. "Access-list name\n"
  316. "Filter incoming routing updates\n"
  317. "Filter outgoing routing updates\n"
  318. "Interface name\n")
  319. {
  320. enum distribute_type type;
  321. struct distribute *dist;
  322. /* Check of distribute list type. */
  323. if (strncmp (argv[1], "i", 1) == 0)
  324. type = DISTRIBUTE_IN;
  325. else if (strncmp (argv[1], "o", 1) == 0)
  326. type = DISTRIBUTE_OUT;
  327. else
  328. {
  329. vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
  330. return CMD_WARNING;
  331. }
  332. /* Get interface name corresponding distribute list. */
  333. dist = distribute_list_set (argv[2], type, argv[0]);
  334. return CMD_SUCCESS;
  335. }
  336. ALIAS (distribute_list,
  337. ipv6_distribute_list_cmd,
  338. "distribute-list WORD (in|out) WORD",
  339. "Filter networks in routing updates\n"
  340. "Access-list name\n"
  341. "Filter incoming routing updates\n"
  342. "Filter outgoing routing updates\n"
  343. "Interface name\n")
  344. DEFUN (no_districute_list, no_distribute_list_cmd,
  345. "no distribute-list WORD (in|out) WORD",
  346. NO_STR
  347. "Filter networks in routing updates\n"
  348. "Access-list name\n"
  349. "Filter incoming routing updates\n"
  350. "Filter outgoing routing updates\n"
  351. "Interface name\n")
  352. {
  353. int ret;
  354. enum distribute_type type;
  355. /* Check of distribute list type. */
  356. if (strncmp (argv[1], "i", 1) == 0)
  357. type = DISTRIBUTE_IN;
  358. else if (strncmp (argv[1], "o", 1) == 0)
  359. type = DISTRIBUTE_OUT;
  360. else
  361. {
  362. vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE);
  363. return CMD_WARNING;
  364. }
  365. ret = distribute_list_unset (argv[2], type, argv[0]);
  366. if (! ret)
  367. {
  368. vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  369. return CMD_WARNING;
  370. }
  371. return CMD_SUCCESS;
  372. }
  373. ALIAS (no_districute_list, no_ipv6_distribute_list_cmd,
  374. "no distribute-list WORD (in|out) WORD",
  375. NO_STR
  376. "Filter networks in routing updates\n"
  377. "Access-list name\n"
  378. "Filter incoming routing updates\n"
  379. "Filter outgoing routing updates\n"
  380. "Interface name\n")
  381. DEFUN (districute_list_prefix_all,
  382. distribute_list_prefix_all_cmd,
  383. "distribute-list prefix WORD (in|out)",
  384. "Filter networks in routing updates\n"
  385. "Filter prefixes in routing updates\n"
  386. "Name of an IP prefix-list\n"
  387. "Filter incoming routing updates\n"
  388. "Filter outgoing routing updates\n")
  389. {
  390. enum distribute_type type;
  391. struct distribute *dist;
  392. /* Check of distribute list type. */
  393. if (strncmp (argv[1], "i", 1) == 0)
  394. type = DISTRIBUTE_IN;
  395. else if (strncmp (argv[1], "o", 1) == 0)
  396. type = DISTRIBUTE_OUT;
  397. else
  398. {
  399. vty_out (vty, "distribute list direction must be [in|out]%s",
  400. VTY_NEWLINE);
  401. return CMD_WARNING;
  402. }
  403. /* Get interface name corresponding distribute list. */
  404. dist = distribute_list_prefix_set (NULL, type, argv[0]);
  405. return CMD_SUCCESS;
  406. }
  407. ALIAS (districute_list_prefix_all,
  408. ipv6_distribute_list_prefix_all_cmd,
  409. "distribute-list prefix WORD (in|out)",
  410. "Filter networks in routing updates\n"
  411. "Filter prefixes in routing updates\n"
  412. "Name of an IP prefix-list\n"
  413. "Filter incoming routing updates\n"
  414. "Filter outgoing routing updates\n")
  415. DEFUN (no_districute_list_prefix_all,
  416. no_distribute_list_prefix_all_cmd,
  417. "no distribute-list prefix WORD (in|out)",
  418. NO_STR
  419. "Filter networks in routing updates\n"
  420. "Filter prefixes in routing updates\n"
  421. "Name of an IP prefix-list\n"
  422. "Filter incoming routing updates\n"
  423. "Filter outgoing routing updates\n")
  424. {
  425. int ret;
  426. enum distribute_type type;
  427. /* Check of distribute list type. */
  428. if (strncmp (argv[1], "i", 1) == 0)
  429. type = DISTRIBUTE_IN;
  430. else if (strncmp (argv[1], "o", 1) == 0)
  431. type = DISTRIBUTE_OUT;
  432. else
  433. {
  434. vty_out (vty, "distribute list direction must be [in|out]%s",
  435. VTY_NEWLINE);
  436. return CMD_WARNING;
  437. }
  438. ret = distribute_list_prefix_unset (NULL, type, argv[0]);
  439. if (! ret)
  440. {
  441. vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  442. return CMD_WARNING;
  443. }
  444. return CMD_SUCCESS;
  445. }
  446. ALIAS (no_districute_list_prefix_all,
  447. no_ipv6_distribute_list_prefix_all_cmd,
  448. "no distribute-list prefix WORD (in|out)",
  449. NO_STR
  450. "Filter networks in routing updates\n"
  451. "Filter prefixes in routing updates\n"
  452. "Name of an IP prefix-list\n"
  453. "Filter incoming routing updates\n"
  454. "Filter outgoing routing updates\n")
  455. DEFUN (districute_list_prefix, distribute_list_prefix_cmd,
  456. "distribute-list prefix WORD (in|out) WORD",
  457. "Filter networks in routing updates\n"
  458. "Filter prefixes in routing updates\n"
  459. "Name of an IP prefix-list\n"
  460. "Filter incoming routing updates\n"
  461. "Filter outgoing routing updates\n"
  462. "Interface name\n")
  463. {
  464. enum distribute_type type;
  465. struct distribute *dist;
  466. /* Check of distribute list type. */
  467. if (strncmp (argv[1], "i", 1) == 0)
  468. type = DISTRIBUTE_IN;
  469. else if (strncmp (argv[1], "o", 1) == 0)
  470. type = DISTRIBUTE_OUT;
  471. else
  472. {
  473. vty_out (vty, "distribute list direction must be [in|out]%s",
  474. VTY_NEWLINE);
  475. return CMD_WARNING;
  476. }
  477. /* Get interface name corresponding distribute list. */
  478. dist = distribute_list_prefix_set (argv[2], type, argv[0]);
  479. return CMD_SUCCESS;
  480. }
  481. ALIAS (districute_list_prefix, ipv6_distribute_list_prefix_cmd,
  482. "distribute-list prefix WORD (in|out) WORD",
  483. "Filter networks in routing updates\n"
  484. "Filter prefixes in routing updates\n"
  485. "Name of an IP prefix-list\n"
  486. "Filter incoming routing updates\n"
  487. "Filter outgoing routing updates\n"
  488. "Interface name\n")
  489. DEFUN (no_districute_list_prefix, no_distribute_list_prefix_cmd,
  490. "no distribute-list prefix WORD (in|out) WORD",
  491. NO_STR
  492. "Filter networks in routing updates\n"
  493. "Filter prefixes in routing updates\n"
  494. "Name of an IP prefix-list\n"
  495. "Filter incoming routing updates\n"
  496. "Filter outgoing routing updates\n"
  497. "Interface name\n")
  498. {
  499. int ret;
  500. enum distribute_type type;
  501. /* Check of distribute list type. */
  502. if (strncmp (argv[1], "i", 1) == 0)
  503. type = DISTRIBUTE_IN;
  504. else if (strncmp (argv[1], "o", 1) == 0)
  505. type = DISTRIBUTE_OUT;
  506. else
  507. {
  508. vty_out (vty, "distribute list direction must be [in|out]%s",
  509. VTY_NEWLINE);
  510. return CMD_WARNING;
  511. }
  512. ret = distribute_list_prefix_unset (argv[2], type, argv[0]);
  513. if (! ret)
  514. {
  515. vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE);
  516. return CMD_WARNING;
  517. }
  518. return CMD_SUCCESS;
  519. }
  520. ALIAS (no_districute_list_prefix, no_ipv6_distribute_list_prefix_cmd,
  521. "no distribute-list prefix WORD (in|out) WORD",
  522. NO_STR
  523. "Filter networks in routing updates\n"
  524. "Filter prefixes in routing updates\n"
  525. "Name of an IP prefix-list\n"
  526. "Filter incoming routing updates\n"
  527. "Filter outgoing routing updates\n"
  528. "Interface name\n")
  529. int
  530. config_show_distribute (struct vty *vty)
  531. {
  532. unsigned int i;
  533. struct hash_backet *mp;
  534. struct distribute *dist;
  535. /* Output filter configuration. */
  536. dist = distribute_lookup (NULL);
  537. if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]))
  538. {
  539. vty_out (vty, " Outgoing update filter list for all interface is");
  540. if (dist->list[DISTRIBUTE_OUT])
  541. vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
  542. if (dist->prefix[DISTRIBUTE_OUT])
  543. vty_out (vty, "%s (prefix-list) %s",
  544. dist->list[DISTRIBUTE_OUT] ? "," : "",
  545. dist->prefix[DISTRIBUTE_OUT]);
  546. vty_out (vty, "%s", VTY_NEWLINE);
  547. }
  548. else
  549. vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE);
  550. for (i = 0; i < disthash->size; i++)
  551. for (mp = disthash->index[i]; mp; mp = mp->next)
  552. {
  553. dist = mp->data;
  554. if (dist->ifname)
  555. if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])
  556. {
  557. vty_out (vty, " %s filtered by", dist->ifname);
  558. if (dist->list[DISTRIBUTE_OUT])
  559. vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]);
  560. if (dist->prefix[DISTRIBUTE_OUT])
  561. vty_out (vty, "%s (prefix-list) %s",
  562. dist->list[DISTRIBUTE_OUT] ? "," : "",
  563. dist->prefix[DISTRIBUTE_OUT]);
  564. vty_out (vty, "%s", VTY_NEWLINE);
  565. }
  566. }
  567. /* Input filter configuration. */
  568. dist = distribute_lookup (NULL);
  569. if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]))
  570. {
  571. vty_out (vty, " Incoming update filter list for all interface is");
  572. if (dist->list[DISTRIBUTE_IN])
  573. vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
  574. if (dist->prefix[DISTRIBUTE_IN])
  575. vty_out (vty, "%s (prefix-list) %s",
  576. dist->list[DISTRIBUTE_IN] ? "," : "",
  577. dist->prefix[DISTRIBUTE_IN]);
  578. vty_out (vty, "%s", VTY_NEWLINE);
  579. }
  580. else
  581. vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE);
  582. for (i = 0; i < disthash->size; i++)
  583. for (mp = disthash->index[i]; mp; mp = mp->next)
  584. {
  585. dist = mp->data;
  586. if (dist->ifname)
  587. if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])
  588. {
  589. vty_out (vty, " %s filtered by", dist->ifname);
  590. if (dist->list[DISTRIBUTE_IN])
  591. vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]);
  592. if (dist->prefix[DISTRIBUTE_IN])
  593. vty_out (vty, "%s (prefix-list) %s",
  594. dist->list[DISTRIBUTE_IN] ? "," : "",
  595. dist->prefix[DISTRIBUTE_IN]);
  596. vty_out (vty, "%s", VTY_NEWLINE);
  597. }
  598. }
  599. return 0;
  600. }
  601. /* Configuration write function. */
  602. int
  603. config_write_distribute (struct vty *vty)
  604. {
  605. unsigned int i;
  606. struct hash_backet *mp;
  607. int write = 0;
  608. for (i = 0; i < disthash->size; i++)
  609. for (mp = disthash->index[i]; mp; mp = mp->next)
  610. {
  611. struct distribute *dist;
  612. dist = mp->data;
  613. if (dist->list[DISTRIBUTE_IN])
  614. {
  615. vty_out (vty, " distribute-list %s in %s%s",
  616. dist->list[DISTRIBUTE_IN],
  617. dist->ifname ? dist->ifname : "",
  618. VTY_NEWLINE);
  619. write++;
  620. }
  621. if (dist->list[DISTRIBUTE_OUT])
  622. {
  623. vty_out (vty, " distribute-list %s out %s%s",
  624. dist->list[DISTRIBUTE_OUT],
  625. dist->ifname ? dist->ifname : "",
  626. VTY_NEWLINE);
  627. write++;
  628. }
  629. if (dist->prefix[DISTRIBUTE_IN])
  630. {
  631. vty_out (vty, " distribute-list prefix %s in %s%s",
  632. dist->prefix[DISTRIBUTE_IN],
  633. dist->ifname ? dist->ifname : "",
  634. VTY_NEWLINE);
  635. write++;
  636. }
  637. if (dist->prefix[DISTRIBUTE_OUT])
  638. {
  639. vty_out (vty, " distribute-list prefix %s out %s%s",
  640. dist->prefix[DISTRIBUTE_OUT],
  641. dist->ifname ? dist->ifname : "",
  642. VTY_NEWLINE);
  643. write++;
  644. }
  645. }
  646. return write;
  647. }
  648. /* Clear all distribute list. */
  649. void
  650. distribute_list_reset ()
  651. {
  652. hash_clean (disthash, (void (*) (void *)) distribute_free);
  653. }
  654. /* Initialize distribute list related hash. */
  655. void
  656. distribute_list_init (int node)
  657. {
  658. disthash = hash_create (distribute_hash_make,
  659. (int (*) (const void *, const void *)) distribute_cmp);
  660. if(node==RIP_NODE) {
  661. install_element (RIP_NODE, &distribute_list_all_cmd);
  662. install_element (RIP_NODE, &no_distribute_list_all_cmd);
  663. install_element (RIP_NODE, &distribute_list_cmd);
  664. install_element (RIP_NODE, &no_distribute_list_cmd);
  665. install_element (RIP_NODE, &distribute_list_prefix_all_cmd);
  666. install_element (RIP_NODE, &no_distribute_list_prefix_all_cmd);
  667. install_element (RIP_NODE, &distribute_list_prefix_cmd);
  668. install_element (RIP_NODE, &no_distribute_list_prefix_cmd);
  669. } else {
  670. install_element (RIPNG_NODE, &ipv6_distribute_list_all_cmd);
  671. install_element (RIPNG_NODE, &no_ipv6_distribute_list_all_cmd);
  672. install_element (RIPNG_NODE, &ipv6_distribute_list_cmd);
  673. install_element (RIPNG_NODE, &no_ipv6_distribute_list_cmd);
  674. install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_all_cmd);
  675. install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_all_cmd);
  676. install_element (RIPNG_NODE, &ipv6_distribute_list_prefix_cmd);
  677. install_element (RIPNG_NODE, &no_ipv6_distribute_list_prefix_cmd);
  678. }
  679. }