diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-11-01 10:58:30 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-11-01 10:58:30 +0000 |
commit | bed0359dda1f1de56865b5bf8d013c0c84fe4ba2 (patch) | |
tree | fc9aa6b67295c4c0b6980d2ea35f79f1c58634a7 | |
parent | 8ee6bca0a986f60e072d3b5d9593d08416fcc6e2 (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.c | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 7 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 121 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 8 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 18 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 17 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_update.c | 11 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 27 |
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; |