📄 bgp_ecommunity.c
字号:
} goto error; } goto error; } while (isdigit ((int) *p) || *p == ':' || *p == '.') { if (*p == ':') { if (separator) goto error; separator = 1; digit = 0; if (dot) { if ((p - str) > INET_ADDRSTRLEN) goto error; memset (ipstr, 0, INET_ADDRSTRLEN + 1); memcpy (ipstr, str, p - str); ret = inet_aton (ipstr, &ip); if (ret == 0) goto error; } else val_high = val_low; val_low = 0; } else if (*p == '.') { if (separator) goto error; dot++; if (dot > 4) goto error; } else { digit = 1; val_low *= 10; val_low += (*p - '0'); } p++; } /* Low digit part must be there. */ if (! digit || ! separator) goto error; /* Encode result into routing distinguisher. */ if (dot) { eval->val[0] = ECOMMUNITY_ENCODE_IP; eval->val[1] = 0; memcpy (&eval->val[2], &ip, sizeof (struct in_addr)); eval->val[6] = (val_low >> 8) & 0xff; eval->val[7] = val_low & 0xff; } else { eval->val[0] = ECOMMUNITY_ENCODE_AS; eval->val[1] = 0; eval->val[2] = (val_high >>8) & 0xff; eval->val[3] = val_high & 0xff; eval->val[4] = (val_low >>24) & 0xff; eval->val[5] = (val_low >>16) & 0xff; eval->val[6] = (val_low >>8) & 0xff; eval->val[7] = val_low & 0xff; } *token = ecommunity_token_val; return p; error: *token = ecommunity_token_unknown; return p;}/* 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_ROUTE_TARGET or ECOMMUNITY_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_ROUTE_TARGET keyword_included = 0 "soo 100:1" -> str = "100:1" type = ECOMMUNITY_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_ROUTE_TARGET; } if (token == ecommunity_token_soo) { type = ECOMMUNITY_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;}/* 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_ROUTE_MAP ECOMMUNITY_FORMAT_COMMUNITY_LIST ECOMMUNITY_FORMAT_DISPLAY*/char *ecommunity_ecom2str (struct ecommunity *ecom, int format){ int i; u_char *pnt; int encode = 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++) { pnt = ecom->val + (i * 8); /* High-order octet of type. */ encode = *pnt++; if (encode != ECOMMUNITY_ENCODE_AS && encode != ECOMMUNITY_ENCODE_IP) { if (str_buf) XFREE (MTYPE_ECOMMUNITY_STR, str_buf); return "Unknown"; } /* Low-order octet of type. */ type = *pnt++; if (type != ECOMMUNITY_ROUTE_TARGET && type != ECOMMUNITY_SITE_ORIGIN) { if (str_buf) XFREE (MTYPE_ECOMMUNITY_STR, str_buf); return "Unknown"; } switch (format) { case ECOMMUNITY_FORMAT_COMMUNITY_LIST: prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "rt " : "soo "); break; case ECOMMUNITY_FORMAT_DISPLAY: prefix = (type == ECOMMUNITY_ROUTE_TARGET ? "RT:" : "SoO:"); break; case ECOMMUNITY_FORMAT_ROUTE_MAP: prefix = ""; break; default: if (str_buf) XFREE (MTYPE_ECOMMUNITY_STR, str_buf); return "Unknown"; break; } /* 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++] = ' '; /* Put string into buffer. */ if (encode == 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 == 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -