Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: fix no bgp as-path access-list issue #15385

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions bgpd/bgp_aspath.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ struct aspath {

#define ASPATH_STR_DEFAULT_LEN 32

/* `set as-path exclude ASn' */
struct aspath_exclude {
struct aspath *aspath;
bool exclude_all;
char *exclude_aspath_acl_name;
struct as_list *exclude_aspath_acl;
};


/* Prototypes. */
extern void aspath_init(void);
extern void aspath_finish(void);
Expand Down
18 changes: 18 additions & 0 deletions bgpd/bgp_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,17 @@ static struct as_list *as_list_new(void)

static void as_list_free(struct as_list *aslist)
{
struct bp_as_excl_list *cur_bp = aslist->bp_list;
struct bp_as_excl_list *next_bp = NULL;
XFREE(MTYPE_AS_STR, aslist->name);
XFREE(MTYPE_AS_LIST, aslist);

while(cur_bp) {
next_bp = cur_bp->next;
XFREE(MTYPE_ROUTE_MAP_COMPILED, cur_bp);
cur_bp = next_bp;
}

}

/* Insert new AS list to list of as_list. Each as_list is sorted by
Expand Down Expand Up @@ -290,6 +299,7 @@ static void as_list_delete(struct as_list *aslist)
{
struct as_list_list *list;
struct as_filter *filter, *next;
struct bp_as_excl_list *cur_bp;

for (filter = aslist->head; filter; filter = next) {
next = filter->next;
Expand All @@ -308,6 +318,14 @@ static void as_list_delete(struct as_list *aslist)
else
list->head = aslist->next;

cur_bp = aslist->bp_list;
while (cur_bp) {
cur_bp->bp_as_excl->exclude_aspath_acl = NULL;
cur_bp = cur_bp->next;
}



as_list_free(aslist);
}

Expand Down
9 changes: 9 additions & 0 deletions bgpd/bgp_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ struct as_filter {
int64_t seq;
};


struct bp_as_excl_list {
struct bp_as_excl_list *next;
struct aspath_exclude *bp_as_excl;
};


/* AS path filter list. */
struct as_list {
char *name;
Expand All @@ -34,6 +41,8 @@ struct as_list {

struct as_filter *head;
struct as_filter *tail;
/* back pointer to the aspath_excludes */
struct bp_as_excl_list *bp_list;
};


Expand Down
30 changes: 22 additions & 8 deletions bgpd/bgp_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2323,17 +2323,10 @@ static const struct route_map_rule_cmd route_set_aspath_prepend_cmd = {
route_set_aspath_prepend_free,
};

/* `set as-path exclude ASn' */
struct aspath_exclude {
struct aspath *aspath;
bool exclude_all;
char *exclude_aspath_acl_name;
struct as_list *exclude_aspath_acl;
};

static void *route_aspath_exclude_compile(const char *arg)
{
struct aspath_exclude *ase;
struct bp_as_excl_list *bp;
const char *str = arg;
static const char asp_acl[] = "as-path-access-list";

Expand All @@ -2348,16 +2341,37 @@ static void *route_aspath_exclude_compile(const char *arg)
ase->exclude_aspath_acl = as_list_lookup(str);
} else
ase->aspath = aspath_str2aspath(str, bgp_get_asnotation(NULL));

if (ase->exclude_aspath_acl) {
bp = XCALLOC(MTYPE_ROUTE_MAP_COMPILED,
sizeof(struct bp_as_excl_list));
bp->bp_as_excl = ase;
bp->next = ase->exclude_aspath_acl->bp_list;
ase->exclude_aspath_acl->bp_list = bp;
}


return ase;
}

static void route_aspath_exclude_free(void *rule)
{
struct aspath_exclude *ase = rule;
struct bp_as_excl_list *cur_bp = NULL;
struct bp_as_excl_list *prev_bp = NULL;

aspath_free(ase->aspath);
if (ase->exclude_aspath_acl_name)
XFREE(MTYPE_TMP, ase->exclude_aspath_acl_name);
if (ase->exclude_aspath_acl)
cur_bp = ase->exclude_aspath_acl->bp_list;
while (cur_bp) {
if (cur_bp->bp_as_excl == ase) {
cur_bp = prev_bp;
XFREE(MTYPE_ROUTE_MAP_COMPILED, cur_bp);
break;
}
}
XFREE(MTYPE_ROUTE_MAP_COMPILED, ase);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# pylint: disable=C0413
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from time import sleep


pytestmark = [pytest.mark.bgpd]
Expand Down Expand Up @@ -134,12 +135,66 @@ def _bgp_regexp_1(router):
}
}

# tgen.mininet_cli()
test_func = functools.partial(_bgp_regexp_1, tgen.gears["r1"])
_, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)

assert result is None, "Failed overriding incoming AS-PATH with regex 2 route-map"


def test_no_bgp_set_aspath_exclude_access_list():
tgen = get_topogen()

if tgen.routers_have_failure():
pytest.skip(tgen.errors)

rname = "r1"
r1 = tgen.gears[rname]

r1.vtysh_cmd(
"""
conf
no bgp as-path access-list SECOND permit 2
"""
)

expected = {
"routes": {
"172.16.255.31/32": [{"path": "65003"}],
"172.16.255.32/32": [{"path": "65003"}],
}
}

def _bgp_regexp_2(router):
output = json.loads(router.vtysh_cmd("show bgp ipv4 unicast json"))

return topotest.json_cmp(output, expected)

test_func = functools.partial(_bgp_regexp_2, tgen.gears["r1"])
_, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)

assert result is None, "Failed removing bgp as-path access-list"

r1.vtysh_cmd(
"""
clear bgp *
"""
)

expected = {
"routes": {
"172.16.255.31/32": [{"path": "65002 65003"}],
"172.16.255.32/32": [{"path": "65002 65003"}],
}
}
sleep(10)

test_func = functools.partial(_bgp_regexp_2, tgen.gears["r1"])
_, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)

assert result is None, "Failed to renegociate with peers"


if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
Loading