diff options
Diffstat (limited to 'bgpd/bgp_clist.c')
| -rw-r--r-- | bgpd/bgp_clist.c | 169 |
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); |
