Merge pull request #2684 from netravnen/feature/bgpd/well-known-communities

Add missing bgp well-known communities
This commit is contained in:
Russ White 2018-08-04 09:57:32 -04:00 committed by GitHub
commit c8f70278bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 404 additions and 63 deletions

View File

@ -346,6 +346,36 @@ static char *community_str_get(struct community *com, int i)
case COMMUNITY_INTERNET:
len = strlen(" internet");
break;
case COMMUNITY_GSHUT:
len = strlen(" graceful-shutdown");
break;
case COMMUNITY_ACCEPT_OWN:
len = strlen(" accept-own");
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v4:
len = strlen(" route-filter-translated-v4");
break;
case COMMUNITY_ROUTE_FILTER_v4:
len = strlen(" route-filter-v4");
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v6:
len = strlen(" route-filter-translated-v6");
break;
case COMMUNITY_ROUTE_FILTER_v6:
len = strlen(" route-filter-v6");
break;
case COMMUNITY_LLGR_STALE:
len = strlen(" llgr-stale");
break;
case COMMUNITY_NO_LLGR:
len = strlen(" no-llgr");
break;
case COMMUNITY_ACCEPT_OWN_NEXTHOP:
len = strlen(" accept-own-nexthop");
break;
case COMMUNITY_BLACKHOLE:
len = strlen(" blackhole");
break;
case COMMUNITY_NO_EXPORT:
len = strlen(" no-export");
break;
@ -355,8 +385,8 @@ static char *community_str_get(struct community *com, int i)
case COMMUNITY_LOCAL_AS:
len = strlen(" local-AS");
break;
case COMMUNITY_GSHUT:
len = strlen(" graceful-shutdown");
case COMMUNITY_NO_PEER:
len = strlen(" no-peer");
break;
default:
len = strlen(" 65536:65535");
@ -371,6 +401,46 @@ static char *community_str_get(struct community *com, int i)
strcpy(pnt, "internet");
pnt += strlen("internet");
break;
case COMMUNITY_GSHUT:
strcpy(pnt, "graceful-shutdown");
pnt += strlen("graceful-shutdown");
break;
case COMMUNITY_ACCEPT_OWN:
strcpy(pnt, "accept-own");
pnt += strlen("accept-own");
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v4:
strcpy(pnt, "route-filter-translated-v4");
pnt += strlen("route-filter-translated-v4");
break;
case COMMUNITY_ROUTE_FILTER_v4:
strcpy(pnt, "route-filter-v4");
pnt += strlen("route-filter-v4");
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v6:
strcpy(pnt, "route-filter-translated-v6");
pnt += strlen("route-filter-translated-v6");
break;
case COMMUNITY_ROUTE_FILTER_v6:
strcpy(pnt, "route-filter-v6");
pnt += strlen("route-filter-v6");
break;
case COMMUNITY_LLGR_STALE:
strcpy(pnt, "llgr-stale");
pnt += strlen("llgr-stale");
break;
case COMMUNITY_NO_LLGR:
strcpy(pnt, "no-llgr");
pnt += strlen("no-llgr");
break;
case COMMUNITY_ACCEPT_OWN_NEXTHOP:
strcpy(pnt, "accept-own-nexthop");
pnt += strlen("accept-own-nexthop");
break;
case COMMUNITY_BLACKHOLE:
strcpy(pnt, "blackhole");
pnt += strlen("blackhole");
break;
case COMMUNITY_NO_EXPORT:
strcpy(pnt, "no-export");
pnt += strlen("no-export");
@ -383,9 +453,9 @@ static char *community_str_get(struct community *com, int i)
strcpy(pnt, "local-AS");
pnt += strlen("local-AS");
break;
case COMMUNITY_GSHUT:
strcpy(pnt, "graceful-shutdown");
pnt += strlen("graceful-shutdown");
case COMMUNITY_NO_PEER:
strcpy(pnt, "no-peer");
pnt += strlen("no-peer");
break;
default:
as = (comval >> 16) & 0xFFFF;
@ -547,47 +617,77 @@ static int ecommunity_regexp_match(struct ecommunity *ecom, regex_t *reg)
static struct community *
community_regexp_delete (struct community *com, regex_t * reg)
{
int i;
uint32_t comval;
/* Maximum is "65535:65535" + '\0'. */
char c[12];
const char *str;
int i;
uint32_t comval;
/* Maximum is "65535:65535" + '\0'. */
char c[12];
const char *str;
if (!com)
return NULL;
if (!com)
return NULL;
i = 0;
while (i < com->size)
{
memcpy (&comval, com_nthval (com, i), sizeof (uint32_t));
comval = ntohl (comval);
i = 0;
while (i < com->size)
{
memcpy (&comval, com_nthval (com, i), sizeof (uint32_t));
comval = ntohl (comval);
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:
sprintf (c, "%d:%d", (comval >> 16) & 0xFFFF, comval & 0xFFFF);
str = c;
break;
}
switch (comval) {
case COMMUNITY_INTERNET:
str = "internet";
break;
case COMMUNITY_ACCEPT_OWN:
str = "accept-own";
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v4:
str = "route-filter-translated-v4";
break;
case COMMUNITY_ROUTE_FILTER_v4:
str = "route-filter-v4";
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v6:
str = "route-filter-translated-v6";
break;
case COMMUNITY_ROUTE_FILTER_v6:
str = "route-filter-v6";
break;
case COMMUNITY_LLGR_STALE:
str = "llgr-stale";
break;
case COMMUNITY_NO_LLGR:
str = "no-llgr";
break;
case COMMUNITY_ACCEPT_OWN_NEXTHOP:
str = "accept-own-nexthop";
break;
case COMMUNITY_BLACKHOLE:
str = "blackhole";
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;
case COMMUNITY_NO_PEER:
str = "no-peer";
break;
default:
sprintf (c, "%d:%d", (comval >> 16) & 0xFFFF,
comval & 0xFFFF);
str = c;
break;
}
if (regexec (reg, str, 0, NULL, 0) == 0)
community_del_val (com, com_nthval (com, i));
else
i++;
}
return com;
if (regexec (reg, str, 0, NULL, 0) == 0)
community_del_val (com, com_nthval (com, i));
else
i++;
}
return com;
}
#endif

