📄 bgp_clist.c
字号:
{ case COMMUNITY_INTERNET: str = "internet"; break; case COMMUNITY_NO_EXPORT: str = "no-export"; break; case COMMUNITY_NO_ADVERTISE: str = "no-advertise"; break; case COMMUNITY_LOCAL_AS: str = "local-AS"; break; default: snprintf (c, sizeof c, "%d:%d", (comval >> 16) & 0xFFFF, comval & 0xFFFF); str = c; break; } if (regexec (reg, str, 0, NULL, 0) == 0) return 1; return 0;}/* Delete all permitted communities in the list from com. */struct community *community_list_match_delete (struct community *com, struct community_list *clist){ int i; u_int32_t comval; struct community *merge; struct community_entry *entry; /* Empty community value check. */ if (! com) return NULL; /* Duplicate communities value. */ merge = community_dup (com); /* For each communities value, we have to check each community-list. */ for (i = 0; i < com->size; i ++) { /* Get one communities value. */ memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t)); comval = ntohl (comval); /* Loop community-list. */ for (entry = clist->head; entry; entry = entry->next) { /* Various match condition check. */ if (entry->any || (entry->style == COMMUNITY_LIST_STANDARD && entry->u.com && community_include (entry->u.com, comval)) || (entry->style == COMMUNITY_LIST_EXPANDED && entry->reg && comval_regexp_match (comval, entry->reg))) { /* If the rule is "permit", delete this community value. */ if (entry->direct == COMMUNITY_PERMIT) community_del_val (merge, com_nthval (com, i)); /* Exit community-list loop, goto next communities value. */ break; } } } return merge;}/* To avoid duplicated entry in the community-list, this function compares specified entry to existing entry. */intcommunity_list_dup_check (struct community_list *list, struct community_entry *new){ struct community_entry *entry; for (entry = list->head; entry; entry = entry->next) { if (entry->style != new->style) continue; if (entry->direct != new->direct) continue; if (entry->any != new->any) continue; if (entry->any) return 1; switch (entry->style) { case COMMUNITY_LIST_STANDARD: if (community_cmp (entry->u.com, new->u.com)) return 1; break; case EXTCOMMUNITY_LIST_STANDARD: if (ecommunity_cmp (entry->u.ecom, new->u.ecom)) return 1; break; case COMMUNITY_LIST_EXPANDED: case EXTCOMMUNITY_LIST_EXPANDED: if (strcmp (entry->config, new->config) == 0) return 1; break; default: break; } } return 0;}/* Set community-list. */intcommunity_list_set (struct community_list_handler *ch, char *name, char *str, int direct, int style){ struct community_entry *entry; struct community_list *list; struct community *com; regex_t *regex; entry = NULL; /* Get community list. */ list = community_list_get (ch, name, style); /* When community-list already has entry, new entry should have same style. If you want to have mixed style community-list, you can comment out this check. */ if (! community_list_empty_p (list)) { struct community_entry *first; first = list->head; if (style == COMMUNITY_LIST_AUTO) style = first->style; else if (style != first->style) { return (first->style == COMMUNITY_LIST_STANDARD ? COMMUNITY_LIST_ERR_STANDARD_CONFLICT : COMMUNITY_LIST_ERR_EXPANDED_CONFLICT); } } /* When str is NULL, it is matches any. */ if (! str) { entry = community_entry_new (); entry->direct = direct; entry->any = 1; if (style == COMMUNITY_LIST_AUTO) entry->style = COMMUNITY_LIST_STANDARD; else entry->style = style; } else { /* Standard community-list parse. String must be converted into community structure without problem. */ if (style == COMMUNITY_LIST_STANDARD || style == COMMUNITY_LIST_AUTO) { com = community_str2com (str); if (com) { entry = community_entry_new (); entry->u.com = com; entry->direct = direct; entry->style = COMMUNITY_LIST_STANDARD; } else if (style == COMMUNITY_LIST_STANDARD) return COMMUNITY_LIST_ERR_MALFORMED_VAL; /* We can't convert string into communities value. When community-list type is auto, fall dawn to regular expression match. */ } /* Expanded community-list parse. String may include regular expression. */ if (! entry && (style == COMMUNITY_LIST_EXPANDED || style == COMMUNITY_LIST_AUTO)) { regex = bgp_regcomp (str); if (regex) { entry = community_entry_new (); entry->reg = regex; entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str); entry->direct = direct; entry->style = COMMUNITY_LIST_EXPANDED; } else return COMMUNITY_LIST_ERR_MALFORMED_VAL; } } /* Do not put duplicated community entry. */ if (community_list_dup_check (list, entry)) community_entry_free (entry); else community_list_entry_add (list, entry); return 0;}/* Unset community-list. When str is NULL, delete all of community-list entry belongs to the specified name. */intcommunity_list_unset (struct community_list_handler *ch, char *name, char *str, int direct, int style){ struct community_entry *entry; struct community_list *list; struct community *com; regex_t *regex; entry = NULL; /* Lookup community list. */ list = community_list_lookup (ch, name, style); if (list == NULL) return COMMUNITY_LIST_ERR_CANT_FIND_LIST; /* Delete all of entry belongs to this community-list. */ if (! str) { community_list_delete (list); return 0; } /* Community list string is specified. Lookup entry from community list. */ if (style == COMMUNITY_LIST_STANDARD || style == COMMUNITY_LIST_AUTO) { com = community_str2com (str); if (com) { entry = community_list_entry_lookup (list, com, direct); community_free (com); } else if (style == COMMUNITY_LIST_STANDARD) return COMMUNITY_LIST_ERR_MALFORMED_VAL; /* If we can't convert string into community and community-list type is auto, fall dawn to expanded community-list. */ } /* Expanded community-list parse. String may include regular expression. */ if (! entry && (style == COMMUNITY_LIST_EXPANDED || style == COMMUNITY_LIST_AUTO)) { regex = bgp_regcomp (str); if (regex) { entry = community_list_entry_lookup (list, str, direct); bgp_regex_free (regex); } else return COMMUNITY_LIST_ERR_MALFORMED_VAL; } if (! entry) return COMMUNITY_LIST_ERR_CANT_FIND_LIST; community_list_entry_delete (list, entry, style); return 0;}/* Set extcommunity-list. */intextcommunity_list_set (struct community_list_handler *ch, char *name, char *str, int direct, int style){ struct community_entry *entry; struct community_list *list; struct ecommunity *ecom; regex_t *regex; entry = NULL; /* Get community list. */ list = community_list_get (ch, name, style); /* When community-list already has entry, new entry should have same style. If you want to have mixed style community-list, you can comment out this check. */ if (! community_list_empty_p (list)) { struct community_entry *first; first = list->head; if (style == EXTCOMMUNITY_LIST_AUTO) style = first->style; else if (style != first->style) { return (first->style == EXTCOMMUNITY_LIST_STANDARD ? COMMUNITY_LIST_ERR_STANDARD_CONFLICT : COMMUNITY_LIST_ERR_EXPANDED_CONFLICT); } } /* When str is NULL, it is matches any. */ if (! str) { entry = community_entry_new (); entry->direct = direct; entry->any = 1; if (style == EXTCOMMUNITY_LIST_AUTO) entry->style = EXTCOMMUNITY_LIST_STANDARD; else entry->style = style; } else { /* Standard extcommunity-list parse. String is converted into ecommunity structure. */ if (style == EXTCOMMUNITY_LIST_STANDARD || style == EXTCOMMUNITY_LIST_AUTO) { /* Type is unknown. String includes keyword. */ ecom = ecommunity_str2com (str, 0, 1); if (ecom) { entry = community_entry_new (); entry->config = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST); ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY); entry->u.ecom = ecom; entry->direct = direct; entry->style = EXTCOMMUNITY_LIST_STANDARD; } else if (style == EXTCOMMUNITY_LIST_STANDARD) return COMMUNITY_LIST_ERR_MALFORMED_VAL; /* We can't convert string into communities value. When community-list type is auto, fall dawn to regular expression match. */ } /* Expanded extcommunity-list parse. String may include regular expression. */ if (! entry && (style == EXTCOMMUNITY_LIST_EXPANDED || style == EXTCOMMUNITY_LIST_AUTO)) { regex = bgp_regcomp (str); if (regex) { entry = community_entry_new (); entry->reg = regex; entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str); entry->direct = direct; entry->style = EXTCOMMUNITY_LIST_EXPANDED; } else return COMMUNITY_LIST_ERR_MALFORMED_VAL; } } /* Do not put duplicated community entry. */ if (community_list_dup_check (list, entry)) community_entry_free (entry); else community_list_entry_add (list, entry); return 0;}/* Unset extcommunity-list. When str is NULL, delete all of extcommunity-list entry belongs to the specified name. */intextcommunity_list_unset (struct community_list_handler *ch, char *name, char *str, int direct, int style){ struct community_entry *entry; struct community_list *list; struct ecommunity *ecom = NULL; regex_t *regex; entry = NULL; /* Lookup extcommunity list. */ list = community_list_lookup (ch, name, style); if (list == NULL) return COMMUNITY_LIST_ERR_CANT_FIND_LIST; /* Delete all of entry belongs to this extcommunity-list. */ if (! str) { community_list_delete (list); return 0; } /* Community list string is specified. Lookup entry from community list. */ if (style == EXTCOMMUNITY_LIST_STANDARD || style == EXTCOMMUNITY_LIST_AUTO) { ecom = ecommunity_str2com (str, 0, 1); if (ecom) { entry = community_list_entry_lookup (list, ecom, direct); ecommunity_free (ecom); } else if (style == COMMUNITY_LIST_STANDARD) return COMMUNITY_LIST_ERR_MALFORMED_VAL; /* If we can't convert string into community and community-list type is auto, fall dawn to expanded community-list. */ } /* Expanded community-list parse. String may include regular expression. */ if (! entry && (style == COMMUNITY_LIST_EXPANDED || style == COMMUNITY_LIST_AUTO)) { regex = bgp_regcomp (str); if (regex) { entry = community_list_entry_lookup (list, str, direct); bgp_regex_free (regex); } else return COMMUNITY_LIST_ERR_MALFORMED_VAL; } if (! entry) return COMMUNITY_LIST_ERR_CANT_FIND_LIST; community_list_entry_delete (list, entry, style); return 0;}/* Initializa community-list. Return community-list handler. */struct community_list_handler *community_list_init (){ struct community_list_handler *ch; ch = XCALLOC (MTYPE_COMMUNITY_LIST_HANDLER, sizeof (struct community_list_handler)); return ch;}/* Terminate community-list. */voidcommunity_list_terminate (struct community_list_handler *ch){ struct community_list_master *cm; struct community_list *list; cm = &ch->community_list; while ((list = cm->num.head) != NULL) community_list_delete (list); while ((list = cm->str.head) != NULL) community_list_delete (list); cm = &ch->extcommunity_list; while ((list = cm->num.head) != NULL) community_list_delete (list); while ((list = cm->str.head) != NULL) community_list_delete (list); XFREE (MTYPE_COMMUNITY_LIST_HANDLER, ch);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -