From: Donatas Abraitis Date: Thu, 17 Oct 2024 08:31:10 +0000 (+0300) Subject: bgpd: Add a function to strip non-transitive extended communities X-Git-Tag: base_10.3~320^2~3 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=5ca4656ad79718809600913c41b432a270ef3d29;p=mirror%2Ffrr.git bgpd: Add a function to strip non-transitive extended communities Signed-off-by: Donatas Abraitis --- diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index e0bf196e79..e2292bb963 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -1588,6 +1588,50 @@ bool ecommunity_strip(struct ecommunity *ecom, uint8_t type, return true; } +/* Delete all non-transitive extended communities */ +bool ecommunity_strip_non_transitive(struct ecommunity *ecom) +{ + uint8_t *p, *q, *new; + uint32_t c, found = 0; + + if (!ecom || !ecom->val) + return false; + + /* Certain extended communities like the Route Target can be present + * multiple times, handle that. + */ + c = 0; + for (p = ecom->val; c < ecom->size; p += ecom->unit_size, c++) + if (CHECK_FLAG(*p, ECOMMUNITY_FLAG_NON_TRANSITIVE)) + found++; + + if (!found) + return false; + + /* Handle the case where everything needs to be stripped. */ + if (found == ecom->size) { + XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val); + ecom->size = 0; + return true; + } + + /* Strip extended communities with non-transitive flag set */ + new = XMALLOC(MTYPE_ECOMMUNITY_VAL, (ecom->size - found) * ecom->unit_size); + q = new; + for (c = 0, p = ecom->val; c < ecom->size; c++, p += ecom->unit_size) { + if (!CHECK_FLAG(*p, ECOMMUNITY_FLAG_NON_TRANSITIVE)) { + memcpy(q, p, ecom->unit_size); + q += ecom->unit_size; + } + } + + XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val); + ecom->val = new; + ecom->size -= found; + + return true; +} + /* * Remove specified extended community value from extended community. * Returns 1 if value was present (and hence, removed), 0 otherwise. diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index 67c16aeb9e..e076885fb5 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -398,6 +398,7 @@ extern struct ecommunity *ecommunity_new(void); 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 bool ecommunity_del_val(struct ecommunity *ecom, struct ecommunity_val *eval); struct bgp_pbr_entry_action;