Skip to content

Commit

Permalink
Merge branch 'FRRouting:master' into avoid-loop
Browse files Browse the repository at this point in the history
  • Loading branch information
lsang6WIND authored Jun 25, 2024
2 parents 6d11dd8 + aeeceef commit fb19324
Show file tree
Hide file tree
Showing 52 changed files with 1,118 additions and 419 deletions.
2 changes: 2 additions & 0 deletions alpine/APKBUILD.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ _libdir=/usr/lib
_user=frr

build() {
export ABUILD_APK_INDEX_OPTS="--allow-untrusted"

cd "$builddir"

./configure \
Expand Down
47 changes: 47 additions & 0 deletions bgpd/bgp_aspath.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ static struct hash *ashash;
/* Stream for SNMP. See aspath_snmp_pathseg */
static struct stream *snmp_stream;

/* as-path orphan exclude list */
static struct as_list_list_head as_exclude_list_orphan;

/* Callers are required to initialize the memory */
static as_t *assegment_data_new(int num)
{
Expand Down Expand Up @@ -1558,6 +1561,38 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
/* Not reached */
}

/* insert aspath exclude in head of orphan exclude list*/
void as_exclude_set_orphan(struct aspath_exclude *ase)
{
ase->exclude_aspath_acl = NULL;
as_list_list_add_head(&as_exclude_list_orphan, ase);
}

void as_exclude_remove_orphan(struct aspath_exclude *ase)
{
if (as_list_list_count(&as_exclude_list_orphan))
as_list_list_del(&as_exclude_list_orphan, ase);
}

/* currently provide only one exclude, not a list */
struct aspath_exclude *as_exclude_lookup_orphan(const char *acl_name)
{
struct aspath_exclude *ase = NULL;
char *name = NULL;

frr_each (as_list_list, &as_exclude_list_orphan, ase) {
if (ase->exclude_aspath_acl_name) {
name = ase->exclude_aspath_acl_name;
if (!strcmp(name, acl_name))
break;
}
}
if (ase)
as_exclude_remove_orphan(ase);

return ase;
}

/* Iterate over AS_PATH segments and wipe all occurrences of the
* listed AS numbers. Hence some segments may lose some or even
* all data on the way, the operation is implemented as a smarter
Expand Down Expand Up @@ -2236,14 +2271,26 @@ void aspath_init(void)
{
ashash = hash_create_size(32768, aspath_key_make, aspath_cmp,
"BGP AS Path");

as_list_list_init(&as_exclude_list_orphan);
}

void aspath_finish(void)
{
struct aspath_exclude *ase;

hash_clean_and_free(&ashash, (void (*)(void *))aspath_free);

if (snmp_stream)
stream_free(snmp_stream);

while ((ase = as_list_list_pop(&as_exclude_list_orphan))) {
aspath_free(ase->aspath);
if (ase->exclude_aspath_acl_name)
XFREE(MTYPE_TMP, ase->exclude_aspath_acl_name);
XFREE(MTYPE_ROUTE_MAP_COMPILED, ase);
}
as_list_list_fini(&as_exclude_list_orphan);
}

/* return and as path value */
Expand Down
7 changes: 7 additions & 0 deletions bgpd/bgp_aspath.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "lib/json.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_filter.h"
#include <typesafe.h>

/* AS path segment type. */
#define AS_SET 1
Expand Down Expand Up @@ -67,11 +68,14 @@ struct aspath {

/* `set as-path exclude ASn' */
struct aspath_exclude {
struct as_list_list_item exclude_list;
struct aspath *aspath;
bool exclude_all;
char *exclude_aspath_acl_name;
struct as_list *exclude_aspath_acl;
};
DECLARE_DLIST(as_list_list, struct aspath_exclude, exclude_list);


/* Prototypes. */
extern void aspath_init(void);
Expand All @@ -83,6 +87,9 @@ extern struct aspath *aspath_parse(struct stream *s, size_t length,
extern struct aspath *aspath_dup(struct aspath *aspath);
extern struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2);
extern struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2);
extern void as_exclude_set_orphan(struct aspath_exclude *ase);
extern void as_exclude_remove_orphan(struct aspath_exclude *ase);
extern struct aspath_exclude *as_exclude_lookup_orphan(const char *acl_name);
extern struct aspath *aspath_filter_exclude(struct aspath *source,
struct aspath *exclude_list);
extern struct aspath *aspath_filter_exclude_all(struct aspath *source);
Expand Down
13 changes: 8 additions & 5 deletions bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2721,17 +2721,20 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args)
}
}

