-/* $OpenBSD: parse.y,v 1.337 2018/09/07 11:50:32 benno Exp $ */
+/* $OpenBSD: parse.y,v 1.338 2018/09/08 09:33:54 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
static struct peer *curpeer;
static struct peer *curgroup;
static struct rdomain *currdom;
+static struct prefixset *curpset;
static struct filter_head *filter_l;
static struct filter_head *peerfilter_l;
static struct filter_head *groupfilter_l;
int add_rib(char *, u_int, u_int16_t);
struct rde_rib *find_rib(char *);
int get_id(struct peer *);
-int merge_prefixspec(struct filter_prefix_l *,
+int merge_prefixspec(struct filter_prefix *,
struct filter_prefixlen *);
int expand_rule(struct filter_rule *, struct filter_rib_l *,
struct filter_peers_l *, struct filter_match_l *,
u_int8_t len;
} prefix;
struct filter_prefixlen prefixlen;
- struct prefixset *prefixset;
+ struct prefixset_item *prefixset_item;
struct {
u_int8_t enc_alg;
char enc_key[IPSEC_ENC_KEY_LEN];
%type <v.string> string
%type <v.addr> address
%type <v.prefix> prefix addrspec
-%type <v.prefixset> prefixset
+%type <v.prefixset_item> prefixset_item
%type <v.u8> action quick direction delete
%type <v.filter_rib> filter_rib_h filter_rib_l filter_rib
%type <v.filter_peers> filter_peer filter_peer_l filter_peer_h
| grammar varset '\n'
| grammar include '\n'
| grammar asset '\n'
+ | grammar prefixset '\n'
| grammar conf_main '\n'
| grammar rdomain '\n'
| grammar neighbor '\n'
asset_l : as4number_any { asset_add($1); }
| asset_l optnl as4number_any { asset_add($3); }
+prefixset : PREFIXSET STRING '{' optnl {
+ if (find_prefixset($2, conf->prefixsets) != NULL) {
+ yyerror("duplicate prefixset %s", $2);
+ free($2);
+ YYERROR;
+ }
+ if ((curpset = calloc(1, sizeof(*curpset))) == NULL)
+ fatal("prefixset");
+ if (strlcpy(curpset->name, $2, sizeof(curpset->name)) >=
+ sizeof(curpset->name)) {
+ yyerror("prefix-set \"%s\" too long: max %zu",
+ $2, sizeof(curpset->name) - 1);
+ free($2);
+ YYERROR;
+ }
+ SIMPLEQ_INIT(&curpset->psitems);
+ } prefixset_l optnl '}' {
+ SIMPLEQ_INSERT_TAIL(conf->prefixsets, curpset, entry);
+ curpset = NULL;
+ }
+
+prefixset_l : prefixset_item {
+ SIMPLEQ_INSERT_TAIL(&curpset->psitems, $1, entry);
+ }
+ | prefixset_l optnl prefixset_item {
+ SIMPLEQ_INSERT_TAIL(&curpset->psitems, $3, entry);
+ }
+ ;
+
+prefixset_item : prefix prefixlenop {
+ if (($$ = calloc(1, sizeof(*$$))) == NULL)
+ fatal(NULL);
+ memcpy(&$$->p.addr, &$1.prefix, sizeof($$->p.addr));
+ $$->p.len = $1.len;
+
+ if (merge_prefixspec(&$$->p, &$2) == -1) {
+ free($$);
+ YYERROR;
+ }
+ }
+ ;
+
conf_main : AS as4number {
conf->as = $2;
if ($2 > USHRT_MAX)
free($2);
}
| network
- | prefixset {
- SIMPLEQ_INSERT_TAIL(conf->prefixsets, $1, entry);
- }
| DUMP STRING STRING optnumber {
int action;
}
;
-prefixset : PREFIXSET STRING '{' filter_prefix_l '}' {
- struct filter_prefix_l *n, *p;
- struct prefixset_item *pi;
- if (find_prefixset($2, conf->prefixsets) != NULL) {
- yyerror("duplicate prefixset %s", $2);
- free($2);
- YYERROR;
- }
- if (($$ = calloc(1, sizeof(*$$)))
- == NULL)
- fatal("prefixset");
- if (strlcpy($$->name, $2,
- sizeof($$->name)) >=
- sizeof($$->name)) {
- yyerror("prefix-set \"%s\" too long: max %zu",
- $2, sizeof($$->name) - 1);
- free($2);
- YYERROR;
- }
- SIMPLEQ_INIT(&$$->psitems);
- n = $4;
- while (n != NULL) {
- if ((pi = calloc(1, sizeof(*pi))) == NULL)
- fatal("prefixset item");
- pi->p = n->p;
- SIMPLEQ_INSERT_TAIL(&$$->psitems, pi, entry);
- p = n;
- n = n->next;
- free(p);
- }
- }
-
network : NETWORK prefix filter_set {
struct network *n, *m;
}
| NETWORK PREFIXSET STRING filter_set {
if ((find_prefixset($3, conf->prefixsets)) == NULL) {
- yyerror("prefix-set not defined");
+ yyerror("prefix-set %s not defined", $3);
free($3);
free($4);
YYERROR;
NULL)
fatal(NULL);
$$->p.addr.aid = AID_INET;
- if (merge_prefixspec($$, &$2) == -1) {
+ if (merge_prefixspec(&$$->p, &$2) == -1) {
free($$);
YYERROR;
}
NULL)
fatal(NULL);
$$->p.addr.aid = AID_INET6;
- if (merge_prefixspec($$, &$2) == -1) {
+ if (merge_prefixspec(&$$->p, &$2) == -1) {
free($$);
YYERROR;
}
sizeof($$->p.addr));
$$->p.len = $1.len;
- if (merge_prefixspec($$, &$2) == -1) {
+ if (merge_prefixspec(&$$->p, &$2) == -1) {
free($$);
YYERROR;
}
}
int
-merge_prefixspec(struct filter_prefix_l *p, struct filter_prefixlen *pl)
+merge_prefixspec(struct filter_prefix *p, struct filter_prefixlen *pl)
{
u_int8_t max_len = 0;
- switch (p->p.addr.aid) {
+ switch (p->addr.aid) {
case AID_INET:
case AID_VPN_IPv4:
max_len = 32;
}
if (pl->op == OP_NONE) {
- p->p.len_min = p->p.len_max = p->p.len;
+ p->len_min = p->len_max = p->len;
return (0);
}
if (pl->len_min == -1)
- pl->len_min = p->p.len;
+ pl->len_min = p->len;
if (pl->len_max == -1)
pl->len_max = max_len;
pl->len_min, pl->len_max);
return (-1);
}
- if (pl->len_min < p->p.len) {
+ if (pl->len_min < p->len) {
yyerror("prefixlen %d smaller than prefix, limit %d",
- pl->len_min, p->p.len);
+ pl->len_min, p->len);
return (-1);
}
- p->p.op = pl->op;
- p->p.len_min = pl->len_min;
- p->p.len_max = pl->len_max;
+ p->op = pl->op;
+ p->len_min = pl->len_min;
+ p->len_max = pl->len_max;
return (0);
}