-/* $OpenBSD: parse.y,v 1.332 2018/09/05 09:49:57 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.333 2018/09/05 17:32:43 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
prefixlenop : /* empty */ { bzero(&$$, sizeof($$)); }
| LONGER {
bzero(&$$, sizeof($$));
- $$.op = OP_GE;
+ $$.op = OP_RANGE;
$$.len_min = -1;
+ $$.len_max = -1;
}
| PREFIXLEN unaryop NUMBER {
+ int min, max;
+
bzero(&$$, sizeof($$));
if ($3 < 0 || $3 > 128) {
yyerror("prefixlen must be >= 0 and <= 128");
YYERROR;
}
- if ($2 == OP_GT && $3 == 0) {
- yyerror("prefixlen must be > 0");
- YYERROR;
+ /*
+ * convert the unary operation into the equivalent
+ * range check
+ */
+ $$.op = OP_RANGE;
+
+ switch ($2) {
+ case OP_EQ:
+ case OP_NE:
+ min = max = $3;
+ $$.op = $2;
+ break;
+ case OP_LT:
+ if ($3 == 0) {
+ yyerror("prefixlen must be > 0");
+ YYERROR;
+ }
+ $3 -= 1;
+ case OP_LE:
+ min = -1;
+ max = $3;
+ break;
+ case OP_GT:
+ $3 += 1;
+ case OP_GE:
+ min = $3;
+ max = -1;
+ break;
}
- $$.op = $2;
- $$.len_min = $3;
+ $$.len_min = min;
+ $$.len_max = max;
}
| PREFIXLEN NUMBER binaryop NUMBER {
bzero(&$$, sizeof($$));
yyerror("prefixlen must be < 128");
YYERROR;
}
- if ($2 >= $4) {
+ if ($2 > $4) {
yyerror("start prefixlen is bigger than end");
YYERROR;
}
break;
}
- switch (pl->op) {
- case OP_NONE:
+ if (pl->op == OP_NONE) {
+ p->p.len_min = p->p.len_max = p->p.len;
return (0);
- case OP_RANGE:
- case OP_XRANGE:
- if (pl->len_min > max_len || pl->len_max > max_len) {
- yyerror("prefixlen %d too big for AF, limit %d",
- pl->len_min > max_len ? pl->len_min : pl->len_max,
- max_len);
- return (-1);
- }
- if (pl->len_min < p->p.len) {
- yyerror("prefixlen %d smaller than prefix, limit %d",
- pl->len_min, p->p.len);
- return (-1);
- }
- p->p.len_max = pl->len_max;
- break;
- case OP_GE:
- /* fix up the "or-longer" case */
- if (pl->len_min == -1)
- pl->len_min = p->p.len;
- /* FALLTHROUGH */
- case OP_EQ:
- case OP_NE:
- case OP_LE:
- case OP_GT:
- if (pl->len_min > max_len) {
- yyerror("prefixlen %d too big for AF, limit %d",
- pl->len_min, max_len);
- return (-1);
- }
- if (pl->len_min < p->p.len) {
- yyerror("prefixlen %d smaller than prefix, limit %d",
- pl->len_min, p->p.len);
- return (-1);
- }
- break;
- case OP_LT:
- if (pl->len_min > max_len - 1) {
- yyerror("prefixlen %d too big for AF, limit %d",
- pl->len_min, max_len - 1);
- return (-1);
- }
- if (pl->len_min < p->p.len + 1) {
- yyerror("prefixlen %d too small for prefix, limit %d",
- pl->len_min, p->p.len + 1);
- return (-1);
- }
- break;
+ }
+
+ if (pl->len_min == -1)
+ pl->len_min = p->p.len;
+ if (pl->len_max == -1)
+ pl->len_max = max_len;
+
+ if (pl->len_max > max_len) {
+ yyerror("prefixlen %d too big, limit %d",
+ pl->len_max, max_len);
+ return (-1);
+ }
+ if (pl->len_min > pl->len_max) {
+ yyerror("prefixlen %d too big, limit %d",
+ pl->len_min, pl->len_max);
+ return (-1);
+ }
+ if (pl->len_min < p->p.len) {
+ yyerror("prefixlen %d smaller than prefix, limit %d",
+ pl->len_min, p->p.len);
+ return (-1);
}
p->p.op = pl->op;
p->p.len_min = pl->len_min;
+ p->p.len_max = pl->len_max;
return (0);
}
-/* $OpenBSD: printconf.c,v 1.110 2018/09/05 09:49:57 claudio Exp $ */
+/* $OpenBSD: printconf.c,v 1.111 2018/09/05 17:32:43 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
#include "rde.h"
#include "log.h"
-void print_op(enum comp_ops);
+void print_prefix(struct filter_prefix *p, const char *);
void print_community(int, int);
void print_largecommunity(int64_t, int64_t, int64_t);
void print_extcommunity(struct filter_extcommunity *);
int peer_compare(const void *, const void *);
void
-print_op(enum comp_ops op)
+print_prefix(struct filter_prefix *p, const char *s)
{
- switch (op) {
- case OP_RANGE:
- printf("-");
+ u_int8_t max_len = 0;
+
+ switch (p->addr.aid) {
+ case AID_INET:
+ case AID_VPN_IPv4:
+ max_len = 32;
break;
- case OP_XRANGE:
- printf("><");
+ case AID_INET6:
+ max_len = 128;
+ break;
+ case AID_UNSPEC:
+ /* no prefix to print */
+ return;
+ }
+
+ printf("%s%s/%u ", s, log_addr(&p->addr), p->len);
+
+ switch (p->op) {
+ case OP_NONE:
break;
case OP_EQ:
- printf("=");
+ printf("prefixlen = %u ", p->len_min);
break;
case OP_NE:
- printf("!=");
- break;
- case OP_LE:
- printf("<=");
+ printf("prefixlen != %u ", p->len_min);
break;
- case OP_LT:
- printf("<");
- break;
- case OP_GE:
- printf(">=");
+ case OP_XRANGE:
+ printf("prefixlen %u >< %u ", p->len_min, p->len_max);
break;
- case OP_GT:
- printf(">");
+ case OP_RANGE:
+ if (p->len == p->len_min && p->len_max == max_len)
+ printf("or-longer ");
+ else if (p->len_max == max_len)
+ printf("prefixlen >= %u ", p->len_min);
+ else
+ printf("prefixlen %u - %u ", p->len_min, p->len_max);
break;
default:
- printf("?");
+ printf("prefixlen %u ??? %u ", p->len_min, p->len_max);
break;
}
}
SIMPLEQ_FOREACH(ps, psh, entry) {
printf("prefix-set \"%s\" { ", ps->name);
- SIMPLEQ_FOREACH(psi, &ps->psitems, entry) {
- if (psi->p.addr.aid)
- printf("%s/%u ", log_addr(&psi->p.addr),
- psi->p.len);
- if (psi->p.op) {
- if (psi->p.op == OP_RANGE ||
- psi->p.op == OP_XRANGE) {
- printf("prefixlen %u ", psi->p.len_min);
- print_op(psi->p.op);
- printf(" %u ", psi->p.len_max);
- } else {
- printf("prefixlen ");
- print_op(psi->p.op);
- printf(" %u ", psi->p.len_min);
- }
- }
- }
+ SIMPLEQ_FOREACH(psi, &ps->psitems, entry)
+ print_prefix(&psi->p, "");
printf(" }\n");
}
}
} else
printf("any ");
- if (r->match.prefix.addr.aid)
- printf("prefix %s/%u ", log_addr(&r->match.prefix.addr),
- r->match.prefix.len);
-
- if (r->match.prefix.op) {
- if (r->match.prefix.op == OP_RANGE ||
- r->match.prefix.op == OP_XRANGE) {
- printf("prefixlen %u ", r->match.prefix.len_min);
- print_op(r->match.prefix.op);
- printf(" %u ", r->match.prefix.len_max);
- } else {
- printf("prefixlen ");
- print_op(r->match.prefix.op);
- printf(" %u ", r->match.prefix.len_min);
- }
- }
+ print_prefix(&r->match.prefix, "prefix ");
if (r->match.prefixset.flags & PREFIXSET_FLAG_FILTER)
printf("prefix-set \"%s\" ", r->match.prefixset.name);
-/* $OpenBSD: rde_filter.c,v 1.100 2018/09/05 09:49:57 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.101 2018/09/05 17:32:43 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
case OP_XRANGE:
return ((plen < fp->len_min) ||
(plen > fp->len_max));
- case OP_LE:
- return (plen <= fp->len_min);
- case OP_LT:
- return (plen < fp->len_min);
- case OP_GE:
- return (plen >= fp->len_min);
- case OP_GT:
- return (plen > fp->len_min);
+ default:
+ log_warnx("%s: unsupported prefix operation", __func__);
+ return (0);
}
- return (0); /* should not be reached */
}
/* return true when the rule f can never match for this peer */