mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
bgpd: Add function to filter extended communities
Support filtering extended communities with a callback. So that we can strip multiple values in one pass. Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
This commit is contained in:
parent
3da1473093
commit
f84e89ec0d
|
@ -1712,6 +1712,46 @@ bool ecommunity_strip_non_transitive(struct ecommunity *ecom)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Filter source Extended Communities Attribute. May return NULL if the result
|
||||
* is empty, or the source ecommunity, if not modified.
|
||||
*/
|
||||
struct ecommunity *ecommunity_filter(struct ecommunity *ecom,
|
||||
bool (*filter)(uint8_t *, uint8_t, void *), void *arg)
|
||||
{
|
||||
struct ecommunity *new;
|
||||
uint8_t *new_val, *p, *q;
|
||||
uint32_t c, new_size;
|
||||
|
||||
if (!ecom || !ecom->size)
|
||||
return NULL;
|
||||
|
||||
new_val = XMALLOC(MTYPE_ECOMMUNITY_VAL, ecom->size * ecom->unit_size);
|
||||
new_size = 0;
|
||||
for (c = 0, p = ecom->val, q = new_val; c < ecom->size; c++, p += ecom->unit_size) {
|
||||
if (filter(p, ecom->unit_size, arg)) {
|
||||
memcpy(q, p, ecom->unit_size);
|
||||
q += ecom->unit_size;
|
||||
new_size++;
|
||||
}
|
||||
}
|
||||
if (!new_size) {
|
||||
XFREE(MTYPE_ECOMMUNITY_VAL, new_val);
|
||||
return NULL;
|
||||
}
|
||||
if (new_size == ecom->size) {
|
||||
XFREE(MTYPE_ECOMMUNITY_VAL, new_val);
|
||||
return ecom;
|
||||
}
|
||||
|
||||
new = XCALLOC(MTYPE_ECOMMUNITY, sizeof(struct ecommunity));
|
||||
new->size = new_size;
|
||||
new->unit_size = ecom->unit_size;
|
||||
new->val = new_val;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove specified extended community value from extended community.
|
||||
* Returns 1 if value was present (and hence, removed), 0 otherwise.
|
||||
|
|
|
@ -405,6 +405,9 @@ extern bool ecommunity_strip(struct ecommunity *ecom, uint8_t type,
|
|||
uint8_t subtype);
|
||||
extern struct ecommunity *ecommunity_new(void);
|
||||
extern bool ecommunity_strip_non_transitive(struct ecommunity *ecom);
|
||||
extern struct ecommunity *ecommunity_filter(struct ecommunity *ecom,
|
||||
bool (*filter)(uint8_t *val, uint8_t usize, void *arg),
|
||||
void *arg);
|
||||
extern bool ecommunity_del_val(struct ecommunity *ecom,
|
||||
struct ecommunity_val *eval);
|
||||
struct bgp_pbr_entry_action;
|
||||
|
|
Loading…
Reference in a new issue