2002-12-13 21:15:29 +01:00
|
|
|
/* Prefix list functions.
|
|
|
|
* Copyright (C) 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 "command.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "plist.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"
|
2016-09-23 02:58:26 +02:00
|
|
|
#include "lib/json.h"
|
2017-05-08 03:06:07 +02:00
|
|
|
#include "libfrr.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-04-13 10:21:34 +02:00
|
|
|
#include "plist_int.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-29 05:48:31 +02:00
|
|
|
DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST, "Prefix List")
|
|
|
|
DEFINE_MTYPE_STATIC(LIB, MPREFIX_LIST_STR, "Prefix List Str")
|
|
|
|
DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_ENTRY, "Prefix List Entry")
|
|
|
|
DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST_TRIE, "Prefix List Trie Table")
|
|
|
|
|
2015-04-13 10:21:36 +02:00
|
|
|
/* not currently changeable, code assumes bytes further down */
|
|
|
|
#define PLC_BITS 8
|
|
|
|
#define PLC_LEN (1 << PLC_BITS)
|
|
|
|
#define PLC_MAXLEVELV4 2 /* /24 for IPv4 */
|
|
|
|
#define PLC_MAXLEVELV6 4 /* /48 for IPv6 */
|
|
|
|
#define PLC_MAXLEVEL 4 /* max(v4,v6) */
|
|
|
|
|
|
|
|
struct pltrie_entry {
|
|
|
|
union {
|
|
|
|
struct pltrie_table *next_table;
|
|
|
|
struct prefix_list_entry *final_chain;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct prefix_list_entry *up_chain;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct pltrie_table {
|
|
|
|
struct pltrie_entry entries[PLC_LEN];
|
|
|
|
};
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* List of struct prefix_list. */
|
|
|
|
struct prefix_list_list
|
|
|
|
{
|
|
|
|
struct prefix_list *head;
|
|
|
|
struct prefix_list *tail;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Master structure of prefix_list. */
|
|
|
|
struct prefix_master
|
|
|
|
{
|
|
|
|
/* List of prefix_list which name is number. */
|
|
|
|
struct prefix_list_list num;
|
|
|
|
|
|
|
|
/* List of prefix_list which name is string. */
|
|
|
|
struct prefix_list_list str;
|
|
|
|
|
|
|
|
/* Whether sequential number is used. */
|
|
|
|
int seqnum;
|
|
|
|
|
|
|
|
/* The latest update. */
|
|
|
|
struct prefix_list *recent;
|
|
|
|
|
|
|
|
/* Hook function which is executed when new prefix_list is added. */
|
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
|
|
|
void (*add_hook) (struct prefix_list *);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Hook function which is executed when prefix_list is deleted. */
|
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
|
|
|
void (*delete_hook) (struct prefix_list *);
|
2015-04-13 10:21:36 +02:00
|
|
|
|
|
|
|
/* number of bytes that have a trie level */
|
|
|
|
size_t trie_depth;
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Static structure of IPv4 prefix_list's master. */
|
|
|
|
static struct prefix_master prefix_master_ipv4 =
|
|
|
|
{
|
|
|
|
{NULL, NULL},
|
|
|
|
{NULL, NULL},
|
|
|
|
1,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2015-04-13 10:21:36 +02:00
|
|
|
NULL,
|
|
|
|
PLC_MAXLEVELV4,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Static structure of IPv6 prefix-list's master. */
|
|
|
|
static struct prefix_master prefix_master_ipv6 =
|
|
|
|
{
|
|
|
|
{NULL, NULL},
|
|
|
|
{NULL, NULL},
|
|
|
|
1,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2015-04-13 10:21:36 +02:00
|
|
|
NULL,
|
|
|
|
PLC_MAXLEVELV6,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Static structure of BGP ORF prefix_list's master. */
|
2015-04-13 10:21:36 +02:00
|
|
|
static struct prefix_master prefix_master_orf_v4 =
|
|
|
|
{
|
2015-04-13 10:21:35 +02:00
|
|
|
{NULL, NULL},
|
|
|
|
{NULL, NULL},
|
|
|
|
1,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2015-04-13 10:21:36 +02:00
|
|
|
NULL,
|
|
|
|
PLC_MAXLEVELV4,
|
2015-04-13 10:21:35 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Static structure of BGP ORF prefix_list's master. */
|
2015-04-13 10:21:36 +02:00
|
|
|
static struct prefix_master prefix_master_orf_v6 =
|
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
{NULL, NULL},
|
|
|
|
{NULL, NULL},
|
|
|
|
1,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2015-04-13 10:21:36 +02:00
|
|
|
NULL,
|
|
|
|
PLC_MAXLEVELV6,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_master *
|
2015-04-13 10:21:35 +02:00
|
|
|
prefix_master_get (afi_t afi, int orf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (afi == AFI_IP)
|
2015-04-13 10:21:35 +02:00
|
|
|
return orf ? &prefix_master_orf_v4 : &prefix_master_ipv4;
|
|
|
|
if (afi == AFI_IP6)
|
|
|
|
return orf ? &prefix_master_orf_v6 : &prefix_master_ipv6;
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-04-13 10:21:34 +02:00
|
|
|
const char *prefix_list_name (struct prefix_list *plist)
|
|
|
|
{
|
|
|
|
return plist->name;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Lookup prefix_list from list of prefix_list by name. */
|
2015-04-13 10:21:35 +02:00
|
|
|
static struct prefix_list *
|
|
|
|
prefix_list_lookup_do (afi_t afi, int orf, const char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_master *master;
|
|
|
|
|
|
|
|
if (name == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
master = prefix_master_get (afi, orf);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (master == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (plist = master->num.head; plist; plist = plist->next)
|
|
|
|
if (strcmp (plist->name, name) == 0)
|
|
|
|
return plist;
|
|
|
|
|
|
|
|
for (plist = master->str.head; plist; plist = plist->next)
|
|
|
|
if (strcmp (plist->name, name) == 0)
|
|
|
|
return plist;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
struct prefix_list *
|
|
|
|
prefix_list_lookup (afi_t afi, const char *name)
|
|
|
|
{
|
|
|
|
return prefix_list_lookup_do (afi, 0, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct prefix_list *
|
|
|
|
prefix_bgp_orf_lookup (afi_t afi, const char *name)
|
|
|
|
{
|
|
|
|
return prefix_list_lookup_do (afi, 1, name);
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list *
|
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
|
|
|
prefix_list_new (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *new;
|
|
|
|
|
|
|
|
new = XCALLOC (MTYPE_PREFIX_LIST, sizeof (struct prefix_list));
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_free (struct prefix_list *plist)
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_PREFIX_LIST, plist);
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list_entry *
|
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
|
|
|
prefix_list_entry_new (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list_entry *new;
|
|
|
|
|
|
|
|
new = XCALLOC (MTYPE_PREFIX_LIST_ENTRY, sizeof (struct prefix_list_entry));
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_entry_free (struct prefix_list_entry *pentry)
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_PREFIX_LIST_ENTRY, pentry);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Insert new prefix list to list of prefix_list. Each prefix_list
|
|
|
|
is sorted by the name. */
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list *
|
2015-04-13 10:21:35 +02:00
|
|
|
prefix_list_insert (afi_t afi, int orf, 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 prefix_list *plist;
|
|
|
|
struct prefix_list *point;
|
|
|
|
struct prefix_list_list *list;
|
|
|
|
struct prefix_master *master;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
master = prefix_master_get (afi, orf);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (master == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Allocate new prefix_list and copy given name. */
|
|
|
|
plist = prefix_list_new ();
|
2015-05-29 05:48:31 +02:00
|
|
|
plist->name = XSTRDUP (MTYPE_MPREFIX_LIST_STR, name);
|
2002-12-13 21:15:29 +01:00
|
|
|
plist->master = master;
|
2015-04-13 10:21:36 +02:00
|
|
|
plist->trie = XCALLOC (MTYPE_PREFIX_LIST_TRIE, sizeof (struct pltrie_table));
|
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++)
|
|
|
|
{
|
|
|
|
if (isdigit ((int) name[i]))
|
|
|
|
number = (number * 10) + (name[i] - '0');
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In case of name is all digit character */
|
|
|
|
if (i == strlen (name))
|
|
|
|
{
|
|
|
|
plist->type = PREFIX_TYPE_NUMBER;
|
|
|
|
|
|
|
|
/* Set prefix_list to number list. */
|
|
|
|
list = &master->num;
|
|
|
|
|
|
|
|
for (point = list->head; point; point = point->next)
|
|
|
|
if (atol (point->name) >= number)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
plist->type = PREFIX_TYPE_STRING;
|
|
|
|
|
|
|
|
/* Set prefix_list to string list. */
|
|
|
|
list = &master->str;
|
|
|
|
|
|
|
|
/* Set point to insertion point. */
|
|
|
|
for (point = list->head; point; point = point->next)
|
|
|
|
if (strcmp (point->name, name) >= 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In case of this is the first element of master. */
|
|
|
|
if (list->head == NULL)
|
|
|
|
{
|
|
|
|
list->head = list->tail = plist;
|
|
|
|
return plist;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In case of insertion is made at the tail of access_list. */
|
|
|
|
if (point == NULL)
|
|
|
|
{
|
|
|
|
plist->prev = list->tail;
|
|
|
|
list->tail->next = plist;
|
|
|
|
list->tail = plist;
|
|
|
|
return plist;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In case of insertion is made at the head of access_list. */
|
|
|
|
if (point == list->head)
|
|
|
|
{
|
|
|
|
plist->next = list->head;
|
|
|
|
list->head->prev = plist;
|
|
|
|
list->head = plist;
|
|
|
|
return plist;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Insertion is made at middle of the access_list. */
|
|
|
|
plist->next = point;
|
|
|
|
plist->prev = point->prev;
|
|
|
|
|
|
|
|
if (point->prev)
|
|
|
|
point->prev->next = plist;
|
|
|
|
point->prev = plist;
|
|
|
|
|
|
|
|
return plist;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list *
|
2015-04-13 10:21:35 +02:00
|
|
|
prefix_list_get (afi_t afi, int orf, const char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
plist = prefix_list_lookup_do (afi, orf, name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (plist == NULL)
|
2015-04-13 10:21:35 +02:00
|
|
|
plist = prefix_list_insert (afi, orf, name);
|
2002-12-13 21:15:29 +01:00
|
|
|
return plist;
|
|
|
|
}
|
|
|
|
|
2017-02-01 13:21:40 +01:00
|
|
|
static void prefix_list_trie_del (struct prefix_list *plist,
|
|
|
|
struct prefix_list_entry *pentry);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Delete prefix-list from prefix_list_master and free it. */
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_delete (struct prefix_list *plist)
|
|
|
|
{
|
|
|
|
struct prefix_list_list *list;
|
|
|
|
struct prefix_master *master;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
struct prefix_list_entry *next;
|
|
|
|
|
|
|
|
/* If prefix-list contain prefix_list_entry free all of it. */
|
|
|
|
for (pentry = plist->head; pentry; pentry = next)
|
|
|
|
{
|
|
|
|
next = pentry->next;
|
2017-02-01 13:21:40 +01:00
|
|
|
prefix_list_trie_del (plist, pentry);
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_entry_free (pentry);
|
|
|
|
plist->count--;
|
|
|
|
}
|
|
|
|
|
|
|
|
master = plist->master;
|
|
|
|
|
|
|
|
if (plist->type == PREFIX_TYPE_NUMBER)
|
|
|
|
list = &master->num;
|
|
|
|
else
|
|
|
|
list = &master->str;
|
|
|
|
|
|
|
|
if (plist->next)
|
|
|
|
plist->next->prev = plist->prev;
|
|
|
|
else
|
|
|
|
list->tail = plist->prev;
|
|
|
|
|
|
|
|
if (plist->prev)
|
|
|
|
plist->prev->next = plist->next;
|
|
|
|
else
|
|
|
|
list->head = plist->next;
|
|
|
|
|
|
|
|
if (plist->desc)
|
|
|
|
XFREE (MTYPE_TMP, plist->desc);
|
|
|
|
|
|
|
|
/* Make sure master's recent changed prefix-list information is
|
|
|
|
cleared. */
|
|
|
|
master->recent = NULL;
|
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
route_map_notify_dependencies(plist->name, RMAP_EVENT_PLIST_DELETED);
|
|
|
|
|
|
|
|
if (master->delete_hook)
|
2015-05-20 03:03:47 +02:00
|
|
|
(*master->delete_hook) (plist);
|
2015-05-20 02:40:45 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (plist->name)
|
2015-05-29 05:48:31 +02:00
|
|
|
XFREE (MTYPE_MPREFIX_LIST_STR, plist->name);
|
2015-05-20 02:40:45 +02:00
|
|
|
|
2015-04-13 10:21:36 +02:00
|
|
|
XFREE (MTYPE_PREFIX_LIST_TRIE, plist->trie);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_free (plist);
|
2015-05-20 02:40:45 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list_entry *
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_entry_make (struct prefix *prefix, enum prefix_list_type type,
|
|
|
|
int seq, int le, int ge, int any)
|
|
|
|
{
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
|
|
|
pentry = prefix_list_entry_new ();
|
|
|
|
|
|
|
|
if (any)
|
|
|
|
pentry->any = 1;
|
|
|
|
|
|
|
|
prefix_copy (&pentry->prefix, prefix);
|
|
|
|
pentry->type = type;
|
|
|
|
pentry->seq = seq;
|
|
|
|
pentry->le = le;
|
|
|
|
pentry->ge = ge;
|
|
|
|
|
|
|
|
return pentry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add hook function. */
|
|
|
|
void
|
|
|
|
prefix_list_add_hook (void (*func) (struct prefix_list *plist))
|
|
|
|
{
|
|
|
|
prefix_master_ipv4.add_hook = func;
|
|
|
|
prefix_master_ipv6.add_hook = func;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete hook function. */
|
|
|
|
void
|
|
|
|
prefix_list_delete_hook (void (*func) (struct prefix_list *plist))
|
|
|
|
{
|
|
|
|
prefix_master_ipv4.delete_hook = func;
|
|
|
|
prefix_master_ipv6.delete_hook = func;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate new sequential number. */
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_new_seq_get (struct prefix_list *plist)
|
|
|
|
{
|
|
|
|
int maxseq;
|
|
|
|
int newseq;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
|
|
|
maxseq = newseq = 0;
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
if (maxseq < pentry->seq)
|
|
|
|
maxseq = pentry->seq;
|
|
|
|
}
|
|
|
|
|
|
|
|
newseq = ((maxseq / 5) * 5) + 5;
|
|
|
|
|
|
|
|
return newseq;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return prefix list entry which has same seq number. */
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list_entry *
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_seq_check (struct prefix_list *plist, int seq)
|
|
|
|
{
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
if (pentry->seq == seq)
|
|
|
|
return pentry;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list_entry *
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_entry_lookup (struct prefix_list *plist, struct prefix *prefix,
|
|
|
|
enum prefix_list_type type, int seq, int le, int ge)
|
|
|
|
{
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
if (prefix_same (&pentry->prefix, prefix) && pentry->type == type)
|
|
|
|
{
|
|
|
|
if (seq >= 0 && pentry->seq != seq)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (pentry->le != le)
|
|
|
|
continue;
|
|
|
|
if (pentry->ge != ge)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
return pentry;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-04-13 10:21:36 +02:00
|
|
|
static void
|
|
|
|
trie_walk_affected (size_t validbits, struct pltrie_table *table, uint8_t byte,
|
|
|
|
struct prefix_list_entry *object,
|
|
|
|
void (*fn)(struct prefix_list_entry *object,
|
|
|
|
struct prefix_list_entry **updptr))
|
|
|
|
{
|
|
|
|
uint8_t mask;
|
|
|
|
uint16_t bwalk;
|
|
|
|
|
|
|
|
if (validbits > PLC_BITS)
|
|
|
|
{
|
|
|
|
fn (object, &table->entries[byte].final_chain);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mask = (1 << (8 - validbits)) - 1;
|
|
|
|
for (bwalk = byte & ~mask; bwalk <= byte + mask; bwalk++)
|
|
|
|
{
|
|
|
|
fn (object, &table->entries[bwalk].up_chain);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void trie_uninstall_fn (struct prefix_list_entry *object,
|
|
|
|
struct prefix_list_entry **updptr)
|
|
|
|
{
|
|
|
|
for (; *updptr; updptr = &(*updptr)->next_best)
|
|
|
|
if (*updptr == object)
|
|
|
|
{
|
|
|
|
*updptr = object->next_best;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
trie_table_empty (struct pltrie_table *table)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < PLC_LEN; i++)
|
2016-03-01 22:44:23 +01:00
|
|
|
if (table->entries[i].next_table || table->entries[i].up_chain)
|
2015-04-13 10:21:36 +02:00
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
prefix_list_trie_del (struct prefix_list *plist,
|
|
|
|
struct prefix_list_entry *pentry)
|
|
|
|
{
|
|
|
|
size_t depth, maxdepth = plist->master->trie_depth;
|
|
|
|
uint8_t *bytes = &pentry->prefix.u.prefix;
|
|
|
|
size_t validbits = pentry->prefix.prefixlen;
|
|
|
|
struct pltrie_table *table, **tables[PLC_MAXLEVEL];
|
|
|
|
|
|
|
|
table = plist->trie;
|
|
|
|
for (depth = 0; validbits > PLC_BITS && depth < maxdepth - 1; depth++)
|
|
|
|
{
|
|
|
|
uint8_t byte = bytes[depth];
|
|
|
|
assert (table->entries[byte].next_table);
|
|
|
|
|
|
|
|
tables[depth + 1] = &table->entries[byte].next_table;
|
|
|
|
table = table->entries[byte].next_table;
|
|
|
|
|
|
|
|
validbits -= PLC_BITS;
|
|
|
|
}
|
|
|
|
|
|
|
|
trie_walk_affected (validbits, table, bytes[depth], pentry, trie_uninstall_fn);
|
|
|
|
|
|
|
|
for (; depth > 0; depth--)
|
|
|
|
if (trie_table_empty (*tables[depth]))
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_PREFIX_LIST_TRIE, *tables[depth]);
|
|
|
|
*tables[depth] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_entry_delete (struct prefix_list *plist,
|
|
|
|
struct prefix_list_entry *pentry,
|
|
|
|
int update_list)
|
|
|
|
{
|
|
|
|
if (plist == NULL || pentry == NULL)
|
|
|
|
return;
|
2017-02-08 15:14:23 +01:00
|
|
|
|
|
|
|
prefix_list_trie_del (plist, pentry);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (pentry->prev)
|
|
|
|
pentry->prev->next = pentry->next;
|
|
|
|
else
|
|
|
|
plist->head = pentry->next;
|
|
|
|
if (pentry->next)
|
|
|
|
pentry->next->prev = pentry->prev;
|
|
|
|
else
|
|
|
|
plist->tail = pentry->prev;
|
|
|
|
|
|
|
|
prefix_list_entry_free (pentry);
|
|
|
|
|
|
|
|
plist->count--;
|
|
|
|
|
|
|
|
if (update_list)
|
|
|
|
{
|
2015-05-20 02:40:45 +02:00
|
|
|
route_map_notify_dependencies(plist->name, RMAP_EVENT_PLIST_DELETED);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (plist->master->delete_hook)
|
|
|
|
(*plist->master->delete_hook) (plist);
|
|
|
|
|
|
|
|
if (plist->head == NULL && plist->tail == NULL && plist->desc == NULL)
|
|
|
|
prefix_list_delete (plist);
|
|
|
|
else
|
|
|
|
plist->master->recent = plist;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-13 10:21:36 +02:00
|
|
|
static void trie_install_fn (struct prefix_list_entry *object,
|
|
|
|
struct prefix_list_entry **updptr)
|
|
|
|
{
|
|
|
|
while (*updptr)
|
|
|
|
{
|
|
|
|
if (*updptr == object)
|
|
|
|
return;
|
|
|
|
if ((*updptr)->prefix.prefixlen < object->prefix.prefixlen)
|
|
|
|
break;
|
|
|
|
if ((*updptr)->seq > object->seq)
|
|
|
|
break;
|
|
|
|
updptr = &(*updptr)->next_best;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!object->next_best)
|
|
|
|
object->next_best = *updptr;
|
|
|
|
else
|
|
|
|
assert (object->next_best == *updptr || !*updptr);
|
|
|
|
|
|
|
|
*updptr = object;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
prefix_list_trie_add (struct prefix_list *plist,
|
|
|
|
struct prefix_list_entry *pentry)
|
|
|
|
{
|
|
|
|
size_t depth = plist->master->trie_depth;
|
|
|
|
uint8_t *bytes = &pentry->prefix.u.prefix;
|
|
|
|
size_t validbits = pentry->prefix.prefixlen;
|
|
|
|
struct pltrie_table *table;
|
|
|
|
|
|
|
|
table = plist->trie;
|
|
|
|
while (validbits > PLC_BITS && depth > 1)
|
|
|
|
{
|
|
|
|
if (!table->entries[*bytes].next_table)
|
|
|
|
table->entries[*bytes].next_table = XCALLOC (MTYPE_PREFIX_LIST_TRIE,
|
|
|
|
sizeof(struct pltrie_table));
|
|
|
|
table = table->entries[*bytes].next_table;
|
|
|
|
bytes++;
|
|
|
|
depth--;
|
|
|
|
validbits -= PLC_BITS;
|
|
|
|
}
|
|
|
|
|
|
|
|
trie_walk_affected (validbits, table, *bytes, pentry, trie_install_fn);
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_entry_add (struct prefix_list *plist,
|
|
|
|
struct prefix_list_entry *pentry)
|
|
|
|
{
|
|
|
|
struct prefix_list_entry *replace;
|
|
|
|
struct prefix_list_entry *point;
|
|
|
|
|
|
|
|
/* Automatic asignment of seq no. */
|
|
|
|
if (pentry->seq == -1)
|
|
|
|
pentry->seq = prefix_new_seq_get (plist);
|
|
|
|
|
2015-04-13 10:21:37 +02:00
|
|
|
if (plist->tail && pentry->seq > plist->tail->seq)
|
|
|
|
point = NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Is there any same seq prefix list entry? */
|
|
|
|
replace = prefix_seq_check (plist, pentry->seq);
|
|
|
|
if (replace)
|
|
|
|
prefix_list_entry_delete (plist, replace, 0);
|
|
|
|
|
|
|
|
/* Check insert point. */
|
|
|
|
for (point = plist->head; point; point = point->next)
|
|
|
|
if (point->seq >= pentry->seq)
|
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* In case of this is the first element of the list. */
|
|
|
|
pentry->next = point;
|
|
|
|
|
|
|
|
if (point)
|
|
|
|
{
|
|
|
|
if (point->prev)
|
|
|
|
point->prev->next = pentry;
|
|
|
|
else
|
|
|
|
plist->head = pentry;
|
|
|
|
|
|
|
|
pentry->prev = point->prev;
|
|
|
|
point->prev = pentry;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (plist->tail)
|
|
|
|
plist->tail->next = pentry;
|
|
|
|
else
|
|
|
|
plist->head = pentry;
|
|
|
|
|
|
|
|
pentry->prev = plist->tail;
|
|
|
|
plist->tail = pentry;
|
|
|
|
}
|
|
|
|
|
2015-04-13 10:21:36 +02:00
|
|
|
prefix_list_trie_add (plist, pentry);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Increment count. */
|
|
|
|
plist->count++;
|
|
|
|
|
|
|
|
/* Run hook function. */
|
|
|
|
if (plist->master->add_hook)
|
|
|
|
(*plist->master->add_hook) (plist);
|
|
|
|
|
2015-05-20 02:40:45 +02:00
|
|
|
route_map_notify_dependencies(plist->name, RMAP_EVENT_PLIST_ADDED);
|
2002-12-13 21:15:29 +01:00
|
|
|
plist->master->recent = plist;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return string of prefix_list_type. */
|
2008-08-15 15:05:22 +02:00
|
|
|
static const char *
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_type_str (struct prefix_list_entry *pentry)
|
|
|
|
{
|
|
|
|
switch (pentry->type)
|
|
|
|
{
|
|
|
|
case PREFIX_PERMIT:
|
|
|
|
return "permit";
|
|
|
|
case PREFIX_DENY:
|
|
|
|
return "deny";
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_entry_match (struct prefix_list_entry *pentry, struct prefix *p)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = prefix_match (&pentry->prefix, p);
|
|
|
|
if (! ret)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* In case of le nor ge is specified, exact match is performed. */
|
|
|
|
if (! pentry->le && ! pentry->ge)
|
|
|
|
{
|
|
|
|
if (pentry->prefix.prefixlen != p->prefixlen)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pentry->le)
|
|
|
|
if (p->prefixlen > pentry->le)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (pentry->ge)
|
|
|
|
if (p->prefixlen < pentry->ge)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum prefix_list_type
|
|
|
|
prefix_list_apply (struct prefix_list *plist, void *object)
|
|
|
|
{
|
2015-04-13 10:21:36 +02:00
|
|
|
struct prefix_list_entry *pentry, *pbest = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-04-13 10:21:36 +02:00
|
|
|
struct prefix *p = (struct prefix *) object;
|
|
|
|
uint8_t *byte = &p->u.prefix;
|
2015-11-06 17:36:37 +01:00
|
|
|
size_t depth;
|
2015-04-13 10:21:36 +02:00
|
|
|
size_t validbits = p->prefixlen;
|
|
|
|
struct pltrie_table *table;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (plist == NULL)
|
|
|
|
return PREFIX_DENY;
|
|
|
|
|
|
|
|
if (plist->count == 0)
|
|
|
|
return PREFIX_PERMIT;
|
|
|
|
|
2015-11-06 17:36:37 +01:00
|
|
|
depth = plist->master->trie_depth;
|
2015-04-13 10:21:36 +02:00
|
|
|
table = plist->trie;
|
|
|
|
while (1)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-04-13 10:21:36 +02:00
|
|
|
for (pentry = table->entries[*byte].up_chain; pentry; pentry = pentry->next_best)
|
|
|
|
{
|
|
|
|
if (pbest && pbest->seq < pentry->seq)
|
|
|
|
continue;
|
|
|
|
if (prefix_list_entry_match (pentry, p))
|
|
|
|
pbest = pentry;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (validbits <= PLC_BITS)
|
|
|
|
break;
|
|
|
|
validbits -= PLC_BITS;
|
|
|
|
|
|
|
|
if (--depth)
|
|
|
|
{
|
|
|
|
if (!table->entries[*byte].next_table)
|
|
|
|
break;
|
|
|
|
|
|
|
|
table = table->entries[*byte].next_table;
|
|
|
|
byte++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (pentry = table->entries[*byte].final_chain; pentry; pentry = pentry->next_best)
|
|
|
|
{
|
|
|
|
if (pbest && pbest->seq < pentry->seq)
|
|
|
|
continue;
|
|
|
|
if (prefix_list_entry_match (pentry, p))
|
|
|
|
pbest = pentry;
|
|
|
|
}
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2015-04-13 10:21:36 +02:00
|
|
|
if (pbest == NULL)
|
|
|
|
return PREFIX_DENY;
|
|
|
|
|
|
|
|
return pbest->type;
|
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 __attribute__ ((unused))
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_print (struct prefix_list *plist)
|
|
|
|
{
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
|
|
|
if (plist == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
printf ("ip prefix-list %s: %d entries\n", plist->name, plist->count);
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
if (pentry->any)
|
|
|
|
printf ("any %s\n", prefix_list_type_str (pentry));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct prefix *p;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
p = &pentry->prefix;
|
|
|
|
|
2016-03-02 21:42:01 +01:00
|
|
|
printf (" seq %u %s %s/%d",
|
2002-12-13 21:15:29 +01:00
|
|
|
pentry->seq,
|
|
|
|
prefix_list_type_str (pentry),
|
|
|
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
|
|
|
p->prefixlen);
|
|
|
|
if (pentry->ge)
|
|
|
|
printf (" ge %d", pentry->ge);
|
|
|
|
if (pentry->le)
|
|
|
|
printf (" le %d", pentry->le);
|
|
|
|
printf ("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Retrun 1 when plist already include pentry policy. */
|
2004-06-11 13:27:03 +02:00
|
|
|
static struct prefix_list_entry *
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_entry_dup_check (struct prefix_list *plist,
|
|
|
|
struct prefix_list_entry *new)
|
|
|
|
{
|
2015-04-13 10:21:37 +02:00
|
|
|
size_t depth, maxdepth = plist->master->trie_depth;
|
|
|
|
uint8_t byte, *bytes = &new->prefix.u.prefix;
|
|
|
|
size_t validbits = new->prefix.prefixlen;
|
|
|
|
struct pltrie_table *table;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
int seq = 0;
|
|
|
|
|
|
|
|
if (new->seq == -1)
|
|
|
|
seq = prefix_new_seq_get (plist);
|
|
|
|
else
|
|
|
|
seq = new->seq;
|
|
|
|
|
2015-04-13 10:21:37 +02:00
|
|
|
table = plist->trie;
|
|
|
|
for (depth = 0; validbits > PLC_BITS && depth < maxdepth - 1; depth++)
|
|
|
|
{
|
|
|
|
byte = bytes[depth];
|
|
|
|
if (!table->entries[byte].next_table)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
table = table->entries[byte].next_table;
|
|
|
|
validbits -= PLC_BITS;
|
|
|
|
}
|
|
|
|
|
|
|
|
byte = bytes[depth];
|
|
|
|
if (validbits > PLC_BITS)
|
|
|
|
pentry = table->entries[byte].final_chain;
|
|
|
|
else
|
|
|
|
pentry = table->entries[byte].up_chain;
|
|
|
|
|
|
|
|
for (; pentry; pentry = pentry->next_best)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (prefix_same (&pentry->prefix, &new->prefix)
|
|
|
|
&& pentry->type == new->type
|
|
|
|
&& pentry->le == new->le
|
|
|
|
&& pentry->ge == new->ge
|
|
|
|
&& pentry->seq != seq)
|
|
|
|
return pentry;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
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
|
|
|
vty_invalid_prefix_range (struct vty *vty, const char *prefix)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Invalid prefix range for %s, make sure: len < ge-value <= le-value",
|
|
|
|
prefix);
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
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
|
|
|
vty_prefix_list_install (struct vty *vty, afi_t afi, const char *name,
|
|
|
|
const char *seq, const char *typestr,
|
|
|
|
const char *prefix, const char *ge, const char *le)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
enum prefix_list_type type;
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
struct prefix_list_entry *dup;
|
2016-09-12 15:32:11 +02:00
|
|
|
struct prefix p, p_tmp;
|
2002-12-13 21:15:29 +01:00
|
|
|
int any = 0;
|
|
|
|
int seqnum = -1;
|
|
|
|
int lenum = 0;
|
|
|
|
int genum = 0;
|
|
|
|
|
|
|
|
/* Sequential number. */
|
|
|
|
if (seq)
|
|
|
|
seqnum = atoi (seq);
|
|
|
|
|
|
|
|
/* ge and le number */
|
|
|
|
if (ge)
|
|
|
|
genum = atoi (ge);
|
|
|
|
if (le)
|
|
|
|
lenum = atoi (le);
|
|
|
|
|
|
|
|
/* Check filter type. */
|
|
|
|
if (strncmp ("permit", typestr, 1) == 0)
|
|
|
|
type = PREFIX_PERMIT;
|
|
|
|
else if (strncmp ("deny", typestr, 1) == 0)
|
|
|
|
type = PREFIX_DENY;
|
|
|
|
else
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% prefix type must be permit or deny");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* "any" is special token for matching any IPv4 addresses. */
|
2016-01-07 15:33:28 +01:00
|
|
|
switch (afi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-01-07 15:33:28 +01:00
|
|
|
case AFI_IP:
|
2002-12-13 21:15:29 +01:00
|
|
|
if (strncmp ("any", prefix, strlen (prefix)) == 0)
|
|
|
|
{
|
|
|
|
ret = str2prefix_ipv4 ("0.0.0.0/0", (struct prefix_ipv4 *) &p);
|
|
|
|
genum = 0;
|
|
|
|
lenum = IPV4_MAX_BITLEN;
|
|
|
|
any = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = str2prefix_ipv4 (prefix, (struct prefix_ipv4 *) &p);
|
|
|
|
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Malformed IPv4 prefix");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2016-09-12 15:32:11 +02:00
|
|
|
|
|
|
|
/* make a copy to verify prefix matches mask length */
|
|
|
|
prefix_copy (&p_tmp, &p);
|
|
|
|
apply_mask_ipv4 ((struct prefix_ipv4 *) &p_tmp);
|
|
|
|
|
2016-01-07 15:33:28 +01:00
|
|
|
break;
|
|
|
|
case AFI_IP6:
|
2002-12-13 21:15:29 +01:00
|
|
|
if (strncmp ("any", prefix, strlen (prefix)) == 0)
|
|
|
|
{
|
|
|
|
ret = str2prefix_ipv6 ("::/0", (struct prefix_ipv6 *) &p);
|
|
|
|
genum = 0;
|
|
|
|
lenum = IPV6_MAX_BITLEN;
|
|
|
|
any = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = str2prefix_ipv6 (prefix, (struct prefix_ipv6 *) &p);
|
|
|
|
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Malformed IPv6 prefix");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
2016-09-12 15:32:11 +02:00
|
|
|
|
|
|
|
/* make a copy to verify prefix matches mask length */
|
|
|
|
prefix_copy (&p_tmp, &p);
|
|
|
|
apply_mask_ipv6 ((struct prefix_ipv6 *) &p_tmp);
|
|
|
|
|
2016-01-07 15:33:28 +01:00
|
|
|
break;
|
2017-02-03 07:59:20 +01:00
|
|
|
case AFI_L2VPN:
|
2016-04-19 22:08:59 +02:00
|
|
|
default:
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Unrecognized AFI (%d)", afi);
|
2016-04-19 22:08:59 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-09-12 15:32:11 +02:00
|
|
|
/* If prefix has bits not under the mask, adjust it to fit */
|
|
|
|
if (!prefix_same (&p_tmp, &p))
|
|
|
|
{
|
|
|
|
char buf[PREFIX2STR_BUFFER];
|
|
|
|
char buf_tmp[PREFIX2STR_BUFFER];
|
|
|
|
prefix2str(&p, buf, sizeof(buf));
|
|
|
|
prefix2str(&p_tmp, buf_tmp, sizeof(buf_tmp));
|
|
|
|
zlog_warn ("Prefix-list %s prefix changed from %s to %s to match length",
|
|
|
|
name, buf, buf_tmp);
|
|
|
|
p = p_tmp;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* ge and le check. */
|
2014-09-19 17:55:46 +02:00
|
|
|
if (genum && (genum <= p.prefixlen))
|
2002-12-13 21:15:29 +01:00
|
|
|
return vty_invalid_prefix_range (vty, prefix);
|
|
|
|
|
2014-09-19 17:55:46 +02:00
|
|
|
if (lenum && (lenum <= p.prefixlen))
|
2002-12-13 21:15:29 +01:00
|
|
|
return vty_invalid_prefix_range (vty, prefix);
|
|
|
|
|
2014-09-19 17:55:46 +02:00
|
|
|
if (lenum && (genum > lenum))
|
2002-12-13 21:15:29 +01:00
|
|
|
return vty_invalid_prefix_range (vty, prefix);
|
|
|
|
|
2014-09-19 17:55:46 +02:00
|
|
|
if (genum && (lenum == (afi == AFI_IP ? 32 : 128)))
|
2002-12-13 21:15:29 +01:00
|
|
|
lenum = 0;
|
|
|
|
|
|
|
|
/* Get prefix_list with name. */
|
2015-04-13 10:21:35 +02:00
|
|
|
plist = prefix_list_get (afi, 0, name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Make prefix entry. */
|
|
|
|
pentry = prefix_list_entry_make (&p, type, seqnum, lenum, genum, any);
|
|
|
|
|
|
|
|
/* Check same policy. */
|
|
|
|
dup = prefix_entry_dup_check (plist, pentry);
|
|
|
|
|
|
|
|
if (dup)
|
|
|
|
{
|
|
|
|
prefix_list_entry_free (pentry);
|
2016-04-04 18:40:33 +02:00
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Install new filter to the access_list. */
|
|
|
|
prefix_list_entry_add (plist, pentry);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
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
|
|
|
vty_prefix_list_uninstall (struct vty *vty, afi_t afi, const char *name,
|
|
|
|
const char *seq, const char *typestr,
|
|
|
|
const char *prefix, const char *ge, const char *le)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
enum prefix_list_type type;
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
struct prefix p;
|
|
|
|
int seqnum = -1;
|
|
|
|
int lenum = 0;
|
|
|
|
int genum = 0;
|
|
|
|
|
|
|
|
/* Check prefix list name. */
|
|
|
|
plist = prefix_list_lookup (afi, name);
|
|
|
|
if (! plist)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Can't find specified prefix-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only prefix-list name specified, delete the entire prefix-list. */
|
|
|
|
if (seq == NULL && typestr == NULL && prefix == NULL &&
|
|
|
|
ge == NULL && le == NULL)
|
|
|
|
{
|
|
|
|
prefix_list_delete (plist);
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-05-13 01:17:38 +02:00
|
|
|
/* We must have, at a minimum, both the type and prefix here */
|
|
|
|
if ((typestr == NULL) || (prefix == NULL))
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Both prefix and type required");
|
2006-05-13 01:17:38 +02:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check sequence number. */
|
|
|
|
if (seq)
|
|
|
|
seqnum = atoi (seq);
|
|
|
|
|
|
|
|
/* ge and le number */
|
|
|
|
if (ge)
|
|
|
|
genum = atoi (ge);
|
|
|
|
if (le)
|
|
|
|
lenum = atoi (le);
|
|
|
|
|
|
|
|
/* Check of filter type. */
|
|
|
|
if (strncmp ("permit", typestr, 1) == 0)
|
|
|
|
type = PREFIX_PERMIT;
|
|
|
|
else if (strncmp ("deny", typestr, 1) == 0)
|
|
|
|
type = PREFIX_DENY;
|
|
|
|
else
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% prefix type must be permit or deny");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* "any" is special token for matching any IPv4 addresses. */
|
|
|
|
if (afi == AFI_IP)
|
|
|
|
{
|
|
|
|
if (strncmp ("any", prefix, strlen (prefix)) == 0)
|
|
|
|
{
|
|
|
|
ret = str2prefix_ipv4 ("0.0.0.0/0", (struct prefix_ipv4 *) &p);
|
|
|
|
genum = 0;
|
|
|
|
lenum = IPV4_MAX_BITLEN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = str2prefix_ipv4 (prefix, (struct prefix_ipv4 *) &p);
|
|
|
|
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Malformed IPv4 prefix");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (afi == AFI_IP6)
|
|
|
|
{
|
|
|
|
if (strncmp ("any", prefix, strlen (prefix)) == 0)
|
|
|
|
{
|
|
|
|
ret = str2prefix_ipv6 ("::/0", (struct prefix_ipv6 *) &p);
|
|
|
|
genum = 0;
|
|
|
|
lenum = IPV6_MAX_BITLEN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ret = str2prefix_ipv6 (prefix, (struct prefix_ipv6 *) &p);
|
|
|
|
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Malformed IPv6 prefix");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lookup prefix entry. */
|
|
|
|
pentry = prefix_list_entry_lookup(plist, &p, type, seqnum, lenum, genum);
|
|
|
|
|
|
|
|
if (pentry == NULL)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Can't find specified prefix-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install new filter to the access_list. */
|
|
|
|
prefix_list_entry_delete (plist, pentry, 1);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
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
|
|
|
vty_prefix_list_desc_unset (struct vty *vty, afi_t afi, const char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
|
|
|
|
plist = prefix_list_lookup (afi, name);
|
|
|
|
if (! plist)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Can't find specified prefix-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plist->desc)
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_TMP, plist->desc);
|
|
|
|
plist->desc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plist->head == NULL && plist->tail == NULL && plist->desc == NULL)
|
|
|
|
prefix_list_delete (plist);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum display_type
|
|
|
|
{
|
|
|
|
normal_display,
|
|
|
|
summary_display,
|
|
|
|
detail_display,
|
|
|
|
sequential_display,
|
|
|
|
longer_display,
|
|
|
|
first_match_display
|
|
|
|
};
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_show_prefix_entry (struct vty *vty, afi_t afi, struct prefix_list *plist,
|
|
|
|
struct prefix_master *master, enum display_type dtype,
|
|
|
|
int seqnum)
|
|
|
|
{
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
2005-09-29 13:25:50 +02:00
|
|
|
/* Print the name of the protocol */
|
2017-05-08 03:06:07 +02:00
|
|
|
vty_out(vty, "%s: ", frr_protoname);
|
2005-09-29 13:25:50 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (dtype == normal_display)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "ip%s prefix-list %s: %d entries",
|
2002-12-13 21:15:29 +01:00
|
|
|
afi == AFI_IP ? "" : "v6",
|
2017-06-21 05:10:57 +02:00
|
|
|
plist->name, plist->count);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (plist->desc)
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, " Description: %s", plist->desc);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
else if (dtype == summary_display || dtype == detail_display)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "ip%s prefix-list %s:",
|
|
|
|
afi == AFI_IP ? "" : "v6", plist->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (plist->desc)
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, " Description: %s", plist->desc);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, " count: %d, range entries: %d, sequences: %u - %u",
|
2002-12-13 21:15:29 +01:00
|
|
|
plist->count, plist->rangecount,
|
|
|
|
plist->head ? plist->head->seq : 0,
|
2017-06-21 05:10:57 +02:00
|
|
|
plist->tail ? plist->tail->seq : 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dtype != summary_display)
|
|
|
|
{
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
if (dtype == sequential_display && pentry->seq != seqnum)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
vty_out (vty, " ");
|
|
|
|
|
|
|
|
if (master->seqnum)
|
2016-03-02 21:42:01 +01:00
|
|
|
vty_out (vty, "seq %u ", pentry->seq);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_out (vty, "%s ", prefix_list_type_str (pentry));
|
|
|
|
|
|
|
|
if (pentry->any)
|
|
|
|
vty_out (vty, "any");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct prefix *p = &pentry->prefix;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
vty_out (vty, "%s/%d",
|
|
|
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
|
|
|
p->prefixlen);
|
|
|
|
|
|
|
|
if (pentry->ge)
|
|
|
|
vty_out (vty, " ge %d", pentry->ge);
|
|
|
|
if (pentry->le)
|
|
|
|
vty_out (vty, " le %d", pentry->le);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dtype == detail_display || dtype == sequential_display)
|
|
|
|
vty_out (vty, " (hit count: %ld, refcount: %ld)",
|
|
|
|
pentry->hitcnt, pentry->refcnt);
|
|
|
|
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
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
|
|
|
vty_show_prefix_list (struct vty *vty, afi_t afi, const char *name,
|
|
|
|
const char *seq, enum display_type dtype)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_master *master;
|
|
|
|
int seqnum = 0;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
master = prefix_master_get (afi, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (master == NULL)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
if (seq)
|
|
|
|
seqnum = atoi (seq);
|
|
|
|
|
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
plist = prefix_list_lookup (afi, name);
|
|
|
|
if (! plist)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Can't find specified prefix-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
vty_show_prefix_entry (vty, afi, plist, master, dtype, seqnum);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (dtype == detail_display || dtype == summary_display)
|
|
|
|
{
|
|
|
|
if (master->recent)
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "Prefix-list with the last deletion/insertion: %s",
|
|
|
|
master->recent->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (plist = master->num.head; plist; plist = plist->next)
|
|
|
|
vty_show_prefix_entry (vty, afi, plist, master, dtype, seqnum);
|
|
|
|
|
|
|
|
for (plist = master->str.head; plist; plist = plist->next)
|
|
|
|
vty_show_prefix_entry (vty, afi, plist, master, dtype, seqnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
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
|
|
|
vty_show_prefix_list_prefix (struct vty *vty, afi_t afi, const char *name,
|
|
|
|
const char *prefix, enum display_type type)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
struct prefix p;
|
|
|
|
int ret;
|
|
|
|
int match;
|
|
|
|
|
|
|
|
plist = prefix_list_lookup (afi, name);
|
|
|
|
if (! plist)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Can't find specified prefix-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = str2prefix (prefix, &p);
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% prefix is malformed");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
match = 0;
|
|
|
|
|
|
|
|
if (type == normal_display || type == first_match_display)
|
|
|
|
if (prefix_same (&p, &pentry->prefix))
|
|
|
|
match = 1;
|
|
|
|
|
|
|
|
if (type == longer_display)
|
|
|
|
if (prefix_match (&p, &pentry->prefix))
|
|
|
|
match = 1;
|
|
|
|
|
|
|
|
if (match)
|
|
|
|
{
|
2016-03-02 21:42:01 +01:00
|
|
|
vty_out (vty, " seq %u %s ",
|
2002-12-13 21:15:29 +01:00
|
|
|
pentry->seq,
|
|
|
|
prefix_list_type_str (pentry));
|
|
|
|
|
|
|
|
if (pentry->any)
|
|
|
|
vty_out (vty, "any");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct prefix *p = &pentry->prefix;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
vty_out (vty, "%s/%d",
|
|
|
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
|
|
|
p->prefixlen);
|
|
|
|
|
|
|
|
if (pentry->ge)
|
|
|
|
vty_out (vty, " ge %d", pentry->ge);
|
|
|
|
if (pentry->le)
|
|
|
|
vty_out (vty, " le %d", pentry->le);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type == normal_display || type == first_match_display)
|
|
|
|
vty_out (vty, " (hit count: %ld, refcount: %ld)",
|
|
|
|
pentry->hitcnt, pentry->refcnt);
|
|
|
|
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (type == first_match_display)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
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
|
|
|
vty_clear_prefix_list (struct vty *vty, afi_t afi, const char *name,
|
|
|
|
const char *prefix)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_master *master;
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
int ret;
|
|
|
|
struct prefix p;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
master = prefix_master_get (afi, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (master == NULL)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
if (name == NULL && prefix == NULL)
|
|
|
|
{
|
|
|
|
for (plist = master->num.head; plist; plist = plist->next)
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
pentry->hitcnt = 0;
|
|
|
|
|
|
|
|
for (plist = master->str.head; plist; plist = plist->next)
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
pentry->hitcnt = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
plist = prefix_list_lookup (afi, name);
|
|
|
|
if (! plist)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% Can't find specified prefix-list");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prefix)
|
|
|
|
{
|
|
|
|
ret = str2prefix (prefix, &p);
|
|
|
|
if (ret <= 0)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%% prefix is malformed");
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
if (prefix)
|
|
|
|
{
|
|
|
|
if (prefix_match (&pentry->prefix, &p))
|
|
|
|
pentry->hitcnt = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
pentry->hitcnt = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
#ifndef VTYSH_EXTRACT_PL
|
|
|
|
#include "plist_clippy.c"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DEFPY (ip_prefix_list,
|
|
|
|
ip_prefix_list_cmd,
|
|
|
|
"ip prefix-list WORD [seq (1-4294967295)] <deny|permit>$action <any$dest|A.B.C.D/M$dest [{ge (0-32)|le (0-32)}]>",
|
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"sequence number of an entry\n"
|
|
|
|
"Sequence number\n"
|
|
|
|
"Specify packets to reject\n"
|
|
|
|
"Specify packets to forward\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Any prefix match. Same as \"0.0.0.0/0 le 32\"\n"
|
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
|
|
|
|
"Minimum prefix length to be matched\n"
|
|
|
|
"Minimum prefix length\n"
|
2002-12-13 21:15:29 +01:00
|
|
|
"Maximum prefix length to be matched\n"
|
|
|
|
"Maximum prefix length\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_prefix_list_install (vty, AFI_IP, prefix_list, seq_str, action,
|
|
|
|
dest, ge_str, le_str);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (no_ip_prefix_list,
|
|
|
|
no_ip_prefix_list_cmd,
|
|
|
|
"no ip prefix-list WORD [seq (1-4294967295)] <deny|permit>$action <any$dest|A.B.C.D/M$dest [{ge (0-32)|le (0-32)}]>",
|
|
|
|
NO_STR
|
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"sequence number of an entry\n"
|
|
|
|
"Sequence number\n"
|
|
|
|
"Specify packets to reject\n"
|
|
|
|
"Specify packets to forward\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Any prefix match. Same as \"0.0.0.0/0 le 32\"\n"
|
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
|
2002-12-13 21:15:29 +01:00
|
|
|
"Minimum prefix length to be matched\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Minimum prefix length\n"
|
|
|
|
"Maximum prefix length to be matched\n"
|
|
|
|
"Maximum prefix length\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_prefix_list_uninstall (vty, AFI_IP, prefix_list, seq_str, action,
|
|
|
|
dest, ge_str, le_str);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (no_ip_prefix_list_all,
|
|
|
|
no_ip_prefix_list_all_cmd,
|
|
|
|
"no ip prefix-list WORD",
|
2002-12-13 21:15:29 +01:00
|
|
|
NO_STR
|
2016-11-18 14:05:49 +01:00
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_prefix_list_uninstall (vty, AFI_IP, prefix_list, NULL, NULL,
|
2002-12-13 21:15:29 +01:00
|
|
|
NULL, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (ip_prefix_list_sequence_number,
|
|
|
|
ip_prefix_list_sequence_number_cmd,
|
|
|
|
"[no] ip prefix-list sequence-number",
|
2002-12-13 21:15:29 +01:00
|
|
|
NO_STR
|
2016-11-18 14:05:49 +01:00
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
2016-11-18 14:05:49 +01:00
|
|
|
"Include/exclude sequence numbers in NVGEN\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
prefix_master_ipv4.seqnum = no ? 0 : 1;
|
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFUN (ip_prefix_list_description,
|
|
|
|
ip_prefix_list_description_cmd,
|
|
|
|
"ip prefix-list WORD description LINE...",
|
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Prefix-list specific description\n"
|
|
|
|
"Up to 80 characters describing this prefix-list\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
int idx_word = 2;
|
|
|
|
int idx_line = 4;
|
|
|
|
struct prefix_list *plist;
|
|
|
|
|
|
|
|
plist = prefix_list_get (AFI_IP, 0, argv[idx_word]->arg);
|
|
|
|
|
|
|
|
if (plist->desc)
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_TMP, plist->desc);
|
|
|
|
plist->desc = NULL;
|
|
|
|
}
|
|
|
|
plist->desc = argv_concat(argv, argc, idx_line);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFUN (no_ip_prefix_list_description,
|
|
|
|
no_ip_prefix_list_description_cmd,
|
|
|
|
"no ip prefix-list WORD description",
|
2002-12-13 21:15:29 +01:00
|
|
|
NO_STR
|
2016-11-18 14:05:49 +01:00
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Prefix-list specific description\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 3;
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_prefix_list_desc_unset (vty, AFI_IP, argv[idx_word]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
/* ALIAS_FIXME */
|
|
|
|
DEFUN (no_ip_prefix_list_description_comment,
|
|
|
|
no_ip_prefix_list_description_comment_cmd,
|
|
|
|
"no ip prefix-list WORD description LINE...",
|
2002-12-13 21:15:29 +01:00
|
|
|
NO_STR
|
2016-11-18 14:05:49 +01:00
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Prefix-list specific description\n"
|
|
|
|
"Up to 80 characters describing this prefix-list\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return no_ip_prefix_list_description (self, vty, argc, argv);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ip_prefix_list,
|
|
|
|
show_ip_prefix_list_cmd,
|
|
|
|
"show ip prefix-list [WORD [seq$dseq (1-4294967295)$arg]]",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"sequence number of an entry\n"
|
|
|
|
"Sequence number\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
enum display_type dtype = normal_display;
|
|
|
|
if (dseq)
|
|
|
|
dtype = sequential_display;
|
|
|
|
|
|
|
|
return vty_show_prefix_list (vty, AFI_IP, prefix_list, arg_str, dtype);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ip_prefix_list_prefix,
|
|
|
|
show_ip_prefix_list_prefix_cmd,
|
|
|
|
"show ip prefix-list WORD A.B.C.D/M$prefix [longer$dl|first-match$dfm]",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
|
|
|
|
"Lookup longer prefix\n"
|
|
|
|
"First matched prefix\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
enum display_type dtype = normal_display;
|
|
|
|
if (dl)
|
|
|
|
dtype = longer_display;
|
|
|
|
else if (dfm)
|
|
|
|
dtype = first_match_display;
|
|
|
|
|
|
|
|
return vty_show_prefix_list_prefix (vty, AFI_IP, prefix_list, prefix_str, dtype);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ip_prefix_list_summary,
|
|
|
|
show_ip_prefix_list_summary_cmd,
|
|
|
|
"show ip prefix-list summary [WORD$prefix_list]",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
2016-11-18 14:05:49 +01:00
|
|
|
"Summary of prefix lists\n"
|
|
|
|
"Name of a prefix list\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_show_prefix_list (vty, AFI_IP, prefix_list, NULL, summary_display);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ip_prefix_list_detail,
|
|
|
|
show_ip_prefix_list_detail_cmd,
|
|
|
|
"show ip prefix-list detail [WORD$prefix_list]",
|
|
|
|
SHOW_STR
|
|
|
|
IP_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Detail of prefix lists\n"
|
|
|
|
"Name of a prefix list\n")
|
|
|
|
{
|
|
|
|
return vty_show_prefix_list (vty, AFI_IP, prefix_list, NULL, detail_display);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (clear_ip_prefix_list,
|
|
|
|
clear_ip_prefix_list_cmd,
|
|
|
|
"clear ip prefix-list [WORD [A.B.C.D/M$prefix]]",
|
|
|
|
CLEAR_STR
|
|
|
|
IP_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_clear_prefix_list (vty, AFI_IP, prefix_list, prefix_str);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFPY (ipv6_prefix_list,
|
|
|
|
ipv6_prefix_list_cmd,
|
|
|
|
"ipv6 prefix-list WORD [seq (1-4294967295)] <deny|permit>$action <any$dest|X:X::X:X/M$dest [{ge (0-128)|le (0-128)}]>",
|
2002-12-13 21:15:29 +01:00
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"sequence number of an entry\n"
|
|
|
|
"Sequence number\n"
|
|
|
|
"Specify packets to reject\n"
|
|
|
|
"Specify packets to forward\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Any prefix match. Same as \"::0/0 le 128\"\n"
|
2002-12-13 21:15:29 +01:00
|
|
|
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
|
|
|
|
"Maximum prefix length to be matched\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Maximum prefix length\n"
|
|
|
|
"Minimum prefix length to be matched\n"
|
|
|
|
"Minimum prefix length\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_prefix_list_install (vty, AFI_IP6, prefix_list, seq_str, action,
|
|
|
|
dest, ge_str, le_str);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (no_ipv6_prefix_list,
|
|
|
|
no_ipv6_prefix_list_cmd,
|
|
|
|
"no ipv6 prefix-list WORD [seq (1-4294967295)] <deny|permit>$action <any$dest|X:X::X:X/M$dest [{ge (0-128)|le (0-128)}]>",
|
2002-12-13 21:15:29 +01:00
|
|
|
NO_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"sequence number of an entry\n"
|
|
|
|
"Sequence number\n"
|
|
|
|
"Specify packets to reject\n"
|
|
|
|
"Specify packets to forward\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Any prefix match. Same as \"::0/0 le 128\"\n"
|
2002-12-13 21:15:29 +01:00
|
|
|
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
|
|
|
|
"Maximum prefix length to be matched\n"
|
|
|
|
"Maximum prefix length\n"
|
|
|
|
"Minimum prefix length to be matched\n"
|
|
|
|
"Minimum prefix length\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_prefix_list_uninstall (vty, AFI_IP6, prefix_list, seq_str, action,
|
|
|
|
dest, ge_str, le_str);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (no_ipv6_prefix_list_all,
|
|
|
|
no_ipv6_prefix_list_all_cmd,
|
|
|
|
"no ipv6 prefix-list WORD",
|
|
|
|
NO_STR
|
2002-12-13 21:15:29 +01:00
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
2016-11-18 14:05:49 +01:00
|
|
|
"Name of a prefix list\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_prefix_list_uninstall (vty, AFI_IP6, prefix_list, NULL, NULL,
|
|
|
|
NULL, NULL, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (ipv6_prefix_list_sequence_number,
|
|
|
|
ipv6_prefix_list_sequence_number_cmd,
|
|
|
|
"[no] ipv6 prefix-list sequence-number",
|
2002-12-13 21:15:29 +01:00
|
|
|
NO_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Include/exclude sequence numbers in NVGEN\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
prefix_master_ipv6.seqnum = no ? 0 : 1;
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (ipv6_prefix_list_description,
|
|
|
|
ipv6_prefix_list_description_cmd,
|
2016-09-27 02:07:46 +02:00
|
|
|
"ipv6 prefix-list WORD description LINE...",
|
2002-12-13 21:15:29 +01:00
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"Prefix-list specific description\n"
|
|
|
|
"Up to 80 characters describing this prefix-list\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 2;
|
2016-09-30 02:16:31 +02:00
|
|
|
int iddx_line = 4;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct prefix_list *plist;
|
|
|
|
|
2016-09-23 22:17:29 +02:00
|
|
|
plist = prefix_list_get (AFI_IP6, 0, argv[idx_word]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (plist->desc)
|
|
|
|
{
|
|
|
|
XFREE (MTYPE_TMP, plist->desc);
|
|
|
|
plist->desc = NULL;
|
|
|
|
}
|
2016-09-30 02:16:31 +02:00
|
|
|
plist->desc = argv_concat(argv, argc, iddx_line);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2016-09-23 22:17:29 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
DEFUN (no_ipv6_prefix_list_description,
|
|
|
|
no_ipv6_prefix_list_description_cmd,
|
|
|
|
"no ipv6 prefix-list WORD description",
|
|
|
|
NO_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"Prefix-list specific description\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 3;
|
|
|
|
return vty_prefix_list_desc_unset (vty, AFI_IP6, argv[idx_word]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-09-23 23:34:33 +02:00
|
|
|
/* ALIAS_FIXME */
|
|
|
|
DEFUN (no_ipv6_prefix_list_description_comment,
|
|
|
|
no_ipv6_prefix_list_description_comment_cmd,
|
|
|
|
"no ipv6 prefix-list WORD description LINE...",
|
|
|
|
NO_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"Prefix-list specific description\n"
|
|
|
|
"Up to 80 characters describing this prefix-list\n")
|
|
|
|
{
|
2016-11-18 22:27:30 +01:00
|
|
|
return no_ipv6_prefix_list_description (self, vty, argc, argv);
|
2016-09-23 23:34:33 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ipv6_prefix_list,
|
2002-12-13 21:15:29 +01:00
|
|
|
show_ipv6_prefix_list_cmd,
|
2016-11-18 14:05:49 +01:00
|
|
|
"show ipv6 prefix-list [WORD [seq$dseq (1-4294967295)$arg]]",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"sequence number of an entry\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Sequence number\n"
|
|
|
|
"Lookup longer prefix\n"
|
|
|
|
"First matched prefix\n")
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
enum display_type dtype = normal_display;
|
|
|
|
if (dseq)
|
|
|
|
dtype = sequential_display;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_show_prefix_list (vty, AFI_IP6, prefix_list, arg_str, dtype);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ipv6_prefix_list_prefix,
|
|
|
|
show_ipv6_prefix_list_prefix_cmd,
|
|
|
|
"show ipv6 prefix-list WORD X:X::X:X/M$prefix [longer$dl|first-match$dfm]",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
|
2016-11-18 14:05:49 +01:00
|
|
|
"Lookup longer prefix\n"
|
2002-12-13 21:15:29 +01:00
|
|
|
"First matched prefix\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
enum display_type dtype = normal_display;
|
|
|
|
if (dl)
|
|
|
|
dtype = longer_display;
|
|
|
|
else if (dfm)
|
|
|
|
dtype = first_match_display;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_show_prefix_list_prefix (vty, AFI_IP6, prefix_list, prefix_str, dtype);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ipv6_prefix_list_summary,
|
|
|
|
show_ipv6_prefix_list_summary_cmd,
|
|
|
|
"show ipv6 prefix-list summary [WORD$prefix-list]",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Summary of prefix lists\n"
|
|
|
|
"Name of a prefix list\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_show_prefix_list (vty, AFI_IP6, prefix_list, NULL, summary_display);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (show_ipv6_prefix_list_detail,
|
2002-12-13 21:15:29 +01:00
|
|
|
show_ipv6_prefix_list_detail_cmd,
|
2016-11-18 14:05:49 +01:00
|
|
|
"show ipv6 prefix-list detail [WORD$prefix-list]",
|
2002-12-13 21:15:29 +01:00
|
|
|
SHOW_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Detail of prefix lists\n"
|
|
|
|
"Name of a prefix list\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_show_prefix_list (vty, AFI_IP6, prefix_list, NULL, detail_display);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-11-18 14:05:49 +01:00
|
|
|
DEFPY (clear_ipv6_prefix_list,
|
2002-12-13 21:15:29 +01:00
|
|
|
clear_ipv6_prefix_list_cmd,
|
2016-11-18 14:05:49 +01:00
|
|
|
"clear ipv6 prefix-list [WORD [X:X::X:X/M$prefix]]",
|
2002-12-13 21:15:29 +01:00
|
|
|
CLEAR_STR
|
|
|
|
IPV6_STR
|
|
|
|
PREFIX_LIST_STR
|
|
|
|
"Name of a prefix list\n"
|
|
|
|
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
|
|
|
|
{
|
2016-11-18 14:05:49 +01:00
|
|
|
return vty_clear_prefix_list (vty, AFI_IP6, prefix_list, prefix_str);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Configuration write function. */
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
config_write_prefix_afi (afi_t afi, struct vty *vty)
|
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
struct prefix_master *master;
|
|
|
|
int write = 0;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
master = prefix_master_get (afi, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (master == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (! master->seqnum)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "no ip%s prefix-list sequence-number",
|
|
|
|
afi == AFI_IP ? "" : "v6");
|
|
|
|
vty_outln (vty, "!");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (plist = master->num.head; plist; plist = plist->next)
|
|
|
|
{
|
|
|
|
if (plist->desc)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "ip%s prefix-list %s description %s",
|
2002-12-13 21:15:29 +01:00
|
|
|
afi == AFI_IP ? "" : "v6",
|
2017-06-21 05:10:57 +02:00
|
|
|
plist->name, plist->desc);
|
2002-12-13 21:15:29 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
vty_out (vty, "ip%s prefix-list %s ",
|
|
|
|
afi == AFI_IP ? "" : "v6",
|
|
|
|
plist->name);
|
|
|
|
|
|
|
|
if (master->seqnum)
|
2016-03-02 21:42:01 +01:00
|
|
|
vty_out (vty, "seq %u ", pentry->seq);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_out (vty, "%s ", prefix_list_type_str (pentry));
|
|
|
|
|
|
|
|
if (pentry->any)
|
|
|
|
vty_out (vty, "any");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct prefix *p = &pentry->prefix;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
vty_out (vty, "%s/%d",
|
|
|
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
|
|
|
p->prefixlen);
|
|
|
|
|
|
|
|
if (pentry->ge)
|
|
|
|
vty_out (vty, " ge %d", pentry->ge);
|
|
|
|
if (pentry->le)
|
|
|
|
vty_out (vty, " le %d", pentry->le);
|
|
|
|
}
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "");
|
2002-12-13 21:15:29 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
/* vty_out (vty, "!%s", VTY_NEWLINE); */
|
|
|
|
}
|
|
|
|
|
|
|
|
for (plist = master->str.head; plist; plist = plist->next)
|
|
|
|
{
|
|
|
|
if (plist->desc)
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "ip%s prefix-list %s description %s",
|
2002-12-13 21:15:29 +01:00
|
|
|
afi == AFI_IP ? "" : "v6",
|
2017-06-21 05:10:57 +02:00
|
|
|
plist->name, plist->desc);
|
2002-12-13 21:15:29 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
vty_out (vty, "ip%s prefix-list %s ",
|
|
|
|
afi == AFI_IP ? "" : "v6",
|
|
|
|
plist->name);
|
|
|
|
|
|
|
|
if (master->seqnum)
|
2016-03-02 21:42:01 +01:00
|
|
|
vty_out (vty, "seq %u ", pentry->seq);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_out (vty, "%s", prefix_list_type_str (pentry));
|
|
|
|
|
|
|
|
if (pentry->any)
|
|
|
|
vty_out (vty, " any");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct prefix *p = &pentry->prefix;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
|
|
|
vty_out (vty, " %s/%d",
|
|
|
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
|
|
|
p->prefixlen);
|
|
|
|
|
|
|
|
if (pentry->ge)
|
|
|
|
vty_out (vty, " ge %d", pentry->ge);
|
|
|
|
if (pentry->le)
|
|
|
|
vty_out (vty, " le %d", pentry->le);
|
|
|
|
}
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "");
|
2002-12-13 21:15:29 +01:00
|
|
|
write++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return write;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct stream *
|
|
|
|
prefix_bgp_orf_entry (struct stream *s, struct prefix_list *plist,
|
|
|
|
u_char init_flag, u_char permit_flag, u_char deny_flag)
|
|
|
|
{
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
|
|
|
if (! plist)
|
|
|
|
return s;
|
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
u_char flag = init_flag;
|
|
|
|
struct prefix *p = &pentry->prefix;
|
|
|
|
|
|
|
|
flag |= (pentry->type == PREFIX_PERMIT ?
|
|
|
|
permit_flag : deny_flag);
|
|
|
|
stream_putc (s, flag);
|
|
|
|
stream_putl (s, (u_int32_t)pentry->seq);
|
|
|
|
stream_putc (s, (u_char)pentry->ge);
|
|
|
|
stream_putc (s, (u_char)pentry->le);
|
|
|
|
stream_put_prefix (s, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
prefix_bgp_orf_set (char *name, afi_t afi, struct orf_prefix *orfp,
|
|
|
|
int permit, int set)
|
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list_entry *pentry;
|
|
|
|
|
|
|
|
/* ge and le value check */
|
|
|
|
if (orfp->ge && orfp->ge <= orfp->p.prefixlen)
|
|
|
|
return CMD_WARNING;
|
|
|
|
if (orfp->le && orfp->le <= orfp->p.prefixlen)
|
|
|
|
return CMD_WARNING;
|
|
|
|
if (orfp->le && orfp->ge > orfp->le)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
if (orfp->ge && orfp->le == (afi == AFI_IP ? 32 : 128))
|
|
|
|
orfp->le = 0;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
plist = prefix_list_get (afi, 1, name);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (! plist)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
if (set)
|
|
|
|
{
|
|
|
|
pentry = prefix_list_entry_make (&orfp->p,
|
|
|
|
(permit ? PREFIX_PERMIT : PREFIX_DENY),
|
|
|
|
orfp->seq, orfp->le, orfp->ge, 0);
|
|
|
|
|
|
|
|
if (prefix_entry_dup_check (plist, pentry))
|
|
|
|
{
|
|
|
|
prefix_list_entry_free (pentry);
|
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
prefix_list_entry_add (plist, pentry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pentry = prefix_list_entry_lookup (plist, &orfp->p,
|
|
|
|
(permit ? PREFIX_PERMIT : PREFIX_DENY),
|
|
|
|
orfp->seq, orfp->le, orfp->ge);
|
|
|
|
|
|
|
|
if (! pentry)
|
|
|
|
return CMD_WARNING;
|
|
|
|
|
|
|
|
prefix_list_entry_delete (plist, pentry, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-04-13 10:21:35 +02:00
|
|
|
prefix_bgp_orf_remove_all (afi_t afi, char *name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
plist = prefix_bgp_orf_lookup (afi, name);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (plist)
|
|
|
|
prefix_list_delete (plist);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return prefix count */
|
|
|
|
int
|
2015-08-12 15:59:18 +02:00
|
|
|
prefix_bgp_show_prefix_list (struct vty *vty, afi_t afi, char *name, u_char use_json)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list_entry *pentry;
|
2015-08-12 15:59:18 +02:00
|
|
|
json_object *json = NULL;
|
|
|
|
json_object *json_prefix = NULL;
|
|
|
|
json_object *json_list = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
plist = prefix_bgp_orf_lookup (afi, name);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (! plist)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (! vty)
|
|
|
|
return plist->count;
|
|
|
|
|
2015-08-12 15:59:18 +02:00
|
|
|
if(use_json)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2015-08-12 15:59:18 +02:00
|
|
|
json = json_object_new_object();
|
|
|
|
json_prefix = json_object_new_object();
|
|
|
|
json_list = json_object_new_object();
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-08-12 15:59:18 +02:00
|
|
|
json_object_int_add(json_prefix, "prefixListCounter", plist->count);
|
|
|
|
json_object_string_add(json_prefix, "prefixListName", plist->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-08-12 15:59:18 +02:00
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
struct prefix *p = &pentry->prefix;
|
|
|
|
char buf_a[BUFSIZ];
|
|
|
|
char buf_b[BUFSIZ];
|
|
|
|
|
|
|
|
sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ),
|
|
|
|
p->prefixlen);
|
|
|
|
|
|
|
|
json_object_int_add(json_list, "seq", pentry->seq);
|
|
|
|
json_object_string_add(json_list, "seqPrefixListType", prefix_list_type_str (pentry));
|
|
|
|
|
|
|
|
if (pentry->ge)
|
|
|
|
json_object_int_add(json_list, "ge", pentry->ge);
|
|
|
|
if (pentry->le)
|
|
|
|
json_object_int_add(json_list, "le", pentry->le);
|
|
|
|
|
|
|
|
json_object_object_add(json_prefix, buf_a, json_list);
|
|
|
|
}
|
|
|
|
if (afi == AFI_IP)
|
|
|
|
json_object_object_add(json, "ipPrefixList", json_prefix);
|
|
|
|
else
|
|
|
|
json_object_object_add(json, "ipv6PrefixList", json_prefix);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "%s",
|
|
|
|
json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
|
2015-08-12 15:59:18 +02:00
|
|
|
json_object_free(json);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "ip%s prefix-list %s: %d entries",
|
2015-08-12 15:59:18 +02:00
|
|
|
afi == AFI_IP ? "" : "v6",
|
2017-06-21 05:10:57 +02:00
|
|
|
plist->name, plist->count);
|
2015-08-12 15:59:18 +02:00
|
|
|
|
|
|
|
for (pentry = plist->head; pentry; pentry = pentry->next)
|
|
|
|
{
|
|
|
|
struct prefix *p = &pentry->prefix;
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
|
2016-03-02 21:42:01 +01:00
|
|
|
vty_out (vty, " seq %u %s %s/%d", pentry->seq,
|
2015-08-12 15:59:18 +02:00
|
|
|
prefix_list_type_str (pentry),
|
|
|
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
|
|
|
p->prefixlen);
|
|
|
|
|
|
|
|
if (pentry->ge)
|
|
|
|
vty_out (vty, " ge %d", pentry->ge);
|
|
|
|
if (pentry->le)
|
|
|
|
vty_out (vty, " le %d", pentry->le);
|
|
|
|
|
2017-06-21 05:10:57 +02:00
|
|
|
vty_outln (vty, "");
|
2015-08-12 15:59:18 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
return plist->count;
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
2015-04-13 10:21:35 +02:00
|
|
|
prefix_list_reset_afi (afi_t afi, int orf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_list *next;
|
|
|
|
struct prefix_master *master;
|
|
|
|
|
2015-04-13 10:21:35 +02:00
|
|
|
master = prefix_master_get (afi, orf);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (master == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (plist = master->num.head; plist; plist = next)
|
|
|
|
{
|
|
|
|
next = plist->next;
|
|
|
|
prefix_list_delete (plist);
|
|
|
|
}
|
|
|
|
for (plist = master->str.head; plist; plist = next)
|
|
|
|
{
|
|
|
|
next = plist->next;
|
|
|
|
prefix_list_delete (plist);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert (master->num.head == NULL);
|
|
|
|
assert (master->num.tail == NULL);
|
|
|
|
|
|
|
|
assert (master->str.head == NULL);
|
|
|
|
assert (master->str.tail == NULL);
|
|
|
|
|
|
|
|
master->seqnum = 1;
|
|
|
|
master->recent = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Prefix-list node. */
|
2008-12-01 20:10:34 +01:00
|
|
|
static struct cmd_node prefix_node =
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
PREFIX_NODE,
|
|
|
|
"", /* Prefix list has no interface. */
|
|
|
|
1
|
|
|
|
};
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
config_write_prefix_ipv4 (struct vty *vty)
|
|
|
|
{
|
|
|
|
return config_write_prefix_afi (AFI_IP, vty);
|
|
|
|
}
|
|
|
|
|
2016-11-19 11:57:08 +01:00
|
|
|
static void
|
|
|
|
plist_autocomplete_afi (afi_t afi, vector comps, struct cmd_token *token)
|
|
|
|
{
|
|
|
|
struct prefix_list *plist;
|
|
|
|
struct prefix_master *master;
|
|
|
|
|
|
|
|
master = prefix_master_get (afi, 0);
|
|
|
|
if (master == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (plist = master->str.head; plist; plist = plist->next)
|
|
|
|
vector_set (comps, XSTRDUP (MTYPE_COMPLETION, plist->name));
|
|
|
|
for (plist = master->num.head; plist; plist = plist->next)
|
|
|
|
vector_set (comps, XSTRDUP (MTYPE_COMPLETION, plist->name));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
plist_autocomplete(vector comps, struct cmd_token *token)
|
|
|
|
{
|
|
|
|
plist_autocomplete_afi (AFI_IP, comps, token);
|
|
|
|
plist_autocomplete_afi (AFI_IP6, comps, token);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct cmd_variable_handler plist_var_handlers[] = {
|
|
|
|
{
|
|
|
|
/* "prefix-list WORD" */
|
|
|
|
.varname = "prefix_list",
|
|
|
|
.completions = plist_autocomplete
|
|
|
|
}, {
|
|
|
|
.completions = NULL
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
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
|
|
|
prefix_list_init_ipv4 (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
install_node (&prefix_node, config_write_prefix_ipv4);
|
|
|
|
|
|
|
|
install_element (CONFIG_NODE, &ip_prefix_list_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_prefix_list_cmd);
|
2016-11-18 14:05:49 +01:00
|
|
|
install_element (CONFIG_NODE, &no_ip_prefix_list_all_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
install_element (CONFIG_NODE, &ip_prefix_list_description_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ip_prefix_list_description_cmd);
|
2016-09-23 23:34:33 +02:00
|
|
|
install_element (CONFIG_NODE, &no_ip_prefix_list_description_comment_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
install_element (CONFIG_NODE, &ip_prefix_list_sequence_number_cmd);
|
|
|
|
|
|
|
|
install_element (VIEW_NODE, &show_ip_prefix_list_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ip_prefix_list_prefix_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ip_prefix_list_summary_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ip_prefix_list_detail_cmd);
|
|
|
|
|
|
|
|
install_element (ENABLE_NODE, &clear_ip_prefix_list_cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Prefix-list node. */
|
2008-12-01 20:10:34 +01:00
|
|
|
static struct cmd_node prefix_ipv6_node =
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
PREFIX_IPV6_NODE,
|
|
|
|
"", /* Prefix list has no interface. */
|
|
|
|
1
|
|
|
|
};
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
config_write_prefix_ipv6 (struct vty *vty)
|
|
|
|
{
|
|
|
|
return config_write_prefix_afi (AFI_IP6, vty);
|
|
|
|
}
|
|
|
|
|
2004-06-11 13:27:03 +02:00
|
|
|
static void
|
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
|
|
|
prefix_list_init_ipv6 (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
install_node (&prefix_ipv6_node, config_write_prefix_ipv6);
|
|
|
|
|
|
|
|
install_element (CONFIG_NODE, &ipv6_prefix_list_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ipv6_prefix_list_cmd);
|
2016-11-18 14:05:49 +01:00
|
|
|
install_element (CONFIG_NODE, &no_ipv6_prefix_list_all_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
install_element (CONFIG_NODE, &ipv6_prefix_list_description_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_ipv6_prefix_list_description_cmd);
|
2016-09-23 23:34:33 +02:00
|
|
|
install_element (CONFIG_NODE, &no_ipv6_prefix_list_description_comment_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
install_element (CONFIG_NODE, &ipv6_prefix_list_sequence_number_cmd);
|
|
|
|
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_prefix_list_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_prefix_list_prefix_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_prefix_list_summary_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_ipv6_prefix_list_detail_cmd);
|
|
|
|
|
|
|
|
install_element (ENABLE_NODE, &clear_ipv6_prefix_list_cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
prefix_list_init ()
|
|
|
|
{
|
2016-11-19 11:57:08 +01:00
|
|
|
cmd_variable_handler_register(plist_var_handlers);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
prefix_list_init_ipv4 ();
|
|
|
|
prefix_list_init_ipv6 ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
prefix_list_reset ()
|
|
|
|
{
|
2015-04-13 10:21:35 +02:00
|
|
|
prefix_list_reset_afi (AFI_IP, 0);
|
|
|
|
prefix_list_reset_afi (AFI_IP6, 0);
|
|
|
|
prefix_list_reset_afi (AFI_IP, 1);
|
|
|
|
prefix_list_reset_afi (AFI_IP6, 1);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|