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

📄 bgp_ecommunity.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Convert string to extended community attribute.    When type is already known, please specify both str and type.  str   should not include keyword such as "rt" and "soo".  Type is   ECOMMUNITY_TYPE_ROUTE_TARGET or ECOMMUNITY_TYPE_SITE_ORIGIN.   keyword_included should be zero.   For example route-map's "set extcommunity" command case:   "rt 100:1 100:2 100:3"        -> str = "100:1 100:2 100:3"                                    type = ECOMMUNITY_TYPE_ROUTE_TARGET                                    keyword_included = 0   "soo 100:1"                   -> str = "100:1"                                    type = ECOMMUNITY_TYPE_SITE_ORIGIN                                    keyword_included = 0   When string includes keyword for each extended community value.   Please specify keyword_included as non-zero value.   For example standard extcommunity-list case:   "rt 100:1 rt 100:2 soo 100:1" -> str = "rt 100:1 rt 100:2 soo 100:1"                                    type = 0                                    keyword_include = 1*/struct ecommunity *ecommunity_str2com (char *str, int type, int keyword_included){  struct ecommunity *ecom = NULL;  enum ecommunity_token token;  struct ecommunity_val eval;  int keyword = 0;  while ((str = ecommunity_gettoken (str, &eval, &token)))    {      switch (token)	{	case ecommunity_token_rt:	case ecommunity_token_soo:	  if (! keyword_included || keyword)	    {	      if (ecom)		ecommunity_free (ecom);	      return NULL;	    }	  keyword = 1;	  if (token == ecommunity_token_rt)	    {	      type = ECOMMUNITY_TYPE_ROUTE_TARGET;	    }	  if (token == ecommunity_token_soo)	    {	      type = ECOMMUNITY_TYPE_SITE_ORIGIN;	    }	  break;	case ecommunity_token_val:	  if (keyword_included)	    {	      if (! keyword)		{		  if (ecom)		    ecommunity_free (ecom);		  return NULL;		}	      keyword = 0;	    }	  if (ecom == NULL)	    ecom = ecommunity_new ();	  eval.val[1] = type;	  ecommunity_add_val (ecom, &eval);	  break;	case ecommunity_token_unknown:	default:	  if (ecom)	    ecommunity_free (ecom);	  return NULL;	  break;	}    }  return ecom;}struct ecommunity *ecommunity_cost_str2com (char *str, u_char poi){  struct ecommunity *ecom = NULL;  struct ecommunity_cost ecost;  u_int32_t id = 0;  u_int32_t val = 0;  char *p = str;  while (isspace ((int) *p))    p++;  while (isdigit ((int) *p))    {      id *= 10;      id += (*p - '0');      p++;    }  while (isspace ((int) *p))    p++;  while (isdigit ((int) *p))    {      val *= 10;      val += (*p - '0');      p++;    }  ecost.type = ntohs (ECOMMUNITY_COST_COMMUNITY);  ecost.poi = poi;  ecost.id = id;  ecost.val = ntohl (val);  ecom = ecommunity_new ();  ecommunity_add_val (ecom, (struct ecommunity_val *)&ecost);  return ecom;}/* Convert extended community attribute to string.     Due to historical reason of industry standard implementation, there   are three types of format.   route-map set extcommunity format        "rt 100:1 100:2"        "soo 100:3"   extcommunity-list        "rt 100:1 rt 100:2 soo 100:3"   "show ip bgp" and extcommunity-list regular expression matching        "RT:100:1 RT:100:2 SoO:100:3"   For each formath please use below definition for format:   ECOMMUNITY_FORMAT_CONFIG   ECOMMUNITY_FORMAT_DISPLAY*/char *ecommunity_cost_poi_print (u_char poi){  if (poi == ECOMMUNITY_COST_POI_IGP)    return "igp";  return "?";}char *ecommunity_ecom2str (struct ecommunity *ecom, int format){  int i;  u_char *pnt;  int encode = 0;  int encode_check = 0;  int type = 0;#define ECOMMUNITY_STR_DEFAULT_LEN  26  int str_size;  int str_pnt;  u_char *str_buf;  char *prefix;  int len = 0;  int first = 1;  /* For parse Extended Community attribute tupple. */  struct ecommunity_as  {    as_t as;    u_int32_t val;  } eas;  struct ecommunity_ip  {    struct in_addr ip;    u_int16_t val;  } eip;  if (ecom->size == 0)    {      str_buf = XMALLOC (MTYPE_ECOMMUNITY_STR, 1);      str_buf[0] = '\0';      return str_buf;    }  /* Prepare buffer.  */  str_buf = XMALLOC (MTYPE_ECOMMUNITY_STR, ECOMMUNITY_STR_DEFAULT_LEN + 1);  str_size = ECOMMUNITY_STR_DEFAULT_LEN + 1;  str_pnt = 0;  for (i = 0; i < ecom->size; i++)    {      /* Make it sure size is enough.  */      while (str_pnt + ECOMMUNITY_STR_DEFAULT_LEN >= str_size)	{	  str_size *= 2;	  str_buf = XREALLOC (MTYPE_ECOMMUNITY_STR, str_buf, str_size);	}      /* Space between each value.  */      if (! first)	str_buf[str_pnt++] = ' ';      pnt = ecom->val + (i * 8);      /* High-order octet of type. */      encode = *pnt++;      encode_check = encode & ~ECOMMUNITY_FLAG_NON_TRANSITIVE;      if (encode_check != ECOMMUNITY_ENCODE_AS          && encode_check != ECOMMUNITY_ENCODE_IP          && encode_check != ECOMMUNITY_ENCODE_OPAQUE)	{	  len = sprintf (str_buf + str_pnt, "?");	  str_pnt += len;	  first = 0;	  continue;	}            /* Low-order octet of type. */      type = *pnt++;      if ((encode_check == ECOMMUNITY_ENCODE_AS	   || encode_check == ECOMMUNITY_ENCODE_IP	   || encode_check == ECOMMUNITY_ENCODE_4OCTET_AS)	  && (type == ECOMMUNITY_TYPE_ROUTE_TARGET || type == ECOMMUNITY_TYPE_SITE_ORIGIN)	  && ! CHECK_FLAG (encode, ECOMMUNITY_FLAG_NON_TRANSITIVE))	{	  switch (format)	    {	      case ECOMMUNITY_FORMAT_CONFIG:		prefix = (type == ECOMMUNITY_TYPE_ROUTE_TARGET ? "rt " : "soo ");		break;	      case ECOMMUNITY_FORMAT_DISPLAY:		prefix = (type == ECOMMUNITY_TYPE_ROUTE_TARGET ? "RT:" : "SoO:");		break;	      default:		prefix = "";		break;	    }	}      else if (encode_check == ECOMMUNITY_ENCODE_OPAQUE	       && type == ECOMMUNITY_TYPE_COST_COMMUNITY	       && CHECK_FLAG (encode, ECOMMUNITY_FLAG_NON_TRANSITIVE))	{	  u_int32_t val;	  u_char poi;	  u_char id;          poi = *pnt++;	  id =  *pnt++;	  memcpy (&val, pnt, 4);	  len = sprintf (str_buf + str_pnt, "Cost:%s:%d:%u",			 ecommunity_cost_poi_print (poi), id, ntohl (val));	  str_pnt += len;	  first = 0;	  continue;	}      else	{	  len = sprintf (str_buf + str_pnt, "?");	  str_pnt += len;	  first = 0;	  continue;	}      /* Put string into buffer.  */      if (encode_check == ECOMMUNITY_ENCODE_AS)	{	  eas.as = (*pnt++ << 8);	  eas.as |= (*pnt++);	  eas.val = (*pnt++ << 24);	  eas.val |= (*pnt++ << 16);	  eas.val |= (*pnt++ << 8);	  eas.val |= (*pnt++);	  len = sprintf (str_buf + str_pnt, "%s%d:%d", prefix,			 eas.as, eas.val);	  str_pnt += len;	  first = 0;	}      else if (encode_check == ECOMMUNITY_ENCODE_IP)	{	  memcpy (&eip.ip, pnt, 4);	  pnt += 4;	  eip.val = (*pnt++ << 8);	  eip.val |= (*pnt++);	  len = sprintf (str_buf + str_pnt, "%s%s:%d", prefix,			 inet_ntoa (eip.ip), eip.val);	  str_pnt += len;	  first = 0;	}    }  return str_buf;}intecommunity_match (struct ecommunity *ecom1, struct ecommunity *ecom2){  int i = 0;  int j = 0;  if (ecom1 == NULL && ecom2 == NULL)    return 1;  if (ecom1 == NULL || ecom2 == NULL)    return 0;  if (ecom1->size < ecom2->size)    return 0;  /* Every community on com2 needs to be on com1 for this to match */  while (i < ecom1->size && j < ecom2->size)    {      if (memcmp (ecom1->val + i, ecom2->val + j, ECOMMUNITY_SIZE) == 0)        j++;      i++;    }  if (j == ecom2->size)    return 1;  else    return 0;}intecommunity_cost_cmp (struct ecommunity *ecom1, struct ecommunity *ecom2, u_char poi){  int i = 0;  int j = 0;  int find1 = 0;  int find2 = 0;  u_char id1 = 0;  u_char id2 = 0;  u_int32_t val1 = 0;  u_int32_t val2 = 0;  /* For parse Extended Community attribute tupple. */  struct ecommunity_cost  {    u_int16_t type;    u_char poi;    u_char id;    u_int32_t val;  } ecost;  if (ecom1 == NULL && ecom2 == NULL)    return 0;  while (1)    {      while (ecom1 && i < ecom1->size)	{	  memcpy (&ecost, (ecom1->val + (i * 8)), sizeof (struct ecommunity_cost));	  if (ntohs (ecost.type) == ECOMMUNITY_COST_COMMUNITY	      && ecost.poi == poi)	    {	      id1 = ecost.id;	      val1 = ntohl (ecost.val);	      find1 = 1;	      break;	    }	  i++;	}      while (ecom2 && j < ecom2->size)	{	  memcpy (&ecost, ecom2->val + (j * 8), sizeof (struct ecommunity_cost));	  if (ntohs (ecost.type) == ECOMMUNITY_COST_COMMUNITY	      && ecost.poi == poi)	    {	      id2 = ecost.id;	      val2 = ntohl (ecost.val);	      find2 = 1;	      break;	    }	  j++;	}      if (! find1 || ! find2)	break;      if (id1 != id2)	break;      if (val1 != val2)	break;      find1 = 0;      find2 = 0;      i++;      j++;    }  if (! find1)    val1 = COST_COMMUNITY_DEFAULT_COST;  if (! find2)    val2 = COST_COMMUNITY_DEFAULT_COST;  if (find1 && find2)    {      if (id1 < id2)	return 1;      if (id1 > id2)	return -1;    }  if (val1 < val2)    return 1;  if (val1 > val2)    return -1;  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -