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

View File

@ -188,10 +188,20 @@ struct community *community_uniq_sort(struct community *com)
For Well-known communities value, below keyword is used. For Well-known communities value, below keyword is used.
0x0 "internet" 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" 0xFFFFFF01 "no-export"
0xFFFFFF02 "no-advertise" 0xFFFFFF02 "no-advertise"
0xFFFFFF03 "local-AS" 0xFFFFFF03 "local-AS"
0xFFFF0000 "graceful-shutdown" 0xFFFFFF04 "no-peer"
For other values, "AS:VAL" format is used. */ For other values, "AS:VAL" format is used. */
static void set_community_string(struct community *com, bool make_json) 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: case COMMUNITY_INTERNET:
len += strlen(" internet"); len += strlen(" internet");
break; 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: case COMMUNITY_NO_EXPORT:
len += strlen(" no-export"); len += strlen(" no-export");
break; break;
@ -250,8 +290,8 @@ static void set_community_string(struct community *com, bool make_json)
case COMMUNITY_LOCAL_AS: case COMMUNITY_LOCAL_AS:
len += strlen(" local-AS"); len += strlen(" local-AS");
break; break;
case COMMUNITY_GSHUT: case COMMUNITY_NO_PEER:
len += strlen(" graceful-shutdown"); len += strlen(" no-peer");
break; break;
default: default:
len += strlen(" 65536:65535"); len += strlen(" 65536:65535");
@ -284,6 +324,106 @@ static void set_community_string(struct community *com, bool make_json)
json_string); json_string);
} }
break; 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: case COMMUNITY_NO_EXPORT:
strcpy(pnt, "no-export"); strcpy(pnt, "no-export");
pnt += strlen("no-export"); pnt += strlen("no-export");
@ -313,12 +453,11 @@ static void set_community_string(struct community *com, bool make_json)
json_string); json_string);
} }
break; break;
case COMMUNITY_GSHUT: case COMMUNITY_NO_PEER:
strcpy(pnt, "graceful-shutdown"); strcpy(pnt, "no-peer");
pnt += strlen("graceful-shutdown"); pnt += strlen("no-peer");
if (make_json) { if (make_json) {
json_string = json_object_new_string( json_string = json_object_new_string("noPeer");
"gracefulShutdown");
json_object_array_add(json_community_list, json_object_array_add(json_community_list,
json_string); json_string);
} }
@ -508,10 +647,20 @@ struct community *community_merge(struct community *com1,
/* Community token enum. */ /* Community token enum. */
enum community_token { enum community_token {
community_token_val, 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_export,
community_token_no_advertise, community_token_no_advertise,
community_token_local_as, community_token_local_as,
community_token_gshut, community_token_no_peer,
community_token_unknown community_token_unknown
}; };
@ -537,6 +686,79 @@ community_gettoken(const char *buf, enum community_token *token, uint32_t *val)
p += strlen("internet"); p += strlen("internet");
return p; 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) { if (strncmp(p, "no-export", strlen("no-export")) == 0) {
*val = COMMUNITY_NO_EXPORT; *val = COMMUNITY_NO_EXPORT;
*token = community_token_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"); p += strlen("local-AS");
return p; return p;
} }
if (strncmp(p, "graceful-shutdown", strlen("graceful-shutdown")) if (strncmp(p, "no-peer", strlen("no-peer")) == 0) {
== 0) { *val = COMMUNITY_NO_PEER;
*val = COMMUNITY_GSHUT; *token = community_token_no_peer;
*token = community_token_gshut; p += strlen("no-peer");
p += strlen("graceful-shutdown");
return p; return p;
} }
@ -631,10 +852,20 @@ struct community *community_str2com(const char *str)
switch (token) { switch (token) {
case community_token_val: 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_export:
case community_token_no_advertise: case community_token_no_advertise:
case community_token_local_as: case community_token_local_as:
case community_token_gshut: case community_token_no_peer:
if (com == NULL) { if (com == NULL) {
com = community_new(); com = community_new();
com->json = NULL; com->json = NULL;

View File

@ -43,12 +43,22 @@ struct community {
}; };
/* Well-known communities value. */ /* Well-known communities value. */
#define COMMUNITY_INTERNET 0x0 #define COMMUNITY_INTERNET 0x0
#define COMMUNITY_NO_EXPORT 0xFFFFFF01 #define COMMUNITY_GSHUT 0xFFFF0000
#define COMMUNITY_NO_ADVERTISE 0xFFFFFF02 #define COMMUNITY_ACCEPT_OWN 0xFFFF0001
#define COMMUNITY_NO_EXPORT_SUBCONFED 0xFFFFFF03 #define COMMUNITY_ROUTE_FILTER_TRANSLATED_v4 0xFFFF0002
#define COMMUNITY_LOCAL_AS 0xFFFFFF03 #define COMMUNITY_ROUTE_FILTER_v4 0xFFFF0003
#define COMMUNITY_GSHUT 0xFFFF0000 #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. */ /* Macros of community attribute. */
#define com_length(X) ((X)->size * 4) #define com_length(X) ((X)->size * 4)