⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bgp_clist.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 2 页
字号:
	}      else if (entry->style == EXTCOMMUNITY_LIST_EXPANDED)	{	  if (ecommunity_regexp_match (ecom, entry->reg))	    return entry->direct == COMMUNITY_PERMIT ? 1 : 0;	}    }  return 0;}/* Perform exact matching.  In case of expanded community-list, do   same thing as community_list_match().  */intcommunity_list_exact_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 ? 1 : 0;      if (entry->style == COMMUNITY_LIST_STANDARD)	{	  if (community_include (entry->u.com, COMMUNITY_INTERNET))	    return entry->direct == COMMUNITY_PERMIT ? 1 : 0;	  if (community_cmp (com, entry->u.com))	    return entry->direct == COMMUNITY_PERMIT ? 1 : 0;	}      else if (entry->style == COMMUNITY_LIST_EXPANDED)	{	  if (community_regexp_match (com, entry->reg))	    return entry->direct == COMMUNITY_PERMIT ? 1 : 0;	}    }  return 0;}/* Do regular expression matching with single community val.  */static intcomval_regexp_match (u_int32_t comval, regex_t *reg){  /* Maximum is "65535:65535" + '\0'. */  char c[12];  char *str;  switch (comval)    {    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 = NULL;  struct community_list *list;  struct community *com = NULL;  regex_t *regex = NULL;  /* Get community list. */  list = community_list_get (ch, name, COMMUNITY_LIST_MASTER);  /* 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 != first->style)	{	  return (first->style == COMMUNITY_LIST_STANDARD		  ? COMMUNITY_LIST_ERR_STANDARD_CONFLICT		  : COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);	}    }  if (str)    {      if (style == COMMUNITY_LIST_STANDARD)	com = community_str2com (str);      else	regex = bgp_regcomp (str);      if (! com && ! regex)	return COMMUNITY_LIST_ERR_MALFORMED_VAL;    }  entry = community_entry_new ();  entry->direct = direct;  entry->style = style;  entry->any = (str ? 0 : 1);  entry->u.com = com;  entry->reg = regex;  entry->config = (regex ? XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str) : NULL);  /* 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 = NULL;  struct community_list *list;  struct community *com = NULL;  regex_t *regex = NULL;  /* Lookup community list.  */  list = community_list_lookup (ch, name, COMMUNITY_LIST_MASTER);  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;    }  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)    entry = community_list_entry_lookup (list, com, direct);  else    entry = community_list_entry_lookup (list, str, direct);  if (com)    community_free (com);  if (regex)    bgp_regex_free (regex);  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 = NULL;  struct community_list *list;  struct ecommunity *ecom = NULL;  regex_t *regex = NULL;  entry = NULL;  /* Get community list. */  list = community_list_get (ch, name, EXTCOMMUNITY_LIST_MASTER);  /* 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 != first->style)	{	  return (first->style == EXTCOMMUNITY_LIST_STANDARD		  ? COMMUNITY_LIST_ERR_STANDARD_CONFLICT		  : COMMUNITY_LIST_ERR_EXPANDED_CONFLICT);	}    }  if (str)    {      if (style == EXTCOMMUNITY_LIST_STANDARD)	ecom = ecommunity_str2com (str, 0, 1);      else	regex = bgp_regcomp (str);      if (! ecom && ! regex)	return COMMUNITY_LIST_ERR_MALFORMED_VAL;    }  if (ecom)    ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_DISPLAY);  entry = community_entry_new ();  entry->direct = direct;  entry->style = style;  entry->any = (str ? 0 : 1);  if (ecom)    entry->config = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_CONFIG);  else if (regex)    entry->config = XSTRDUP (MTYPE_COMMUNITY_LIST_CONFIG, str);  else    entry->config = NULL;  entry->u.ecom = ecom;  entry->reg = regex;  /* 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 = NULL;  struct community_list *list;  struct ecommunity *ecom = NULL;  regex_t *regex = NULL;  /* Lookup extcommunity list.  */  list = community_list_lookup (ch, name, EXTCOMMUNITY_LIST_MASTER);  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;    }  if (style == EXTCOMMUNITY_LIST_STANDARD)    ecom = ecommunity_str2com (str, 0, 1);  else    regex = bgp_regcomp (str);  if (! ecom && ! regex)    return COMMUNITY_LIST_ERR_MALFORMED_VAL;  if (ecom)    entry = community_list_entry_lookup (list, ecom, direct);  else    entry = community_list_entry_lookup (list, str, direct);  if (ecom)    ecommunity_free (ecom);  if (regex)    bgp_regex_free (regex);  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 + -