Merge pull request #8283 from chiragshah6/mdev

bgpd: add seqno in bgp as-path access-list policy
This commit is contained in:
Donatas Abraitis 2021-03-18 17:24:35 +02:00 committed by GitHub
commit 0966b412ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 125 additions and 16 deletions

View File

@ -62,6 +62,9 @@ struct as_filter {
regex_t *reg;
char *reg_str;
/* Sequence number. */
int64_t seq;
};
/* AS path filter list. */
@ -77,6 +80,38 @@ struct as_list {
struct as_filter *tail;
};
/* Calculate new sequential number. */
static int64_t bgp_alist_new_seq_get(struct as_list *list)
{
int64_t maxseq;
int64_t newseq;
struct as_filter *entry;
maxseq = 0;
for (entry = list->head; entry; entry = entry->next) {
if (maxseq < entry->seq)
maxseq = entry->seq;
}
newseq = ((maxseq / 5) * 5) + 5;
return (newseq > UINT_MAX) ? UINT_MAX : newseq;
}
/* Return as-list entry which has same seq number. */
static struct as_filter *bgp_aslist_seq_check(struct as_list *list, int64_t seq)
{
struct as_filter *entry;
for (entry = list->head; entry; entry = entry->next)
if (entry->seq == seq)
return entry;
return NULL;
}
/* as-path access-list 10 permit AS1. */
static struct as_list_master as_list_master = {{NULL, NULL},
@ -125,17 +160,69 @@ static struct as_filter *as_filter_lookup(struct as_list *aslist,
return NULL;
}
static void as_filter_entry_replace(struct as_list *list,
struct as_filter *replace,
struct as_filter *entry)
{
if (replace->next) {
entry->next = replace->next;
replace->next->prev = entry;
} else {
entry->next = NULL;
list->tail = entry;
}
if (replace->prev) {
entry->prev = replace->prev;
replace->prev->next = entry;
} else {
entry->prev = NULL;
list->head = entry;
}
as_filter_free(replace);
}
static void as_list_filter_add(struct as_list *aslist,
struct as_filter *asfilter)
{
asfilter->next = NULL;
asfilter->prev = aslist->tail;
struct as_filter *point;
struct as_filter *replace;
if (aslist->tail)
aslist->tail->next = asfilter;
else
aslist->head = asfilter;
aslist->tail = asfilter;
if (aslist->tail && asfilter->seq > aslist->tail->seq)
point = NULL;
else {
replace = bgp_aslist_seq_check(aslist, asfilter->seq);
if (replace) {
as_filter_entry_replace(aslist, replace, asfilter);
return;
}
/* Check insert point. */
for (point = aslist->head; point; point = point->next)
if (point->seq >= asfilter->seq)
break;
}
asfilter->next = point;
if (point) {
if (point->prev)
point->prev->next = asfilter;
else
aslist->head = asfilter;
asfilter->prev = point->prev;
point->prev = asfilter;
} else {
if (aslist->tail)
aslist->tail->next = asfilter;
else
aslist->head = asfilter;
asfilter->prev = aslist->tail;
aslist->tail = asfilter;
}
/* Run hook function. */
if (as_list_master.add_hook)
@ -391,11 +478,13 @@ bool config_bgp_aspath_validate(const char *regstr)
}
DEFUN(as_path, bgp_as_path_cmd,
"bgp as-path access-list WORD <deny|permit> LINE...",
"bgp as-path access-list WORD [seq (0-4294967295)] <deny|permit> LINE...",
BGP_STR
"BGP autonomous system path filter\n"
"Specify an access list name\n"
"Regular expression access list name\n"
"Sequence number of an entry\n"
"Sequence number\n"
"Specify packets to reject\n"
"Specify packets to forward\n"
"A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
@ -406,11 +495,15 @@ DEFUN(as_path, bgp_as_path_cmd,
struct as_list *aslist;
regex_t *regex;
char *regstr;
int64_t seqnum = ASPATH_SEQ_NUMBER_AUTO;
/* Retrieve access list name */
argv_find(argv, argc, "WORD", &idx);
char *alname = argv[idx]->arg;
if (argv_find(argv, argc, "(0-4294967295)", &idx))
seqnum = (int64_t)atol(argv[idx]->arg);
/* Check the filter type. */
type = argv_find(argv, argc, "deny", &idx) ? AS_FILTER_DENY
: AS_FILTER_PERMIT;
@ -439,6 +532,11 @@ DEFUN(as_path, bgp_as_path_cmd,
/* Install new filter to the access_list. */
aslist = as_list_get(alname);
if (seqnum == ASPATH_SEQ_NUMBER_AUTO)
seqnum = bgp_alist_new_seq_get(aslist);
asfilter->seq = seqnum;
/* Duplicate insertion check. */;
if (as_list_dup_check(aslist, asfilter))
as_filter_free(asfilter);
@ -449,12 +547,14 @@ DEFUN(as_path, bgp_as_path_cmd,
}
DEFUN(no_as_path, no_bgp_as_path_cmd,
"no bgp as-path access-list WORD <deny|permit> LINE...",
"no bgp as-path access-list WORD [seq (0-4294967295)] <deny|permit> LINE...",
NO_STR
BGP_STR
"BGP autonomous system path filter\n"
"Specify an access list name\n"
"Regular expression access list name\n"
"Sequence number of an entry\n"
"Sequence number\n"
"Specify packets to reject\n"
"Specify packets to forward\n"
"A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
@ -643,8 +743,11 @@ static int config_write_as_list(struct vty *vty)
for (aslist = as_list_master.num.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, "bgp as-path access-list %s %s %s\n",
aslist->name, filter_type_str(asfilter->type),
vty_out(vty,
"bgp as-path access-list %s seq %" PRId64
" %s %s\n",
aslist->name, asfilter->seq,
filter_type_str(asfilter->type),
asfilter->reg_str);
write++;
}
@ -652,8 +755,11 @@ static int config_write_as_list(struct vty *vty)
for (aslist = as_list_master.str.head; aslist; aslist = aslist->next)
for (asfilter = aslist->head; asfilter;
asfilter = asfilter->next) {
vty_out(vty, "bgp as-path access-list %s %s %s\n",
aslist->name, filter_type_str(asfilter->type),
vty_out(vty,
"bgp as-path access-list %s seq %" PRId64
" %s %s\n",
aslist->name, asfilter->seq,
filter_type_str(asfilter->type),
asfilter->reg_str);
write++;
}

View File

@ -21,6 +21,8 @@
#ifndef _QUAGGA_BGP_FILTER_H
#define _QUAGGA_BGP_FILTER_H
#define ASPATH_SEQ_NUMBER_AUTO -1
enum as_filter_type { AS_FILTER_DENY, AS_FILTER_PERMIT };
extern void bgp_filter_init(void);

View File

@ -1783,7 +1783,7 @@ AS Path Access Lists
AS path access list is user defined AS path.
.. clicmd:: bgp as-path access-list WORD permit|deny LINE
.. clicmd:: bgp as-path access-list WORD [seq (0-4294967295)] permit|deny LINE
This command defines a new AS path access list.
@ -1799,6 +1799,7 @@ Bogon ASN filter policy configuration example
bgp as-path access-list 99 permit _0_
bgp as-path access-list 99 permit _23456_
bgp as-path access-list 99 permit _1310[0-6][0-9]_|_13107[0-1]_
bgp as-path access-list 99 seq 20 permit ^65
.. _bgp-using-as-path-in-route-map:
@ -3597,8 +3598,8 @@ certainly contains silly mistakes, if not serious flaws.
ip prefix-list pl-peer2-network permit 192.168.2.0/24
ip prefix-list pl-peer2-network permit 172.16.1/24
!
bgp as-path access-list asp-own-as permit ^$
bgp as-path access-list asp-own-as permit _64512_
bgp as-path access-list seq 5 asp-own-as permit ^$
bgp as-path access-list seq 10 asp-own-as permit _64512_
!
! #################################################################
! Match communities we provide actions for, on routes receives from