View File

@ -188,10 +188,20 @@ struct community *community_uniq_sort(struct community *com)
For Well-known communities value, below keyword is used.
0x0 "internet"
0xFFFF0000 "graceful-shutdown"
0xFFFF0001 "accept-own"
0xFFFF0002 "route-filter-translated-v4"
0xFFFF0003 "route-filter-v4"
0xFFFF0004 "route-filter-translated-v6"
0xFFFF0005 "route-filter-v6"
0xFFFF0006 "llgr-stale"
0xFFFF0007 "no-llgr"
0xFFFF0008 "accept-own-nexthop"
0xFFFF029A "blackhole"
0xFFFFFF01 "no-export"
0xFFFFFF02 "no-advertise"
0xFFFFFF03 "local-AS"
0xFFFF0000 "graceful-shutdown"
0xFFFFFF04 "no-peer"
For other values, "AS:VAL" format is used. */
static void set_community_string(struct community *com, bool make_json)
@ -241,6 +251,36 @@ static void set_community_string(struct community *com, bool make_json)
case COMMUNITY_INTERNET:
len += strlen(" internet");
break;
case COMMUNITY_GSHUT:
len += strlen(" graceful-shutdown");
break;
case COMMUNITY_ACCEPT_OWN:
len += strlen(" accept-own");
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v4:
len += strlen(" route-filter-translated-v4");
break;
case COMMUNITY_ROUTE_FILTER_v4:
len += strlen(" route-filter-v4");
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v6:
len += strlen(" route-filter-translated-v6");
break;
case COMMUNITY_ROUTE_FILTER_v6:
len += strlen(" route-filter-v6");
break;
case COMMUNITY_LLGR_STALE:
len += strlen(" llgr-stale");
break;
case COMMUNITY_NO_LLGR:
len += strlen(" no-llgr");
break;
case COMMUNITY_ACCEPT_OWN_NEXTHOP:
len += strlen(" accept-own-nexthop");
break;
case COMMUNITY_BLACKHOLE:
len += strlen(" blackhole");
break;
case COMMUNITY_NO_EXPORT:
len += strlen(" no-export");
break;
@ -250,8 +290,8 @@ static void set_community_string(struct community *com, bool make_json)
case COMMUNITY_LOCAL_AS:
len += strlen(" local-AS");
break;
case COMMUNITY_GSHUT:
len += strlen(" graceful-shutdown");
case COMMUNITY_NO_PEER:
len += strlen(" no-peer");
break;
default:
len += strlen(" 65536:65535");
@ -284,6 +324,106 @@ static void set_community_string(struct community *com, bool make_json)
json_string);
}
break;
case COMMUNITY_GSHUT:
strcpy(pnt, "graceful-shutdown");
pnt += strlen("graceful-shutdown");
if (make_json) {
json_string = json_object_new_string(
"gracefulShutdown");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_ACCEPT_OWN:
strcpy(pnt, "accept-own");
pnt += strlen("accept-own");
if (make_json) {
json_string = json_object_new_string(
"acceptown");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v4:
strcpy(pnt, "route-filter-translated-v4");
pnt += strlen("route-filter-translated-v4");
if (make_json) {
json_string = json_object_new_string(
"routeFilterTranslatedV4");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_ROUTE_FILTER_v4:
strcpy(pnt, "route-filter-v4");
pnt += strlen("route-filter-v4");
if (make_json) {
json_string = json_object_new_string(
"routeFilterV4");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_ROUTE_FILTER_TRANSLATED_v6:
strcpy(pnt, "route-filter-translated-v6");
pnt += strlen("route-filter-translated-v6");
if (make_json) {
json_string = json_object_new_string(
"routeFilterTranslatedV6");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_ROUTE_FILTER_v6:
strcpy(pnt, "route-filter-v6");
pnt += strlen("route-filter-v6");
if (make_json) {
json_string = json_object_new_string(
"routeFilterV6");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_LLGR_STALE:
strcpy(pnt, "llgr-stale");
pnt += strlen("llgr-stale");
if (make_json) {
json_string = json_object_new_string(
"llgrStale");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_NO_LLGR:
strcpy(pnt, "no-llgr");
pnt += strlen("no-llgr");
if (make_json) {
json_string = json_object_new_string(
"noLlgr");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_ACCEPT_OWN_NEXTHOP:
strcpy(pnt, "accept-own-nexthop");
pnt += strlen("accept-own-nexthop");
if (make_json) {
json_string = json_object_new_string(
"acceptownnexthop");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_BLACKHOLE:
strcpy(pnt, "blackhole");
pnt += strlen("blackhole");
if (make_json) {
json_string = json_object_new_string(
"blackhole");
json_object_array_add(json_community_list,
json_string);
}
break;
case COMMUNITY_NO_EXPORT:
strcpy(pnt, "no-export");
pnt += strlen("no-export");
@ -313,12 +453,11 @@ static void set_community_string(struct community *com, bool make_json)
json_string);
}
break;
case COMMUNITY_GSHUT:
strcpy(pnt, "graceful-shutdown");
pnt += strlen("graceful-shutdown");
case COMMUNITY_NO_PEER:
strcpy(pnt, "no-peer");
pnt += strlen("no-peer");
if (make_json) {
json_string = json_object_new_string(
"gracefulShutdown");
json_string = json_object_new_string("noPeer");
json_object_array_add(json_community_list,
json_string);
}
@ -508,10 +647,20 @@ struct community *community_merge(struct community *com1,
/* Community token enum. */
enum community_token {
community_token_val,
community_token_gshut,
community_token_accept_own,
community_token_route_filter_translated_v4,
community_token_route_filter_v4,
community_token_route_filter_translated_v6,
community_token_route_filter_v6,
community_token_llgr_stale,
community_token_no_llgr,
community_token_accept_own_nexthop,
community_token_blackhole,
community_token_no_export,
community_token_no_advertise,
community_token_local_as,
community_token_gshut,
community_token_no_peer,
community_token_unknown
};
@ -537,6 +686,79 @@ community_gettoken(const char *buf, enum community_token *token, uint32_t *val)
p += strlen("internet");
return p;
}
if (strncmp(p, "graceful-shutdown", strlen("graceful-shutdown"))
== 0) {
*val = COMMUNITY_GSHUT;
*token = community_token_gshut;
p += strlen("graceful-shutdown");
return p;
}
if (strncmp(p, "accept-own", strlen("accept-own"))
== 0) {
*val = COMMUNITY_ACCEPT_OWN;
*token = community_token_accept_own;
p += strlen("accept-own");
return p;
}
if (strncmp(p, "route-filter-translated-v4",
strlen("route-filter-translated-v4"))
== 0) {
*val = COMMUNITY_ROUTE_FILTER_TRANSLATED_v4;
*token = community_token_route_filter_translated_v4;
p += strlen("route-filter-translated-v4");
return p;
}
if (strncmp(p, "route-filter-v4", strlen("route-filter-v4"))
== 0) {
*val = COMMUNITY_ROUTE_FILTER_v4;
*token = community_token_route_filter_v4;
p += strlen("route-filter-v4");
return p;
}
if (strncmp(p, "route-filter-translated-v6",
strlen("route-filter-translated-v6"))
== 0) {
*val = COMMUNITY_ROUTE_FILTER_TRANSLATED_v6;
*token = community_token_route_filter_translated_v6;
p += strlen("route-filter-translated-v6");
return p;
}
if (strncmp(p, "route-filter-v6", strlen("route-filter-v6"))
== 0) {
*val = COMMUNITY_ROUTE_FILTER_v6;
*token = community_token_route_filter_v6;
p += strlen("route-filter-v6");
return p;
}
if (strncmp(p, "llgr-stale", strlen("llgr-stale"))
== 0) {
*val = COMMUNITY_LLGR_STALE;
*token = community_token_llgr_stale;
p += strlen("llgr-stale");
return p;
}
if (strncmp(p, "no-llgr", strlen("no-llgr"))
== 0) {
*val = COMMUNITY_NO_LLGR;
*token = community_token_no_llgr;
p += strlen("no-llgr");
return p;
}
if (strncmp(p, "accept-own-nexthop",
strlen("accept-own-nexthop"))
== 0) {
*val = COMMUNITY_ACCEPT_OWN_NEXTHOP;
*token = community_token_accept_own_nexthop;
p += strlen("accept-own-nexthop");
return p;
}
if (strncmp(p, "blackhole", strlen("blackhole"))
== 0) {
*val = COMMUNITY_BLACKHOLE;
*token = community_token_blackhole;
p += strlen("blackhole");
return p;
}
if (strncmp(p, "no-export", strlen("no-export")) == 0) {
*val = COMMUNITY_NO_EXPORT;
*token = community_token_no_export;
@ -555,11 +777,10 @@ community_gettoken(const char *buf, enum community_token *token, uint32_t *val)
p += strlen("local-AS");
return p;
}
if (strncmp(p, "graceful-shutdown", strlen("graceful-shutdown"))
== 0) {
*val = COMMUNITY_GSHUT;
*token = community_token_gshut;
p += strlen("graceful-shutdown");
if (strncmp(p, "no-peer", strlen("no-peer")) == 0) {
*val = COMMUNITY_NO_PEER;
*token = community_token_no_peer;
p += strlen("no-peer");
return p;
}
@ -631,10 +852,20 @@ struct community *community_str2com(const char *str)
switch (token) {
case community_token_val:
case community_token_gshut:
case community_token_accept_own:
case community_token_route_filter_translated_v4:
case community_token_route_filter_v4:
case community_token_route_filter_translated_v6:
case community_token_route_filter_v6:
case community_token_llgr_stale:
case community_token_no_llgr:
case community_token_accept_own_nexthop:
case community_token_blackhole:
case community_token_no_export:
case community_token_no_advertise:
case community_token_local_as:
case community_token_gshut:
case community_token_no_peer:
if (com == NULL) {
com = community_new();
com->json = NULL;

View File

@ -43,12 +43,22 @@ struct community {
};
/* Well-known communities value. */
#define COMMUNITY_INTERNET 0x0
#define COMMUNITY_NO_EXPORT 0xFFFFFF01
#define COMMUNITY_NO_ADVERTISE 0xFFFFFF02
#define COMMUNITY_NO_EXPORT_SUBCONFED 0xFFFFFF03
#define COMMUNITY_LOCAL_AS 0xFFFFFF03
#define COMMUNITY_GSHUT 0xFFFF0000
#define COMMUNITY_INTERNET 0x0
#define COMMUNITY_GSHUT 0xFFFF0000
#define COMMUNITY_ACCEPT_OWN 0xFFFF0001
#define COMMUNITY_ROUTE_FILTER_TRANSLATED_v4 0xFFFF0002
#define COMMUNITY_ROUTE_FILTER_v4 0xFFFF0003
#define COMMUNITY_ROUTE_FILTER_TRANSLATED_v6 0xFFFF0004
#define COMMUNITY_ROUTE_FILTER_v6 0xFFFF0005
#define COMMUNITY_LLGR_STALE 0xFFFF0006
#define COMMUNITY_NO_LLGR 0xFFFF0007
#define COMMUNITY_ACCEPT_OWN_NEXTHOP 0xFFFF0008
#define COMMUNITY_BLACKHOLE 0xFFFF029A
#define COMMUNITY_NO_EXPORT 0xFFFFFF01
#define COMMUNITY_NO_ADVERTISE 0xFFFFFF02
#define COMMUNITY_NO_EXPORT_SUBCONFED 0xFFFFFF03
#define COMMUNITY_LOCAL_AS 0xFFFFFF03
#define COMMUNITY_NO_PEER 0xFFFFFF04
/* Macros of community attribute. */
#define com_length(X) ((X)->size * 4)