while (length >= 4) {
while (STREAM_READABLE(BGP_INPUT(peer)) >= 4) {
uint16_t subtype = 0;
uint16_t sublength = 0;
struct bgp_attr_encap_subtlv *tlv;

if (BGP_ATTR_ENCAP == type) {
subtype = stream_getc(BGP_INPUT(peer));
sublength = (subtype < 128)
? stream_getc(BGP_INPUT(peer))
: stream_getw(BGP_INPUT(peer));
length -= 2;
if (subtype < 128) {
sublength = stream_getc(BGP_INPUT(peer));
length -= 2;
} else {
sublength = stream_getw(BGP_INPUT(peer));
length -= 3;
}
#ifdef ENABLE_BGP_VNC
} else {
subtype = stream_getw(BGP_INPUT(peer));
Expand Down
41 changes: 25 additions & 16 deletions bgpd/bgp_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_regex.h"

/* List of AS filter list. */
/* List of AS list. */
struct as_list_list {
struct as_list *head;
struct as_list *tail;
Expand Down Expand Up @@ -205,14 +205,6 @@ static struct as_list *as_list_new(void)

static void as_list_free(struct as_list *aslist)
{
struct aspath_exclude_list *cur_bp = aslist->exclude_list;
struct aspath_exclude_list *next_bp = NULL;

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

XFREE (MTYPE_AS_STR, aslist->name);
XFREE (MTYPE_AS_LIST, aslist);
Expand Down Expand Up @@ -299,7 +291,6 @@ static void as_list_delete(struct as_list *aslist)
{
struct as_list_list *list;
struct as_filter *filter, *next;
struct aspath_exclude_list *cur_bp;

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

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

as_list_free(aslist);
}

Expand Down Expand Up @@ -431,6 +416,7 @@ DEFUN(as_path, bgp_as_path_cmd,
enum as_filter_type type;
struct as_filter *asfilter;
struct as_list *aslist;
struct aspath_exclude *ase;
regex_t *regex;
char *regstr;
int64_t seqnum = ASPATH_SEQ_NUMBER_AUTO;
Expand Down Expand Up @@ -482,6 +468,22 @@ DEFUN(as_path, bgp_as_path_cmd,
else
as_list_filter_add(aslist, asfilter);

/* init the exclude rule list*/
as_list_list_init(&aslist->exclude_rule);

/* get aspath orphan exclude that are using this acl */
ase = as_exclude_lookup_orphan(alname);
if (ase) {
as_list_list_add_head(&aslist->exclude_rule, ase);
/* set reverse pointer */
ase->exclude_aspath_acl = aslist;
/* set list of aspath excludes using that acl */
while ((ase = as_exclude_lookup_orphan(alname))) {
as_list_list_add_head(&aslist->exclude_rule, ase);
ase->exclude_aspath_acl = aslist;
}
}

return CMD_SUCCESS;
}

Expand All @@ -502,6 +504,7 @@ DEFUN(no_as_path, no_bgp_as_path_cmd,
enum as_filter_type type;
struct as_filter *asfilter;
struct as_list *aslist;
struct aspath_exclude *ase;
char *regstr;
regex_t *regex;

Expand Down Expand Up @@ -556,6 +559,12 @@ DEFUN(no_as_path, no_bgp_as_path_cmd,

XFREE(MTYPE_TMP, regstr);

/* put aspath exclude list into orphan */
if (as_list_list_count(&aslist->exclude_rule))
while ((ase = as_list_list_pop(&aslist->exclude_rule)))
as_exclude_set_orphan(ase);

as_list_list_fini(&aslist->exclude_rule);
as_list_filter_delete(aslist, asfilter);

return CMD_SUCCESS;
Expand Down
13 changes: 6 additions & 7 deletions bgpd/bgp_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
#ifndef _QUAGGA_BGP_FILTER_H
#define _QUAGGA_BGP_FILTER_H

#include <typesafe.h>

#define ASPATH_SEQ_NUMBER_AUTO -1

enum as_filter_type { AS_FILTER_DENY, AS_FILTER_PERMIT };


/* Element of AS path filter. */
struct as_filter {
struct as_filter *next;
Expand All @@ -25,11 +26,7 @@ struct as_filter {
int64_t seq;
};

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

PREDECL_DLIST(as_list_list);
/* AS path filter list. */
struct as_list {
char *name;
Expand All @@ -39,7 +36,9 @@ struct as_list {

struct as_filter *head;
struct as_filter *tail;
struct aspath_exclude_list *exclude_list;

/* Changes in AS path */
struct as_list_list_head exclude_rule;
};


Expand Down
6 changes: 3 additions & 3 deletions bgpd/bgp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -3438,7 +3438,7 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,
}

len = *data;
if (data + len > end) {
if (data + len + 1 > end) {
zlog_err("%pBP: Received invalid FQDN capability length (host name) %d",
peer, hdr->length);
return;
Expand Down Expand Up @@ -3469,7 +3469,7 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action,

/* domainname */
len = *data;
if (data + len > end) {
if (data + len + 1 > end) {
zlog_err("%pBP: Received invalid FQDN capability length (domain name) %d",
peer, len);
return;
Expand Down Expand Up @@ -3695,7 +3695,7 @@ static void bgp_dynamic_capability_software_version(uint8_t *pnt, int action,
char soft_version[BGP_MAX_SOFT_VERSION + 1] = {};

if (action == CAPABILITY_ACTION_SET) {
if (data + len > end) {
if (data + len + 1 > end) {
zlog_err("%pBP: Received invalid Software Version capability length %d",
peer, len);
return;
Expand Down
4 changes: 2 additions & 2 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -6333,7 +6333,7 @@ void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)

bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
{
if (peer->sort == BGP_PEER_IBGP)
if (peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD)
return true;

if (peer->sort == BGP_PEER_EBGP &&
Expand All @@ -6346,7 +6346,7 @@ bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)

bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
{
if (peer->sort == BGP_PEER_IBGP)
if (peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD)
return true;

if (peer->sort == BGP_PEER_EBGP
Expand Down
Loading

0 comments on commit fb19324

Please sign in to comment.