summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.c12
-rw-r--r--usr.sbin/bgpd/bgpd.h11
-rw-r--r--usr.sbin/bgpd/name2id.c27
-rw-r--r--usr.sbin/bgpd/parse.y55
-rw-r--r--usr.sbin/bgpd/rde.c28
-rw-r--r--usr.sbin/bgpd/rde.h6
-rw-r--r--usr.sbin/bgpd/rde_rib.c18
-rw-r--r--usr.sbin/bgpd/session.c12
-rw-r--r--usr.sbin/bgpd/session.h9
9 files changed, 120 insertions, 58 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index 1ebdb298aba..9fae6fb701d 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.145 2008/05/12 19:15:02 pyr Exp $ */
+/* $OpenBSD: bgpd.c,v 1.146 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -58,6 +58,7 @@ volatile sig_atomic_t reconfig = 0;
pid_t reconfpid = 0;
struct imsgbuf *ibuf_se;
struct imsgbuf *ibuf_rde;
+struct rib_names ribnames = SIMPLEQ_HEAD_INITIALIZER(ribnames);
void
sighdlr(int sig)
@@ -108,6 +109,7 @@ main(int argc, char *argv[])
struct filter_rule *r;
struct mrt *m;
struct listen_addr *la;
+ struct rde_rib *rr;
struct pollfd pfd[POLL_MAX];
pid_t io_pid = 0, rde_pid = 0, pid;
char *conffile;
@@ -225,9 +227,9 @@ main(int argc, char *argv[])
prepare_listeners(&conf);
/* fork children */
- rde_pid = rde_main(&conf, peer_l, &net_l, rules_l, &mrt_l,
+ rde_pid = rde_main(&conf, peer_l, &net_l, rules_l, &mrt_l, &ribnames,
pipe_m2r, pipe_s2r, pipe_m2s, pipe_s2r_c, debug);
- io_pid = session_main(&conf, peer_l, &net_l, rules_l, &mrt_l,
+ io_pid = session_main(&conf, peer_l, &net_l, rules_l, &mrt_l, &ribnames,
pipe_m2s, pipe_s2r, pipe_m2r, pipe_s2r_c);
setproctitle("parent");
@@ -271,6 +273,10 @@ main(int argc, char *argv[])
close(la->fd);
la->fd = -1;
}
+ while ((rr = SIMPLEQ_FIRST(&ribnames))) {
+ SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
+ free(rr);
+ }
mrt_reconfigure(&mrt_l);
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index cac9fc9aa8c..0ab07b09512 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.232 2009/05/27 04:18:21 reyk Exp $ */
+/* $OpenBSD: bgpd.h,v 1.233 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -722,6 +722,15 @@ struct rde_memstats {
int64_t attr_dcnt;
};
+struct rde_rib {
+ SIMPLEQ_ENTRY(rde_rib) entry;
+ char name[PEER_DESCR_LEN];
+ u_int16_t id;
+ u_int16_t flags;
+};
+SIMPLEQ_HEAD(rib_names, rde_rib);
+extern struct rib_names ribnames;
+
/* Address Family Numbers as per RFC 1700 */
#define AFI_IPv4 1
#define AFI_IPv6 2
diff --git a/usr.sbin/bgpd/name2id.c b/usr.sbin/bgpd/name2id.c
index 9e8774fd628..2af133278f9 100644
--- a/usr.sbin/bgpd/name2id.c
+++ b/usr.sbin/bgpd/name2id.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: name2id.c,v 1.8 2009/05/17 12:25:15 claudio Exp $ */
+/* $OpenBSD: name2id.c,v 1.9 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -43,35 +43,10 @@ const char *_id2name(struct n2id_labels *, u_int16_t);
void _unref(struct n2id_labels *, u_int16_t);
void _ref(struct n2id_labels *, u_int16_t);
-struct n2id_labels rib_labels = TAILQ_HEAD_INITIALIZER(rib_labels);
struct n2id_labels rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
struct n2id_labels pftable_labels = TAILQ_HEAD_INITIALIZER(pftable_labels);
u_int16_t
-rib_name2id(const char *name)
-{
- return (_name2id(&rib_labels, name));
-}
-
-const char *
-rib_id2name(u_int16_t id)
-{
- return (_id2name(&rib_labels, id));
-}
-
-void
-rib_unref(u_int16_t id)
-{
- _unref(&rib_labels, id);
-}
-
-void
-rib_ref(u_int16_t id)
-{
- _ref(&rib_labels, id);
-}
-
-u_int16_t
rtlabel_name2id(const char *name)
{
return (_name2id(&rt_labels, name));
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 5e72b794674..a960352d4ec 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.225 2009/05/27 04:18:21 reyk Exp $ */
+/* $OpenBSD: parse.y,v 1.226 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -39,6 +39,7 @@
#include "bgpd.h"
#include "mrt.h"
#include "session.h"
+#include "rde.h"
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
static struct file {
@@ -111,6 +112,7 @@ 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_rib(char *, int);
int get_id(struct peer *);
int expand_rule(struct filter_rule *, struct filter_peers_l *,
struct filter_match_l *, struct filter_set_head *);
@@ -155,7 +157,7 @@ typedef struct {
%}
%token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE RTABLE
-%token RDE EVALUATE IGNORE COMPARE
+%token RDE RIB EVALUATE IGNORE COMPARE
%token GROUP NEIGHBOR NETWORK
%token REMOTEAS DESCR LOCALADDR MULTIHOP PASSIVE MAXPREFIX RESTART
%token ANNOUNCE DEMOTE CONNECTRETRY
@@ -381,6 +383,24 @@ conf_main : AS as4number {
else
conf->flags &= ~BGPD_FLAG_NO_EVALUATE;
}
+ | RDE RIB STRING {
+ if (add_rib($3, 0)) {
+ free($3);
+ YYERROR;
+ }
+ free($3);
+ }
+ | RDE RIB STRING yesno EVALUATE {
+ if ($4) {
+ free($3);
+ YYERROR;
+ }
+ if (!add_rib($3, 1)) {
+ free($3);
+ YYERROR;
+ }
+ free($3);
+ }
| TRANSPARENT yesno {
if ($2 == 1)
conf->flags |= BGPD_FLAG_DECISION_TRANS_AS;
@@ -1840,6 +1860,7 @@ lookup(char *s)
{ "reject", REJECT},
{ "remote-as", REMOTEAS},
{ "restart", RESTART},
+ { "rib", RIB},
{ "route-collector", ROUTECOLL},
{ "route-reflector", REFLECTOR},
{ "router-id", ROUTERID},
@@ -2227,6 +2248,9 @@ parse_config(char *filename, struct bgpd_config *xconf,
/* init the empty filter list for later */
TAILQ_INIT(xfilter_l);
+ add_rib("Adj-RIB-In", 1);
+ add_rib("DEFAULT", 0);
+
yyparse();
errors = file->errors;
popfile();
@@ -2559,6 +2583,33 @@ add_mrtconfig(enum mrt_type type, char *name, time_t timeout, struct peer *p)
}
int
+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 ((rr = calloc(1, sizeof(*rr))) == NULL) {
+ log_warn("add_rib");
+ return (-1);
+ }
+ if (strlcpy(rr->name, name, sizeof(rr->name)) >= sizeof(rr->name)) {
+ yyerror("rib name \"%s\" too long: max %u",
+ name, sizeof(rr->name) - 1);
+ return (-1);
+ }
+ if (noeval)
+ rr->flags |= F_RIB_NOEVALUATE;
+ SIMPLEQ_INSERT_TAIL(&ribnames, rr, entry);
+ 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 4f830d55300..1e22999c170 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.249 2009/06/02 01:02:28 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.250 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -139,8 +139,8 @@ u_int32_t nexthophashsize = 64;
pid_t
rde_main(struct bgpd_config *config, struct peer *peer_l,
struct network_head *net_l, struct filter_head *rules,
- struct mrt_head *mrt_l, int pipe_m2r[2], int pipe_s2r[2], int pipe_m2s[2],
- int pipe_s2rctl[2], int debug)
+ struct mrt_head *mrt_l, struct rib_names *rib_n, int pipe_m2r[2],
+ int pipe_s2r[2], int pipe_m2s[2], int pipe_s2rctl[2], int debug)
{
pid_t pid;
struct passwd *pw;
@@ -150,6 +150,7 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
struct filter_rule *f;
struct filter_set *set;
struct nexthop *nh;
+ struct rde_rib *rr;
int i, timeout;
switch (pid = fork()) {
@@ -219,7 +220,12 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
free(config->listen_addrs);
pt_init();
- rib_init();
+ while ((rr = SIMPLEQ_FIRST(&ribnames))) {
+ SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
+ rib_new(-1, rr->name, rr->flags);
+ free(rr);
+ }
+
path_init(pathhashsize);
aspath_init(pathhashsize);
attr_init(attrhashsize);
@@ -1035,12 +1041,15 @@ done:
return (error);
}
+extern u_int16_t rib_size;
+
void
rde_update_update(struct rde_peer *peer, struct rde_aspath *asp,
struct bgpd_addr *prefix, u_int8_t prefixlen)
{
struct rde_aspath *fasp;
int r = 0;
+ u_int16_t i;
peer->prefix_rcvd_update++;
/* add original path to the Adj-RIB-In */
@@ -1057,7 +1066,8 @@ rde_update_update(struct rde_peer *peer, struct rde_aspath *asp,
rde_update_log("update", peer, &fasp->nexthop->exit_nexthop,
prefix, prefixlen);
- r += path_update(&ribs[1], peer, fasp, prefix, prefixlen);
+ for (i = 1; i < rib_size; i++)
+ r += path_update(&ribs[i], peer, fasp, prefix, prefixlen);
done:
/* free modified aspath */
@@ -1073,12 +1083,16 @@ rde_update_withdraw(struct rde_peer *peer, struct bgpd_addr *prefix,
u_int8_t prefixlen)
{
int r = 0;
+ u_int16_t i;
peer->prefix_rcvd_withdraw++;
rde_update_log("withdraw", peer, NULL, prefix, prefixlen);
- r += prefix_remove(&ribs[1], peer, prefix, prefixlen, 0);
- r += prefix_remove(&ribs[0], peer, prefix, prefixlen, 0);
+ for (i = rib_size - 1; ; i--) {
+ r += prefix_remove(&ribs[i], peer, prefix, prefixlen, 0);
+ if (i == 0)
+ break;
+ }
if (r)
peer->prefix_cnt--;
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index fc469950e44..00ea19504ad 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.115 2009/06/03 20:17:59 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.116 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -246,6 +246,7 @@ struct rib_context {
struct rib *ctx_rib;
void (*ctx_upcall)(struct rib_entry *, void *);
void (*ctx_done)(void *);
+ void (*ctx_wait)(void *);
void *ctx_arg;
unsigned int ctx_count;
sa_family_t ctx_af;
@@ -345,8 +346,7 @@ void community_delete(struct rde_aspath *, int, int);
extern u_int16_t rib_size;
extern struct rib *ribs;
-void rib_init(void);
-u_int16_t rib_new(u_int16_t, char *, u_int16_t);
+u_int16_t rib_new(int, char *, u_int16_t);
void rib_free(struct rib *);
struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int);
struct rib_entry *rib_lookup(struct rib *, struct bgpd_addr *);
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index b023c3c7fca..761db5db985 100644
--- a/usr.sbin/bgpd/rde_rib.c
+++ b/usr.sbin/bgpd/rde_rib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_rib.c,v 1.112 2009/06/03 20:22:04 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.113 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -49,19 +49,19 @@ RB_GENERATE(rib_tree, rib_entry, rib_e, rib_compare);
/* RIB specific functions */
-void
-rib_init(void)
-{
- rib_new(1, "DEFAULT", 0);
- rib_new(0, "Adj-RIB-In", F_RIB_NOEVALUATE);
-}
-
u_int16_t
-rib_new(u_int16_t id, char *name, u_int16_t flags)
+rib_new(int id, char *name, u_int16_t flags)
{
struct rib *xribs;
size_t newsize;
+ if (id < 0) {
+ for (id = 0; id < rib_size; id++) {
+ if (*ribs[id].name == '\0')
+ break;
+ }
+ }
+
if (id >= rib_size) {
newsize = sizeof(struct rib) * (id + 1);
if ((xribs = realloc(ribs, newsize)) == NULL) {
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 42c5dffbf95..c43f7be159d 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.290 2009/05/27 04:18:21 reyk Exp $ */
+/* $OpenBSD: session.c,v 1.291 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -177,8 +177,8 @@ setup_listeners(u_int *la_cnt)
pid_t
session_main(struct bgpd_config *config, struct peer *cpeers,
struct network_head *net_l, struct filter_head *rules,
- struct mrt_head *m_l, int pipe_m2s[2], int pipe_s2r[2], int pipe_m2r[2],
- int pipe_s2rctl[2])
+ struct mrt_head *m_l, struct rib_names *rib_l, int pipe_m2s[2],
+ int pipe_s2r[2], int pipe_m2r[2], int pipe_s2rctl[2])
{
int nfds, timeout;
unsigned int i, j, idx_peers, idx_listeners, idx_mrts;
@@ -195,6 +195,7 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
struct pollfd *pfd = NULL;
struct ctl_conn *ctl_conn;
struct listen_addr *la;
+ struct rde_rib *rr;
void *newp;
short events;
@@ -283,6 +284,11 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
LIST_REMOVE(m, entry);
free(m);
}
+ /* rib names not used in the SE */
+ while ((rr = SIMPLEQ_FIRST(&ribnames))) {
+ SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
+ free(rr);
+ }
while (session_quit == 0) {
/* check for peers to be initialized or deleted */
diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h
index b1f8553444b..3cd4c52b87a 100644
--- a/usr.sbin/bgpd/session.h
+++ b/usr.sbin/bgpd/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.99 2008/09/11 14:49:58 henning Exp $ */
+/* $OpenBSD: session.h,v 1.100 2009/06/04 04:46:42 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -228,7 +228,8 @@ struct ctl_timer {
void session_socket_blockmode(int, enum blockmodes);
pid_t session_main(struct bgpd_config *, struct peer *,
struct network_head *, struct filter_head *,
- struct mrt_head *, int[2], int[2], int[2], int[2]);
+ struct mrt_head *, struct rib_names *,
+ int[2], int[2], int[2], int[2]);
void bgp_fsm(struct peer *, enum session_events);
int session_neighbor_rrefresh(struct peer *p);
struct peer *getpeerbyaddr(struct bgpd_addr *);
@@ -255,8 +256,8 @@ void prepare_listeners(struct bgpd_config *);
/* rde.c */
pid_t rde_main(struct bgpd_config *, struct peer *, struct network_head *,
- struct filter_head *, struct mrt_head *, int[2], int[2], int[2],
- int[2], int);
+ struct filter_head *, struct mrt_head *, struct rib_names *,
+ int[2], int[2], int[2], int[2], int);
/* control.c */
int control_init(int, char *);