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

📄 bgp_clist.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
    {    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 + -