summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Benoit <benno@cvs.openbsd.org>2018-09-09 11:00:52 +0000
committerSebastian Benoit <benno@cvs.openbsd.org>2018-09-09 11:00:52 +0000
commitc6764a1531f7d408ef82823f541a3c5791115d8f (patch)
tree32785dd89eb2b0bc20e1e30b69e3457775cee698
parent3926e5997298af73f2314c224131235a3ca35a7b (diff)
Add network prefix-set <name> syntax to announce networks in a prefix-set.
feature discussed with deraadt@ and job@, ok claudio@
-rw-r--r--usr.sbin/bgpd/bgpd.c3
-rw-r--r--usr.sbin/bgpd/bgpd.conf.511
-rw-r--r--usr.sbin/bgpd/bgpd.h6
-rw-r--r--usr.sbin/bgpd/config.c51
-rw-r--r--usr.sbin/bgpd/kroute.c14
-rw-r--r--usr.sbin/bgpd/parse.y54
-rw-r--r--usr.sbin/bgpd/printconf.c10
7 files changed, 112 insertions, 37 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c
index 7f2b963c7dd..c06100781c9 100644
--- a/usr.sbin/bgpd/bgpd.c
+++ b/usr.sbin/bgpd/bgpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.c,v 1.197 2018/09/07 10:59:16 claudio Exp $ */
+/* $OpenBSD: bgpd.c,v 1.198 2018/09/09 11:00:51 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -452,6 +452,7 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct peer **peer_l)
reconfpending = 0;
return (1);
}
+ expand_networks(conf);
cflags = conf->flags;
prepare_listeners(conf);
diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5
index cbfe0110868..31a14bd86c3 100644
--- a/usr.sbin/bgpd/bgpd.conf.5
+++ b/usr.sbin/bgpd/bgpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.conf.5,v 1.176 2018/09/08 15:54:41 jmc Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.177 2018/09/09 11:00:51 benno Exp $
.\"
.\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
.\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -16,7 +16,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: September 8 2018 $
+.Dd $Mdocdate: September 9 2018 $
.Dt BGPD.CONF 5
.Os
.Sh NAME
@@ -290,6 +290,10 @@ Log received and sent updates.
.Ic network
.Pq Ic inet Ns | Ns Ic inet6
.Ic priority Ar number Op Ic set ...\&
+.It Xo
+.Ic network prefix-set
+.Ar name
+.Op Ic set ...\&
.Xc
Announce the specified network as belonging to our AS.
If set to
@@ -308,6 +312,9 @@ If set to
routes with the specified
.Ar priority
will be announced.
+If a prefix-set
+.Ar name
+is specified, all networks in the prefix-set will be announced.
.Bd -literal -offset indent
network 192.168.7.0/24
.Ed
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 0f4d1d088b4..0ab67baae63 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.337 2018/09/08 15:25:27 benno Exp $ */
+/* $OpenBSD: bgpd.h,v 1.338 2018/09/09 11:00:51 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -354,12 +354,14 @@ enum network_type {
NETWORK_RTLABEL,
NETWORK_MRTCLONE,
NETWORK_PRIORITY,
+ NETWORK_PREFIXSET,
};
struct network_config {
struct bgpd_addr prefix;
struct filter_set_head attrset;
struct rde_aspath *asp;
+ char psname[SET_NAME_LEN];
u_int rtableid;
u_int16_t rtlabel;
enum network_type type;
@@ -1081,6 +1083,8 @@ void free_config(struct bgpd_config *);
void free_prefixsets(struct prefixset_head *);
void filterlist_free(struct filter_head *);
int host(const char *, struct bgpd_addr *, u_int8_t *);
+void copy_filterset(struct filter_set_head *, struct filter_set_head *);
+void expand_networks(struct bgpd_config *);
/* kroute.c */
int kr_init(void);
diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c
index bf4752b7ba4..1c0984facaf 100644
--- a/usr.sbin/bgpd/config.c
+++ b/usr.sbin/bgpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.72 2018/09/07 05:43:33 claudio Exp $ */
+/* $OpenBSD: config.c,v 1.73 2018/09/09 11:00:51 benno Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -497,3 +497,52 @@ get_mpe_label(struct rdomain *r)
r->label = shim.shim_label;
return (0);
}
+
+void
+copy_filterset(struct filter_set_head *source, struct filter_set_head *dest)
+{
+ struct filter_set *s, *t;
+
+ if (source == NULL)
+ return;
+
+ TAILQ_FOREACH(s, source, entry) {
+ if ((t = malloc(sizeof(struct filter_set))) == NULL)
+ fatal(NULL);
+ memcpy(t, s, sizeof(struct filter_set));
+ TAILQ_INSERT_TAIL(dest, t, entry);
+ }
+}
+
+void
+expand_networks(struct bgpd_config *c)
+{
+ struct network *n, *m, *tmp;
+ struct network_head *nw = &c->networks;
+ struct prefixset *ps;
+ struct prefixset_item *psi;
+
+ TAILQ_FOREACH_SAFE(n, nw, entry, tmp) {
+ if (n->net.type == NETWORK_PREFIXSET) {
+ TAILQ_REMOVE(nw, n, entry);
+ if ((ps = find_prefixset(n->net.psname, c->prefixsets))
+ == NULL)
+ fatal("%s: prefixset %s not found", __func__,
+ n->net.psname);
+ SIMPLEQ_FOREACH(psi, &ps->psitems, entry) {
+ if ((m = calloc(1, sizeof(struct network)))
+ == NULL)
+ fatal(NULL);
+ memcpy(&m->net.prefix, &psi->p.addr,
+ sizeof(m->net.prefix));
+ m->net.prefixlen = psi->p.len;
+ TAILQ_INIT(&m->net.attrset);
+ copy_filterset(&n->net.attrset,
+ &m->net.attrset);
+ TAILQ_INSERT_TAIL(nw, m, entry);
+ }
+ filterset_free(&n->net.attrset);
+ free(n);
+ }
+ }
+}
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c
index 8902eef1fd4..99bda3c50a3 100644
--- a/usr.sbin/bgpd/kroute.c
+++ b/usr.sbin/bgpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.222 2018/07/22 16:55:01 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.223 2018/09/09 11:00:51 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1131,6 +1131,11 @@ kr_net_match(struct ktable *kt, struct kroute *kr)
if (kr->priority == xn->net.priority)
return (xn);
break;
+ case NETWORK_PREFIXSET:
+ /* must not happen */
+ log_warnx("%s: found a NETWORK_PREFIXSET, "
+ "please send a bug report", __func__);
+ break;
}
}
return (NULL);
@@ -1171,6 +1176,11 @@ kr_net_match6(struct ktable *kt, struct kroute6 *kr6)
if (kr6->priority == xn->net.priority)
return (xn);
break;
+ case NETWORK_PREFIXSET:
+ /* must not happen */
+ log_warnx("%s: found a NETWORK_PREFIXSET, "
+ "please send a bug report", __func__);
+ break;
}
}
return (NULL);
@@ -1208,6 +1218,8 @@ kr_net_reload(u_int rtableid, struct network_head *nh)
n->net.old = 1;
while ((n = TAILQ_FIRST(nh)) != NULL) {
+ log_debug("%s: processing %s/%u", __func__,
+ log_addr(&n->net.prefix), n->net.prefixlen);
TAILQ_REMOVE(nh, n, entry);
n->net.old = 0;
n->net.rtableid = rtableid;
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 7a9abf303fb..508696a8910 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.341 2018/09/08 15:25:27 benno Exp $ */
+/* $OpenBSD: parse.y,v 1.342 2018/09/09 11:00:51 benno Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -149,8 +149,6 @@ int expand_rule(struct filter_rule *, struct filter_rib_l *,
int str2key(char *, char *, size_t);
int neighbor_consistent(struct peer *);
int merge_filterset(struct filter_set_head *, struct filter_set *);
-void copy_filterset(struct filter_set_head *,
- struct filter_set_head *);
void merge_filter_lists(struct filter_head *, struct filter_head *);
struct filter_rule *get_rule(enum action_types);
@@ -448,7 +446,8 @@ prefixset_item : prefix prefixlenop {
fatal(NULL);
memcpy(&$$->p.addr, &$1.prefix, sizeof($$->p.addr));
$$->p.len = $1.len;
-
+ if ($2.op != OP_NONE)
+ curpset->sflags |= PREFIXSET_FLAG_OPS;
if (merge_prefixspec(&$$->p, &$2) == -1) {
free($$);
YYERROR;
@@ -785,19 +784,34 @@ network : NETWORK prefix filter_set {
TAILQ_INSERT_TAIL(netconf, n, entry);
}
| NETWORK PREFIXSET STRING filter_set {
- if ((find_prefixset($3, conf->prefixsets)) == NULL) {
- yyerror("prefix-set %s not defined", $3);
+ struct prefixset *ps;
+ struct network *n;
+ if ((ps = find_prefixset($3, conf->prefixsets))
+ == NULL) {
+ yyerror("prefix-set %s not defined", ps->name);
free($3);
+ filterset_free($4);
free($4);
YYERROR;
}
- /*
- * XXX not implemented
- */
- yyerror("network prefix-set not implemented.");
+ if (ps->sflags & PREFIXSET_FLAG_OPS) {
+ yyerror("prefix-set %s has prefixlen operators "
+ "and cannot be used in network statements.",
+ ps->name);
+ free($3);
+ filterset_free($4);
+ free($4);
+ YYERROR;
+ }
+ if ((n = calloc(1, sizeof(struct network))) == NULL)
+ fatal("new_network");
+ strlcpy(n->net.psname, ps->name, sizeof(n->net.psname));
+ TAILQ_INIT(&n->net.attrset);
+ TAILQ_CONCAT(&n->net.attrset, $4, entry);
+ n->net.type = NETWORK_PREFIXSET;
+ TAILQ_INSERT_TAIL(netconf, n, entry);
free($3);
free($4);
- YYERROR;
}
| NETWORK family RTLABEL STRING filter_set {
struct network *n;
@@ -2141,7 +2155,7 @@ filter_elm : filter_prefix_h {
}
if ($3.op == OP_RANGE && ps->sflags & PREFIXSET_FLAG_OPS) {
yyerror("prefix-set %s contains prefixlen "
- "operators and cannot be used in with a "
+ "operators and cannot be used with an "
"or-longer filter", ps->name);
free($2);
YYERROR;
@@ -4091,22 +4105,6 @@ merge_filterset(struct filter_set_head *sh, struct filter_set *s)
}
void
-copy_filterset(struct filter_set_head *source, struct filter_set_head *dest)
-{
- struct filter_set *s, *t;
-
- if (source == NULL)
- return;
-
- TAILQ_FOREACH(s, source, entry) {
- if ((t = malloc(sizeof(struct filter_set))) == NULL)
- fatal(NULL);
- memcpy(t, s, sizeof(struct filter_set));
- TAILQ_INSERT_TAIL(dest, t, entry);
- }
-}
-
-void
merge_filter_lists(struct filter_head *dst, struct filter_head *src)
{
struct filter_rule *r;
diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c
index 361ebed7c28..37422139747 100644
--- a/usr.sbin/bgpd/printconf.c
+++ b/usr.sbin/bgpd/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.114 2018/09/08 15:25:27 benno Exp $ */
+/* $OpenBSD: printconf.c,v 1.115 2018/09/09 11:00:51 benno Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -426,6 +426,9 @@ print_network(struct network_config *n, const char *c)
printf("%snetwork %s priority %d", c,
print_af(n->prefix.aid), n->priority);
break;
+ case NETWORK_PREFIXSET:
+ printf("%snetwork prefix-set %s", c, n->psname);
+ break;
default:
printf("%snetwork %s/%u", c, log_addr(&n->prefix),
n->prefixlen);
@@ -854,6 +857,9 @@ print_config(struct bgpd_config *conf, struct rib_names *rib_l,
print_mainconf(conf);
printf("\n");
+ print_prefixsets(conf->prefixsets);
+ print_as_sets(conf->as_sets);
+ printf("\n");
TAILQ_FOREACH(n, net_l, entry)
print_network(&n->net, "");
printf("\n");
@@ -871,8 +877,6 @@ print_config(struct bgpd_config *conf, struct rib_names *rib_l,
"no" : "yes");
}
printf("\n");
- print_prefixsets(conf->prefixsets);
- print_as_sets(conf->as_sets);
print_mrt(conf, 0, 0, "", "");
printf("\n");
print_groups(conf, peer_l);