Skip to content

Commit

Permalink
Merge pull request #8283 from chiragshah6/mdev
Browse files Browse the repository at this point in the history
bgpd: add seqno in bgp as-path access-list policy
  • Loading branch information
ton31337 authored Mar 18, 2021
2 parents bb5dddf + e6e62ee commit 0966b41
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 16 deletions.
132 changes: 119 additions & 13 deletions bgpd/bgp_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ struct as_filter {

regex_t *reg;
char *reg_str;

/* Sequence number. */
int64_t seq;
};

/* AS path filter list. */
Expand All @@ -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},
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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")
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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")
Expand Down Expand Up @@ -643,17 +743,23 @@ 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++;
}

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++;
}
Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 4 additions & 3 deletions doc/user/bgp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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:

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 0966b41

Please sign in to comment.