filter.c 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065
  1. /* Route filtering function.
  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 "prefix.h"
  23. #include "filter.h"
  24. #include "memory.h"
  25. #include "command.h"
  26. #include "sockunion.h"
  27. #include "buffer.h"
  28. #include "log.h"
  29. struct filter_cisco
  30. {
  31. /* Cisco access-list */
  32. int extended;
  33. struct in_addr addr;
  34. struct in_addr addr_mask;
  35. struct in_addr mask;
  36. struct in_addr mask_mask;
  37. };
  38. struct filter_zebra
  39. {
  40. /* If this filter is "exact" match then this flag is set. */
  41. int exact;
  42. /* Prefix information. */
  43. struct prefix prefix;
  44. };
  45. /* Filter element of access list */
  46. struct filter
  47. {
  48. /* For doubly linked list. */
  49. struct filter *next;
  50. struct filter *prev;
  51. /* Filter type information. */
  52. enum filter_type type;
  53. /* Cisco access-list */
  54. int cisco;
  55. union
  56. {
  57. struct filter_cisco cfilter;
  58. struct filter_zebra zfilter;
  59. } u;
  60. };
  61. /* List of access_list. */
  62. struct access_list_list
  63. {
  64. struct access_list *head;
  65. struct access_list *tail;
  66. };
  67. /* Master structure of access_list. */
  68. struct access_master
  69. {
  70. /* List of access_list which name is number. */
  71. struct access_list_list num;
  72. /* List of access_list which name is string. */
  73. struct access_list_list str;
  74. /* Hook function which is executed when new access_list is added. */
  75. void (*add_hook) (const char *);
  76. /* Hook function which is executed when access_list is deleted. */
  77. void (*delete_hook) (const char *);
  78. };
  79. /* Static structure for IPv4 access_list's master. */
  80. static struct access_master access_master_ipv4 =
  81. {
  82. {NULL, NULL},
  83. {NULL, NULL},
  84. NULL,
  85. NULL,
  86. };
  87. #ifdef HAVE_IPV6
  88. /* Static structure for IPv6 access_list's master. */
  89. static struct access_master access_master_ipv6 =
  90. {
  91. {NULL, NULL},
  92. {NULL, NULL},
  93. NULL,
  94. NULL,
  95. };
  96. #endif /* HAVE_IPV6 */
  97. static struct access_master *
  98. access_master_get (afi_t afi)
  99. {
  100. if (afi == AFI_IP)
  101. return &access_master_ipv4;
  102. #ifdef HAVE_IPV6
  103. else if (afi == AFI_IP6)
  104. return &access_master_ipv6;
  105. #endif /* HAVE_IPV6 */
  106. return NULL;
  107. }
  108. /* Allocate new filter structure. */
  109. static struct filter *
  110. filter_new (void)
  111. {
  112. return (struct filter *) XCALLOC (MTYPE_ACCESS_FILTER,
  113. sizeof (struct filter));
  114. }
  115. static void
  116. filter_free (struct filter *filter)
  117. {
  118. XFREE (MTYPE_ACCESS_FILTER, filter);
  119. }
  120. /* Return string of filter_type. */
  121. static const char *
  122. filter_type_str (struct filter *filter)
  123. {
  124. switch (filter->type)
  125. {
  126. case FILTER_PERMIT:
  127. return "permit";
  128. break;
  129. case FILTER_DENY:
  130. return "deny";
  131. break;
  132. case FILTER_DYNAMIC:
  133. return "dynamic";
  134. break;
  135. default:
  136. return "";
  137. break;
  138. }
  139. }
  140. /* If filter match to the prefix then return 1. */
  141. static int
  142. filter_match_cisco (struct filter *mfilter, struct prefix *p)
  143. {
  144. struct filter_cisco *filter;
  145. struct in_addr mask;
  146. u_int32_t check_addr;
  147. u_int32_t check_mask;
  148. filter = &mfilter->u.cfilter;
  149. check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
  150. if (filter->extended)
  151. {
  152. masklen2ip (p->prefixlen, &mask);
  153. check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
  154. if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0
  155. && memcmp (&check_mask, &filter->mask.s_addr, 4) == 0)
  156. return 1;
  157. }
  158. else if (memcmp (&check_addr, &filter->addr.s_addr, 4) == 0)
  159. return 1;
  160. return 0;
  161. }
  162. /* If filter match to the prefix then return 1. */
  163. static int
  164. filter_match_zebra (struct filter *mfilter, struct prefix *p)
  165. {
  166. struct filter_zebra *filter;
  167. filter = &mfilter->u.zfilter;
  168. if (filter->prefix.family == p->family)
  169. {
  170. if (filter->exact)
  171. {
  172. if (filter->prefix.prefixlen == p->prefixlen)
  173. return prefix_match (&filter->prefix, p);
  174. else
  175. return 0;
  176. }
  177. else
  178. return prefix_match (&filter->prefix, p);
  179. }
  180. else
  181. return 0;
  182. }
  183. /* Allocate new access list structure. */
  184. static struct access_list *
  185. access_list_new (void)
  186. {
  187. return (struct access_list *) XCALLOC (MTYPE_ACCESS_LIST,
  188. sizeof (struct access_list));
  189. }
  190. /* Free allocated access_list. */
  191. static void
  192. access_list_free (struct access_list *access)
  193. {
  194. XFREE (MTYPE_ACCESS_LIST, access);
  195. }
  196. /* Delete access_list from access_master and free it. */
  197. static void
  198. access_list_delete (struct access_list *access)
  199. {
  200. struct filter *filter;
  201. struct filter *next;
  202. struct access_list_list *list;
  203. struct access_master *master;
  204. for (filter = access->head; filter; filter = next)
  205. {
  206. next = filter->next;
  207. filter_free (filter);
  208. }
  209. master = access->master;
  210. if (access->type == ACCESS_TYPE_NUMBER)
  211. list = &master->num;
  212. else
  213. list = &master->str;
  214. if (access->next)
  215. access->next->prev = access->prev;
  216. else
  217. list->tail = access->prev;
  218. if (access->prev)
  219. access->prev->next = access->next;
  220. else
  221. list->head = access->next;
  222. if (access->name)
  223. XFREE (MTYPE_ACCESS_LIST_STR, access->name);
  224. if (access->remark)
  225. XFREE (MTYPE_TMP, access->remark);
  226. access_list_free (access);
  227. }
  228. /* Insert new access list to list of access_list. Each acceess_list
  229. is sorted by the name. */
  230. static struct access_list *
  231. access_list_insert (afi_t afi, const char *name)
  232. {
  233. unsigned int i;
  234. long number;
  235. struct access_list *access;
  236. struct access_list *point;
  237. struct access_list_list *alist;
  238. struct access_master *master;
  239. master = access_master_get (afi);
  240. if (master == NULL)
  241. return NULL;
  242. /* Allocate new access_list and copy given name. */
  243. access = access_list_new ();
  244. access->name = XSTRDUP (MTYPE_ACCESS_LIST_STR, name);
  245. access->master = master;
  246. /* If name is made by all digit character. We treat it as
  247. number. */
  248. for (number = 0, i = 0; i < strlen (name); i++)
  249. {
  250. if (isdigit ((int) name[i]))
  251. number = (number * 10) + (name[i] - '0');
  252. else
  253. break;
  254. }
  255. /* In case of name is all digit character */
  256. if (i == strlen (name))
  257. {
  258. access->type = ACCESS_TYPE_NUMBER;
  259. /* Set access_list to number list. */
  260. alist = &master->num;
  261. for (point = alist->head; point; point = point->next)
  262. if (atol (point->name) >= number)
  263. break;
  264. }
  265. else
  266. {
  267. access->type = ACCESS_TYPE_STRING;
  268. /* Set access_list to string list. */
  269. alist = &master->str;
  270. /* Set point to insertion point. */
  271. for (point = alist->head; point; point = point->next)
  272. if (point->name && strcmp (point->name, name) >= 0)
  273. break;
  274. }
  275. /* In case of this is the first element of master. */
  276. if (alist->head == NULL)
  277. {
  278. alist->head = alist->tail = access;
  279. return access;
  280. }
  281. /* In case of insertion is made at the tail of access_list. */
  282. if (point == NULL)
  283. {
  284. access->prev = alist->tail;
  285. alist->tail->next = access;
  286. alist->tail = access;
  287. return access;
  288. }
  289. /* In case of insertion is made at the head of access_list. */
  290. if (point == alist->head)
  291. {
  292. access->next = alist->head;
  293. alist->head->prev = access;
  294. alist->head = access;
  295. return access;
  296. }
  297. /* Insertion is made at middle of the access_list. */
  298. access->next = point;
  299. access->prev = point->prev;
  300. if (point->prev)
  301. point->prev->next = access;
  302. point->prev = access;
  303. return access;
  304. }
  305. /* Lookup access_list from list of access_list by name. */
  306. struct access_list *
  307. access_list_lookup (afi_t afi, const char *name)
  308. {
  309. struct access_list *access;
  310. struct access_master *master;
  311. if (name == NULL)
  312. return NULL;
  313. master = access_master_get (afi);
  314. if (master == NULL)
  315. return NULL;
  316. for (access = master->num.head; access; access = access->next)
  317. if (access->name && strcmp (access->name, name) == 0)
  318. return access;
  319. for (access = master->str.head; access; access = access->next)
  320. if (access->name && strcmp (access->name, name) == 0)
  321. return access;
  322. return NULL;
  323. }
  324. /* Get access list from list of access_list. If there isn't matched
  325. access_list create new one and return it. */
  326. static struct access_list *
  327. access_list_get (afi_t afi, const char *name)
  328. {
  329. struct access_list *access;
  330. access = access_list_lookup (afi, name);
  331. if (access == NULL)
  332. access = access_list_insert (afi, name);
  333. return access;
  334. }
  335. /* Apply access list to object (which should be struct prefix *). */
  336. enum filter_type
  337. access_list_apply (struct access_list *access, void *object)
  338. {
  339. struct filter *filter;
  340. struct prefix *p;
  341. p = (struct prefix *) object;
  342. if (access == NULL)
  343. return FILTER_DENY;
  344. for (filter = access->head; filter; filter = filter->next)
  345. {
  346. if (filter->cisco)
  347. {
  348. if (filter_match_cisco (filter, p))
  349. return filter->type;
  350. }
  351. else
  352. {
  353. if (filter_match_zebra (filter, p))
  354. return filter->type;
  355. }
  356. }
  357. return FILTER_DENY;
  358. }
  359. /* Add hook function. */
  360. void
  361. access_list_add_hook (void (*func) (const char *))
  362. {
  363. access_master_ipv4.add_hook = func;
  364. #ifdef HAVE_IPV6
  365. access_master_ipv6.add_hook = func;
  366. #endif /* HAVE_IPV6 */
  367. }
  368. /* Delete hook function. */
  369. void
  370. access_list_delete_hook (void (*func) (const char *))
  371. {
  372. access_master_ipv4.delete_hook = func;
  373. #ifdef HAVE_IPV6
  374. access_master_ipv6.delete_hook = func;
  375. #endif /* HAVE_IPV6 */
  376. }
  377. /* Add new filter to the end of specified access_list. */
  378. static void
  379. access_list_filter_add (struct access_list *access, struct filter *filter)
  380. {
  381. filter->next = NULL;
  382. filter->prev = access->tail;
  383. if (access->tail)
  384. access->tail->next = filter;
  385. else
  386. access->head = filter;
  387. access->tail = filter;
  388. /* Run hook function. */
  389. if (access->master->add_hook)
  390. (*access->master->add_hook) (access->name);
  391. }
  392. /* If access_list has no filter then return 1. */
  393. static int
  394. access_list_empty (struct access_list *access)
  395. {
  396. if (access->head == NULL && access->tail == NULL)
  397. return 1;
  398. else
  399. return 0;
  400. }
  401. /* Delete filter from specified access_list. If there is hook
  402. function execute it. */
  403. static void
  404. access_list_filter_delete (struct access_list *access, struct filter *filter)
  405. {
  406. struct access_master *master;
  407. /* transfer ownership of access->name to a local, to retain the name
  408. * to pass to a delete hook, while the access-list is deleted
  409. *
  410. * It is important that access-lists that are deleted, or are in process
  411. * of being deleted, are not visible via access_list_lookup. This is
  412. * because some (all?) users process the delete_hook callback the same
  413. * as an add - they simply refresh all their access_list name references
  414. * by looking up the name.
  415. *
  416. * If an access list can be looked up while being deleted, such users will
  417. * not remove an access-list, and will keep dangling references to
  418. * freed access lists.
  419. */
  420. char *name = access->name;
  421. access->name = NULL;
  422. master = access->master;
  423. if (filter->next)
  424. filter->next->prev = filter->prev;
  425. else
  426. access->tail = filter->prev;
  427. if (filter->prev)
  428. filter->prev->next = filter->next;
  429. else
  430. access->head = filter->next;
  431. filter_free (filter);
  432. /* If access_list becomes empty delete it from access_master. */
  433. if (access_list_empty (access))
  434. access_list_delete (access);
  435. /* Run hook function. */
  436. if (master->delete_hook)
  437. (*master->delete_hook) (name);
  438. XFREE (MTYPE_ACCESS_LIST_STR, name);
  439. }
  440. /*
  441. deny Specify packets to reject
  442. permit Specify packets to forward
  443. dynamic ?
  444. */
  445. /*
  446. Hostname or A.B.C.D Address to match
  447. any Any source host
  448. host A single host address
  449. */
  450. static struct filter *
  451. filter_lookup_cisco (struct access_list *access, struct filter *mnew)
  452. {
  453. struct filter *mfilter;
  454. struct filter_cisco *filter;
  455. struct filter_cisco *new;
  456. new = &mnew->u.cfilter;
  457. for (mfilter = access->head; mfilter; mfilter = mfilter->next)
  458. {
  459. filter = &mfilter->u.cfilter;
  460. if (filter->extended)
  461. {
  462. if (mfilter->type == mnew->type
  463. && filter->addr.s_addr == new->addr.s_addr
  464. && filter->addr_mask.s_addr == new->addr_mask.s_addr
  465. && filter->mask.s_addr == new->mask.s_addr
  466. && filter->mask_mask.s_addr == new->mask_mask.s_addr)
  467. return mfilter;
  468. }
  469. else
  470. {
  471. if (mfilter->type == mnew->type
  472. && filter->addr.s_addr == new->addr.s_addr
  473. && filter->addr_mask.s_addr == new->addr_mask.s_addr)
  474. return mfilter;
  475. }
  476. }
  477. return NULL;
  478. }
  479. static struct filter *
  480. filter_lookup_zebra (struct access_list *access, struct filter *mnew)
  481. {
  482. struct filter *mfilter;
  483. struct filter_zebra *filter;
  484. struct filter_zebra *new;
  485. new = &mnew->u.zfilter;
  486. for (mfilter = access->head; mfilter; mfilter = mfilter->next)
  487. {
  488. filter = &mfilter->u.zfilter;
  489. if (filter->exact == new->exact
  490. && mfilter->type == mnew->type
  491. && prefix_same (&filter->prefix, &new->prefix))
  492. return mfilter;
  493. }
  494. return NULL;
  495. }
  496. static int
  497. vty_access_list_remark_unset (struct vty *vty, afi_t afi, const char *name)
  498. {
  499. struct access_list *access;
  500. access = access_list_lookup (afi, name);
  501. if (! access)
  502. {
  503. vty_out (vty, "%% access-list %s doesn't exist%s", name,
  504. VTY_NEWLINE);
  505. return CMD_WARNING;
  506. }
  507. if (access->remark)
  508. {
  509. XFREE (MTYPE_TMP, access->remark);
  510. access->remark = NULL;
  511. }
  512. if (access->head == NULL && access->tail == NULL && access->remark == NULL)
  513. access_list_delete (access);
  514. return CMD_SUCCESS;
  515. }
  516. static int
  517. filter_set_cisco (struct vty *vty, const char *name_str, const char *type_str,
  518. const char *addr_str, const char *addr_mask_str,
  519. const char *mask_str, const char *mask_mask_str,
  520. int extended, int set)
  521. {
  522. int ret;
  523. enum filter_type type;
  524. struct filter *mfilter;
  525. struct filter_cisco *filter;
  526. struct access_list *access;
  527. struct in_addr addr;
  528. struct in_addr addr_mask;
  529. struct in_addr mask;
  530. struct in_addr mask_mask;
  531. /* Check of filter type. */
  532. if (strncmp (type_str, "p", 1) == 0)
  533. type = FILTER_PERMIT;
  534. else if (strncmp (type_str, "d", 1) == 0)
  535. type = FILTER_DENY;
  536. else
  537. {
  538. vty_out (vty, "%% filter type must be permit or deny%s", VTY_NEWLINE);
  539. return CMD_WARNING;
  540. }
  541. ret = inet_aton (addr_str, &addr);
  542. if (ret <= 0)
  543. {
  544. vty_out (vty, "%%Inconsistent address and mask%s",
  545. VTY_NEWLINE);
  546. return CMD_WARNING;
  547. }
  548. ret = inet_aton (addr_mask_str, &addr_mask);
  549. if (ret <= 0)
  550. {
  551. vty_out (vty, "%%Inconsistent address and mask%s",
  552. VTY_NEWLINE);
  553. return CMD_WARNING;
  554. }
  555. if (extended)
  556. {
  557. ret = inet_aton (mask_str, &mask);
  558. if (ret <= 0)
  559. {
  560. vty_out (vty, "%%Inconsistent address and mask%s",
  561. VTY_NEWLINE);
  562. return CMD_WARNING;
  563. }
  564. ret = inet_aton (mask_mask_str, &mask_mask);
  565. if (ret <= 0)
  566. {
  567. vty_out (vty, "%%Inconsistent address and mask%s",
  568. VTY_NEWLINE);
  569. return CMD_WARNING;
  570. }
  571. }
  572. mfilter = filter_new();
  573. mfilter->type = type;
  574. mfilter->cisco = 1;
  575. filter = &mfilter->u.cfilter;
  576. filter->extended = extended;
  577. filter->addr.s_addr = addr.s_addr & ~addr_mask.s_addr;
  578. filter->addr_mask.s_addr = addr_mask.s_addr;
  579. if (extended)
  580. {
  581. filter->mask.s_addr = mask.s_addr & ~mask_mask.s_addr;
  582. filter->mask_mask.s_addr = mask_mask.s_addr;
  583. }
  584. /* Install new filter to the access_list. */
  585. access = access_list_get (AFI_IP, name_str);
  586. if (set)
  587. {
  588. if (filter_lookup_cisco (access, mfilter))
  589. filter_free (mfilter);
  590. else
  591. access_list_filter_add (access, mfilter);
  592. }
  593. else
  594. {
  595. struct filter *delete_filter;
  596. delete_filter = filter_lookup_cisco (access, mfilter);
  597. if (delete_filter)
  598. access_list_filter_delete (access, delete_filter);
  599. filter_free (mfilter);
  600. }
  601. return CMD_SUCCESS;
  602. }
  603. /* Standard access-list */
  604. DEFUN (access_list_standard,
  605. access_list_standard_cmd,
  606. "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
  607. "Add an access list entry\n"
  608. "IP standard access list\n"
  609. "IP standard access list (expanded range)\n"
  610. "Specify packets to reject\n"
  611. "Specify packets to forward\n"
  612. "Address to match\n"
  613. "Wildcard bits\n")
  614. {
  615. return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
  616. NULL, NULL, 0, 1);
  617. }
  618. DEFUN (access_list_standard_nomask,
  619. access_list_standard_nomask_cmd,
  620. "access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
  621. "Add an access list entry\n"
  622. "IP standard access list\n"
  623. "IP standard access list (expanded range)\n"
  624. "Specify packets to reject\n"
  625. "Specify packets to forward\n"
  626. "Address to match\n")
  627. {
  628. return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
  629. NULL, NULL, 0, 1);
  630. }
  631. DEFUN (access_list_standard_host,
  632. access_list_standard_host_cmd,
  633. "access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
  634. "Add an access list entry\n"
  635. "IP standard access list\n"
  636. "IP standard access list (expanded range)\n"
  637. "Specify packets to reject\n"
  638. "Specify packets to forward\n"
  639. "A single host address\n"
  640. "Address to match\n")
  641. {
  642. return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
  643. NULL, NULL, 0, 1);
  644. }
  645. DEFUN (access_list_standard_any,
  646. access_list_standard_any_cmd,
  647. "access-list (<1-99>|<1300-1999>) (deny|permit) any",
  648. "Add an access list entry\n"
  649. "IP standard access list\n"
  650. "IP standard access list (expanded range)\n"
  651. "Specify packets to reject\n"
  652. "Specify packets to forward\n"
  653. "Any source host\n")
  654. {
  655. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  656. "255.255.255.255", NULL, NULL, 0, 1);
  657. }
  658. DEFUN (no_access_list_standard,
  659. no_access_list_standard_cmd,
  660. "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D A.B.C.D",
  661. NO_STR
  662. "Add an access list entry\n"
  663. "IP standard access list\n"
  664. "IP standard access list (expanded range)\n"
  665. "Specify packets to reject\n"
  666. "Specify packets to forward\n"
  667. "Address to match\n"
  668. "Wildcard bits\n")
  669. {
  670. return filter_set_cisco (vty, argv[0], argv[1], argv[2], argv[3],
  671. NULL, NULL, 0, 0);
  672. }
  673. DEFUN (no_access_list_standard_nomask,
  674. no_access_list_standard_nomask_cmd,
  675. "no access-list (<1-99>|<1300-1999>) (deny|permit) A.B.C.D",
  676. NO_STR
  677. "Add an access list entry\n"
  678. "IP standard access list\n"
  679. "IP standard access list (expanded range)\n"
  680. "Specify packets to reject\n"
  681. "Specify packets to forward\n"
  682. "Address to match\n")
  683. {
  684. return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
  685. NULL, NULL, 0, 0);
  686. }
  687. DEFUN (no_access_list_standard_host,
  688. no_access_list_standard_host_cmd,
  689. "no access-list (<1-99>|<1300-1999>) (deny|permit) host A.B.C.D",
  690. NO_STR
  691. "Add an access list entry\n"
  692. "IP standard access list\n"
  693. "IP standard access list (expanded range)\n"
  694. "Specify packets to reject\n"
  695. "Specify packets to forward\n"
  696. "A single host address\n"
  697. "Address to match\n")
  698. {
  699. return filter_set_cisco (vty, argv[0], argv[1], argv[2], "0.0.0.0",
  700. NULL, NULL, 0, 0);
  701. }
  702. DEFUN (no_access_list_standard_any,
  703. no_access_list_standard_any_cmd,
  704. "no access-list (<1-99>|<1300-1999>) (deny|permit) any",
  705. NO_STR
  706. "Add an access list entry\n"
  707. "IP standard access list\n"
  708. "IP standard access list (expanded range)\n"
  709. "Specify packets to reject\n"
  710. "Specify packets to forward\n"
  711. "Any source host\n")
  712. {
  713. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  714. "255.255.255.255", NULL, NULL, 0, 0);
  715. }
  716. /* Extended access-list */
  717. DEFUN (access_list_extended,
  718. access_list_extended_cmd,
  719. "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
  720. "Add an access list entry\n"
  721. "IP extended access list\n"
  722. "IP extended access list (expanded range)\n"
  723. "Specify packets to reject\n"
  724. "Specify packets to forward\n"
  725. "Any Internet Protocol\n"
  726. "Source address\n"
  727. "Source wildcard bits\n"
  728. "Destination address\n"
  729. "Destination Wildcard bits\n")
  730. {
  731. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  732. argv[3], argv[4], argv[5], 1 ,1);
  733. }
  734. DEFUN (access_list_extended_mask_any,
  735. access_list_extended_mask_any_cmd,
  736. "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
  737. "Add an access list entry\n"
  738. "IP extended access list\n"
  739. "IP extended access list (expanded range)\n"
  740. "Specify packets to reject\n"
  741. "Specify packets to forward\n"
  742. "Any Internet Protocol\n"
  743. "Source address\n"
  744. "Source wildcard bits\n"
  745. "Any destination host\n")
  746. {
  747. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  748. argv[3], "0.0.0.0",
  749. "255.255.255.255", 1, 1);
  750. }
  751. DEFUN (access_list_extended_any_mask,
  752. access_list_extended_any_mask_cmd,
  753. "access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
  754. "Add an access list entry\n"
  755. "IP extended access list\n"
  756. "IP extended access list (expanded range)\n"
  757. "Specify packets to reject\n"
  758. "Specify packets to forward\n"
  759. "Any Internet Protocol\n"
  760. "Any source host\n"
  761. "Destination address\n"
  762. "Destination Wildcard bits\n")
  763. {
  764. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  765. "255.255.255.255", argv[2],
  766. argv[3], 1, 1);
  767. }
  768. DEFUN (access_list_extended_any_any,
  769. access_list_extended_any_any_cmd,
  770. "access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
  771. "Add an access list entry\n"
  772. "IP extended access list\n"
  773. "IP extended access list (expanded range)\n"
  774. "Specify packets to reject\n"
  775. "Specify packets to forward\n"
  776. "Any Internet Protocol\n"
  777. "Any source host\n"
  778. "Any destination host\n")
  779. {
  780. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  781. "255.255.255.255", "0.0.0.0",
  782. "255.255.255.255", 1, 1);
  783. }
  784. DEFUN (access_list_extended_mask_host,
  785. access_list_extended_mask_host_cmd,
  786. "access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
  787. "Add an access list entry\n"
  788. "IP extended access list\n"
  789. "IP extended access list (expanded range)\n"
  790. "Specify packets to reject\n"
  791. "Specify packets to forward\n"
  792. "Any Internet Protocol\n"
  793. "Source address\n"
  794. "Source wildcard bits\n"
  795. "A single destination host\n"
  796. "Destination address\n")
  797. {
  798. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  799. argv[3], argv[4],
  800. "0.0.0.0", 1, 1);
  801. }
  802. DEFUN (access_list_extended_host_mask,
  803. access_list_extended_host_mask_cmd,
  804. "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
  805. "Add an access list entry\n"
  806. "IP extended access list\n"
  807. "IP extended access list (expanded range)\n"
  808. "Specify packets to reject\n"
  809. "Specify packets to forward\n"
  810. "Any Internet Protocol\n"
  811. "A single source host\n"
  812. "Source address\n"
  813. "Destination address\n"
  814. "Destination Wildcard bits\n")
  815. {
  816. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  817. "0.0.0.0", argv[3],
  818. argv[4], 1, 1);
  819. }
  820. DEFUN (access_list_extended_host_host,
  821. access_list_extended_host_host_cmd,
  822. "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
  823. "Add an access list entry\n"
  824. "IP extended access list\n"
  825. "IP extended access list (expanded range)\n"
  826. "Specify packets to reject\n"
  827. "Specify packets to forward\n"
  828. "Any Internet Protocol\n"
  829. "A single source host\n"
  830. "Source address\n"
  831. "A single destination host\n"
  832. "Destination address\n")
  833. {
  834. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  835. "0.0.0.0", argv[3],
  836. "0.0.0.0", 1, 1);
  837. }
  838. DEFUN (access_list_extended_any_host,
  839. access_list_extended_any_host_cmd,
  840. "access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
  841. "Add an access list entry\n"
  842. "IP extended access list\n"
  843. "IP extended access list (expanded range)\n"
  844. "Specify packets to reject\n"
  845. "Specify packets to forward\n"
  846. "Any Internet Protocol\n"
  847. "Any source host\n"
  848. "A single destination host\n"
  849. "Destination address\n")
  850. {
  851. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  852. "255.255.255.255", argv[2],
  853. "0.0.0.0", 1, 1);
  854. }
  855. DEFUN (access_list_extended_host_any,
  856. access_list_extended_host_any_cmd,
  857. "access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
  858. "Add an access list entry\n"
  859. "IP extended access list\n"
  860. "IP extended access list (expanded range)\n"
  861. "Specify packets to reject\n"
  862. "Specify packets to forward\n"
  863. "Any Internet Protocol\n"
  864. "A single source host\n"
  865. "Source address\n"
  866. "Any destination host\n")
  867. {
  868. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  869. "0.0.0.0", "0.0.0.0",
  870. "255.255.255.255", 1, 1);
  871. }
  872. DEFUN (no_access_list_extended,
  873. no_access_list_extended_cmd,
  874. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D A.B.C.D A.B.C.D",
  875. NO_STR
  876. "Add an access list entry\n"
  877. "IP extended access list\n"
  878. "IP extended access list (expanded range)\n"
  879. "Specify packets to reject\n"
  880. "Specify packets to forward\n"
  881. "Any Internet Protocol\n"
  882. "Source address\n"
  883. "Source wildcard bits\n"
  884. "Destination address\n"
  885. "Destination Wildcard bits\n")
  886. {
  887. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  888. argv[3], argv[4], argv[5], 1, 0);
  889. }
  890. DEFUN (no_access_list_extended_mask_any,
  891. no_access_list_extended_mask_any_cmd,
  892. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D any",
  893. NO_STR
  894. "Add an access list entry\n"
  895. "IP extended access list\n"
  896. "IP extended access list (expanded range)\n"
  897. "Specify packets to reject\n"
  898. "Specify packets to forward\n"
  899. "Any Internet Protocol\n"
  900. "Source address\n"
  901. "Source wildcard bits\n"
  902. "Any destination host\n")
  903. {
  904. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  905. argv[3], "0.0.0.0",
  906. "255.255.255.255", 1, 0);
  907. }
  908. DEFUN (no_access_list_extended_any_mask,
  909. no_access_list_extended_any_mask_cmd,
  910. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any A.B.C.D A.B.C.D",
  911. NO_STR
  912. "Add an access list entry\n"
  913. "IP extended access list\n"
  914. "IP extended access list (expanded range)\n"
  915. "Specify packets to reject\n"
  916. "Specify packets to forward\n"
  917. "Any Internet Protocol\n"
  918. "Any source host\n"
  919. "Destination address\n"
  920. "Destination Wildcard bits\n")
  921. {
  922. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  923. "255.255.255.255", argv[2],
  924. argv[3], 1, 0);
  925. }
  926. DEFUN (no_access_list_extended_any_any,
  927. no_access_list_extended_any_any_cmd,
  928. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any any",
  929. NO_STR
  930. "Add an access list entry\n"
  931. "IP extended access list\n"
  932. "IP extended access list (expanded range)\n"
  933. "Specify packets to reject\n"
  934. "Specify packets to forward\n"
  935. "Any Internet Protocol\n"
  936. "Any source host\n"
  937. "Any destination host\n")
  938. {
  939. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  940. "255.255.255.255", "0.0.0.0",
  941. "255.255.255.255", 1, 0);
  942. }
  943. DEFUN (no_access_list_extended_mask_host,
  944. no_access_list_extended_mask_host_cmd,
  945. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip A.B.C.D A.B.C.D host A.B.C.D",
  946. NO_STR
  947. "Add an access list entry\n"
  948. "IP extended access list\n"
  949. "IP extended access list (expanded range)\n"
  950. "Specify packets to reject\n"
  951. "Specify packets to forward\n"
  952. "Any Internet Protocol\n"
  953. "Source address\n"
  954. "Source wildcard bits\n"
  955. "A single destination host\n"
  956. "Destination address\n")
  957. {
  958. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  959. argv[3], argv[4],
  960. "0.0.0.0", 1, 0);
  961. }
  962. DEFUN (no_access_list_extended_host_mask,
  963. no_access_list_extended_host_mask_cmd,
  964. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D A.B.C.D A.B.C.D",
  965. NO_STR
  966. "Add an access list entry\n"
  967. "IP extended access list\n"
  968. "IP extended access list (expanded range)\n"
  969. "Specify packets to reject\n"
  970. "Specify packets to forward\n"
  971. "Any Internet Protocol\n"
  972. "A single source host\n"
  973. "Source address\n"
  974. "Destination address\n"
  975. "Destination Wildcard bits\n")
  976. {
  977. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  978. "0.0.0.0", argv[3],
  979. argv[4], 1, 0);
  980. }
  981. DEFUN (no_access_list_extended_host_host,
  982. no_access_list_extended_host_host_cmd,
  983. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D host A.B.C.D",
  984. NO_STR
  985. "Add an access list entry\n"
  986. "IP extended access list\n"
  987. "IP extended access list (expanded range)\n"
  988. "Specify packets to reject\n"
  989. "Specify packets to forward\n"
  990. "Any Internet Protocol\n"
  991. "A single source host\n"
  992. "Source address\n"
  993. "A single destination host\n"
  994. "Destination address\n")
  995. {
  996. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  997. "0.0.0.0", argv[3],
  998. "0.0.0.0", 1, 0);
  999. }
  1000. DEFUN (no_access_list_extended_any_host,
  1001. no_access_list_extended_any_host_cmd,
  1002. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip any host A.B.C.D",
  1003. NO_STR
  1004. "Add an access list entry\n"
  1005. "IP extended access list\n"
  1006. "IP extended access list (expanded range)\n"
  1007. "Specify packets to reject\n"
  1008. "Specify packets to forward\n"
  1009. "Any Internet Protocol\n"
  1010. "Any source host\n"
  1011. "A single destination host\n"
  1012. "Destination address\n")
  1013. {
  1014. return filter_set_cisco (vty, argv[0], argv[1], "0.0.0.0",
  1015. "255.255.255.255", argv[2],
  1016. "0.0.0.0", 1, 0);
  1017. }
  1018. DEFUN (no_access_list_extended_host_any,
  1019. no_access_list_extended_host_any_cmd,
  1020. "no access-list (<100-199>|<2000-2699>) (deny|permit) ip host A.B.C.D any",
  1021. NO_STR
  1022. "Add an access list entry\n"
  1023. "IP extended access list\n"
  1024. "IP extended access list (expanded range)\n"
  1025. "Specify packets to reject\n"
  1026. "Specify packets to forward\n"
  1027. "Any Internet Protocol\n"
  1028. "A single source host\n"
  1029. "Source address\n"
  1030. "Any destination host\n")
  1031. {
  1032. return filter_set_cisco (vty, argv[0], argv[1], argv[2],
  1033. "0.0.0.0", "0.0.0.0",
  1034. "255.255.255.255", 1, 0);
  1035. }
  1036. static int
  1037. filter_set_zebra (struct vty *vty, const char *name_str, const char *type_str,
  1038. afi_t afi, const char *prefix_str, int exact, int set)
  1039. {
  1040. int ret;
  1041. enum filter_type type;
  1042. struct filter *mfilter;
  1043. struct filter_zebra *filter;
  1044. struct access_list *access;
  1045. struct prefix p;
  1046. /* Check of filter type. */
  1047. if (strncmp (type_str, "p", 1) == 0)
  1048. type = FILTER_PERMIT;
  1049. else if (strncmp (type_str, "d", 1) == 0)
  1050. type = FILTER_DENY;
  1051. else
  1052. {
  1053. vty_out (vty, "filter type must be [permit|deny]%s", VTY_NEWLINE);
  1054. return CMD_WARNING;
  1055. }
  1056. /* Check string format of prefix and prefixlen. */
  1057. if (afi == AFI_IP)
  1058. {
  1059. ret = str2prefix_ipv4 (prefix_str, (struct prefix_ipv4 *)&p);
  1060. if (ret <= 0)
  1061. {
  1062. vty_out (vty, "IP address prefix/prefixlen is malformed%s",
  1063. VTY_NEWLINE);
  1064. return CMD_WARNING;
  1065. }
  1066. }
  1067. #ifdef HAVE_IPV6
  1068. else if (afi == AFI_IP6)
  1069. {
  1070. ret = str2prefix_ipv6 (prefix_str, (struct prefix_ipv6 *) &p);
  1071. if (ret <= 0)
  1072. {
  1073. vty_out (vty, "IPv6 address prefix/prefixlen is malformed%s",
  1074. VTY_NEWLINE);
  1075. return CMD_WARNING;
  1076. }
  1077. }
  1078. #endif /* HAVE_IPV6 */
  1079. else
  1080. return CMD_WARNING;
  1081. mfilter = filter_new ();
  1082. mfilter->type = type;
  1083. filter = &mfilter->u.zfilter;
  1084. prefix_copy (&filter->prefix, &p);
  1085. /* "exact-match" */
  1086. if (exact)
  1087. filter->exact = 1;
  1088. /* Install new filter to the access_list. */
  1089. access = access_list_get (afi, name_str);
  1090. if (set)
  1091. {
  1092. if (filter_lookup_zebra (access, mfilter))
  1093. filter_free (mfilter);
  1094. else
  1095. access_list_filter_add (access, mfilter);
  1096. }
  1097. else
  1098. {
  1099. struct filter *delete_filter;
  1100. delete_filter = filter_lookup_zebra (access, mfilter);
  1101. if (delete_filter)
  1102. access_list_filter_delete (access, delete_filter);
  1103. filter_free (mfilter);
  1104. }
  1105. return CMD_SUCCESS;
  1106. }
  1107. /* Zebra access-list */
  1108. DEFUN (access_list,
  1109. access_list_cmd,
  1110. "access-list WORD (deny|permit) A.B.C.D/M",
  1111. "Add an access list entry\n"
  1112. "IP zebra access-list name\n"
  1113. "Specify packets to reject\n"
  1114. "Specify packets to forward\n"
  1115. "Prefix to match. e.g. 10.0.0.0/8\n")
  1116. {
  1117. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 1);
  1118. }
  1119. DEFUN (access_list_exact,
  1120. access_list_exact_cmd,
  1121. "access-list WORD (deny|permit) A.B.C.D/M exact-match",
  1122. "Add an access list entry\n"
  1123. "IP zebra access-list name\n"
  1124. "Specify packets to reject\n"
  1125. "Specify packets to forward\n"
  1126. "Prefix to match. e.g. 10.0.0.0/8\n"
  1127. "Exact match of the prefixes\n")
  1128. {
  1129. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 1);
  1130. }
  1131. DEFUN (access_list_any,
  1132. access_list_any_cmd,
  1133. "access-list WORD (deny|permit) any",
  1134. "Add an access list entry\n"
  1135. "IP zebra access-list name\n"
  1136. "Specify packets to reject\n"
  1137. "Specify packets to forward\n"
  1138. "Prefix to match. e.g. 10.0.0.0/8\n")
  1139. {
  1140. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 1);
  1141. }
  1142. DEFUN (no_access_list,
  1143. no_access_list_cmd,
  1144. "no access-list WORD (deny|permit) A.B.C.D/M",
  1145. NO_STR
  1146. "Add an access list entry\n"
  1147. "IP zebra access-list name\n"
  1148. "Specify packets to reject\n"
  1149. "Specify packets to forward\n"
  1150. "Prefix to match. e.g. 10.0.0.0/8\n")
  1151. {
  1152. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 0, 0);
  1153. }
  1154. DEFUN (no_access_list_exact,
  1155. no_access_list_exact_cmd,
  1156. "no access-list WORD (deny|permit) A.B.C.D/M exact-match",
  1157. NO_STR
  1158. "Add an access list entry\n"
  1159. "IP zebra access-list name\n"
  1160. "Specify packets to reject\n"
  1161. "Specify packets to forward\n"
  1162. "Prefix to match. e.g. 10.0.0.0/8\n"
  1163. "Exact match of the prefixes\n")
  1164. {
  1165. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, argv[2], 1, 0);
  1166. }
  1167. DEFUN (no_access_list_any,
  1168. no_access_list_any_cmd,
  1169. "no access-list WORD (deny|permit) any",
  1170. NO_STR
  1171. "Add an access list entry\n"
  1172. "IP zebra access-list name\n"
  1173. "Specify packets to reject\n"
  1174. "Specify packets to forward\n"
  1175. "Prefix to match. e.g. 10.0.0.0/8\n")
  1176. {
  1177. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP, "0.0.0.0/0", 0, 0);
  1178. }
  1179. DEFUN (no_access_list_all,
  1180. no_access_list_all_cmd,
  1181. "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
  1182. NO_STR
  1183. "Add an access list entry\n"
  1184. "IP standard access list\n"
  1185. "IP extended access list\n"
  1186. "IP standard access list (expanded range)\n"
  1187. "IP extended access list (expanded range)\n"
  1188. "IP zebra access-list name\n")
  1189. {
  1190. struct access_list *access;
  1191. struct access_master *master;
  1192. char *name;
  1193. /* Looking up access_list. */
  1194. access = access_list_lookup (AFI_IP, argv[0]);
  1195. if (access == NULL)
  1196. {
  1197. vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
  1198. VTY_NEWLINE);
  1199. return CMD_WARNING;
  1200. }
  1201. master = access->master;
  1202. /* transfer ownership of access->name to a local, to retain
  1203. * a while longer, past access_list being freed */
  1204. name = access->name;
  1205. access->name = NULL;
  1206. /* Delete all filter from access-list. */
  1207. access_list_delete (access);
  1208. /* Run hook function. */
  1209. if (master->delete_hook)
  1210. (*master->delete_hook) (name);
  1211. XFREE (MTYPE_ACCESS_LIST_STR, name);
  1212. return CMD_SUCCESS;
  1213. }
  1214. DEFUN (access_list_remark,
  1215. access_list_remark_cmd,
  1216. "access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
  1217. "Add an access list entry\n"
  1218. "IP standard access list\n"
  1219. "IP extended access list\n"
  1220. "IP standard access list (expanded range)\n"
  1221. "IP extended access list (expanded range)\n"
  1222. "IP zebra access-list\n"
  1223. "Access list entry comment\n"
  1224. "Comment up to 100 characters\n")
  1225. {
  1226. struct access_list *access;
  1227. access = access_list_get (AFI_IP, argv[0]);
  1228. if (access->remark)
  1229. {
  1230. XFREE (MTYPE_TMP, access->remark);
  1231. access->remark = NULL;
  1232. }
  1233. access->remark = argv_concat(argv, argc, 1);
  1234. return CMD_SUCCESS;
  1235. }
  1236. DEFUN (no_access_list_remark,
  1237. no_access_list_remark_cmd,
  1238. "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark",
  1239. NO_STR
  1240. "Add an access list entry\n"
  1241. "IP standard access list\n"
  1242. "IP extended access list\n"
  1243. "IP standard access list (expanded range)\n"
  1244. "IP extended access list (expanded range)\n"
  1245. "IP zebra access-list\n"
  1246. "Access list entry comment\n")
  1247. {
  1248. return vty_access_list_remark_unset (vty, AFI_IP, argv[0]);
  1249. }
  1250. ALIAS (no_access_list_remark,
  1251. no_access_list_remark_arg_cmd,
  1252. "no access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD) remark .LINE",
  1253. NO_STR
  1254. "Add an access list entry\n"
  1255. "IP standard access list\n"
  1256. "IP extended access list\n"
  1257. "IP standard access list (expanded range)\n"
  1258. "IP extended access list (expanded range)\n"
  1259. "IP zebra access-list\n"
  1260. "Access list entry comment\n"
  1261. "Comment up to 100 characters\n")
  1262. #ifdef HAVE_IPV6
  1263. DEFUN (ipv6_access_list,
  1264. ipv6_access_list_cmd,
  1265. "ipv6 access-list WORD (deny|permit) X:X::X:X/M",
  1266. IPV6_STR
  1267. "Add an access list entry\n"
  1268. "IPv6 zebra access-list\n"
  1269. "Specify packets to reject\n"
  1270. "Specify packets to forward\n"
  1271. "Prefix to match. e.g. 3ffe:506::/32\n")
  1272. {
  1273. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 1);
  1274. }
  1275. DEFUN (ipv6_access_list_exact,
  1276. ipv6_access_list_exact_cmd,
  1277. "ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
  1278. IPV6_STR
  1279. "Add an access list entry\n"
  1280. "IPv6 zebra access-list\n"
  1281. "Specify packets to reject\n"
  1282. "Specify packets to forward\n"
  1283. "Prefix to match. e.g. 3ffe:506::/32\n"
  1284. "Exact match of the prefixes\n")
  1285. {
  1286. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 1);
  1287. }
  1288. DEFUN (ipv6_access_list_any,
  1289. ipv6_access_list_any_cmd,
  1290. "ipv6 access-list WORD (deny|permit) any",
  1291. IPV6_STR
  1292. "Add an access list entry\n"
  1293. "IPv6 zebra access-list\n"
  1294. "Specify packets to reject\n"
  1295. "Specify packets to forward\n"
  1296. "Any prefixi to match\n")
  1297. {
  1298. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 1);
  1299. }
  1300. DEFUN (no_ipv6_access_list,
  1301. no_ipv6_access_list_cmd,
  1302. "no ipv6 access-list WORD (deny|permit) X:X::X:X/M",
  1303. NO_STR
  1304. IPV6_STR
  1305. "Add an access list entry\n"
  1306. "IPv6 zebra access-list\n"
  1307. "Specify packets to reject\n"
  1308. "Specify packets to forward\n"
  1309. "Prefix to match. e.g. 3ffe:506::/32\n")
  1310. {
  1311. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 0, 0);
  1312. }
  1313. DEFUN (no_ipv6_access_list_exact,
  1314. no_ipv6_access_list_exact_cmd,
  1315. "no ipv6 access-list WORD (deny|permit) X:X::X:X/M exact-match",
  1316. NO_STR
  1317. IPV6_STR
  1318. "Add an access list entry\n"
  1319. "IPv6 zebra access-list\n"
  1320. "Specify packets to reject\n"
  1321. "Specify packets to forward\n"
  1322. "Prefix to match. e.g. 3ffe:506::/32\n"
  1323. "Exact match of the prefixes\n")
  1324. {
  1325. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, argv[2], 1, 0);
  1326. }
  1327. DEFUN (no_ipv6_access_list_any,
  1328. no_ipv6_access_list_any_cmd,
  1329. "no ipv6 access-list WORD (deny|permit) any",
  1330. NO_STR
  1331. IPV6_STR
  1332. "Add an access list entry\n"
  1333. "IPv6 zebra access-list\n"
  1334. "Specify packets to reject\n"
  1335. "Specify packets to forward\n"
  1336. "Any prefixi to match\n")
  1337. {
  1338. return filter_set_zebra (vty, argv[0], argv[1], AFI_IP6, "::/0", 0, 0);
  1339. }
  1340. DEFUN (no_ipv6_access_list_all,
  1341. no_ipv6_access_list_all_cmd,
  1342. "no ipv6 access-list WORD",
  1343. NO_STR
  1344. IPV6_STR
  1345. "Add an access list entry\n"
  1346. "IPv6 zebra access-list\n")
  1347. {
  1348. struct access_list *access;
  1349. struct access_master *master;
  1350. char *name;
  1351. /* Looking up access_list. */
  1352. access = access_list_lookup (AFI_IP6, argv[0]);
  1353. if (access == NULL)
  1354. {
  1355. vty_out (vty, "%% access-list %s doesn't exist%s", argv[0],
  1356. VTY_NEWLINE);
  1357. return CMD_WARNING;
  1358. }
  1359. master = access->master;
  1360. name = access->name;
  1361. access->name = NULL;
  1362. /* Delete all filter from access-list. */
  1363. access_list_delete (access);
  1364. /* Run hook function. */
  1365. if (master->delete_hook)
  1366. (*master->delete_hook) (name);
  1367. XFREE (MTYPE_ACCESS_LIST_STR, name);
  1368. return CMD_SUCCESS;
  1369. }
  1370. DEFUN (ipv6_access_list_remark,
  1371. ipv6_access_list_remark_cmd,
  1372. "ipv6 access-list WORD remark .LINE",
  1373. IPV6_STR
  1374. "Add an access list entry\n"
  1375. "IPv6 zebra access-list\n"
  1376. "Access list entry comment\n"
  1377. "Comment up to 100 characters\n")
  1378. {
  1379. struct access_list *access;
  1380. access = access_list_get (AFI_IP6, argv[0]);
  1381. if (access->remark)
  1382. {
  1383. XFREE (MTYPE_TMP, access->remark);
  1384. access->remark = NULL;
  1385. }
  1386. access->remark = argv_concat(argv, argc, 1);
  1387. return CMD_SUCCESS;
  1388. }
  1389. DEFUN (no_ipv6_access_list_remark,
  1390. no_ipv6_access_list_remark_cmd,
  1391. "no ipv6 access-list WORD remark",
  1392. NO_STR
  1393. IPV6_STR
  1394. "Add an access list entry\n"
  1395. "IPv6 zebra access-list\n"
  1396. "Access list entry comment\n")
  1397. {
  1398. return vty_access_list_remark_unset (vty, AFI_IP6, argv[0]);
  1399. }
  1400. ALIAS (no_ipv6_access_list_remark,
  1401. no_ipv6_access_list_remark_arg_cmd,
  1402. "no ipv6 access-list WORD remark .LINE",
  1403. NO_STR
  1404. IPV6_STR
  1405. "Add an access list entry\n"
  1406. "IPv6 zebra access-list\n"
  1407. "Access list entry comment\n"
  1408. "Comment up to 100 characters\n")
  1409. #endif /* HAVE_IPV6 */
  1410. void config_write_access_zebra (struct vty *, struct filter *);
  1411. void config_write_access_cisco (struct vty *, struct filter *);
  1412. /* show access-list command. */
  1413. static int
  1414. filter_show (struct vty *vty, const char *name, afi_t afi)
  1415. {
  1416. struct access_list *access;
  1417. struct access_master *master;
  1418. struct filter *mfilter;
  1419. struct filter_cisco *filter;
  1420. int write = 0;
  1421. master = access_master_get (afi);
  1422. if (master == NULL)
  1423. return 0;
  1424. /* Print the name of the protocol */
  1425. if (zlog_default)
  1426. vty_out (vty, "%s:%s",
  1427. zlog_proto_names[zlog_default->protocol], VTY_NEWLINE);
  1428. for (access = master->num.head; access; access = access->next)
  1429. {
  1430. if (!access->name || (name && strcmp (access->name, name) != 0))
  1431. continue;
  1432. write = 1;
  1433. for (mfilter = access->head; mfilter; mfilter = mfilter->next)
  1434. {
  1435. filter = &mfilter->u.cfilter;
  1436. if (write)
  1437. {
  1438. vty_out (vty, "%s IP%s access list %s%s",
  1439. mfilter->cisco ?
  1440. (filter->extended ? "Extended" : "Standard") : "Zebra",
  1441. afi == AFI_IP6 ? "v6" : "",
  1442. access->name, VTY_NEWLINE);
  1443. write = 0;
  1444. }
  1445. vty_out (vty, " %s%s", filter_type_str (mfilter),
  1446. mfilter->type == FILTER_DENY ? " " : "");
  1447. if (! mfilter->cisco)
  1448. config_write_access_zebra (vty, mfilter);
  1449. else if (filter->extended)
  1450. config_write_access_cisco (vty, mfilter);
  1451. else
  1452. {
  1453. if (filter->addr_mask.s_addr == 0xffffffff)
  1454. vty_out (vty, " any%s", VTY_NEWLINE);
  1455. else
  1456. {
  1457. vty_out (vty, " %s", inet_ntoa (filter->addr));
  1458. if (filter->addr_mask.s_addr != 0)
  1459. vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
  1460. vty_out (vty, "%s", VTY_NEWLINE);
  1461. }
  1462. }
  1463. }
  1464. }
  1465. for (access = master->str.head; access; access = access->next)
  1466. {
  1467. if (!access->name || (name && strcmp (access->name, name) != 0))
  1468. continue;
  1469. write = 1;
  1470. for (mfilter = access->head; mfilter; mfilter = mfilter->next)
  1471. {
  1472. filter = &mfilter->u.cfilter;
  1473. if (write)
  1474. {
  1475. vty_out (vty, "%s IP%s access list %s%s",
  1476. mfilter->cisco ?
  1477. (filter->extended ? "Extended" : "Standard") : "Zebra",
  1478. afi == AFI_IP6 ? "v6" : "",
  1479. access->name, VTY_NEWLINE);
  1480. write = 0;
  1481. }
  1482. vty_out (vty, " %s%s", filter_type_str (mfilter),
  1483. mfilter->type == FILTER_DENY ? " " : "");
  1484. if (! mfilter->cisco)
  1485. config_write_access_zebra (vty, mfilter);
  1486. else if (filter->extended)
  1487. config_write_access_cisco (vty, mfilter);
  1488. else
  1489. {
  1490. if (filter->addr_mask.s_addr == 0xffffffff)
  1491. vty_out (vty, " any%s", VTY_NEWLINE);
  1492. else
  1493. {
  1494. vty_out (vty, " %s", inet_ntoa (filter->addr));
  1495. if (filter->addr_mask.s_addr != 0)
  1496. vty_out (vty, ", wildcard bits %s", inet_ntoa (filter->addr_mask));
  1497. vty_out (vty, "%s", VTY_NEWLINE);
  1498. }
  1499. }
  1500. }
  1501. }
  1502. return CMD_SUCCESS;
  1503. }
  1504. DEFUN (show_ip_access_list,
  1505. show_ip_access_list_cmd,
  1506. "show ip access-list",
  1507. SHOW_STR
  1508. IP_STR
  1509. "List IP access lists\n")
  1510. {
  1511. return filter_show (vty, NULL, AFI_IP);
  1512. }
  1513. DEFUN (show_ip_access_list_name,
  1514. show_ip_access_list_name_cmd,
  1515. "show ip access-list (<1-99>|<100-199>|<1300-1999>|<2000-2699>|WORD)",
  1516. SHOW_STR
  1517. IP_STR
  1518. "List IP access lists\n"
  1519. "IP standard access list\n"
  1520. "IP extended access list\n"
  1521. "IP standard access list (expanded range)\n"
  1522. "IP extended access list (expanded range)\n"
  1523. "IP zebra access-list\n")
  1524. {
  1525. return filter_show (vty, argv[0], AFI_IP);
  1526. }
  1527. #ifdef HAVE_IPV6
  1528. DEFUN (show_ipv6_access_list,
  1529. show_ipv6_access_list_cmd,
  1530. "show ipv6 access-list",
  1531. SHOW_STR
  1532. IPV6_STR
  1533. "List IPv6 access lists\n")
  1534. {
  1535. return filter_show (vty, NULL, AFI_IP6);
  1536. }
  1537. DEFUN (show_ipv6_access_list_name,
  1538. show_ipv6_access_list_name_cmd,
  1539. "show ipv6 access-list WORD",
  1540. SHOW_STR
  1541. IPV6_STR
  1542. "List IPv6 access lists\n"
  1543. "IPv6 zebra access-list\n")
  1544. {
  1545. return filter_show (vty, argv[0], AFI_IP6);
  1546. }
  1547. #endif /* HAVE_IPV6 */
  1548. void
  1549. config_write_access_cisco (struct vty *vty, struct filter *mfilter)
  1550. {
  1551. struct filter_cisco *filter;
  1552. filter = &mfilter->u.cfilter;
  1553. if (filter->extended)
  1554. {
  1555. vty_out (vty, " ip");
  1556. if (filter->addr_mask.s_addr == 0xffffffff)
  1557. vty_out (vty, " any");
  1558. else if (filter->addr_mask.s_addr == 0)
  1559. vty_out (vty, " host %s", inet_ntoa (filter->addr));
  1560. else
  1561. {
  1562. vty_out (vty, " %s", inet_ntoa (filter->addr));
  1563. vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
  1564. }
  1565. if (filter->mask_mask.s_addr == 0xffffffff)
  1566. vty_out (vty, " any");
  1567. else if (filter->mask_mask.s_addr == 0)
  1568. vty_out (vty, " host %s", inet_ntoa (filter->mask));
  1569. else
  1570. {
  1571. vty_out (vty, " %s", inet_ntoa (filter->mask));
  1572. vty_out (vty, " %s", inet_ntoa (filter->mask_mask));
  1573. }
  1574. vty_out (vty, "%s", VTY_NEWLINE);
  1575. }
  1576. else
  1577. {
  1578. if (filter->addr_mask.s_addr == 0xffffffff)
  1579. vty_out (vty, " any%s", VTY_NEWLINE);
  1580. else
  1581. {
  1582. vty_out (vty, " %s", inet_ntoa (filter->addr));
  1583. if (filter->addr_mask.s_addr != 0)
  1584. vty_out (vty, " %s", inet_ntoa (filter->addr_mask));
  1585. vty_out (vty, "%s", VTY_NEWLINE);
  1586. }
  1587. }
  1588. }
  1589. void
  1590. config_write_access_zebra (struct vty *vty, struct filter *mfilter)
  1591. {
  1592. struct filter_zebra *filter;
  1593. struct prefix *p;
  1594. char buf[BUFSIZ];
  1595. filter = &mfilter->u.zfilter;
  1596. p = &filter->prefix;
  1597. if (p->prefixlen == 0 && ! filter->exact)
  1598. vty_out (vty, " any");
  1599. else
  1600. vty_out (vty, " %s/%d%s",
  1601. inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  1602. p->prefixlen,
  1603. filter->exact ? " exact-match" : "");
  1604. vty_out (vty, "%s", VTY_NEWLINE);
  1605. }
  1606. static int
  1607. config_write_access (struct vty *vty, afi_t afi)
  1608. {
  1609. struct access_list *access;
  1610. struct access_master *master;
  1611. struct filter *mfilter;
  1612. int write = 0;
  1613. master = access_master_get (afi);
  1614. if (master == NULL)
  1615. return 0;
  1616. for (access = master->num.head; access; access = access->next)
  1617. {
  1618. if (access->remark)
  1619. {
  1620. vty_out (vty, "%saccess-list %s remark %s%s",
  1621. afi == AFI_IP ? "" : "ipv6 ",
  1622. access->name, access->remark,
  1623. VTY_NEWLINE);
  1624. write++;
  1625. }
  1626. for (mfilter = access->head; mfilter; mfilter = mfilter->next)
  1627. {
  1628. vty_out (vty, "%saccess-list %s %s",
  1629. afi == AFI_IP ? "" : "ipv6 ",
  1630. access->name,
  1631. filter_type_str (mfilter));
  1632. if (mfilter->cisco)
  1633. config_write_access_cisco (vty, mfilter);
  1634. else
  1635. config_write_access_zebra (vty, mfilter);
  1636. write++;
  1637. }
  1638. }
  1639. for (access = master->str.head; access; access = access->next)
  1640. {
  1641. if (access->remark)
  1642. {
  1643. vty_out (vty, "%saccess-list %s remark %s%s",
  1644. afi == AFI_IP ? "" : "ipv6 ",
  1645. access->name, access->remark,
  1646. VTY_NEWLINE);
  1647. write++;
  1648. }
  1649. for (mfilter = access->head; mfilter; mfilter = mfilter->next)
  1650. {
  1651. vty_out (vty, "%saccess-list %s %s",
  1652. afi == AFI_IP ? "" : "ipv6 ",
  1653. access->name,
  1654. filter_type_str (mfilter));
  1655. if (mfilter->cisco)
  1656. config_write_access_cisco (vty, mfilter);
  1657. else
  1658. config_write_access_zebra (vty, mfilter);
  1659. write++;
  1660. }
  1661. }
  1662. return write;
  1663. }
  1664. /* Access-list node. */
  1665. static struct cmd_node access_node =
  1666. {
  1667. ACCESS_NODE,
  1668. "", /* Access list has no interface. */
  1669. 1
  1670. };
  1671. static int
  1672. config_write_access_ipv4 (struct vty *vty)
  1673. {
  1674. return config_write_access (vty, AFI_IP);
  1675. }
  1676. static void
  1677. access_list_reset_ipv4 (void)
  1678. {
  1679. struct access_list *access;
  1680. struct access_list *next;
  1681. struct access_master *master;
  1682. master = access_master_get (AFI_IP);
  1683. if (master == NULL)
  1684. return;
  1685. for (access = master->num.head; access; access = next)
  1686. {
  1687. next = access->next;
  1688. access_list_delete (access);
  1689. }
  1690. for (access = master->str.head; access; access = next)
  1691. {
  1692. next = access->next;
  1693. access_list_delete (access);
  1694. }
  1695. assert (master->num.head == NULL);
  1696. assert (master->num.tail == NULL);
  1697. assert (master->str.head == NULL);
  1698. assert (master->str.tail == NULL);
  1699. }
  1700. /* Install vty related command. */
  1701. static void
  1702. access_list_init_ipv4 (void)
  1703. {
  1704. install_node (&access_node, config_write_access_ipv4);
  1705. install_element (ENABLE_NODE, &show_ip_access_list_cmd);
  1706. install_element (ENABLE_NODE, &show_ip_access_list_name_cmd);
  1707. /* Zebra access-list */
  1708. install_element (CONFIG_NODE, &access_list_cmd);
  1709. install_element (CONFIG_NODE, &access_list_exact_cmd);
  1710. install_element (CONFIG_NODE, &access_list_any_cmd);
  1711. install_element (CONFIG_NODE, &no_access_list_cmd);
  1712. install_element (CONFIG_NODE, &no_access_list_exact_cmd);
  1713. install_element (CONFIG_NODE, &no_access_list_any_cmd);
  1714. /* Standard access-list */
  1715. install_element (CONFIG_NODE, &access_list_standard_cmd);
  1716. install_element (CONFIG_NODE, &access_list_standard_nomask_cmd);
  1717. install_element (CONFIG_NODE, &access_list_standard_host_cmd);
  1718. install_element (CONFIG_NODE, &access_list_standard_any_cmd);
  1719. install_element (CONFIG_NODE, &no_access_list_standard_cmd);
  1720. install_element (CONFIG_NODE, &no_access_list_standard_nomask_cmd);
  1721. install_element (CONFIG_NODE, &no_access_list_standard_host_cmd);
  1722. install_element (CONFIG_NODE, &no_access_list_standard_any_cmd);
  1723. /* Extended access-list */
  1724. install_element (CONFIG_NODE, &access_list_extended_cmd);
  1725. install_element (CONFIG_NODE, &access_list_extended_any_mask_cmd);
  1726. install_element (CONFIG_NODE, &access_list_extended_mask_any_cmd);
  1727. install_element (CONFIG_NODE, &access_list_extended_any_any_cmd);
  1728. install_element (CONFIG_NODE, &access_list_extended_host_mask_cmd);
  1729. install_element (CONFIG_NODE, &access_list_extended_mask_host_cmd);
  1730. install_element (CONFIG_NODE, &access_list_extended_host_host_cmd);
  1731. install_element (CONFIG_NODE, &access_list_extended_any_host_cmd);
  1732. install_element (CONFIG_NODE, &access_list_extended_host_any_cmd);
  1733. install_element (CONFIG_NODE, &no_access_list_extended_cmd);
  1734. install_element (CONFIG_NODE, &no_access_list_extended_any_mask_cmd);
  1735. install_element (CONFIG_NODE, &no_access_list_extended_mask_any_cmd);
  1736. install_element (CONFIG_NODE, &no_access_list_extended_any_any_cmd);
  1737. install_element (CONFIG_NODE, &no_access_list_extended_host_mask_cmd);
  1738. install_element (CONFIG_NODE, &no_access_list_extended_mask_host_cmd);
  1739. install_element (CONFIG_NODE, &no_access_list_extended_host_host_cmd);
  1740. install_element (CONFIG_NODE, &no_access_list_extended_any_host_cmd);
  1741. install_element (CONFIG_NODE, &no_access_list_extended_host_any_cmd);
  1742. install_element (CONFIG_NODE, &access_list_remark_cmd);
  1743. install_element (CONFIG_NODE, &no_access_list_all_cmd);
  1744. install_element (CONFIG_NODE, &no_access_list_remark_cmd);
  1745. install_element (CONFIG_NODE, &no_access_list_remark_arg_cmd);
  1746. }
  1747. #ifdef HAVE_IPV6
  1748. static struct cmd_node access_ipv6_node =
  1749. {
  1750. ACCESS_IPV6_NODE,
  1751. "",
  1752. 1
  1753. };
  1754. static int
  1755. config_write_access_ipv6 (struct vty *vty)
  1756. {
  1757. return config_write_access (vty, AFI_IP6);
  1758. }
  1759. static void
  1760. access_list_reset_ipv6 (void)
  1761. {
  1762. struct access_list *access;
  1763. struct access_list *next;
  1764. struct access_master *master;
  1765. master = access_master_get (AFI_IP6);
  1766. if (master == NULL)
  1767. return;
  1768. for (access = master->num.head; access; access = next)
  1769. {
  1770. next = access->next;
  1771. access_list_delete (access);
  1772. }
  1773. for (access = master->str.head; access; access = next)
  1774. {
  1775. next = access->next;
  1776. access_list_delete (access);
  1777. }
  1778. assert (master->num.head == NULL);
  1779. assert (master->num.tail == NULL);
  1780. assert (master->str.head == NULL);
  1781. assert (master->str.tail == NULL);
  1782. }
  1783. static void
  1784. access_list_init_ipv6 (void)
  1785. {
  1786. install_node (&access_ipv6_node, config_write_access_ipv6);
  1787. install_element (ENABLE_NODE, &show_ipv6_access_list_cmd);
  1788. install_element (ENABLE_NODE, &show_ipv6_access_list_name_cmd);
  1789. install_element (CONFIG_NODE, &ipv6_access_list_cmd);
  1790. install_element (CONFIG_NODE, &ipv6_access_list_exact_cmd);
  1791. install_element (CONFIG_NODE, &ipv6_access_list_any_cmd);
  1792. install_element (CONFIG_NODE, &no_ipv6_access_list_exact_cmd);
  1793. install_element (CONFIG_NODE, &no_ipv6_access_list_cmd);
  1794. install_element (CONFIG_NODE, &no_ipv6_access_list_any_cmd);
  1795. install_element (CONFIG_NODE, &no_ipv6_access_list_all_cmd);
  1796. install_element (CONFIG_NODE, &ipv6_access_list_remark_cmd);
  1797. install_element (CONFIG_NODE, &no_ipv6_access_list_remark_cmd);
  1798. install_element (CONFIG_NODE, &no_ipv6_access_list_remark_arg_cmd);
  1799. }
  1800. #endif /* HAVE_IPV6 */
  1801. void
  1802. access_list_init ()
  1803. {
  1804. access_list_init_ipv4 ();
  1805. #ifdef HAVE_IPV6
  1806. access_list_init_ipv6();
  1807. #endif /* HAVE_IPV6 */
  1808. }
  1809. void
  1810. access_list_reset ()
  1811. {
  1812. access_list_reset_ipv4 ();
  1813. #ifdef HAVE_IPV6
  1814. access_list_reset_ipv6();
  1815. #endif /* HAVE_IPV6 */
  1816. }