2002-12-13 21:15:29 +01:00
|
|
|
/* Route filtering function.
|
|
|
|
* Copyright (C) 1998, 1999 Kunihiro Ishiguro
|
|
|
|
*
|
|
|
|
* This file is part of GNU Zebra.
|
|
|
|
*
|
|
|
|
* GNU Zebra is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published
|
|
|
|
* by the Free Software Foundation; either version 2, or (at your
|
|
|
|
* option) any later version.
|
|
|
|
*
|
|
|
|
* GNU Zebra is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
2017-05-13 10:25:29 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; see the file COPYING; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "sockunion.h"
|
|
|
|
#include "buffer.h"
|
2005-09-29 13:25:50 +02:00
|
|
|
#include "log.h"
|
2015-05-20 02:40:45 +02:00
|
|
|
#include "routemap.h"
|
2017-05-08 03:06:07 +02:00
|
|
|
#include "libfrr.h"
|
2020-04-30 18:56:05 +02:00
|
|
|
#include "northbound_cli.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-29 05:48:31 +02:00
|
|
|
DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST, "Access List")
|
|
|
|
DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST_STR, "Access List Str")
|
|
|
|
DEFINE_MTYPE_STATIC(LIB, ACCESS_FILTER, "Access Filter")
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-27 18:31:54 +02:00
|
|
|
/* Static structure for mac access_list's master. */
|
2017-06-21 10:02:46 +02:00
|
|
|
static struct access_master access_master_mac = {
|
|
|
|
{NULL, NULL},
|
|
|
|
{NULL, NULL},
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Static structure for IPv4 access_list's master. */
|
|
|
|
static struct access_master access_master_ipv4 = {
|
|
|
|
{NULL, NULL},
|
|
|
|
{NULL, NULL},
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Static structure for IPv6 access_list's master. */
|
|
|
|
static struct access_master access_master_ipv6 = {
|
|
|
|
{NULL, NULL},
|
|
|
|
{NULL, NULL},
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
static struct access_master *access_master_get(afi_t afi)
|
|
|
|
{
|
|
|
|
if (afi == AFI_IP)
|
|
|
|
return &access_master_ipv4;
|
|
|
|
else if (afi == AFI_IP6)
|
|
|
|
return &access_master_ipv6;
|
2017-06-21 10:02:46 +02:00
|
|
|
else if (afi == AFI_L2VPN)
|
|
|
|
return &access_master_mac;
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate new filter structure. */
|
2019-11-08 18:46:17 +01:00
|
|
|
struct filter *filter_new(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-02-25 21:30:31 +01:00
|
|
|
return XCALLOC(MTYPE_ACCESS_FILTER, sizeof(struct filter));
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void filter_free(struct filter *filter)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ACCESS_FILTER, filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return string of filter_type. */
|
|
|
|
static const char *filter_type_str(struct filter *filter)
|
|
|
|
{
|
|
|
|
switch (filter->type) {
|
|
|
|
case FILTER_PERMIT:
|
|
|
|
return "permit";
|
|
|
|
case FILTER_DENY:
|
|
|
|
return "deny";
|
|
|
|
case FILTER_DYNAMIC:
|
|
|
|
return "dynamic";
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If filter match to the prefix then return 1. */
|
2018-07-12 22:05:19 +02:00
|
|
|
static int filter_match_cisco(struct filter *mfilter, const struct prefix *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct filter_cisco *filter;
|
|
|
|
struct in_addr mask;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t check_addr;
|
|
|
|
uint32_t check_mask;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
filter = &mfilter->u.cfilter;
|
|
|
|
check_addr = p->u.prefix4.s_addr & ~filter->addr_mask.s_addr;
|
|
|
|
|
|
|
|
if (filter->extended) {
|
|
|
|
masklen2ip(p->prefixlen, &mask);
|
|
|
|
check_mask = mask.s_addr & ~filter->mask_mask.s_addr;
|
|
|
|
|
|
|
|
if (memcmp(&check_addr, &filter->addr.s_addr, 4) == 0
|
|
|
|
&& memcmp(&check_mask, &filter->mask.s_addr, 4) == 0)
|
|
|
|
return 1;
|
|
|
|
} else if (memcmp(&check_addr, &filter->addr.s_addr, 4) == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If filter match to the prefix then return 1. */
|
2018-07-12 22:05:19 +02:00
|
|
|
static int filter_match_zebra(struct filter *mfilter, const struct prefix *p)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-06-21 10:02:46 +02:00
|
|
|
struct filter_zebra *filter = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
filter = &mfilter->u.zfilter;
|
|
|
|
|
2017-08-09 20:30:34 +02:00
|
|
|
if (filter->prefix.family == p->family) {
|
|
|
|
if (filter->exact) {
|
|
|
|
if (filter->prefix.prefixlen == p->prefixlen)
|
2002-12-13 21:15:29 +01:00
|
|
|
return prefix_match(&filter->prefix, p);
|
2017-08-09 20:30:34 +02:00
|
|
|
else
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
} else
|
2017-08-09 20:30:34 +02:00
|
|
|
return prefix_match(&filter->prefix, p);
|
|
|
|
} else
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Allocate new access list structure. */
|
2005-05-06 Paul Jakma <paul@dishone.st>
* (general) extern and static'ification of functions in code and
header.
Cleanup any definitions with unspecified arguments.
Add casts for callback assignments where the callback is defined,
typically, as passing void *, but the function being assigned has
some other pointer type defined as its argument, as gcc complains
about casts from void * to X* via function arguments.
Fix some old K&R style function argument definitions.
Add noreturn gcc attribute to some functions, as appropriate.
Add unused gcc attribute to some functions (eg ones meant to help
while debugging)
Add guard defines to headers which were missing them.
* command.c: (install_node) add const qualifier, still doesnt shut
up the warning though, because of the double pointer.
(cmp_node) ditto
* keychain.c: (key_str2time) Add GET_LONG_RANGE() macro, derived
fromn vty.h ones to fix some of the (long) < 0 warnings.
* thread.c: (various) use thread_empty
(cpu_record_hash_key) should cast to uintptr_t, a stdint.h type
* vty.h: Add VTY_GET_IPV4_ADDRESS and VTY_GET_IPV4_PREFIX so they
removed from ospfd/ospf_vty.h
* zebra.h: Move definition of ZEBRA_PORT to here, to remove
dependence of lib on zebra/zserv.h
2005-05-06 23:25:49 +02:00
|
|
|
static struct access_list *access_list_new(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-02-25 21:30:31 +01:00
|
|
|
return XCALLOC(MTYPE_ACCESS_LIST, sizeof(struct access_list));
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free allocated access_list. */
|
|
|
|
static void access_list_free(struct access_list *access)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ACCESS_LIST, access);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete access_list from access_master and free it. */
|
2019-11-08 18:46:17 +01:00
|
|
|
void access_list_delete(struct access_list *access)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct filter *filter;
|
|
|
|
struct filter *next;
|
|
|
|
struct access_list_list *list;
|
|
|
|
struct access_master *master;
|
|
|
|
|
|
|
|
for (filter = access->head; filter; filter = next) {
|
|
|
|
next = filter->next;
|
|
|
|
filter_free(filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
master = access->master;
|
|
|
|
|
|
|
|
if (access->type == ACCESS_TYPE_NUMBER)
|
|
|
|
list = &master->num;
|
|
|
|
else
|
|
|
|
list = &master->str;
|
|
|
|
|
|
|
|
if (access->next)
|
|
|
|
access->next->prev = access->prev;
|
|
|
|
else
|
|
|
|
list->tail = access->prev;
|
|
|
|
|
|
|
|
if (access->prev)
|
|
|
|
access->prev->next = access->next;
|
|
|
|
else
|
|
|
|
list->head = access->next;
|
|
|
|
|
2019-02-25 21:18:13 +01:00
|
|
|
XFREE(MTYPE_ACCESS_LIST_STR, access->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-02-25 21:18:13 +01:00
|
|
|
XFREE(MTYPE_TMP, access->remark);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
access_list_free(access);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Insert new access list to list of access_list. Each acceess_list
|
|
|
|
is sorted by the name. */
|
2004-10-05 23:01:23 +02:00
|
|
|
static struct access_list *access_list_insert(afi_t afi, const char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-05 23:01:23 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
long number;
|
|
|
|
struct access_list *access;
|
|
|
|
struct access_list *point;
|
|
|
|
struct access_list_list *alist;
|
|
|
|
struct access_master *master;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
master = access_master_get(afi);
|
|
|
|
if (master == NULL)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Allocate new access_list and copy given name. */
|
|
|
|
access = access_list_new();
|
|
|
|
access->name = XSTRDUP(MTYPE_ACCESS_LIST_STR, name);
|
|
|
|
access->master = master;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If name is made by all digit character. We treat it as
|
|
|
|
number. */
|
|
|
|
for (number = 0, i = 0; i < strlen(name); i++) {
|
2019-08-06 16:54:52 +02:00
|
|
|
if (isdigit((unsigned char)name[i]))
|
2002-12-13 21:15:29 +01:00
|
|
|
number = (number * 10) + (name[i] - '0');
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* In case of name is all digit character */
|
|
|
|
if (i == strlen(name)) {
|
|
|
|
access->type = ACCESS_TYPE_NUMBER;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set access_list to number list. */
|
|
|
|
alist = &master->num;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (point = alist->head; point; point = point->next)
|
|
|
|
if (atol(point->name) >= number)
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
access->type = ACCESS_TYPE_STRING;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set access_list to string list. */
|
|
|
|
alist = &master->str;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set point to insertion point. */
|
|
|
|
for (point = alist->head; point; point = point->next)
|
|
|
|
if (strcmp(point->name, name) >= 0)
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* In case of this is the first element of master. */
|
|
|
|
if (alist->head == NULL) {
|
|
|
|
alist->head = alist->tail = access;
|
|
|
|
return access;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* In case of insertion is made at the tail of access_list. */
|
|
|
|
if (point == NULL) {
|
|
|
|
access->prev = alist->tail;
|
|
|
|
alist->tail->next = access;
|
|
|
|
alist->tail = access;
|
|
|
|
return access;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* In case of insertion is made at the head of access_list. */
|
|
|
|
if (point == alist->head) {
|
|
|
|
access->next = alist->head;
|
|
|
|
alist->head->prev = access;
|
|
|
|
alist->head = access;
|
|
|
|
return access;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Insertion is made at middle of the access_list. */
|
|
|
|
access->next = point;
|
|
|
|
access->prev = point->prev;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (point->prev)
|
|
|
|
point->prev->next = access;
|
|
|
|
point->prev = access;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return access;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lookup access_list from list of access_list by name. */
|
2004-10-05 23:01:23 +02:00
|
|
|
struct access_list *access_list_lookup(afi_t afi, const char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *access;
|
|
|
|
struct access_master *master;
|
|
|
|
|
|
|
|
if (name == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
master = access_master_get(afi);
|
|
|
|
if (master == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (access = master->num.head; access; access = access->next)
|
|
|
|
if (strcmp(access->name, name) == 0)
|
|
|
|
return access;
|
|
|
|
|
|
|
|
for (access = master->str.head; access; access = access->next)
|
|
|
|
if (strcmp(access->name, name) == 0)
|
|
|
|
return access;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get access list from list of access_list. If there isn't matched
|
|
|
|
access_list create new one and return it. */
|
2019-11-08 18:46:17 +01:00
|
|
|
struct access_list *access_list_get(afi_t afi, const char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *access;
|
|
|
|
|
|
|
|
access = access_list_lookup(afi, name);
|
|
|
|
if (access == NULL)
|
|
|
|
access = access_list_insert(afi, name);
|
|
|
|
return access;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Apply access list to object (which should be struct prefix *). */
|
2018-07-12 22:05:19 +02:00
|
|
|
enum filter_type access_list_apply(struct access_list *access,
|
|
|
|
const void *object)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct filter *filter;
|
2018-07-12 22:05:19 +02:00
|
|
|
const struct prefix *p = (const struct prefix *)object;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (access == NULL)
|
|
|
|
return FILTER_DENY;
|
|
|
|
|
|
|
|
for (filter = access->head; filter; filter = filter->next) {
|
|
|
|
if (filter->cisco) {
|
|
|
|
if (filter_match_cisco(filter, p))
|
|
|
|
return filter->type;
|
|
|
|
} else {
|
2017-08-04 21:55:44 +02:00
|
|
|
if (filter_match_zebra(filter, p))
|
2002-12-13 21:15:29 +01:00
|
|
|
return filter->type;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return FILTER_DENY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add hook function. */
|
|
|
|
void access_list_add_hook(void (*func)(struct access_list *access))
|
|
|
|
{
|
|
|
|
access_master_ipv4.add_hook = func;
|
|
|
|
access_master_ipv6.add_hook = func;
|
2017-06-21 10:02:46 +02:00
|
|
|
access_master_mac.add_hook = func;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete hook function. */
|
|
|
|
void access_list_delete_hook(void (*func)(struct access_list *access))
|
|
|
|
{
|
|
|
|
access_master_ipv4.delete_hook = func;
|
|
|
|
access_master_ipv6.delete_hook = func;
|
2017-06-21 10:02:46 +02:00
|
|
|
access_master_mac.delete_hook = func;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2019-06-29 22:31:12 +02:00
|
|
|
/* Calculate new sequential number. */
|
2019-11-08 18:46:17 +01:00
|
|
|
int64_t filter_new_seq_get(struct access_list *access)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-06-29 22:31:12 +02:00
|
|
|
int64_t maxseq;
|
|
|
|
int64_t newseq;
|
|
|
|
struct filter *filter;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-02-24 14:29:27 +01:00
|
|
|
maxseq = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2019-06-29 22:31:12 +02:00
|
|
|
for (filter = access->head; filter; filter = filter->next) {
|
|
|
|
if (maxseq < filter->seq)
|
|
|
|
maxseq = filter->seq;
|
|
|
|
}
|
|
|
|
|
|
|
|
newseq = ((maxseq / 5) * 5) + 5;
|
|
|
|
|
|
|
|
return (newseq > UINT_MAX) ? UINT_MAX : newseq;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return access list entry which has same seq number. */
|
|
|
|
static struct filter *filter_seq_check(struct access_list *access,
|
|
|
|
int64_t seq)
|
|
|
|
{
|
|
|
|
struct filter *filter;
|
|
|
|
|
|
|
|
for (filter = access->head; filter; filter = filter->next)
|
|
|
|
if (filter->seq == seq)
|
|
|
|
return filter;
|
|
|
|
return NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete filter from specified access_list. If there is hook
|
|
|
|
function execute it. */
|
2019-11-08 18:46:17 +01:00
|
|
|
void access_list_filter_delete(struct access_list *access,
|
|
|
|
struct filter *filter)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_master *master;
|
|
|
|
|
|
|
|
master = access->master;
|
|
|
|
|
|
|
|
if (filter->next)
|
|
|
|
filter->next->prev = filter->prev;
|
|
|
|
else
|
|
|
|
access->tail = filter->prev;
|
|
|
|
|
|
|
|
if (filter->prev)
|
|
|
|
filter->prev->next = filter->next;
|
|
|
|
else
|
|
|
|
access->head = filter->next;
|
|
|
|
|
|
|
|
filter_free(filter);
|
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_DELETED);
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Run hook function. */
|
|
|
|
if (master->delete_hook)
|
|
|
|
(*master->delete_hook)(access);
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2019-06-29 22:31:12 +02:00
|
|
|
/* Add new filter to the end of specified access_list. */
|
2019-11-08 18:46:17 +01:00
|
|
|
void access_list_filter_add(struct access_list *access,
|
|
|
|
struct filter *filter)
|
2019-06-29 22:31:12 +02:00
|
|
|
{
|
|
|
|
struct filter *replace;
|
|
|
|
struct filter *point;
|
|
|
|
|
|
|
|
/* Automatic asignment of seq no. */
|
|
|
|
if (filter->seq == -1)
|
|
|
|
filter->seq = filter_new_seq_get(access);
|
|
|
|
|
|
|
|
if (access->tail && filter->seq > access->tail->seq)
|
|
|
|
point = NULL;
|
|
|
|
else {
|
|
|
|
/* Is there any same seq access list filter? */
|
|
|
|
replace = filter_seq_check(access, filter->seq);
|
|
|
|
if (replace)
|
|
|
|
access_list_filter_delete(access, replace);
|
|
|
|
|
|
|
|
/* Check insert point. */
|
|
|
|
for (point = access->head; point; point = point->next)
|
|
|
|
if (point->seq >= filter->seq)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In case of this is the first element of the list. */
|
|
|
|
filter->next = point;
|
|
|
|
|
|
|
|
if (point) {
|
|
|
|
if (point->prev)
|
|
|
|
point->prev->next = filter;
|
|
|
|
else
|
|
|
|
access->head = filter;
|
|
|
|
|
|
|
|
filter->prev = point->prev;
|
|
|
|
point->prev = filter;
|
|
|
|
} else {
|
|
|
|
if (access->tail)
|
|
|
|
access->tail->next = filter;
|
|
|
|
else
|
|
|
|
access->head = filter;
|
|
|
|
|
|
|
|
filter->prev = access->tail;
|
|
|
|
access->tail = filter;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Run hook function. */
|
|
|
|
if (access->master->add_hook)
|
|
|
|
(*access->master->add_hook)(access);
|
|
|
|
route_map_notify_dependencies(access->name, RMAP_EVENT_FILTER_ADDED);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
deny Specify packets to reject
|
|
|
|
permit Specify packets to forward
|
|
|
|
dynamic ?
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Hostname or A.B.C.D Address to match
|
|
|
|
any Any source host
|
|
|
|
host A single host address
|
|
|
|
*/
|
|
|
|
|
2019-11-08 18:46:17 +01:00
|
|
|
struct filter *filter_lookup_cisco(struct access_list *access,
|
|
|
|
struct filter *mnew)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
struct filter *mfilter;
|
|
|
|
struct filter_cisco *filter;
|
|
|
|
struct filter_cisco *new;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
new = &mnew->u.cfilter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
|
|
|
|
filter = &mfilter->u.cfilter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (filter->extended) {
|
|
|
|
if (mfilter->type == mnew->type
|
|
|
|
&& filter->addr.s_addr == new->addr.s_addr
|
|
|
|
&& filter->addr_mask.s_addr == new->addr_mask.s_addr
|
|
|
|
&& filter->mask.s_addr == new->mask.s_addr
|
|
|
|
&& filter->mask_mask.s_addr
|
|
|
|
== new->mask_mask.s_addr)
|
|
|
|
return mfilter;
|
2017-07-17 14:03:14 +02:00
|
|
|
} else {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (mfilter->type == mnew->type
|
|
|
|
&& filter->addr.s_addr == new->addr.s_addr
|
|
|
|
&& filter->addr_mask.s_addr
|
|
|
|
== new->addr_mask.s_addr)
|
|
|
|
return mfilter;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2019-11-08 18:46:17 +01:00
|
|
|
struct filter *filter_lookup_zebra(struct access_list *access,
|
|
|
|
struct filter *mnew)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct filter *mfilter;
|
|
|
|
struct filter_zebra *filter;
|
|
|
|
struct filter_zebra *new;
|
|
|
|
|
|
|
|
new = &mnew->u.zfilter;
|
|
|
|
|
|
|
|
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
|
|
|
|
filter = &mfilter->u.zfilter;
|
|
|
|
|
|
|
|
if (filter->exact == new->exact
|
2017-06-21 10:02:46 +02:00
|
|
|
&& mfilter->type == mnew->type) {
|
2017-08-04 21:55:44 +02:00
|
|
|
if (prefix_same(&filter->prefix, &new->prefix))
|
|
|
|
return mfilter;
|
2017-06-21 10:02:46 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2019-11-27 21:49:00 +01:00
|
|
|
static void config_write_access_zebra(struct vty *, struct filter *);
|
|
|
|
static void config_write_access_cisco(struct vty *, struct filter *);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* show access-list command. */
|
2004-10-10 Paul Jakma <paul@dishone.st>
* version.h.in: (pid_output*) add const qualifier.
* command.h: Change DEFUN func to take const char *[] rather
than char **, to begin process of fixing compile warnings in lib/.
Nearly all other changes in this commit follow from this change.
* buffer.{c,h}: (buffer_write) pointer-arithmetic is gccism, take
const void * and cast an automatic const char *p to it.
(buffer_putstr) add const
* command.c: (zencrypt) const qualifier
(cmd_execute_command_real) ditto
(cmd_execute_command_strict) ditto
(config_log_file) ditto.
Fix leak of getcwd() returned string.
* memory.{c,h}: Add MTYPE_DISTRIBUTE_IFNAME for struct dist ifname.
* distribute.{c,h}: Update with const qualifier.
(distribute_free) use MTYPE_DISTRIBUTE_IFNAME
(distribute_lookup) Cast to char *, note that it's ok.
(distribute_hash_alloc) use MTYPE_DISTRIBUTE_IFNAME.
(distribute_get) Cast to char *, note that it's ok.
* filter.c: Update with const qualifier.
* if.{c,h}: ditto.
* if_rmap.{c,h}: ditto.
(if_rmap_lookup) Cast to char *, note that it's ok.
(if_rmap_get) ditto.
* log.{c,h}: Update with const qualifier.
* plist.{c,h}: ditto.
* routemap.{c,h}: ditto.
* smux.{c,h}: ditto. Fix some signed/unsigned comparisons.
* sockopt.c: (getsockopt_cmsg_data) add return for error case.
* vty.c: Update with const qualifier.
2004-10-10 13:56:56 +02:00
|
|
|
static int filter_show(struct vty *vty, const char *name, afi_t afi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *access;
|
|
|
|
struct access_master *master;
|
|
|
|
struct filter *mfilter;
|
|
|
|
struct filter_cisco *filter;
|
|
|
|
int write = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
master = access_master_get(afi);
|
|
|
|
if (master == NULL)
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-09-29 13:25:50 +02:00
|
|
|
/* Print the name of the protocol */
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, "%s:\n", frr_protoname);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (access = master->num.head; access; access = access->next) {
|
|
|
|
if (name && strcmp(access->name, name) != 0)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
write = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
|
|
|
|
filter = &mfilter->u.cfilter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (write) {
|
2017-06-21 10:02:46 +02:00
|
|
|
vty_out(vty, "%s %s access list %s\n",
|
2002-12-13 21:15:29 +01:00
|
|
|
mfilter->cisco ? (filter->extended
|
|
|
|
? "Extended"
|
|
|
|
: "Standard")
|
|
|
|
: "Zebra",
|
2017-06-21 10:02:46 +02:00
|
|
|
(afi == AFI_IP)
|
2017-08-09 20:30:34 +02:00
|
|
|
? ("IP")
|
|
|
|
: ((afi == AFI_IP6) ? ("IPv6 ")
|
|
|
|
: ("MAC ")),
|
2017-06-21 05:10:57 +02:00
|
|
|
access->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
write = 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-06-29 22:31:12 +02:00
|
|
|
vty_out(vty, " seq %" PRId64, mfilter->seq);
|
|
|
|
vty_out(vty, " %s%s", filter_type_str(mfilter),
|
2002-12-13 21:15:29 +01:00
|
|
|
mfilter->type == FILTER_DENY ? " " : "");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!mfilter->cisco)
|
|
|
|
config_write_access_zebra(vty, mfilter);
|
|
|
|
else if (filter->extended)
|
|
|
|
config_write_access_cisco(vty, mfilter);
|
|
|
|
else {
|
|
|
|
if (filter->addr_mask.s_addr == 0xffffffff)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " any\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
else {
|
|
|
|
vty_out(vty, " %s",
|
|
|
|
inet_ntoa(filter->addr));
|
2020-02-06 07:49:02 +01:00
|
|
|
if (filter->addr_mask.s_addr
|
|
|
|
!= INADDR_ANY)
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out(vty,
|
|
|
|
", wildcard bits %s",
|
|
|
|
inet_ntoa(
|
|
|
|
filter->addr_mask));
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (access = master->str.head; access; access = access->next) {
|
|
|
|
if (name && strcmp(access->name, name) != 0)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
write = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
|
|
|
|
filter = &mfilter->u.cfilter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (write) {
|
2017-06-21 10:02:46 +02:00
|
|
|
vty_out(vty, "%s %s access list %s\n",
|
2002-12-13 21:15:29 +01:00
|
|
|
mfilter->cisco ? (filter->extended
|
|
|
|
? "Extended"
|
|
|
|
: "Standard")
|
|
|
|
: "Zebra",
|
2017-06-21 10:02:46 +02:00
|
|
|
(afi == AFI_IP)
|
2017-08-09 20:30:34 +02:00
|
|
|
? ("IP")
|
|
|
|
: ((afi == AFI_IP6) ? ("IPv6 ")
|
|
|
|
: ("MAC ")),
|
2017-06-21 05:10:57 +02:00
|
|
|
access->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
write = 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-06-29 22:31:12 +02:00
|
|
|
vty_out(vty, " seq %" PRId64, mfilter->seq);
|
|
|
|
vty_out(vty, " %s%s", filter_type_str(mfilter),
|
2002-12-13 21:15:29 +01:00
|
|
|
mfilter->type == FILTER_DENY ? " " : "");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!mfilter->cisco)
|
|
|
|
config_write_access_zebra(vty, mfilter);
|
|
|
|
else if (filter->extended)
|
|
|
|
config_write_access_cisco(vty, mfilter);
|
|
|
|
else {
|
|
|
|
if (filter->addr_mask.s_addr == 0xffffffff)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " any\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
else {
|
|
|
|
vty_out(vty, " %s",
|
|
|
|
inet_ntoa(filter->addr));
|
2020-02-06 07:49:02 +01:00
|
|
|
if (filter->addr_mask.s_addr
|
|
|
|
!= INADDR_ANY)
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out(vty,
|
|
|
|
", wildcard bits %s",
|
|
|
|
inet_ntoa(
|
|
|
|
filter->addr_mask));
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-06-21 10:02:46 +02:00
|
|
|
/* show MAC access list - this only has MAC filters for now*/
|
|
|
|
DEFUN (show_mac_access_list,
|
|
|
|
show_mac_access_list_cmd,
|
|
|
|
"show mac access-list",
|
|
|
|
SHOW_STR
|
|
|
|
"mac access lists\n"
|
|
|
|
"List mac access lists\n")
|
|
|
|
{
|
|
|
|
return filter_show(vty, NULL, AFI_L2VPN);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_mac_access_list_name,
|
|
|
|
show_mac_access_list_name_cmd,
|
|
|
|
"show mac access-list WORD",
|
|
|
|
SHOW_STR
|
2017-07-15 20:15:13 +02:00
|
|
|
"mac access lists\n"
|
2017-06-21 10:02:46 +02:00
|
|
|
"List mac access lists\n"
|
2017-07-15 20:15:13 +02:00
|
|
|
"mac address\n")
|
2017-06-21 10:02:46 +02:00
|
|
|
{
|
|
|
|
return filter_show(vty, argv[3]->arg, AFI_L2VPN);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
DEFUN (show_ip_access_list,
|
|
|
|
show_ip_access_list_cmd,
|
|
|
|
"show ip access-list",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"List IP access lists\n")
|
|
|
|
{
|
|
|
|
return filter_show(vty, NULL, AFI_IP);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ip_access_list_name,
|
|
|
|
show_ip_access_list_name_cmd,
|
2016-09-23 15:47:20 +02:00
|
|
|
"show ip access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)|WORD>",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
"List IP access lists\n"
|
|
|
|
"IP standard access list\n"
|
|
|
|
"IP extended access list\n"
|
|
|
|
"IP standard access list (expanded range)\n"
|
|
|
|
"IP extended access list (expanded range)\n"
|
|
|
|
"IP zebra access-list\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_acl = 3;
|
|
|
|
return filter_show(vty, argv[idx_acl]->arg, AFI_IP);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ipv6_access_list,
|
|
|
|
show_ipv6_access_list_cmd,
|
|
|
|
"show ipv6 access-list",
|
|
|
|
SHOW_STR
|
|
|
|
IPV6_STR
|
|
|
|
"List IPv6 access lists\n")
|
|
|
|
{
|
|
|
|
return filter_show(vty, NULL, AFI_IP6);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (show_ipv6_access_list_name,
|
|
|
|
show_ipv6_access_list_name_cmd,
|
|
|
|
"show ipv6 access-list WORD",
|
|
|
|
SHOW_STR
|
|
|
|
IPV6_STR
|
|
|
|
"List IPv6 access lists\n"
|
|
|
|
"IPv6 zebra access-list\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 3;
|
|
|
|
return filter_show(vty, argv[idx_word]->arg, AFI_IP6);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-27 21:49:00 +01:00
|
|
|
static void config_write_access_cisco(struct vty *vty, struct filter *mfilter)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct filter_cisco *filter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
filter = &mfilter->u.cfilter;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (filter->extended) {
|
|
|
|
vty_out(vty, " ip");
|
|
|
|
if (filter->addr_mask.s_addr == 0xffffffff)
|
|
|
|
vty_out(vty, " any");
|
2020-02-06 07:49:02 +01:00
|
|
|
else if (filter->addr_mask.s_addr == INADDR_ANY)
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out(vty, " host %s", inet_ntoa(filter->addr));
|
|
|
|
else {
|
|
|
|
vty_out(vty, " %s", inet_ntoa(filter->addr));
|
|
|
|
vty_out(vty, " %s", inet_ntoa(filter->addr_mask));
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (filter->mask_mask.s_addr == 0xffffffff)
|
|
|
|
vty_out(vty, " any");
|
2020-02-06 07:49:02 +01:00
|
|
|
else if (filter->mask_mask.s_addr == INADDR_ANY)
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out(vty, " host %s", inet_ntoa(filter->mask));
|
|
|
|
else {
|
|
|
|
vty_out(vty, " %s", inet_ntoa(filter->mask));
|
|
|
|
vty_out(vty, " %s", inet_ntoa(filter->mask_mask));
|
|
|
|
}
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
} else {
|
|
|
|
if (filter->addr_mask.s_addr == 0xffffffff)
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " any\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
else {
|
|
|
|
vty_out(vty, " %s", inet_ntoa(filter->addr));
|
2020-02-06 07:49:02 +01:00
|
|
|
if (filter->addr_mask.s_addr != INADDR_ANY)
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out(vty, " %s",
|
|
|
|
inet_ntoa(filter->addr_mask));
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-27 21:49:00 +01:00
|
|
|
static void config_write_access_zebra(struct vty *vty, struct filter *mfilter)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct filter_zebra *filter;
|
|
|
|
struct prefix *p;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
filter = &mfilter->u.zfilter;
|
|
|
|
p = &filter->prefix;
|
|
|
|
|
|
|
|
if (p->prefixlen == 0 && !filter->exact)
|
|
|
|
vty_out(vty, " any");
|
2017-06-21 10:02:46 +02:00
|
|
|
else if (p->family == AF_INET6 || p->family == AF_INET)
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out(vty, " %s/%d%s",
|
|
|
|
inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
|
|
|
|
p->prefixlen, filter->exact ? " exact-match" : "");
|
2017-07-12 23:27:24 +02:00
|
|
|
else if (p->family == AF_ETHERNET) {
|
2017-08-09 20:30:34 +02:00
|
|
|
if (p->prefixlen == 0)
|
2017-07-12 23:27:24 +02:00
|
|
|
vty_out(vty, " any");
|
|
|
|
else
|
|
|
|
vty_out(vty, " %s", prefix_mac2str(&(p->u.prefix_eth),
|
|
|
|
buf, sizeof(buf)));
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-07-13 19:04:25 +02:00
|
|
|
vty_out(vty, "\n");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2017-06-21 10:02:46 +02:00
|
|
|
static struct cmd_node access_mac_node = {
|
2018-09-09 00:15:50 +02:00
|
|
|
.name = "MAC access list",
|
2018-09-08 21:46:23 +02:00
|
|
|
.node = ACCESS_MAC_NODE,
|
|
|
|
.prompt = "",
|
|
|
|
};
|
2017-06-21 10:02:46 +02:00
|
|
|
|
|
|
|
static void access_list_reset_mac(void)
|
|
|
|
{
|
|
|
|
struct access_list *access;
|
|
|
|
struct access_list *next;
|
|
|
|
struct access_master *master;
|
|
|
|
|
|
|
|
master = access_master_get(AFI_L2VPN);
|
|
|
|
if (master == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (access = master->num.head; access; access = next) {
|
|
|
|
next = access->next;
|
|
|
|
access_list_delete(access);
|
|
|
|
}
|
|
|
|
for (access = master->str.head; access; access = next) {
|
|
|
|
next = access->next;
|
|
|
|
access_list_delete(access);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(master->num.head == NULL);
|
|
|
|
assert(master->num.tail == NULL);
|
|
|
|
|
|
|
|
assert(master->str.head == NULL);
|
|
|
|
assert(master->str.tail == NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install vty related command. */
|
|
|
|
static void access_list_init_mac(void)
|
|
|
|
{
|
2018-09-08 22:31:43 +02:00
|
|
|
install_node(&access_mac_node);
|
2017-06-21 10:02:46 +02:00
|
|
|
|
|
|
|
install_element(ENABLE_NODE, &show_mac_access_list_cmd);
|
|
|
|
install_element(ENABLE_NODE, &show_mac_access_list_name_cmd);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Access-list node. */
|
2020-04-30 18:56:05 +02:00
|
|
|
static int config_write_access(struct vty *vty);
|
2018-09-08 21:46:23 +02:00
|
|
|
static struct cmd_node access_node = {
|
2018-09-09 00:15:50 +02:00
|
|
|
.name = "ipv4 access list",
|
2018-09-08 21:46:23 +02:00
|
|
|
.node = ACCESS_NODE,
|
|
|
|
.prompt = "",
|
2020-04-30 18:56:05 +02:00
|
|
|
.config_write = config_write_access,
|
2018-09-08 21:46:23 +02:00
|
|
|
};
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-04-30 18:56:05 +02:00
|
|
|
static int config_write_access(struct vty *vty)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-04-30 18:56:05 +02:00
|
|
|
struct lyd_node *dnode;
|
|
|
|
int written = 0;
|
|
|
|
|
|
|
|
dnode = yang_dnode_get(running_config->dnode, "/frr-filter:lib");
|
|
|
|
if (dnode) {
|
|
|
|
nb_cli_show_dnode_cmds(vty, dnode, false);
|
|
|
|
written = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return written;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2005-05-06 Paul Jakma <paul@dishone.st>
* (general) extern and static'ification of functions in code and
header.
Cleanup any definitions with unspecified arguments.
Add casts for callback assignments where the callback is defined,
typically, as passing void *, but the function being assigned has
some other pointer type defined as its argument, as gcc complains
about casts from void * to X* via function arguments.
Fix some old K&R style function argument definitions.
Add noreturn gcc attribute to some functions, as appropriate.
Add unused gcc attribute to some functions (eg ones meant to help
while debugging)
Add guard defines to headers which were missing them.
* command.c: (install_node) add const qualifier, still doesnt shut
up the warning though, because of the double pointer.
(cmp_node) ditto
* keychain.c: (key_str2time) Add GET_LONG_RANGE() macro, derived
fromn vty.h ones to fix some of the (long) < 0 warnings.
* thread.c: (various) use thread_empty
(cpu_record_hash_key) should cast to uintptr_t, a stdint.h type
* vty.h: Add VTY_GET_IPV4_ADDRESS and VTY_GET_IPV4_PREFIX so they
removed from ospfd/ospf_vty.h
* zebra.h: Move definition of ZEBRA_PORT to here, to remove
dependence of lib on zebra/zserv.h
2005-05-06 23:25:49 +02:00
|
|
|
static void access_list_reset_ipv4(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *access;
|
|
|
|
struct access_list *next;
|
|
|
|
struct access_master *master;
|
|
|
|
|
|
|
|
master = access_master_get(AFI_IP);
|
|
|
|
if (master == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (access = master->num.head; access; access = next) {
|
|
|
|
next = access->next;
|
|
|
|
access_list_delete(access);
|
|
|
|
}
|
|
|
|
for (access = master->str.head; access; access = next) {
|
|
|
|
next = access->next;
|
|
|
|
access_list_delete(access);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(master->num.head == NULL);
|
|
|
|
assert(master->num.tail == NULL);
|
|
|
|
|
|
|
|
assert(master->str.head == NULL);
|
|
|
|
assert(master->str.tail == NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install vty related command. */
|
2005-05-06 Paul Jakma <paul@dishone.st>
* (general) extern and static'ification of functions in code and
header.
Cleanup any definitions with unspecified arguments.
Add casts for callback assignments where the callback is defined,
typically, as passing void *, but the function being assigned has
some other pointer type defined as its argument, as gcc complains
about casts from void * to X* via function arguments.
Fix some old K&R style function argument definitions.
Add noreturn gcc attribute to some functions, as appropriate.
Add unused gcc attribute to some functions (eg ones meant to help
while debugging)
Add guard defines to headers which were missing them.
* command.c: (install_node) add const qualifier, still doesnt shut
up the warning though, because of the double pointer.
(cmp_node) ditto
* keychain.c: (key_str2time) Add GET_LONG_RANGE() macro, derived
fromn vty.h ones to fix some of the (long) < 0 warnings.
* thread.c: (various) use thread_empty
(cpu_record_hash_key) should cast to uintptr_t, a stdint.h type
* vty.h: Add VTY_GET_IPV4_ADDRESS and VTY_GET_IPV4_PREFIX so they
removed from ospfd/ospf_vty.h
* zebra.h: Move definition of ZEBRA_PORT to here, to remove
dependence of lib on zebra/zserv.h
2005-05-06 23:25:49 +02:00
|
|
|
static void access_list_init_ipv4(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-09-08 22:31:43 +02:00
|
|
|
install_node(&access_node);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element(ENABLE_NODE, &show_ip_access_list_cmd);
|
|
|
|
install_element(ENABLE_NODE, &show_ip_access_list_name_cmd);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-09-08 21:46:23 +02:00
|
|
|
static struct cmd_node access_ipv6_node = {
|
2018-09-09 00:15:50 +02:00
|
|
|
.name = "ipv6 access list",
|
2018-09-08 21:46:23 +02:00
|
|
|
.node = ACCESS_IPV6_NODE,
|
|
|
|
.prompt = "",
|
|
|
|
};
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-05-06 Paul Jakma <paul@dishone.st>
* (general) extern and static'ification of functions in code and
header.
Cleanup any definitions with unspecified arguments.
Add casts for callback assignments where the callback is defined,
typically, as passing void *, but the function being assigned has
some other pointer type defined as its argument, as gcc complains
about casts from void * to X* via function arguments.
Fix some old K&R style function argument definitions.
Add noreturn gcc attribute to some functions, as appropriate.
Add unused gcc attribute to some functions (eg ones meant to help
while debugging)
Add guard defines to headers which were missing them.
* command.c: (install_node) add const qualifier, still doesnt shut
up the warning though, because of the double pointer.
(cmp_node) ditto
* keychain.c: (key_str2time) Add GET_LONG_RANGE() macro, derived
fromn vty.h ones to fix some of the (long) < 0 warnings.
* thread.c: (various) use thread_empty
(cpu_record_hash_key) should cast to uintptr_t, a stdint.h type
* vty.h: Add VTY_GET_IPV4_ADDRESS and VTY_GET_IPV4_PREFIX so they
removed from ospfd/ospf_vty.h
* zebra.h: Move definition of ZEBRA_PORT to here, to remove
dependence of lib on zebra/zserv.h
2005-05-06 23:25:49 +02:00
|
|
|
static void access_list_reset_ipv6(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct access_list *access;
|
|
|
|
struct access_list *next;
|
|
|
|
struct access_master *master;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
master = access_master_get(AFI_IP6);
|
|
|
|
if (master == NULL)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (access = master->num.head; access; access = next) {
|
|
|
|
next = access->next;
|
|
|
|
access_list_delete(access);
|
|
|
|
}
|
|
|
|
for (access = master->str.head; access; access = next) {
|
|
|
|
next = access->next;
|
|
|
|
access_list_delete(access);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(master->num.head == NULL);
|
|
|
|
assert(master->num.tail == NULL);
|
|
|
|
|
|
|
|
assert(master->str.head == NULL);
|
|
|
|
assert(master->str.tail == NULL);
|
|
|
|
}
|
|
|
|
|
2005-05-06 Paul Jakma <paul@dishone.st>
* (general) extern and static'ification of functions in code and
header.
Cleanup any definitions with unspecified arguments.
Add casts for callback assignments where the callback is defined,
typically, as passing void *, but the function being assigned has
some other pointer type defined as its argument, as gcc complains
about casts from void * to X* via function arguments.
Fix some old K&R style function argument definitions.
Add noreturn gcc attribute to some functions, as appropriate.
Add unused gcc attribute to some functions (eg ones meant to help
while debugging)
Add guard defines to headers which were missing them.
* command.c: (install_node) add const qualifier, still doesnt shut
up the warning though, because of the double pointer.
(cmp_node) ditto
* keychain.c: (key_str2time) Add GET_LONG_RANGE() macro, derived
fromn vty.h ones to fix some of the (long) < 0 warnings.
* thread.c: (various) use thread_empty
(cpu_record_hash_key) should cast to uintptr_t, a stdint.h type
* vty.h: Add VTY_GET_IPV4_ADDRESS and VTY_GET_IPV4_PREFIX so they
removed from ospfd/ospf_vty.h
* zebra.h: Move definition of ZEBRA_PORT to here, to remove
dependence of lib on zebra/zserv.h
2005-05-06 23:25:49 +02:00
|
|
|
static void access_list_init_ipv6(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-09-08 22:31:43 +02:00
|
|
|
install_node(&access_ipv6_node);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
install_element(ENABLE_NODE, &show_ipv6_access_list_cmd);
|
|
|
|
install_element(ENABLE_NODE, &show_ipv6_access_list_name_cmd);
|
|
|
|
}
|
|
|
|
|
2019-01-24 10:12:36 +01:00
|
|
|
void access_list_init(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
access_list_init_ipv4();
|
|
|
|
access_list_init_ipv6();
|
2017-06-21 10:02:46 +02:00
|
|
|
access_list_init_mac();
|
2019-11-08 18:50:00 +01:00
|
|
|
|
|
|
|
filter_cli_init();
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2019-01-24 10:12:36 +01:00
|
|
|
void access_list_reset(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
access_list_reset_ipv4();
|
|
|
|
access_list_reset_ipv6();
|
2017-06-21 10:02:46 +02:00
|
|
|
access_list_reset_mac();
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|