-/* $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>
reconfpending = 0;
return (1);
}
+ expand_networks(conf);
cflags = conf->flags;
prepare_listeners(conf);
-.\" $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>
.\" 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
.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
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
-/* $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>
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;
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);
-/* $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>
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);
+ }
+ }
+}
-/* $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>
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);
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);
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;
-/* $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>
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);
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;
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;
}
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;
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
merge_filter_lists(struct filter_head *dst, struct filter_head *src)
{
-/* $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>
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);
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");
"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);