summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2009-06-04 22:08:19 +0000
committerclaudio <claudio@openbsd.org>2009-06-04 22:08:19 +0000
commit16b4414f554de1674b3b28ea22c49d8c7168f732 (patch)
tree7ef6ad63e0dd4192129abc0eb28fa4e6b750e943
parentMore fallback from struct disklabel changes, yawn (diff)
downloadwireguard-openbsd-16b4414f554de1674b3b28ea22c49d8c7168f732.tar.xz
wireguard-openbsd-16b4414f554de1674b3b28ea22c49d8c7168f732.zip
Make mrt understand alternate RIB plus remove some other static rib references.
There is still a problem with the mrt dumps because we only allow one in the RDE. This needs some additional work.
-rw-r--r--usr.sbin/bgpd/mrt.c6
-rw-r--r--usr.sbin/bgpd/mrt.h3
-rw-r--r--usr.sbin/bgpd/parse.y81
-rw-r--r--usr.sbin/bgpd/rde.c28
4 files changed, 96 insertions, 22 deletions
diff --git a/usr.sbin/bgpd/mrt.c b/usr.sbin/bgpd/mrt.c
index 837f3c60d79..31b2de8ec4e 100644
--- a/usr.sbin/bgpd/mrt.c
+++ b/usr.sbin/bgpd/mrt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mrt.c,v 1.60 2009/05/17 12:25:15 claudio Exp $ */
+/* $OpenBSD: mrt.c,v 1.61 2009/06/04 22:08:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -676,8 +676,8 @@ mrt_get(struct mrt_head *c, struct mrt *m)
LIST_FOREACH(t, c, entry) {
if (t->type != m->type)
continue;
- if (t->type == MRT_TABLE_DUMP)
- return (t);
+ if (strcmp(t->rib, m->rib))
+ continue;
if (t->peer_id == m->peer_id &&
t->group_id == m->group_id)
return (t);
diff --git a/usr.sbin/bgpd/mrt.h b/usr.sbin/bgpd/mrt.h
index 1ee1202455d..c19a983f516 100644
--- a/usr.sbin/bgpd/mrt.h
+++ b/usr.sbin/bgpd/mrt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mrt.h,v 1.20 2009/05/17 12:25:15 claudio Exp $ */
+/* $OpenBSD: mrt.h,v 1.21 2009/06/04 22:08:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -271,6 +271,7 @@ enum mrt_state {
};
struct mrt {
+ char rib[PEER_DESCR_LEN];
struct msgbuf wbuf;
LIST_ENTRY(mrt) entry;
u_int32_t peer_id;
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index a960352d4ec..b02cd4f13f7 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.226 2009/06/04 04:46:42 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.227 2009/06/04 22:08:19 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -111,8 +111,10 @@ struct filter_match_l {
struct peer *alloc_peer(void);
struct peer *new_peer(void);
struct peer *new_group(void);
-int add_mrtconfig(enum mrt_type, char *, time_t, struct peer *);
+int add_mrtconfig(enum mrt_type, char *, time_t, struct peer *,
+ char *);
int add_rib(char *, int);
+int find_rib(char *);
int get_id(struct peer *);
int expand_rule(struct filter_rule *, struct filter_peers_l *,
struct filter_match_l *, struct filter_set_head *);
@@ -489,12 +491,42 @@ conf_main : AS as4number {
YYERROR;
}
free($2);
- if (add_mrtconfig(action, $3, $4, NULL) == -1) {
+ if (add_mrtconfig(action, $3, $4, NULL, NULL) == -1) {
free($3);
YYERROR;
}
free($3);
}
+ | DUMP RIB STRING STRING STRING optnumber {
+ int action;
+
+ if ($6 < 0 || $6 > UINT_MAX) {
+ yyerror("bad timeout");
+ free($3);
+ free($4);
+ free($5);
+ YYERROR;
+ }
+ if (!strcmp($4, "table"))
+ action = MRT_TABLE_DUMP;
+ else if (!strcmp($4, "table-mp"))
+ action = MRT_TABLE_DUMP_MP;
+ else {
+ yyerror("unknown mrt dump type");
+ free($3);
+ free($4);
+ free($5);
+ YYERROR;
+ }
+ free($4);
+ if (add_mrtconfig(action, $5, $6, NULL, $3) == -1) {
+ free($3);
+ free($5);
+ YYERROR;
+ }
+ free($3);
+ free($5);
+ }
| mrtdump
| RDE STRING EVALUATE {
if (!strcmp($2, "route-age"))
@@ -577,7 +609,8 @@ mrtdump : DUMP STRING inout STRING optnumber {
free($4);
YYERROR;
}
- if (add_mrtconfig(action, $4, $5, curpeer) == -1) {
+ if (add_mrtconfig(action, $4, $5, curpeer, NULL) ==
+ -1) {
free($2);
free($4);
YYERROR;
@@ -2536,11 +2569,15 @@ new_group(void)
}
int
-add_mrtconfig(enum mrt_type type, char *name, time_t timeout, struct peer *p)
+add_mrtconfig(enum mrt_type type, char *name, time_t timeout, struct peer *p,
+ char *rib)
{
struct mrt *m, *n;
LIST_FOREACH(m, mrtconf, entry) {
+ if ((rib && strcmp(rib, m->rib)) ||
+ (!rib && *m->rib))
+ continue;
if (p == NULL) {
if (m->peer_id != 0 || m->group_id != 0)
continue;
@@ -2576,6 +2613,20 @@ add_mrtconfig(enum mrt_type type, char *name, time_t timeout, struct peer *p)
n->group_id = 0;
}
}
+ if (rib) {
+ if (!find_rib(rib)) {
+ yyerror("rib \"%s\" does not exist.", rib);
+ free(n);
+ return (-1);
+ }
+ if (strlcpy(n->rib, rib, sizeof(n->rib)) >=
+ sizeof(n->rib)) {
+ yyerror("rib name \"%s\" too long: max %u",
+ name, sizeof(n->rib) - 1);
+ free(n);
+ return (-1);
+ }
+ }
LIST_INSERT_HEAD(mrtconf, n, entry);
@@ -2587,11 +2638,9 @@ add_rib(char *name, int noeval)
{
struct rde_rib *rr;
- SIMPLEQ_FOREACH(rr, &ribnames, entry) {
- if (!strcmp(rr->name, name)) {
- yyerror("rib \"%s\" allready exists.", name);
- return (-1);
- }
+ if (find_rib(name)) {
+ yyerror("rib \"%s\" allready exists.", name);
+ return (-1);
}
if ((rr = calloc(1, sizeof(*rr))) == NULL) {
@@ -2610,6 +2659,18 @@ add_rib(char *name, int noeval)
}
int
+find_rib(char *name)
+{
+ struct rde_rib *rr;
+
+ SIMPLEQ_FOREACH(rr, &ribnames, entry) {
+ if (!strcmp(rr->name, name))
+ return (1);
+ }
+ return (0);
+}
+
+int
get_id(struct peer *newpeer)
{
struct peer *p;
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 86723e9bcb8..e5acf6f9727 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.251 2009/06/04 05:29:06 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.252 2009/06/04 22:08:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -630,9 +630,12 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
rib_dump(&ribs[0], rde_softreconfig_in, NULL,
AF_UNSPEC);
/* then sync peers */
- if (reconf_out)
- rib_dump(&ribs[1], rde_softreconfig_out, NULL,
- AF_UNSPEC);
+ if (reconf_out) {
+ int i;
+ for (i = 1; i < rib_size; i++)
+ rib_dump(&ribs[i], rde_softreconfig_out,
+ NULL, AF_UNSPEC);
+ }
while ((r = TAILQ_FIRST(rules_l)) != NULL) {
TAILQ_REMOVE(rules_l, r, entry);
@@ -681,15 +684,22 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
"but didn't receive any");
else if (xmrt->type == MRT_TABLE_DUMP ||
xmrt->type == MRT_TABLE_DUMP_MP) {
+ u_int16_t id;
+
/* do not dump if another is still running */
- if (mrt == NULL || mrt->wbuf.queued == 0) {
+ id = rib_find(mrt->rib);
+ if (id == RIB_FAILED)
+ log_warnx("non existing RIB %s for mrt "
+ "dump", mrt->rib);
+ else if (mrt == NULL || mrt->wbuf.queued == 0) {
free(mrt);
mrt = xmrt;
mrt_clear_seq();
- rib_dump(&ribs[1], mrt_dump_upcall, mrt,
- AF_UNSPEC);
+ rib_dump(&ribs[id], mrt_dump_upcall,
+ mrt, AF_UNSPEC);
break;
- }
+ } else
+ log_warnx("dump failed: already in progress");
}
close(xmrt->wbuf.fd);
free(xmrt);
@@ -2059,6 +2069,8 @@ rde_softreconfig_out(struct rib_entry *re, void *ptr)
LIST_FOREACH(peer, &peerlist, peer_l) {
if (peer->conf.id == 0)
continue;
+ if (peer->ribid != re->ribid)
+ continue;
if (peer->reconf_out == 0)
continue;
if (up_test_update(peer, p) != 1)