summaryrefslogtreecommitdiff
path: root/bgpd/bgp_clist.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_clist.c')
-rw-r--r--bgpd/bgp_clist.c169
1 files changed, 96 insertions, 73 deletions
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index 1d2ba3bf58..8336d6f311 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -128,6 +128,7 @@ static void community_entry_free(struct community_entry *entry)
XFREE(MTYPE_COMMUNITY_LIST_CONFIG, entry->config);
if (entry->reg)
bgp_regex_free(entry->reg);
+ break;
default:
break;
}
@@ -449,13 +450,6 @@ static char *community_str_get(struct community *com, int i)
comval = ntohl(comval);
switch (comval) {
-#if CONFDATE > 20230801
-CPP_NOTICE("Deprecate COMMUNITY_INTERNET BGP community")
-#endif
- case COMMUNITY_INTERNET:
- str = XSTRDUP(MTYPE_COMMUNITY_STR, "internet");
- zlog_warn("`internet` community is deprecated");
- break;
case COMMUNITY_GSHUT:
str = XSTRDUP(MTYPE_COMMUNITY_STR, "graceful-shutdown");
break;
@@ -659,13 +653,7 @@ bool community_list_match(struct community *com, struct community_list *list)
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next) {
- if (entry->any)
- return entry->direct == COMMUNITY_PERMIT;
-
if (entry->style == COMMUNITY_LIST_STANDARD) {
- if (community_include(entry->u.com, COMMUNITY_INTERNET))
- return entry->direct == COMMUNITY_PERMIT;
-
if (community_match(com, entry->u.com))
return entry->direct == COMMUNITY_PERMIT;
} else if (entry->style == COMMUNITY_LIST_EXPANDED) {
@@ -681,9 +669,6 @@ bool lcommunity_list_match(struct lcommunity *lcom, struct community_list *list)
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next) {
- if (entry->any)
- return entry->direct == COMMUNITY_PERMIT;
-
if (entry->style == LARGE_COMMUNITY_LIST_STANDARD) {
if (lcommunity_match(lcom, entry->u.lcom))
return entry->direct == COMMUNITY_PERMIT;
@@ -705,9 +690,6 @@ bool lcommunity_list_exact_match(struct lcommunity *lcom,
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next) {
- if (entry->any)
- return entry->direct == COMMUNITY_PERMIT;
-
if (entry->style == LARGE_COMMUNITY_LIST_STANDARD) {
if (lcommunity_cmp(lcom, entry->u.lcom))
return entry->direct == COMMUNITY_PERMIT;
@@ -724,9 +706,6 @@ bool ecommunity_list_match(struct ecommunity *ecom, struct community_list *list)
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next) {
- if (entry->any)
- return entry->direct == COMMUNITY_PERMIT;
-
if (entry->style == EXTCOMMUNITY_LIST_STANDARD) {
if (ecommunity_match(ecom, entry->u.ecom))
return entry->direct == COMMUNITY_PERMIT;
@@ -746,13 +725,7 @@ bool community_list_exact_match(struct community *com,
struct community_entry *entry;
for (entry = list->head; entry; entry = entry->next) {
- if (entry->any)
- return entry->direct == COMMUNITY_PERMIT;
-
if (entry->style == COMMUNITY_LIST_STANDARD) {
- if (community_include(entry->u.com, COMMUNITY_INTERNET))
- return entry->direct == COMMUNITY_PERMIT;
-
if (community_cmp(com, entry->u.com))
return entry->direct == COMMUNITY_PERMIT;
} else if (entry->style == COMMUNITY_LIST_EXPANDED) {
@@ -763,6 +736,27 @@ bool community_list_exact_match(struct community *com,
return false;
}
+bool community_list_any_match(struct community *com, struct community_list *list)
+{
+ struct community_entry *entry;
+ uint32_t val;
+ int i;
+
+ for (i = 0; i < com->size; i++) {
+ val = community_val_get(com, i);
+
+ for (entry = list->head; entry; entry = entry->next) {
+ if (entry->style == COMMUNITY_LIST_STANDARD &&
+ community_include(entry->u.com, val))
+ return entry->direct == COMMUNITY_PERMIT;
+ if ((entry->style == COMMUNITY_LIST_EXPANDED) &&
+ community_regexp_include(entry->reg, com, i))
+ return entry->direct == COMMUNITY_PERMIT;
+ }
+ }
+ return false;
+}
+
/* Delete all permitted communities in the list from com. */
struct community *community_list_match_delete(struct community *com,
struct community_list *list)
@@ -781,28 +775,15 @@ struct community *community_list_match_delete(struct community *com,
val = community_val_get(com, i);
for (entry = list->head; entry; entry = entry->next) {
- if (entry->any) {
- if (entry->direct == COMMUNITY_PERMIT) {
- com_index_to_delete[delete_index] = i;
- delete_index++;
- }
- break;
- }
-
- else if ((entry->style == COMMUNITY_LIST_STANDARD)
- && (community_include(entry->u.com,
- COMMUNITY_INTERNET)
- || community_include(entry->u.com, val))) {
+ if ((entry->style == COMMUNITY_LIST_STANDARD) &&
+ community_include(entry->u.com, val)) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
break;
- }
-
- else if ((entry->style == COMMUNITY_LIST_EXPANDED)
- && community_regexp_include(entry->reg, com,
- i)) {
+ } else if ((entry->style == COMMUNITY_LIST_EXPANDED) &&
+ community_regexp_include(entry->reg, com, i)) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
@@ -836,12 +817,6 @@ static bool community_list_dup_check(struct community_list *list,
if (entry->direct != new->direct)
continue;
- if (entry->any != new->any)
- continue;
-
- if (entry->any)
- return true;
-
switch (entry->style) {
case COMMUNITY_LIST_STANDARD:
if (community_cmp(entry->u.com, new->u.com))
@@ -899,20 +874,17 @@ int community_list_set(struct community_list_handler *ch, const char *name,
}
}
- if (str) {
- if (style == COMMUNITY_LIST_STANDARD)
- com = community_str2com(str);
- else
- regex = bgp_regcomp(str);
+ if (style == COMMUNITY_LIST_STANDARD)
+ com = community_str2com(str);
+ else
+ regex = bgp_regcomp(str);
- if (!com && !regex)
- return COMMUNITY_LIST_ERR_MALFORMED_VAL;
- }
+ if (!com && !regex)
+ return COMMUNITY_LIST_ERR_MALFORMED_VAL;
entry = community_entry_new();
entry->direct = direct;
entry->style = style;
- entry->any = (str ? false : true);
entry->u.com = com;
entry->reg = regex;
entry->seq = seqnum;
@@ -972,6 +944,28 @@ int community_list_unset(struct community_list_handler *ch, const char *name,
return 0;
}
+bool lcommunity_list_any_match(struct lcommunity *lcom,
+ struct community_list *list)
+{
+ struct community_entry *entry;
+ uint8_t *ptr;
+ int i;
+
+ for (i = 0; i < lcom->size; i++) {
+ ptr = lcom->val + (i * LCOMMUNITY_SIZE);
+
+ for (entry = list->head; entry; entry = entry->next) {
+ if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD) &&
+ lcommunity_include(entry->u.lcom, ptr))
+ return entry->direct == COMMUNITY_PERMIT;
+ if ((entry->style == LARGE_COMMUNITY_LIST_EXPANDED) &&
+ lcommunity_regexp_include(entry->reg, lcom, i))
+ return entry->direct == COMMUNITY_PERMIT;
+ }
+ }
+ return false;
+}
+
/* Delete all permitted large communities in the list from com. */
struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
struct community_list *list)
@@ -989,7 +983,8 @@ struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
for (i = 0; i < lcom->size; i++) {
ptr = lcom->val + (i * LCOMMUNITY_SIZE);
for (entry = list->head; entry; entry = entry->next) {
- if (entry->any) {
+ if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD) &&
+ lcommunity_include(entry->u.lcom, ptr)) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
@@ -997,18 +992,47 @@ struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
break;
}
- else if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD)
- && lcommunity_include(entry->u.lcom, ptr)) {
+ else if ((entry->style ==
+ LARGE_COMMUNITY_LIST_EXPANDED) &&
+ lcommunity_regexp_include(entry->reg, lcom,
+ i)) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
}
break;
}
+ }
+ }
- else if ((entry->style == LARGE_COMMUNITY_LIST_EXPANDED)
- && lcommunity_regexp_include(entry->reg, lcom,
- i)) {
+ /* Delete all of the communities we flagged for deletion */
+ for (i = delete_index - 1; i >= 0; i--) {
+ ptr = lcom->val + (com_index_to_delete[i] * LCOMMUNITY_SIZE);
+ lcommunity_del_val(lcom, ptr);
+ }
+
+ return lcom;
+}
+
+/* Delete all permitted extended communities in the list from ecom.*/
+struct ecommunity *ecommunity_list_match_delete(struct ecommunity *ecom,
+ struct community_list *list)
+{
+ struct community_entry *entry;
+ uint32_t com_index_to_delete[ecom->size];
+ uint8_t *ptr;
+ uint32_t delete_index = 0;
+ uint32_t i;
+ struct ecommunity local_ecom = {.size = 1};
+ struct ecommunity_val local_eval = {0};
+
+ for (i = 0; i < ecom->size; i++) {
+ local_ecom.val = ecom->val + (i * ECOMMUNITY_SIZE);
+ for (entry = list->head; entry; entry = entry->next) {
+ if (((entry->style == EXTCOMMUNITY_LIST_STANDARD) &&
+ ecommunity_include(entry->u.ecom, &local_ecom)) ||
+ ((entry->style == EXTCOMMUNITY_LIST_EXPANDED) &&
+ ecommunity_regexp_match(ecom, entry->reg))) {
if (entry->direct == COMMUNITY_PERMIT) {
com_index_to_delete[delete_index] = i;
delete_index++;
@@ -1018,13 +1042,14 @@ struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
}
}
- /* Delete all of the communities we flagged for deletion */
- for (i = delete_index - 1; i >= 0; i--) {
- ptr = lcom->val + (com_index_to_delete[i] * LCOMMUNITY_SIZE);
- lcommunity_del_val(lcom, ptr);
+ /* Delete all of the extended communities we flagged for deletion */
+ for (i = delete_index; i > 0; i--) {
+ ptr = ecom->val + (com_index_to_delete[i-1] * ECOMMUNITY_SIZE);
+ memcpy(&local_eval.val, ptr, sizeof(local_eval.val));
+ ecommunity_del_val(ecom, &local_eval);
}
- return lcom;
+ return ecom;
}
/* Helper to check if every octet do not exceed UINT_MAX */
@@ -1127,7 +1152,6 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name,
entry = community_entry_new();
entry->direct = direct;
entry->style = style;
- entry->any = (str ? false : true);
entry->u.lcom = lcom;
entry->reg = regex;
entry->seq = seqnum;
@@ -1248,7 +1272,6 @@ int extcommunity_list_set(struct community_list_handler *ch, const char *name,
entry = community_entry_new();
entry->direct = direct;
entry->style = style;
- entry->any = false;
if (ecom)
entry->config = ecommunity_ecom2str(
ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0);