summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-11-01 10:58:30 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-11-01 10:58:30 +0000
commitbed0359dda1f1de56865b5bf8d013c0c84fe4ba2 (patch)
treefc9aa6b67295c4c0b6980d2ea35f79f1c58634a7
parent8ee6bca0a986f60e072d3b5d9593d08416fcc6e2 (diff)
Switch from the per peer filter set list to a filter-only solution.
The default filter_sets are converted into match filter rules that get evaluated first. Simplifies code massively -- mainly the config reload part -- and makes softreconfig out a piece of cake. "get it in" henning@
-rw-r--r--usr.sbin/bgpd/bgpd.c5
-rw-r--r--usr.sbin/bgpd/bgpd.h7
-rw-r--r--usr.sbin/bgpd/parse.y121
-rw-r--r--usr.sbin/bgpd/printconf.c8
-rw-r--r--usr.sbin/bgpd/rde.c18
-rw-r--r--usr.sbin/bgpd/rde_filter.c17
-rw-r--r--usr.sbin/bgpd/rde_update.c11
-rw-r--r--usr.sbin/bgpd/session.c27
8 files changed, 122 insertions, 92 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index 914404d5f62..518b9b829ec 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.124 2005/10/13 09:09:20 claudio Exp $ */
+/* $OpenBSD: bgpd.c,v 1.125 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -433,9 +433,6 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l,
if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1,
&p->conf, sizeof(struct peer_config)) == -1)
return (-1);
- if (send_filterset(ibuf_se, &p->conf.attrset,
- p->conf.id) == -1)
- return (-1);
}
while ((n = TAILQ_FIRST(&net_l)) != NULL) {
if (imsg_compose(ibuf_rde, IMSG_NETWORK_ADD, 0, 0, -1,
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index c4578092e6f..5fdf69f66da 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.179 2005/10/19 12:32:16 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.180 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -212,7 +212,6 @@ struct peer_config {
struct bgpd_addr local_addr;
struct peer_auth auth;
struct capabilities capabilities;
- struct filter_set_head attrset;
char group[PEER_DESCR_LEN];
char descr[PEER_DESCR_LEN];
char if_depend[IFNAMSIZ];
@@ -498,9 +497,7 @@ enum filter_actions {
enum directions {
DIR_IN = 1,
- DIR_OUT,
- DIR_DEFAULT_IN, /* only needed to apply default set */
- DIR_DEFAULT_OUT
+ DIR_OUT
};
enum from_spec {
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index ca7e957b41f..bfe1729a408 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.172 2005/10/19 10:42:06 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.173 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -45,6 +45,10 @@ static struct peer *peer_l, *peer_l_old;
static struct peer *curpeer;
static struct peer *curgroup;
static struct filter_head *filter_l;
+static struct filter_head *peerfilter_l;
+static struct filter_head *groupfilter_l;
+static struct filter_rule *curpeer_filter[2];
+static struct filter_rule *curgroup_filter[2];
static struct listen_addrs *listen_addrs;
static FILE *fin = NULL;
static int lineno = 1;
@@ -97,6 +101,7 @@ void copy_filterset(struct filter_set_head *,
struct filter_set_head *);
void move_filterset(struct filter_set_head *,
struct filter_set_head *);
+struct filter_rule *get_rule(enum action_types);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
@@ -529,6 +534,15 @@ neighbor : { curpeer = new_peer(); }
}
}
peeropts_h {
+ if (curpeer_filter[0] != NULL)
+ TAILQ_INSERT_TAIL(peerfilter_l,
+ curpeer_filter[0], entry);
+ if (curpeer_filter[1] != NULL)
+ TAILQ_INSERT_TAIL(peerfilter_l,
+ curpeer_filter[1], entry);
+ curpeer_filter[0] = NULL;
+ curpeer_filter[1] = NULL;
+
if (neighbor_consistent(curpeer) == -1)
YYERROR;
curpeer->next = peer_l;
@@ -554,6 +568,15 @@ group : GROUP string optnl '{' optnl {
}
}
groupopts_l '}' {
+ if (curgroup_filter[0] != NULL)
+ TAILQ_INSERT_TAIL(groupfilter_l,
+ curgroup_filter[0], entry);
+ if (curgroup_filter[1] != NULL)
+ TAILQ_INSERT_TAIL(groupfilter_l,
+ curgroup_filter[1], entry);
+ curgroup_filter[0] = NULL;
+ curgroup_filter[1] = NULL;
+
free(curgroup);
curgroup = NULL;
}
@@ -814,17 +837,21 @@ peeropts : REMOTEAS asnumber {
curpeer->conf.announce_capa = $3;
}
| SET filter_set_opt {
- if (merge_filterset(&curpeer->conf.attrset, $2) == -1)
+ struct filter_rule *r;
+
+ r = get_rule($2->type);
+ if (merge_filterset(&r->set, $2) == -1)
YYERROR;
}
| SET optnl "{" optnl filter_set_l optnl "}" {
+ struct filter_rule *r;
struct filter_set *s;
while ((s = TAILQ_FIRST($5)) != NULL) {
TAILQ_REMOVE($5, s, entry);
- if (merge_filterset(&curpeer->conf.attrset, s)
- == -1)
- YYERROR;
+ r = get_rule(s->type);
+ if (merge_filterset(&r->set, s) == -1)
+ YYERROR;
}
free($5);
}
@@ -1773,8 +1800,17 @@ parse_config(char *filename, struct bgpd_config *xconf,
fatal(NULL);
if ((listen_addrs = calloc(1, sizeof(struct listen_addrs))) == NULL)
fatal(NULL);
+ if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL)
+ fatal(NULL);
+ if ((peerfilter_l = calloc(1, sizeof(struct filter_head))) == NULL)
+ fatal(NULL);
+ if ((groupfilter_l = calloc(1, sizeof(struct filter_head))) == NULL)
+ fatal(NULL);
LIST_INIT(mrtconf);
TAILQ_INIT(listen_addrs);
+ TAILQ_INIT(filter_l);
+ TAILQ_INIT(peerfilter_l);
+ TAILQ_INIT(groupfilter_l);
peer_l = NULL;
peer_l_old = *xpeers;
@@ -1785,11 +1821,11 @@ parse_config(char *filename, struct bgpd_config *xconf,
id = 1;
conf->opts = xconf->opts;
- /* filter and network list are always empty in the parent */
- filter_l = xfilter_l;
- TAILQ_INIT(filter_l);
+ /* network list is always empty in the parent */
netconf = nc;
TAILQ_INIT(netconf);
+ /* init the empty filter list for later */
+ TAILQ_INIT(xfilter_l);
yyparse();
@@ -1831,6 +1867,16 @@ parse_config(char *filename, struct bgpd_config *xconf,
TAILQ_REMOVE(filter_l, r, entry);
free(r);
}
+
+ while ((r = TAILQ_FIRST(peerfilter_l)) != NULL) {
+ TAILQ_REMOVE(peerfilter_l, r, entry);
+ free(r);
+ }
+
+ while ((r = TAILQ_FIRST(groupfilter_l)) != NULL) {
+ TAILQ_REMOVE(groupfilter_l, r, entry);
+ free(r);
+ }
} else {
errors += merge_config(xconf, conf, peer_l, listen_addrs);
errors += mrt_mergeconfig(xmconf, mrtconf);
@@ -1840,10 +1886,31 @@ parse_config(char *filename, struct bgpd_config *xconf,
pnext = p->next;
free(p);
}
+
+ /*
+ * Move filter list and static group and peer filtersets
+ * together. Static group sets come first then peer sets
+ * last normal filter rules.
+ */
+ while ((r = TAILQ_FIRST(groupfilter_l)) != NULL) {
+ TAILQ_REMOVE(groupfilter_l, r, entry);
+ TAILQ_INSERT_TAIL(xfilter_l, r, entry);
+ }
+ while ((r = TAILQ_FIRST(peerfilter_l)) != NULL) {
+ TAILQ_REMOVE(peerfilter_l, r, entry);
+ TAILQ_INSERT_TAIL(xfilter_l, r, entry);
+ }
+ while ((r = TAILQ_FIRST(filter_l)) != NULL) {
+ TAILQ_REMOVE(filter_l, r, entry);
+ TAILQ_INSERT_TAIL(xfilter_l, r, entry);
+ }
}
free(conf);
free(mrtconf);
+ free(filter_l);
+ free(peerfilter_l);
+ free(groupfilter_l);
return (errors ? -1 : 0);
}
@@ -2019,7 +2086,6 @@ alloc_peer(void)
p->conf.capabilities.mp_v4 = SAFI_UNICAST;
p->conf.capabilities.mp_v6 = SAFI_NONE;
p->conf.capabilities.refresh = 1;
- TAILQ_INIT(&p->conf.attrset);
return (p);
}
@@ -2040,8 +2106,6 @@ new_peer(void)
sizeof(p->conf.descr)) >= sizeof(p->conf.descr))
fatalx("new_peer descr strlcpy");
p->conf.groupid = curgroup->conf.id;
- TAILQ_INIT(&p->conf.attrset);
- copy_filterset(&curgroup->conf.attrset, &p->conf.attrset);
}
p->next = NULL;
@@ -2344,3 +2408,38 @@ move_filterset(struct filter_set_head *source, struct filter_set_head *dest)
}
}
+struct filter_rule *
+get_rule(enum action_types type)
+{
+ struct filter_rule *r;
+ int out;
+
+ switch (type) {
+ case ACTION_SET_PREPEND_SELF:
+ case ACTION_SET_NEXTHOP_NOMODIFY:
+ out = 1;
+ break;
+ default:
+ out = 0;
+ break;
+ }
+ r = (curpeer == curgroup) ? curgroup_filter[out] : curpeer_filter[out];
+ if (r == NULL) {
+ if ((r = calloc(1, sizeof(struct filter_rule))) == NULL)
+ fatal(NULL);
+ r->quick = 0;
+ r->dir = out ? DIR_OUT : DIR_IN;
+ r->action = ACTION_NONE;
+ TAILQ_INIT(&r->set);
+ if (curpeer == curgroup) {
+ /* group */
+ r->peer.groupid = curgroup->conf.id;
+ curgroup_filter[out] = r;
+ } else {
+ /* peer */
+ r->peer.peerid = curpeer->conf.id;
+ curpeer_filter[out] = r;
+ }
+ }
+ return (r);
+}
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index e4ae67401f9..e3857bbef38 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.49 2005/10/31 17:00:05 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.50 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -303,12 +303,6 @@ print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c)
printf("%s\tannounce IPv4 %s\n", c, print_safi(p->capabilities.mp_v4));
printf("%s\tannounce IPv6 %s\n", c, print_safi(p->capabilities.mp_v6));
- if (!TAILQ_EMPTY(&p->attrset))
- printf("%s\t", c);
- print_set(&p->attrset);
- if (!TAILQ_EMPTY(&p->attrset))
- printf("\n");
-
print_mrt(p->id, p->groupid, c, "\t");
printf("%s}\n", c);
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 0a68dc3db66..07077ca53d0 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.174 2005/10/13 09:08:21 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.175 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -303,14 +303,12 @@ rde_dispatch_imsg_session(struct imsgbuf *ibuf)
imsg.hdr.peerid);
break;
}
- session_set = &peer->conf.attrset;
break;
case IMSG_SESSION_UP:
if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(sup))
fatalx("incorrect size of session request");
memcpy(&sup, imsg.data, sizeof(sup));
peer_up(imsg.hdr.peerid, &sup);
- session_set = NULL;
break;
case IMSG_SESSION_DOWN:
peer_down(imsg.hdr.peerid);
@@ -521,6 +519,7 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
nconf = NULL;
parent_set = NULL;
prefix_network_clean(&peerself, reloadtime);
+ /* soft reconfig out */
while ((r = TAILQ_FIRST(rules_l)) != NULL) {
TAILQ_REMOVE(rules_l, r, entry);
filterset_free(&r->set);
@@ -791,9 +790,6 @@ rde_update_dispatch(struct imsg *imsg)
return (0);
}
- /* apply default overrides */
- rde_apply_set(asp, &peer->conf.attrset, AF_INET, peer, DIR_DEFAULT_IN);
-
/* parse nlri prefix */
while (nlri_len > 0) {
if ((pos = rde_update_get_prefix(p, nlri_len, &prefix,
@@ -886,9 +882,6 @@ rde_update_dispatch(struct imsg *imsg)
path_put(asp);
return (-1);
}
- /* apply default overrides */
- rde_apply_set(asp, &peer->conf.attrset, AF_INET6, peer,
- DIR_DEFAULT_IN);
while (mplen > 0) {
if ((pos = rde_update_get_prefix6(mpp, mplen,
@@ -1986,7 +1979,6 @@ peer_add(u_int32_t id, struct peer_config *p_conf)
LIST_INIT(&peer->path_h);
memcpy(&peer->conf, p_conf, sizeof(struct peer_config));
- TAILQ_INIT(&peer->conf.attrset);
peer->remote_bgpid = 0;
peer->state = PEER_NONE;
up_init(peer);
@@ -2004,8 +1996,6 @@ peer_remove(struct rde_peer *peer)
{
LIST_REMOVE(peer, hash_l);
LIST_REMOVE(peer, peer_l);
-
- filterset_free(&peer->conf.attrset);
free(peer);
}
@@ -2207,11 +2197,11 @@ network_add(struct network_config *nc, int flagstatic)
if (flagstatic) {
rde_apply_set(asp, &nc->attrset, nc->prefix.af, &peerself,
- DIR_DEFAULT_IN);
+ DIR_IN);
path_update(&peerself, asp, &nc->prefix, nc->prefixlen);
} else {
rde_apply_set(asp, &nc->attrset, nc->prefix.af, &peerdynamic,
- DIR_DEFAULT_IN);
+ DIR_IN);
path_update(&peerdynamic, asp, &nc->prefix, nc->prefixlen);
}
filterset_free(&nc->attrset);
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index 62aeaf36175..9d197c7f19a 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.34 2005/08/10 08:34:06 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.35 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -73,15 +73,6 @@ rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
return;
TAILQ_FOREACH(set, sh, entry) {
- /*
- * default outgoing overrides are only allowed to
- * set prepend-self and set nexthop no-modify
- */
- if (dir == DIR_DEFAULT_OUT &&
- set->type != ACTION_SET_PREPEND_SELF &&
- set->type != ACTION_SET_NEXTHOP_NOMODIFY)
- continue;
-
switch (set->type) {
case ACTION_SET_LOCALPREF:
asp->lpref = set->action.metric;
@@ -140,9 +131,6 @@ rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
}
break;
case ACTION_SET_PREPEND_SELF:
- /* don't apply if this is a incoming default override */
- if (dir == DIR_DEFAULT_IN)
- break;
as = rde_local_as();
prepend = set->action.prepend;
new = aspath_prepend(asp->aspath, as, prepend);
@@ -162,9 +150,6 @@ rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
case ACTION_SET_NEXTHOP_REJECT:
case ACTION_SET_NEXTHOP_BLACKHOLE:
case ACTION_SET_NEXTHOP_NOMODIFY:
- if (set->type == ACTION_SET_NEXTHOP_NOMODIFY &&
- dir == DIR_DEFAULT_IN)
- break;
nexthop_modify(asp, &set->action.nexthop, set->type,
af);
break;
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index d47461d02ff..6229004f05b 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.40 2005/10/19 10:43:01 henning Exp $ */
+/* $OpenBSD: rde_update.c,v 1.41 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -432,7 +432,7 @@ up_generate_updates(struct rde_peer *peer,
case ANNOUNCE_DEFAULT_ROUTE:
/*
* no need to withdraw old prefix as this will be
- * filtered out to.
+ * filtered out as well.
*/
return;
case ANNOUNCE_ALL:
@@ -469,13 +469,6 @@ up_generate_updates(struct rde_peer *peer,
/* copy attributes for output filter */
fasp = path_copy(new->aspath);
- /*
- * apply default outgoing overrides,
- * actually only prepend-self and nexthop no-modify
- */
- rde_apply_set(fasp, &peer->conf.attrset, new->prefix->af,
- new->aspath->peer, DIR_DEFAULT_OUT);
-
if (rde_filter(peer, fasp, &addr, new->prefix->prefixlen,
new->peer, DIR_OUT) == ACTION_DENY) {
path_put(fasp);
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index 5f1cc83d4a2..6b1205b129f 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.237 2005/10/19 10:42:06 henning Exp $ */
+/* $OpenBSD: session.c,v 1.238 2005/11/01 10:58:29 claudio Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -2074,8 +2074,6 @@ parse_capabilities(struct peer *peer, u_char *d, u_int16_t dlen)
return (0);
}
-struct filter_set_head *session_set;
-
void
session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
{
@@ -2086,7 +2084,6 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
struct peer *p, *next;
struct listen_addr *la, *nla;
struct kif *kif;
- struct filter_set *s;
u_char *data;
enum reconf_action reconf;
int n, depend_ok;
@@ -2138,8 +2135,6 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
reconf = RECONF_KEEP;
memcpy(&p->conf, pconf, sizeof(struct peer_config));
- TAILQ_INIT(&p->conf.attrset);
- session_set = &p->conf.attrset;
p->conf.reconf_action = reconf;
break;
case IMSG_RECONF_LISTENER:
@@ -2228,22 +2223,9 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
free(nconf->listen_addrs);
free(nconf);
nconf = NULL;
- session_set = NULL;
pending_reconf = 0;
log_info("SE reconfigured");
break;
- case IMSG_FILTER_SET:
- if (idx != PFD_PIPE_MAIN)
- fatalx("reconf request not from parent");
- if (session_set == NULL) {
- log_warnx("IMSG_FILTER_SET unexpected");
- break;
- }
- if ((s = malloc(sizeof(struct filter_set))) == NULL)
- fatal(NULL);
- memcpy(s, imsg.data, sizeof(struct filter_set));
- TAILQ_INSERT_TAIL(session_set, s, entry);
- break;
case IMSG_IFINFO:
if (idx != PFD_PIPE_MAIN)
fatalx("IFINFO message not from parent");
@@ -2591,18 +2573,11 @@ void
session_up(struct peer *p)
{
struct session_up sup;
- struct filter_set *s;
if (imsg_compose(ibuf_rde, IMSG_SESSION_ADD, p->conf.id, 0, -1,
&p->conf, sizeof(p->conf)) == -1)
fatalx("imsg_compose error");
- TAILQ_FOREACH(s, &p->conf.attrset, entry) {
- if (imsg_compose(ibuf_rde, IMSG_FILTER_SET, p->conf.id, 0, -1,
- s, sizeof(struct filter_set)) == -1)
- fatalx("imsg_compose error");
- }
-
switch (p->sa_local.ss_family) {
case AF_INET:
sup.local_addr.af = AF_INET;