summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bgpctl/bgpctl.c250
-rw-r--r--usr.sbin/bgpctl/parser.c154
-rw-r--r--usr.sbin/bgpctl/parser.h4
3 files changed, 266 insertions, 142 deletions
diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c
index 1c6f24c0ba7..6470ffa6f2c 100644
--- a/usr.sbin/bgpctl/bgpctl.c
+++ b/usr.sbin/bgpctl/bgpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpctl.c,v 1.238 2019/05/23 14:12:06 claudio Exp $ */
+/* $OpenBSD: bgpctl.c,v 1.239 2019/06/17 11:03:07 claudio Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -81,6 +81,7 @@ int show_rib_detail_msg(struct imsg *, int, int);
void show_rib_brief(struct ctl_show_rib *, u_char *);
void show_rib_detail(struct ctl_show_rib *, u_char *, int, int);
void show_attr(void *, u_int16_t, int);
+void show_communities(u_char *, size_t, int);
void show_community(u_char *, u_int16_t);
void show_large_community(u_char *, u_int16_t);
void show_ext_community(u_char *, u_int16_t);
@@ -282,7 +283,7 @@ main(int argc, char *argv[])
}
if (res->as.type != AS_UNDEF)
ribreq.as = res->as;
- if (res->community.type != COMMUNITY_TYPE_NONE)
+ if (res->community.flags != 0)
ribreq.community = res->community;
ribreq.neighbor = neighbor;
strlcpy(ribreq.rib, res->rib, sizeof(ribreq.rib));
@@ -1252,6 +1253,12 @@ show_rib_detail_msg(struct imsg *imsg, int nodescr, int flag0)
asdata += sizeof(struct ctl_show_rib);
show_rib_detail(&rib, asdata, nodescr, flag0);
break;
+ case IMSG_CTL_SHOW_RIB_COMMUNITIES:
+ ilen = imsg->hdr.len - IMSG_HEADER_SIZE;
+ if (ilen % sizeof(struct community))
+ errx(1, "bad IMSG_CTL_SHOW_RIB_COMMUNITIES received");
+ show_communities(imsg->data, ilen, flag0);
+ break;
case IMSG_CTL_SHOW_RIB_ATTR:
ilen = imsg->hdr.len - IMSG_HEADER_SIZE;
if (ilen < 3)
@@ -1632,6 +1639,154 @@ show_attr(void *b, u_int16_t len, int flag0)
printf("%c", EOL0(flag0));
}
+static void
+print_community(u_int16_t a, u_int16_t v)
+{
+ if (a == COMMUNITY_WELLKNOWN)
+ switch (v) {
+ case COMMUNITY_GRACEFUL_SHUTDOWN:
+ printf("GRACEFUL_SHUTDOWN");
+ break;
+ case COMMUNITY_NO_EXPORT:
+ printf("NO_EXPORT");
+ break;
+ case COMMUNITY_NO_ADVERTISE:
+ printf("NO_ADVERTISE");
+ break;
+ case COMMUNITY_NO_EXPSUBCONFED:
+ printf("NO_EXPORT_SUBCONFED");
+ break;
+ case COMMUNITY_NO_PEER:
+ printf("NO_PEER");
+ break;
+ case COMMUNITY_BLACKHOLE:
+ printf("BLACKHOLE");
+ break;
+ default:
+ printf("%hu:%hu", a, v);
+ break;
+ }
+ else
+ printf("%hu:%hu", a, v);
+}
+
+static void
+print_ext_community(u_int8_t *data)
+{
+ u_int64_t ext;
+ struct in_addr ip;
+ u_int32_t as4, u32;
+ u_int16_t as2, u16;
+ u_int8_t type, subtype;
+
+ type = data[0];
+ subtype = data[1];
+
+ printf("%s ", log_ext_subtype(type, subtype));
+
+ switch (type) {
+ case EXT_COMMUNITY_TRANS_TWO_AS:
+ memcpy(&as2, data + 2, sizeof(as2));
+ memcpy(&u32, data + 4, sizeof(u32));
+ printf("%s:%u", log_as(ntohs(as2)), ntohl(u32));
+ break;
+ case EXT_COMMUNITY_TRANS_IPV4:
+ memcpy(&ip, data + 2, sizeof(ip));
+ memcpy(&u16, data + 6, sizeof(u16));
+ printf("%s:%hu", inet_ntoa(ip), ntohs(u16));
+ break;
+ case EXT_COMMUNITY_TRANS_FOUR_AS:
+ memcpy(&as4, data + 2, sizeof(as4));
+ memcpy(&u16, data + 6, sizeof(u16));
+ printf("%s:%hu", log_as(ntohl(as4)), ntohs(u16));
+ break;
+ case EXT_COMMUNITY_TRANS_OPAQUE:
+ case EXT_COMMUNITY_TRANS_EVPN:
+ memcpy(&ext, data, sizeof(ext));
+ ext = be64toh(ext) & 0xffffffffffffLL;
+ printf("0x%llx", (unsigned long long)ext);
+ break;
+ case EXT_COMMUNITY_NON_TRANS_OPAQUE:
+ memcpy(&ext, data, sizeof(ext));
+ ext = be64toh(ext) & 0xffffffffffffLL;
+ switch (ext) {
+ case EXT_COMMUNITY_OVS_VALID:
+ printf("valid ");
+ break;
+ case EXT_COMMUNITY_OVS_NOTFOUND:
+ printf("not-found ");
+ break;
+ case EXT_COMMUNITY_OVS_INVALID:
+ printf("invalid ");
+ break;
+ default:
+ printf("0x%llx ", (unsigned long long)ext);
+ break;
+ }
+ break;
+ default:
+ memcpy(&ext, data, sizeof(ext));
+ printf("0x%llx", (unsigned long long)be64toh(ext));
+ }
+}
+
+void
+show_communities(u_char *data, size_t len, int flag0)
+{
+ struct community c;
+ size_t i;
+ u_int64_t ext;
+ u_int8_t type = 0, nt;
+
+ if (len % sizeof(c))
+ return;
+
+ for (i = 0; i < len; i += sizeof(c)) {
+ memcpy(&c, data + i, sizeof(c));
+
+ nt = c.flags;
+ if (type != nt) {
+ if (type != 0)
+ printf("%c", EOL0(flag0));
+ printf(" %s:", print_attr(nt,
+ ATTR_OPTIONAL | ATTR_TRANSITIVE));
+ type = nt;
+ }
+ printf(" ");
+
+ switch (nt) {
+ case COMMUNITY_TYPE_BASIC:
+ print_community(c.data1, c.data2);
+ break;
+ case COMMUNITY_TYPE_LARGE:
+ printf("%u:%u:%u", c.data1, c.data2, c.data3);
+ break;
+ case COMMUNITY_TYPE_EXT:
+ ext = (u_int64_t)c.data3 << 48;
+ switch (c.data3 >> 8) {
+ case EXT_COMMUNITY_TRANS_TWO_AS:
+ case EXT_COMMUNITY_TRANS_OPAQUE:
+ case EXT_COMMUNITY_TRANS_EVPN:
+ case EXT_COMMUNITY_NON_TRANS_OPAQUE:
+ ext |= ((u_int64_t)c.data1 & 0xffff) << 32;
+ ext |= (u_int64_t)c.data2;
+ break;
+ case EXT_COMMUNITY_TRANS_FOUR_AS:
+ case EXT_COMMUNITY_TRANS_IPV4:
+ ext |= (u_int64_t)c.data1 << 16;
+ ext |= (u_int64_t)c.data2 & 0xffff;
+ break;
+ }
+ ext = htobe64(ext);
+
+ print_ext_community((void *)&ext);
+ break;
+ }
+ }
+
+ printf("%c", EOL0(flag0));
+}
+
void
show_community(u_char *data, u_int16_t len)
{
@@ -1646,33 +1801,7 @@ show_community(u_char *data, u_int16_t len)
memcpy(&v, data + i + 2, sizeof(v));
a = ntohs(a);
v = ntohs(v);
- if (a == COMMUNITY_WELLKNOWN)
- switch (v) {
- case COMMUNITY_GRACEFUL_SHUTDOWN:
- printf("GRACEFUL_SHUTDOWN");
- break;
- case COMMUNITY_NO_EXPORT:
- printf("NO_EXPORT");
- break;
- case COMMUNITY_NO_ADVERTISE:
- printf("NO_ADVERTISE");
- break;
- case COMMUNITY_NO_EXPSUBCONFED:
- printf("NO_EXPORT_SUBCONFED");
- break;
- case COMMUNITY_NO_PEER:
- printf("NO_PEER");
- break;
- case COMMUNITY_BLACKHOLE:
- printf("BLACKHOLE");
- break;
- default:
- printf("%hu:%hu", a, v);
- break;
- }
- else
- printf("%hu:%hu", a, v);
-
+ print_community(a, v);
if (i + 4 < len)
printf(" ");
}
@@ -1704,67 +1833,16 @@ show_large_community(u_char *data, u_int16_t len)
void
show_ext_community(u_char *data, u_int16_t len)
{
- u_int64_t ext;
- struct in_addr ip;
- u_int32_t as4, u32;
- u_int16_t i, as2, u16;
- u_int8_t type, subtype;
+ u_int16_t i;
if (len & 0x7)
return;
for (i = 0; i < len; i += 8) {
- type = data[i];
- subtype = data[i + 1];
-
- printf("%s ", log_ext_subtype(type, subtype));
+ print_ext_community(data + i);
- switch (type) {
- case EXT_COMMUNITY_TRANS_TWO_AS:
- memcpy(&as2, data + i + 2, sizeof(as2));
- memcpy(&u32, data + i + 4, sizeof(u32));
- printf("%s:%u", log_as(ntohs(as2)), ntohl(u32));
- break;
- case EXT_COMMUNITY_TRANS_IPV4:
- memcpy(&ip, data + i + 2, sizeof(ip));
- memcpy(&u16, data + i + 6, sizeof(u16));
- printf("%s:%hu", inet_ntoa(ip), ntohs(u16));
- break;
- case EXT_COMMUNITY_TRANS_FOUR_AS:
- memcpy(&as4, data + i + 2, sizeof(as4));
- memcpy(&u16, data + i + 6, sizeof(u16));
- printf("%s:%hu", log_as(ntohl(as4)), ntohs(u16));
- break;
- case EXT_COMMUNITY_TRANS_OPAQUE:
- case EXT_COMMUNITY_TRANS_EVPN:
- memcpy(&ext, data + i, sizeof(ext));
- ext = be64toh(ext) & 0xffffffffffffLL;
- printf("0x%llx", (unsigned long long)ext);
- break;
- case EXT_COMMUNITY_NON_TRANS_OPAQUE:
- memcpy(&ext, data + i, sizeof(ext));
- ext = be64toh(ext) & 0xffffffffffffLL;
- switch (ext) {
- case EXT_COMMUNITY_OVS_VALID:
- printf("valid ");
- break;
- case EXT_COMMUNITY_OVS_NOTFOUND:
- printf("not-found ");
- break;
- case EXT_COMMUNITY_OVS_INVALID:
- printf("invalid ");
- break;
- default:
- printf("0x%llx ", (unsigned long long)ext);
- break;
- }
- break;
- default:
- memcpy(&ext, data + i, sizeof(ext));
- printf("0x%llx", (unsigned long long)be64toh(ext));
- }
if (i + 8 < len)
- printf(", ");
+ printf(" ");
}
}
@@ -1817,6 +1895,12 @@ show_rib_memory_msg(struct imsg *imsg)
"%s of memory\n\t and holding %lld references\n",
stats.aspath_cnt, fmt_mem(stats.aspath_size),
stats.aspath_refs);
+ printf("%10lld entries for %lld BGP communities "
+ "using %s of memory\n", stats.comm_cnt, stats.comm_nmemb,
+ fmt_mem(stats.comm_cnt * sizeof(struct rde_community) +
+ stats.comm_size * sizeof(struct community)));
+ printf("\t and holding %lld references\n",
+ stats.comm_refs);
printf("%10lld BGP attributes entries using %s of memory\n",
stats.attr_cnt, fmt_mem(stats.attr_cnt *
sizeof(struct attr)));
diff --git a/usr.sbin/bgpctl/parser.c b/usr.sbin/bgpctl/parser.c
index 3bb427cd623..63e1efd9aa7 100644
--- a/usr.sbin/bgpctl/parser.c
+++ b/usr.sbin/bgpctl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.94 2019/05/23 14:12:06 claudio Exp $ */
+/* $OpenBSD: parser.c,v 1.95 2019/06/17 11:03:07 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -506,8 +506,8 @@ void show_valid_args(const struct token []);
int parse_addr(const char *, struct bgpd_addr *);
int parse_asnum(const char *, size_t, u_int32_t *);
int parse_number(const char *, struct parse_result *, enum token_type);
-void parsecommunity(struct filter_community *c, int type, char *s);
-int parseextcommunity(struct filter_community *c, const char *t, char *s);
+void parsecommunity(struct community *c, int type, char *s);
+void parseextcommunity(struct community *c, const char *t, char *s);
int parse_nexthop(const char *, struct parse_result *);
int bgpctl_getopt(int *, char **[], int);
@@ -733,7 +733,7 @@ match_token(int *argc, char **argv[], const struct token table[])
case RD:
if (word != NULL && wordlen > 0) {
char *p = strdup(word);
- struct filter_community ext;
+ struct community ext;
u_int64_t rd;
if (p == NULL)
@@ -741,21 +741,22 @@ match_token(int *argc, char **argv[], const struct token table[])
parseextcommunity(&ext, "rt", p);
free(p);
- switch (ext.c.e.type) {
+ switch (ext.data3 >> 8) {
case EXT_COMMUNITY_TRANS_TWO_AS:
rd = (0ULL << 48);
- rd |= (u_int64_t)ext.c.e.data1 << 32;
- rd |= ext.c.e.data2 & 0xffffffff;
- break;
+ rd |= ((u_int64_t)ext.data1 & 0xffff)
+ << 32;
+ rd |= (u_int64_t)ext.data2;
+ break;
case EXT_COMMUNITY_TRANS_IPV4:
rd = (1ULL << 48);
- rd |= (u_int64_t)ext.c.e.data1 << 16;
- rd |= ext.c.e.data2 & 0xffff;
+ rd |= (u_int64_t)ext.data1 << 16;
+ rd |= (u_int64_t)ext.data2 & 0xffff;
break;
case EXT_COMMUNITY_TRANS_FOUR_AS:
rd = (2ULL << 48);
- rd |= (u_int64_t)ext.c.e.data1 << 16;
- rd |= ext.c.e.data2 & 0xffff;
+ rd |= (u_int64_t)ext.data1 << 16;
+ rd |= (u_int64_t)ext.data2 & 0xffff;
break;
default:
errx(1, "bad encoding of rd");
@@ -1098,7 +1099,7 @@ parse_number(const char *word, struct parse_result *r, enum token_type type)
}
static void
-getcommunity(char *s, int large, u_int32_t *val, u_int8_t *flag)
+getcommunity(char *s, int large, u_int32_t *val, u_int32_t *flag)
{
long long max = USHRT_MAX;
const char *errstr;
@@ -1123,21 +1124,22 @@ getcommunity(char *s, int large, u_int32_t *val, u_int8_t *flag)
}
static void
-setcommunity(struct filter_community *c, u_int32_t as, u_int32_t data,
- u_int8_t asflag, u_int8_t dataflag)
+setcommunity(struct community *c, u_int32_t as, u_int32_t data,
+ u_int32_t asflag, u_int32_t dataflag)
{
- memset(c, 0, sizeof(*c));
- c->type = COMMUNITY_TYPE_BASIC;
- c->dflag1 = asflag;
- c->dflag2 = dataflag;
- c->c.b.data1 = as;
- c->c.b.data2 = data;
+ c->flags = COMMUNITY_TYPE_BASIC;
+ c->flags |= asflag << 8;
+ c->flags |= dataflag << 16;
+ c->data1 = as;
+ c->data2 = data;
+ c->data3 = 0;
}
static void
-parselargecommunity(struct filter_community *c, char *s)
+parselargecommunity(struct community *c, char *s)
{
char *p, *q;
+ u_int32_t dflag1, dflag2, dflag3;
if ((p = strchr(s, ':')) == NULL)
errx(1, "Bad community syntax");
@@ -1147,19 +1149,21 @@ parselargecommunity(struct filter_community *c, char *s)
errx(1, "Bad community syntax");
*q++ = 0;
- getcommunity(s, 1, &c->c.l.data1, &c->dflag1);
- getcommunity(p, 1, &c->c.l.data2, &c->dflag2);
- getcommunity(q, 1, &c->c.l.data3, &c->dflag3);
+ getcommunity(s, 1, &c->data1, &dflag1);
+ getcommunity(p, 1, &c->data2, &dflag2);
+ getcommunity(q, 1, &c->data3, &dflag3);
- c->type = COMMUNITY_TYPE_LARGE;
+ c->flags = COMMUNITY_TYPE_LARGE;
+ c->flags |= dflag1 << 8;;
+ c->flags |= dflag2 << 16;;
+ c->flags |= dflag3 << 24;;
}
void
-parsecommunity(struct filter_community *c, int type, char *s)
+parsecommunity(struct community *c, int type, char *s)
{
char *p;
- u_int32_t as, data;
- u_int8_t asflag, dataflag;
+ u_int32_t as, data, asflag, dataflag;
if (type == COMMUNITY_TYPE_LARGE) {
parselargecommunity(c, s);
@@ -1208,7 +1212,6 @@ parsesubtype(const char *name, int *type, int *subtype)
const struct ext_comm_pairs *cp;
int found = 0;
-printf("%s: looking for %s\n", __func__, name);
for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
if (strcmp(name, cp->subname) == 0) {
if (found == 0) {
@@ -1224,7 +1227,7 @@ printf("%s: looking for %s\n", __func__, name);
}
static int
-parseextvalue(int type, char *s, u_int32_t *v)
+parseextvalue(int type, char *s, u_int32_t *v, u_int32_t *flag)
{
const char *errstr;
char *p;
@@ -1233,6 +1236,14 @@ parseextvalue(int type, char *s, u_int32_t *v)
if (type != -1) {
/* nothing */
+ } else if (strcmp(s, "neighbor-as") == 0) {
+ *flag = COMMUNITY_NEIGHBOR_AS;
+ *v = 0;
+ return EXT_COMMUNITY_TRANS_FOUR_AS;
+ } else if (strcmp(s, "local-as") == 0) {
+ *flag = COMMUNITY_LOCAL_AS;
+ *v = 0;
+ return EXT_COMMUNITY_TRANS_FOUR_AS;
} else if ((p = strchr(s, '.')) == NULL) {
/* AS_PLAIN number (4 or 2 byte) */
strtonum(s, 0, USHRT_MAX, &errstr);
@@ -1284,16 +1295,20 @@ parseextvalue(int type, char *s, u_int32_t *v)
return (type);
}
-int
-parseextcommunity(struct filter_community *c, const char *t, char *s)
+void
+parseextcommunity(struct community *c, const char *t, char *s)
{
const struct ext_comm_pairs *cp;
- const char *errstr;
- u_int64_t ullval;
- u_int32_t uval;
char *p, *ep;
+ u_int64_t ullval;
+ u_int32_t uval, uval2, dflag1 = 0, dflag2 = 0;
int type = 0, subtype = 0;
+ if (strcmp(t, "*") == 0 && strcmp(s, "*") == 0) {
+ c->flags = COMMUNITY_TYPE_EXT;
+ c->flags |= COMMUNITY_ANY << 24;
+ return;
+ }
if (parsesubtype(t, &type, &subtype) == 0)
errx(1, "Bad ext-community unknown type");
@@ -1302,55 +1317,80 @@ parseextcommunity(struct filter_community *c, const char *t, char *s)
case EXT_COMMUNITY_TRANS_FOUR_AS:
case EXT_COMMUNITY_TRANS_IPV4:
case -1:
+ if (strcmp(s, "*") == 0) {
+ dflag1 = COMMUNITY_ANY;
+ break;
+ }
if ((p = strchr(s, ':')) == NULL)
errx(1, "Bad ext-community %s", s);
*p++ = '\0';
- type = parseextvalue(type, s, &uval);
+ type = parseextvalue(type, s, &uval, &dflag1);
+
switch (type) {
case EXT_COMMUNITY_TRANS_TWO_AS:
- ullval = strtonum(p, 0, UINT_MAX, &errstr);
+ getcommunity(p, 1, &uval2, &dflag2);
break;
case EXT_COMMUNITY_TRANS_IPV4:
case EXT_COMMUNITY_TRANS_FOUR_AS:
- ullval = strtonum(p, 0, USHRT_MAX, &errstr);
+ getcommunity(p, 0, &uval2, &dflag2);
break;
default:
errx(1, "parseextcommunity: unexpected result");
}
- if (errstr)
- errx(1, "Bad ext-community %s is %s", p, errstr);
- c->c.e.data1 = uval;
- c->c.e.data2 = ullval;
+
+ c->data1 = uval;
+ c->data2 = uval2;
break;
case EXT_COMMUNITY_TRANS_OPAQUE:
case EXT_COMMUNITY_TRANS_EVPN:
+ if (strcmp(s, "*") == 0) {
+ dflag1 = COMMUNITY_ANY;
+ break;
+ }
errno = 0;
ullval = strtoull(s, &ep, 0);
if (s[0] == '\0' || *ep != '\0')
errx(1, "Bad ext-community bad value");
if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX)
errx(1, "Bad ext-community value too big");
- c->c.e.data2 = ullval;
+ c->data1 = ullval >> 32;
+ c->data2 = ullval;
break;
case EXT_COMMUNITY_NON_TRANS_OPAQUE:
- if (strcmp(s, "valid") == 0)
- c->c.e.data2 = EXT_COMMUNITY_OVS_VALID;
- else if (strcmp(s, "invalid") == 0)
- c->c.e.data2 = EXT_COMMUNITY_OVS_INVALID;
- else if (strcmp(s, "not-found") == 0)
- c->c.e.data2 = EXT_COMMUNITY_OVS_NOTFOUND;
- else
- errx(1, "Bad ext-community %s", s);
- break;
+ if (subtype == EXT_COMMUNITY_SUBTYPE_OVS) {
+ if (strcmp(s, "valid") == 0) {
+ c->data2 = EXT_COMMUNITY_OVS_VALID;
+ break;
+ } else if (strcmp(s, "invalid") == 0) {
+ c->data2 = EXT_COMMUNITY_OVS_INVALID;
+ break;
+ } else if (strcmp(s, "not-found") == 0) {
+ c->data2 = EXT_COMMUNITY_OVS_NOTFOUND;
+ break;
+ } else if (strcmp(s, "*") == 0) {
+ dflag1 = COMMUNITY_ANY;
+ break;
+ }
+ }
+ errx(1, "Bad ext-community %s", s);
}
- c->c.e.type = type;
- c->c.e.subtype = subtype;
+ c->data3 = type << 8 | subtype;
+
+ /* special handling of ext-community rt * since type is not known */
+ if (dflag1 == COMMUNITY_ANY && type == -1) {
+ c->flags = COMMUNITY_TYPE_EXT;
+ c->flags |= dflag1 << 8;
+ return;
+ }
+
/* verify type/subtype combo */
for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
if (cp->type == type && cp->subtype == subtype) {
- c->type = COMMUNITY_TYPE_EXT;
- return (0);
+ c->flags = COMMUNITY_TYPE_EXT;
+ c->flags |= dflag1 << 8;
+ c->flags |= dflag2 << 16;
+ return;
}
}
diff --git a/usr.sbin/bgpctl/parser.h b/usr.sbin/bgpctl/parser.h
index 4981054cdab..bfafb336405 100644
--- a/usr.sbin/bgpctl/parser.h
+++ b/usr.sbin/bgpctl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.35 2019/02/11 15:47:55 claudio Exp $ */
+/* $OpenBSD: parser.h,v 1.36 2019/06/17 11:03:07 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -62,7 +62,7 @@ struct parse_result {
struct bgpd_addr peeraddr;
struct filter_as as;
struct filter_set_head set;
- struct filter_community community;
+ struct community community;
char peerdesc[PEER_DESCR_LEN];
char rib[PEER_DESCR_LEN];
char shutcomm[SHUT_COMM_LEN];