diff options
author | Donatas Abraitis <donatas.abraitis@gmail.com> | 2021-03-18 16:24:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-18 16:24:35 +0100 |
commit | 0966b412bafd1cb7d1c39fe6002dc5cf03264c21 (patch) | |
tree | c07f35cb14834e2a2a6f612746bb959d8b9c4203 /bgpd | |
parent | Merge pull request #8284 from mjstapp/fix_bgp_zero_timers (diff) | |
parent | doc: add seqno to bgp as path list section (diff) | |
download | frr-0966b412bafd1cb7d1c39fe6002dc5cf03264c21.tar.xz frr-0966b412bafd1cb7d1c39fe6002dc5cf03264c21.zip |
Merge pull request #8283 from chiragshah6/mdev
bgpd: add seqno in bgp as-path access-list policy
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_filter.c | 132 | ||||
-rw-r--r-- | bgpd/bgp_filter.h | 2 |
2 files changed, 121 insertions, 13 deletions
diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index 316257968..5d1a7a98d 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -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++; } diff --git a/bgpd/bgp_filter.h b/bgpd/bgp_filter.h index 9357a2d38..66c83d97e 100644 --- a/bgpd/bgp_filter.h +++ b/bgpd/bgp_filter.h @@ -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); |