summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/bgpd.h4
-rw-r--r--usr.sbin/bgpd/parse.y36
-rw-r--r--usr.sbin/bgpd/printconf.c6
-rw-r--r--usr.sbin/bgpd/rde.c118
-rw-r--r--usr.sbin/bgpd/rde.h10
-rw-r--r--usr.sbin/bgpd/rde_filter.c6
-rw-r--r--usr.sbin/bgpd/rde_update.c18
7 files changed, 120 insertions, 78 deletions
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index a650688de42..749c3cbd4b2 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.234 2009/06/05 19:52:32 claudio Exp $ */
+/* $OpenBSD: bgpd.h,v 1.235 2009/06/06 01:10:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -603,6 +603,7 @@ enum comp_ops {
struct filter_peers {
u_int32_t peerid;
u_int32_t groupid;
+ u_int16_t ribid;
};
/* special community type */
@@ -657,6 +658,7 @@ TAILQ_HEAD(filter_head, filter_rule);
struct filter_rule {
TAILQ_ENTRY(filter_rule) entry;
+ char rib[PEER_DESCR_LEN];
struct filter_peers peer;
struct filter_match match;
struct filter_set_head set;
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index aa453587714..175a9a02fb9 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.230 2009/06/06 01:07:01 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.231 2009/06/06 01:10:29 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -182,7 +182,7 @@ typedef struct {
%token <v.number> NUMBER
%type <v.number> asnumber as4number optnumber yesno inout
%type <v.number> espah family restart
-%type <v.string> string
+%type <v.string> string filter_rib
%type <v.addr> address
%type <v.prefix> prefix addrspec
%type <v.u8> action quick direction delete
@@ -1197,16 +1197,37 @@ encspec : /* nada */ {
}
;
-filterrule : action quick direction filter_peer_h filter_match_h filter_set
+filterrule : action quick filter_rib direction filter_peer_h filter_match_h filter_set
{
struct filter_rule r;
bzero(&r, sizeof(r));
r.action = $1;
r.quick = $2;
- r.dir = $3;
-
- if (expand_rule(&r, $4, &$5, $6) == -1)
+ r.dir = $4;
+ if ($3) {
+ if (r.dir != DIR_IN) {
+ yyerror("rib only allowed on \"from\" "
+ "rules.");
+ free($3);
+ YYERROR;
+ }
+ if (!find_rib($3)) {
+ yyerror("rib \"%s\" does not exist.",
+ $3);
+ free($3);
+ YYERROR;
+ }
+ if (strlcpy(r.rib, $3, sizeof(r.rib)) >=
+ sizeof(r.rib)) {
+ yyerror("rib name \"%s\" too long: "
+ "max %u", $3, sizeof(r.rib) - 1);
+ free($3);
+ YYERROR;
+ }
+ free($3);
+ }
+ if (expand_rule(&r, $5, &$6, $7) == -1)
YYERROR;
}
;
@@ -1224,6 +1245,9 @@ direction : FROM { $$ = DIR_IN; }
| TO { $$ = DIR_OUT; }
;
+filter_rib : /* empty */ { $$ = NULL; }
+ | RIB STRING { $$ = $2; }
+
filter_peer_h : filter_peer
| '{' filter_peer_l '}' { $$ = $2; }
;
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index 358b55e5c47..c64d23dee95 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.69 2009/06/05 20:26:38 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.70 2009/06/06 01:10:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -423,10 +423,12 @@ print_rule(struct peer *peer_l, struct filter_rule *r)
printf("deny ");
else
printf("match ");
-
if (r->quick)
printf("quick ");
+ if (r->rib[0])
+ printf("rib %s ", r->rib);
+
if (r->dir == DIR_IN)
printf("from ");
else if (r->dir == DIR_OUT)
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 26cc8436413..eedec0971ad 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.256 2009/06/06 01:02:51 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.257 2009/06/06 01:10:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -59,7 +59,7 @@ int rde_update_get_prefix6(u_char *, u_int16_t, struct bgpd_addr *,
u_int8_t *);
void rde_update_err(struct rde_peer *, u_int8_t , u_int8_t,
void *, u_int16_t);
-void rde_update_log(const char *,
+void rde_update_log(const char *, u_int16_t,
const struct rde_peer *, const struct bgpd_addr *,
const struct bgpd_addr *, u_int8_t);
void rde_as4byte_fixup(struct rde_peer *, struct rde_aspath *);
@@ -246,6 +246,7 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
log_info("route decision engine ready");
TAILQ_FOREACH(f, rules, entry) {
+ f->peer.ribid = rib_find(f->rib);
TAILQ_FOREACH(set, &f->set, entry) {
if (set->type == ACTION_SET_NEXTHOP) {
nh = nexthop_get(&set->action.nexthop);
@@ -622,6 +623,7 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
fatal(NULL);
memcpy(r, imsg.data, sizeof(struct filter_rule));
TAILQ_INIT(&r->set);
+ r->peer.ribid = rib_find(r->rib);
parent_set = &r->set;
TAILQ_INSERT_TAIL(newrules, r, entry);
break;
@@ -1081,23 +1083,24 @@ rde_update_update(struct rde_peer *peer, struct rde_aspath *asp,
if (peer->conf.softreconfig_in)
r += path_update(&ribs[0], peer, asp, prefix, prefixlen);
- /* input filter */
- if (rde_filter(&fasp, rules_l, peer, asp, prefix, prefixlen,
- peer, DIR_IN) == ACTION_DENY)
- goto done;
+ for (i = 1; i < rib_size; i++) {
+ /* input filter */
+ if (rde_filter(i, &fasp, rules_l, peer, asp, prefix, prefixlen,
+ peer, DIR_IN) == ACTION_DENY)
+ goto done;
- if (fasp == NULL)
- fasp = asp;
+ if (fasp == NULL)
+ fasp = asp;
- rde_update_log("update", peer, &fasp->nexthop->exit_nexthop,
- prefix, prefixlen);
- for (i = 1; i < rib_size; i++)
+ rde_update_log("update", i, peer, &fasp->nexthop->exit_nexthop,
+ prefix, prefixlen);
r += path_update(&ribs[i], peer, fasp, prefix, prefixlen);
done:
- /* free modified aspath */
- if (fasp != asp)
- path_put(fasp);
+ /* free modified aspath */
+ if (fasp != asp)
+ path_put(fasp);
+ }
if (r)
peer->prefix_cnt++;
@@ -1111,10 +1114,13 @@ rde_update_withdraw(struct rde_peer *peer, struct bgpd_addr *prefix,
u_int16_t i;
peer->prefix_rcvd_withdraw++;
- rde_update_log("withdraw", peer, NULL, prefix, prefixlen);
for (i = rib_size - 1; ; i--) {
- r += prefix_remove(&ribs[i], peer, prefix, prefixlen, 0);
+ if (prefix_remove(&ribs[i], peer, prefix, prefixlen, 0)) {
+ rde_update_log("withdraw", i, peer, NULL, prefix,
+ prefixlen);
+ r++;
+ }
if (i == 0)
break;
}
@@ -1563,7 +1569,7 @@ rde_update_err(struct rde_peer *peer, u_int8_t error, u_int8_t suberr,
}
void
-rde_update_log(const char *message,
+rde_update_log(const char *message, u_int16_t rid,
const struct rde_peer *peer, const struct bgpd_addr *next,
const struct bgpd_addr *prefix, u_int8_t prefixlen)
{
@@ -1580,7 +1586,7 @@ rde_update_log(const char *message,
if (asprintf(&p, "%s/%u", log_addr(prefix), prefixlen) == -1)
p = NULL;
l = log_fmt_peer(&peer->conf);
- log_info("%s AS%s: %s %s%s",
+ log_info("Rib %s: %s AS%s: %s %s%s", ribs[rid].name,
l, log_as(peer->conf.remote_as), message,
p ? p : "out of memory", n ? n : "");
@@ -1796,7 +1802,7 @@ rde_dump_filterout(struct rde_peer *peer, struct prefix *p,
return;
pt_getaddr(p->prefix, &addr);
- a = rde_filter(&asp, rules_l, peer, p->aspath, &addr,
+ a = rde_filter(1 /* XXX */, &asp, rules_l, peer, p->aspath, &addr,
p->prefix->prefixlen, p->aspath->peer, DIR_OUT);
if (asp)
asp->peer = p->aspath->peer;
@@ -2125,10 +2131,10 @@ rde_softreconfig_out(struct rib_entry *re, void *ptr)
if (up_test_update(peer, p) != 1)
continue;
- oa = rde_filter(&oasp, rules_l, peer, p->aspath, &addr,
- pt->prefixlen, p->aspath->peer, DIR_OUT);
- na = rde_filter(&nasp, newrules, peer, p->aspath, &addr,
- pt->prefixlen, p->aspath->peer, DIR_OUT);
+ oa = rde_filter(re->ribid, &oasp, rules_l, peer, p->aspath,
+ &addr, pt->prefixlen, p->aspath->peer, DIR_OUT);
+ na = rde_filter(re->ribid, &nasp, newrules, peer, p->aspath,
+ &addr, pt->prefixlen, p->aspath->peer, DIR_OUT);
oasp = oasp != NULL ? oasp : p->aspath;
nasp = nasp != NULL ? nasp : p->aspath;
@@ -2169,6 +2175,7 @@ rde_softreconfig_in(struct rib_entry *re, void *ptr)
struct rde_aspath *asp, *oasp, *nasp;
enum filter_actions oa, na;
struct bgpd_addr addr;
+ u_int16_t i;
pt = re->prefix;
pt_getaddr(pt, &addr);
@@ -2183,39 +2190,44 @@ rde_softreconfig_in(struct rib_entry *re, void *ptr)
if (peer->reconf_in == 0)
continue;
- /* check if prefix changed */
- oa = rde_filter(&oasp, rules_l, peer, asp, &addr,
- pt->prefixlen, peer, DIR_IN);
- na = rde_filter(&nasp, newrules, peer, asp, &addr,
- pt->prefixlen, peer, DIR_IN);
- oasp = oasp != NULL ? oasp : asp;
- nasp = nasp != NULL ? nasp : asp;
-
- if (oa == ACTION_DENY && na == ACTION_DENY)
- /* nothing todo */
- goto done;
- if (oa == ACTION_DENY && na == ACTION_ALLOW) {
- /* update Local-RIB */
- path_update(&ribs[1], peer, nasp, &addr, pt->prefixlen);
- goto done;
- }
- if (oa == ACTION_ALLOW && na == ACTION_DENY) {
- /* remove from Local-RIB */
- prefix_remove(&ribs[1], peer, &addr, pt->prefixlen, 0);
- goto done;
- }
- if (oa == ACTION_ALLOW && na == ACTION_ALLOW) {
- if (path_compare(nasp, oasp) == 0)
+ for (i = 1; i < rib_size; i++) {
+ /* check if prefix changed */
+ oa = rde_filter(i, &oasp, rules_l, peer, asp, &addr,
+ pt->prefixlen, peer, DIR_IN);
+ na = rde_filter(i, &nasp, newrules, peer, asp, &addr,
+ pt->prefixlen, peer, DIR_IN);
+ oasp = oasp != NULL ? oasp : asp;
+ nasp = nasp != NULL ? nasp : asp;
+
+ if (oa == ACTION_DENY && na == ACTION_DENY)
+ /* nothing todo */
goto done;
- /* send update */
- path_update(&ribs[1], peer, nasp, &addr, pt->prefixlen);
- }
+ if (oa == ACTION_DENY && na == ACTION_ALLOW) {
+ /* update Local-RIB */
+ path_update(&ribs[i], peer, nasp, &addr,
+ pt->prefixlen);
+ goto done;
+ }
+ if (oa == ACTION_ALLOW && na == ACTION_DENY) {
+ /* remove from Local-RIB */
+ prefix_remove(&ribs[i], peer, &addr,
+ pt->prefixlen, 0);
+ goto done;
+ }
+ if (oa == ACTION_ALLOW && na == ACTION_ALLOW) {
+ if (path_compare(nasp, oasp) == 0)
+ goto done;
+ /* send update */
+ path_update(&ribs[1], peer, nasp, &addr,
+ pt->prefixlen);
+ }
done:
- if (oasp != asp)
- path_put(oasp);
- if (nasp != asp)
- path_put(nasp);
+ if (oasp != asp)
+ path_put(oasp);
+ if (nasp != asp)
+ path_put(nasp);
+ }
}
}
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 41874f39e85..2664fd470aa 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.119 2009/06/06 01:07:01 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.120 2009/06/06 01:10:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -447,10 +447,10 @@ int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
/* rde_filter.c */
-enum filter_actions rde_filter(struct rde_aspath **, struct filter_head *,
- struct rde_peer *, struct rde_aspath *,
- struct bgpd_addr *, u_int8_t, struct rde_peer *,
- enum directions);
+enum filter_actions rde_filter(u_int16_t, struct rde_aspath **,
+ struct filter_head *, struct rde_peer *,
+ struct rde_aspath *, struct bgpd_addr *, u_int8_t,
+ struct rde_peer *, enum directions);
void rde_apply_set(struct rde_aspath *, struct filter_set_head *,
sa_family_t, struct rde_peer *, struct rde_peer *);
int rde_filter_community(struct rde_aspath *, int, int);
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index f3c40e253bd..001b796489f 100644
--- a/usr.sbin/bgpd/rde_filter.c
+++ b/usr.sbin/bgpd/rde_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_filter.c,v 1.55 2008/09/29 14:03:41 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.56 2009/06/06 01:10:29 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -30,7 +30,7 @@ int rde_filter_match(struct filter_rule *, struct rde_aspath *,
int filterset_equal(struct filter_set_head *, struct filter_set_head *);
enum filter_actions
-rde_filter(struct rde_aspath **new, struct filter_head *rules,
+rde_filter(u_int16_t ribid, struct rde_aspath **new, struct filter_head *rules,
struct rde_peer *peer, struct rde_aspath *asp, struct bgpd_addr *prefix,
u_int8_t prefixlen, struct rde_peer *from, enum directions dir)
{
@@ -43,6 +43,8 @@ rde_filter(struct rde_aspath **new, struct filter_head *rules,
TAILQ_FOREACH(f, rules, entry) {
if (dir != f->dir)
continue;
+ if (dir == DIR_IN && f->peer.ribid != ribid)
+ continue;
if (f->peer.groupid != 0 &&
f->peer.groupid != peer->conf.groupid)
continue;
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 469f584e89e..209664f4a85 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.67 2009/03/26 13:59:30 henning Exp $ */
+/* $OpenBSD: rde_update.c,v 1.68 2009/06/06 01:10:29 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -404,9 +404,9 @@ up_generate_updates(struct filter_head *rules, struct rde_peer *peer,
return;
pt_getaddr(old->prefix, &addr);
- if (rde_filter(NULL, rules, peer, old->aspath, &addr,
- old->prefix->prefixlen, old->aspath->peer, DIR_OUT) ==
- ACTION_DENY)
+ if (rde_filter(peer->ribid, NULL, rules, peer, old->aspath,
+ &addr, old->prefix->prefixlen, old->aspath->peer,
+ DIR_OUT) == ACTION_DENY)
return;
/* withdraw prefix */
@@ -423,9 +423,9 @@ up_generate_updates(struct filter_head *rules, struct rde_peer *peer,
}
pt_getaddr(new->prefix, &addr);
- if (rde_filter(&asp, rules, peer, new->aspath, &addr,
- new->prefix->prefixlen, new->aspath->peer, DIR_OUT) ==
- ACTION_DENY) {
+ if (rde_filter(peer->ribid, &asp, rules, peer, new->aspath,
+ &addr, new->prefix->prefixlen, new->aspath->peer,
+ DIR_OUT) == ACTION_DENY) {
path_put(asp);
up_generate_updates(rules, peer, NULL, old);
return;
@@ -473,8 +473,8 @@ up_generate_default(struct filter_head *rules, struct rde_peer *peer,
bzero(&addr, sizeof(addr));
addr.af = af;
- if (rde_filter(&fasp, rules, peer, asp, &addr, 0, NULL, DIR_OUT) ==
- ACTION_DENY) {
+ if (rde_filter(peer->ribid, &fasp, rules, peer, asp, &addr, 0, NULL,
+ DIR_OUT) == ACTION_DENY) {
path_put(fasp);
path_put(asp);
return;