From 4ea66b693b151debd8ef61045a886ae5edac2fb3 Mon Sep 17 00:00:00 2001 From: claudio Date: Sun, 9 Sep 2018 13:22:41 +0000 Subject: [PATCH] Rework the parser a bit to be more sane when it comes to newline and comma handling. In expansion lists we want that commas and newlines are allowed but optional. In the neighbor, group and rdomain blocks statements need to be newline separated but neighbor 192.0.2.3 { descr "test-peer" } is allowed. OK sthen@ benno@ --- usr.sbin/bgpd/parse.y | 81 +++++++++++++++++++-------------------- usr.sbin/bgpd/printconf.c | 38 ++++++++++-------- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index d9a5da4cba8..273251f1fa7 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.343 2018/09/09 13:06:42 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.344 2018/09/09 13:22:41 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -409,7 +409,8 @@ as_set : ASSET STRING '{' optnl { done_as_set(); } -as_set_l : as4number_any { add_as_set($1); } +as_set_l : /* empty */ + | as4number_any { add_as_set($1); } | as_set_l optnl as4number_any { add_as_set($3); } prefixset : PREFIXSET STRING '{' optnl { @@ -433,10 +434,11 @@ prefixset : PREFIXSET STRING '{' optnl { curpset = NULL; } -prefixset_l : prefixset_item { +prefixset_l : /* empty */ + | prefixset_item { SIMPLEQ_INSERT_TAIL(&curpset->psitems, $1, entry); } - | prefixset_l optnl prefixset_item { + | prefixset_l comma prefixset_item { SIMPLEQ_INSERT_TAIL(&curpset->psitems, $3, entry); } ; @@ -953,18 +955,11 @@ addrspec : address { | prefix ; -optnl : '\n' optnl - | - ; - -nl : '\n' optnl /* one newline or more */ - ; - optnumber : /* empty */ { $$ = 0; } | NUMBER ; -rdomain : RDOMAIN NUMBER optnl '{' optnl { +rdomain : RDOMAIN NUMBER { if ($2 > RT_TABLEID_MAX) { yyerror("rtable %llu too big: max %u", $2, RT_TABLEID_MAX); @@ -982,19 +977,18 @@ rdomain : RDOMAIN NUMBER optnl '{' optnl { TAILQ_INIT(&currdom->export); TAILQ_INIT(&currdom->net_l); netconf = &currdom->net_l; - } - rdomainopts_l '}' { + } '{' rdomainopts_l '}' { /* insert into list */ SIMPLEQ_INSERT_TAIL(&conf->rdomains, currdom, entry); currdom = NULL; netconf = &conf->networks; } - -rdomainopts_l : rdomainopts_l rdomainoptsl - | rdomainoptsl ; -rdomainoptsl : rdomainopts nl +rdomainopts_l : /* empty */ + | rdomainopts_l '\n' + | rdomainopts_l rdomainopts '\n' + | rdomainopts_l error '\n' ; rdomainopts : RD STRING { @@ -1140,7 +1134,7 @@ neighbor : { curpeer = new_peer(); } } ; -group : GROUP string optnl '{' optnl { +group : GROUP string { curgroup = curpeer = new_group(); if (strlcpy(curgroup->conf.group, $2, sizeof(curgroup->conf.group)) >= @@ -1155,8 +1149,7 @@ group : GROUP string optnl '{' optnl { yyerror("get_id failed"); YYERROR; } - } - groupopts_l '}' { + } '{' groupopts_l '}' { if (curgroup_filter[0] != NULL) TAILQ_INSERT_TAIL(groupfilter_l, curgroup_filter[0], entry); @@ -1171,24 +1164,22 @@ group : GROUP string optnl '{' optnl { } ; -groupopts_l : groupopts_l groupoptsl - | groupoptsl - ; - -groupoptsl : peeropts nl - | neighbor nl - | error nl +groupopts_l : /* empty */ + | groupopts_l '\n' + | groupopts_l peeropts '\n' + | groupopts_l neighbor '\n' + | groupopts_l error '\n' ; -peeropts_h : '{' optnl peeropts_l '}' +peeropts_h : '{' '\n' peeropts_l '}' + | '{' peeropts '}' | /* empty */ ; -peeropts_l : peeropts_l peeroptsl - | peeroptsl - ; - -peeroptsl : peeropts nl +peeropts_l : /* empty */ + | peeropts_l '\n' + | peeropts_l peeropts '\n' + | peeropts_l error '\n' ; peeropts : REMOTEAS as4number { @@ -1525,17 +1516,17 @@ peeropts : REMOTEAS as4number { if (merge_filterset(&r->set, $2) == -1) YYERROR; } - | SET optnl "{" optnl filter_set_l optnl "}" { + | SET "{" optnl filter_set_l optnl "}" { struct filter_rule *r; struct filter_set *s; - while ((s = TAILQ_FIRST($5)) != NULL) { - TAILQ_REMOVE($5, s, entry); + while ((s = TAILQ_FIRST($4)) != NULL) { + TAILQ_REMOVE($4, s, entry); r = get_rule(s->type); if (merge_filterset(&r->set, s) == -1) YYERROR; } - free($5); + free($4); } | mrtdump | REFLECTOR { @@ -1714,7 +1705,7 @@ direction : FROM { $$ = DIR_IN; } filter_rib_h : /* empty */ { $$ = NULL; } | RIB filter_rib { $$ = $2; } - | RIB '{' filter_rib_l '}' { $$ = $3; } + | RIB '{' optnl filter_rib_l optnl '}' { $$ = $4; } filter_rib_l : filter_rib { $$ = $1; } | filter_rib_l comma filter_rib { @@ -1746,7 +1737,7 @@ filter_rib : STRING { ; filter_peer_h : filter_peer - | '{' filter_peer_l '}' { $$ = $2; } + | '{' optnl filter_peer_l optnl '}' { $$ = $3; } ; filter_peer_l : filter_peer { $$ = $1; } @@ -2584,8 +2575,14 @@ origincode : string { free($1); }; -comma : "," - | /* empty */ +optnl : /* empty */ + | '\n' optnl + ; + +comma : /* empty */ + | ',' + | '\n' optnl + | ',' '\n' optnl ; unaryop : '=' { $$ = OP_EQ; } diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index 37422139747..cee088a96d1 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.115 2018/09/09 11:00:51 benno Exp $ */ +/* $OpenBSD: printconf.c,v 1.116 2018/09/09 13:22:41 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -29,7 +29,7 @@ #include "rde.h" #include "log.h" -void print_prefix(struct filter_prefix *p, const char *); +void print_prefix(struct filter_prefix *p); void print_community(int, int); void print_largecommunity(int64_t, int64_t, int64_t); void print_extcommunity(struct filter_extcommunity *); @@ -55,7 +55,7 @@ void print_groups(struct bgpd_config *, struct peer *); int peer_compare(const void *, const void *); void -print_prefix(struct filter_prefix *p, const char *s) +print_prefix(struct filter_prefix *p) { u_int8_t max_len = 0; @@ -72,30 +72,30 @@ print_prefix(struct filter_prefix *p, const char *s) return; } - printf("%s%s/%u ", s, log_addr(&p->addr), p->len); + printf("%s/%u", log_addr(&p->addr), p->len); switch (p->op) { case OP_NONE: break; case OP_EQ: - printf("prefixlen = %u ", p->len_min); + printf(" prefixlen = %u", p->len_min); break; case OP_NE: - printf("prefixlen != %u ", p->len_min); + printf(" prefixlen != %u", p->len_min); break; case OP_XRANGE: - printf("prefixlen %u >< %u ", p->len_min, p->len_max); + printf(" prefixlen %u >< %u ", p->len_min, p->len_max); break; case OP_RANGE: if (p->len == p->len_min && p->len_max == max_len) - printf("or-longer "); + printf(" or-longer"); else if (p->len_max == max_len) - printf("prefixlen >= %u ", p->len_min); + printf(" prefixlen >= %u", p->len_min); else - printf("prefixlen %u - %u ", p->len_min, p->len_max); + printf(" prefixlen %u - %u", p->len_min, p->len_max); break; default: - printf("prefixlen %u ??? %u ", p->len_min, p->len_max); + printf(" prefixlen %u ??? %u", p->len_min, p->len_max); break; } } @@ -448,11 +448,13 @@ print_prefixsets(struct prefixset_head *psh) SIMPLEQ_FOREACH(ps, psh, entry) { int count = 0; - printf("prefix-set \"%s\" {\n", ps->name); + printf("prefix-set \"%s\" {", ps->name); SIMPLEQ_FOREACH(psi, &ps->psitems, entry) { - print_prefix(&psi->p, "\t"); - if (count++ & 0x1) - printf("\n"); + if (count++ % 2 == 0) + printf("\n\t"); + else + printf(", "); + print_prefix(&psi->p); } printf("\n}\n\n"); } @@ -684,7 +686,11 @@ print_rule(struct peer *peer_l, struct filter_rule *r) } else printf("any "); - print_prefix(&r->match.prefix, "prefix "); + if (r->match.prefix.addr.aid != AID_UNSPEC) { + printf("prefix "); + print_prefix(&r->match.prefix); + printf(" "); + } if (r->match.prefixset.flags & PREFIXSET_FLAG_FILTER) printf("prefix-set \"%s\" ", r->match.prefixset.name); -- 2.20.1