/* A Bison parser, made by GNU Bison 3.8.2.  */

/* Bison implementation for Yacc-like parsers in C

   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
   Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* As a special exception, you may create a larger work that contains
   part or all of the Bison parser skeleton and distribute that work
   under terms of your choice, so long as that work isn't itself a
   parser generator using the skeleton or a modified version thereof
   as a parser skeleton.  Alternatively, if you modify or redistribute
   the parser skeleton itself, you may (at your option) remove this
   special exception, which will cause the skeleton and the resulting
   Bison output files to be licensed under the GNU General Public
   License without this special exception.

   This special exception was added by the Free Software Foundation in
   version 2.2 of Bison.  */

/* C LALR(1) parser skeleton written by Richard Stallman, by
   simplifying the original so-called "semantic" parser.  */

/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
   especially those whose name start with YY_ or yy_.  They are
   private implementation details that can be changed or removed.  */

/* All symbols defined below should begin with yy or YY, to avoid
   infringing on user name space.  This should be done even for local
   variables, as they might otherwise be expanded by user macros.
   There are some unavoidable exceptions within include files to
   define necessary library symbols; they are noted "INFRINGES ON
   USER NAME SPACE" below.  */

/* Identify Bison output, and Bison version.  */
#define YYBISON 30802

/* Bison version string.  */
#define YYBISON_VERSION "3.8.2"

/* Skeleton name.  */
#define YYSKELETON_NAME "yacc.c"

/* Pure parsers.  */
#define YYPURE 0

/* Push parsers.  */
#define YYPUSH 0

/* Pull parsers.  */
#define YYPULL 1




/* First part of user prologue.  */
#line 25 "../../../openbgpd-portable/src/bgpd/parse.y"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_ipsp.h>
#include <netinet/icmp6.h>
#include <arpa/inet.h>

#include <ctype.h>
#include <endian.h>
#include <err.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <netdb.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>

#include "bgpd.h"
#include "session.h"
#include "rde.h"
#include "log.h"

#define MACRO_NAME_LEN		128

TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
static struct file {
	TAILQ_ENTRY(file)	 entry;
	FILE			*stream;
	char			*name;
	size_t			 ungetpos;
	size_t			 ungetsize;
	u_char			*ungetbuf;
	int			 eof_reached;
	int			 lineno;
	int			 errors;
} *file, *topfile;
struct file	*pushfile(const char *, int);
int		 popfile(void);
int		 check_file_secrecy(int, const char *);
int		 yyparse(void);
int		 yylex(void);
int		 yyerror(const char *, ...)
    __attribute__((__format__ (printf, 1, 2)))
    __attribute__((__nonnull__ (1)));
int		 kw_cmp(const void *, const void *);
int		 lookup(char *);
int		 igetc(void);
int		 lgetc(int);
void		 lungetc(int);
int		 findeol(void);
int		 expand_macro(void);

TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
	TAILQ_ENTRY(sym)	 entry;
	int			 used;
	int			 persist;
	char			*nam;
	char			*val;
};
int		 symset(const char *, const char *, int);
char		*symget(const char *);

struct filter_rib_l {
	struct filter_rib_l	*next;
	char			 name[PEER_DESCR_LEN];
};

struct filter_peers_l {
	struct filter_peers_l	*next;
	struct filter_peers	 p;
};

struct filter_prefix_l {
	struct filter_prefix_l	*next;
	struct filter_prefix	 p;
};

struct filter_prefixlen {
	enum comp_ops		op;
	int			len_min;
	int			len_max;
};

struct filter_as_l {
	struct filter_as_l	*next;
	struct filter_as	 a;
};

struct filter_match_l {
	struct filter_match	 m;
	struct filter_prefix_l	*prefix_l;
	struct filter_as_l	*as_l;
	struct filter_prefixset	*prefixset;
} fmopts;

struct aspa_tas_l {
	struct aspa_tas_l	*next;
	uint32_t		 as;
	uint32_t		 num;
};

struct flowspec_context {
	uint8_t			*components[FLOWSPEC_TYPE_MAX];
	uint16_t		 complen[FLOWSPEC_TYPE_MAX];
	uint8_t			 aid;
	uint8_t			 type;
	uint8_t			 addr_type;
};

struct peer	*alloc_peer(void);
struct peer	*new_peer(void);
struct peer	*new_group(void);
int		 add_mrtconfig(enum mrt_type, char *, int, struct peer *,
		    char *);
struct rde_rib	*add_rib(char *);
struct rde_rib	*find_rib(char *);
int		 rib_add_fib(struct rde_rib *, u_int);
int		 get_id(struct peer *);
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 *,
		    struct filter_set_head *);
int		 str2key(char *, char *, size_t);
int		 neighbor_consistent(struct peer *);
int		 merge_filterset(struct filter_set_head *, struct filter_set *);
void		 optimize_filters(struct filter_head *);
struct filter_rule	*get_rule(enum action_types);

int		 parsecommunity(struct community *, int, char *);
int		 parseextcommunity(struct community *, char *,
		    char *);
static int	 new_as_set(char *);
static void	 add_as_set(uint32_t);
static void	 done_as_set(void);
static struct prefixset	*new_prefix_set(char *, int);
static void	 add_roa_set(struct prefixset_item *, uint32_t, uint8_t,
		    time_t);
static struct rtr_config	*get_rtr(struct bgpd_addr *);
static int	 insert_rtr(struct rtr_config *);
static int	 merge_aspa_set(uint32_t, struct aspa_tas_l *, time_t);
static int	 map_tos(char *, int *);
static int	 getservice(char *);
static int	 parse_flags(char *);
static struct flowspec_config	*flow_to_flowspec(struct flowspec_context *);
static void	 flow_free(struct flowspec_context *);
static int	 push_prefix(struct bgpd_addr *, uint8_t);
static int	 push_binop(uint8_t, long long);
static int	 push_unary_numop(enum comp_ops, long long);
static int	 push_binary_numop(enum comp_ops, long long, long long);
static int	 geticmptypebyname(char *, uint8_t);
static int	 geticmpcodebyname(u_long, char *, uint8_t);
static int	 merge_auth_conf(struct auth_config *, struct auth_config *);

static struct bgpd_config	*conf;
static struct network_head	*netconf;
static struct peer_head		*new_peers, *cur_peers;
static struct rtr_config_head	*cur_rtrs;
static struct peer		*curpeer;
static struct peer		*curgroup;
static struct rde_rib		*currib;
static struct l3vpn		*curvpn;
static struct prefixset		*curpset, *curoset;
static struct roa_tree		*curroatree;
static struct rtr_config	*currtr;
static struct filter_head	*filter_l;
static struct filter_head	*peerfilter_l;
static struct filter_head	*groupfilter_l;
static struct filter_rule	*curpeer_filter[2];
static struct filter_rule	*curgroup_filter[2];
static struct flowspec_context	*curflow;
static int			 noexpires;

typedef struct {
	union {
		long long		 number;
		char			*string;
		struct bgpd_addr	 addr;
		uint8_t			 u8;
		struct filter_rib_l	*filter_rib;
		struct filter_peers_l	*filter_peers;
		struct filter_match_l	 filter_match;
		struct filter_prefixset	*filter_prefixset;
		struct filter_prefix_l	*filter_prefix;
		struct filter_as_l	*filter_as;
		struct filter_set	*filter_set;
		struct filter_set_head	*filter_set_head;
		struct aspa_tas_l	*aspa_elm;
		struct {
			struct bgpd_addr	prefix;
			uint8_t			len;
		}			prefix;
		struct filter_prefixlen	prefixlen;
		struct prefixset_item	*prefixset_item;
		struct auth_config	authconf;
		struct {
			enum auth_enc_alg	enc_alg;
			uint8_t			enc_key_len;
			char			enc_key[IPSEC_ENC_KEY_LEN];
		}			encspec;
	} v;
	int lineno;
} YYSTYPE;


#line 286 "parse.c"

# ifndef YY_CAST
#  ifdef __cplusplus
#   define YY_CAST(Type, Val) static_cast<Type> (Val)
#   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
#  else
#   define YY_CAST(Type, Val) ((Type) (Val))
#   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
#  endif
# endif
# ifndef YY_NULLPTR
#  if defined __cplusplus
#   if 201103L <= __cplusplus
#    define YY_NULLPTR nullptr
#   else
#    define YY_NULLPTR 0
#   endif
#  else
#   define YY_NULLPTR ((void*)0)
#  endif
# endif


/* Debug traces.  */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif

/* Token kinds.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
  enum yytokentype
  {
    YYEMPTY = -2,
    YYEOF = 0,                     /* "end of file"  */
    YYerror = 256,                 /* error  */
    YYUNDEF = 257,                 /* "invalid token"  */
    AS = 258,                      /* AS  */
    ROUTERID = 259,                /* ROUTERID  */
    HOLDTIME = 260,                /* HOLDTIME  */
    YMIN = 261,                    /* YMIN  */
    LISTEN = 262,                  /* LISTEN  */
    ON = 263,                      /* ON  */
    FIBUPDATE = 264,               /* FIBUPDATE  */
    FIBPRIORITY = 265,             /* FIBPRIORITY  */
    RTABLE = 266,                  /* RTABLE  */
    NONE = 267,                    /* NONE  */
    UNICAST = 268,                 /* UNICAST  */
    VPN = 269,                     /* VPN  */
    RD = 270,                      /* RD  */
    EXPORT = 271,                  /* EXPORT  */
    EXPORTTRGT = 272,              /* EXPORTTRGT  */
    IMPORTTRGT = 273,              /* IMPORTTRGT  */
    DEFAULTROUTE = 274,            /* DEFAULTROUTE  */
    RDE = 275,                     /* RDE  */
    RIB = 276,                     /* RIB  */
    EVALUATE = 277,                /* EVALUATE  */
    IGNORE = 278,                  /* IGNORE  */
    COMPARE = 279,                 /* COMPARE  */
    RTR = 280,                     /* RTR  */
    PORT = 281,                    /* PORT  */
    MINVERSION = 282,              /* MINVERSION  */
    STALETIME = 283,               /* STALETIME  */
    GROUP = 284,                   /* GROUP  */
    NEIGHBOR = 285,                /* NEIGHBOR  */
    NETWORK = 286,                 /* NETWORK  */
    EBGP = 287,                    /* EBGP  */
    IBGP = 288,                    /* IBGP  */
    FLOWSPEC = 289,                /* FLOWSPEC  */
    PROTO = 290,                   /* PROTO  */
    FLAGS = 291,                   /* FLAGS  */
    FRAGMENT = 292,                /* FRAGMENT  */
    TOS = 293,                     /* TOS  */
    LENGTH = 294,                  /* LENGTH  */
    ICMPTYPE = 295,                /* ICMPTYPE  */
    CODE = 296,                    /* CODE  */
    LOCALAS = 297,                 /* LOCALAS  */
    REMOTEAS = 298,                /* REMOTEAS  */
    DESCR = 299,                   /* DESCR  */
    LOCALADDR = 300,               /* LOCALADDR  */
    MULTIHOP = 301,                /* MULTIHOP  */
    PASSIVE = 302,                 /* PASSIVE  */
    MAXPREFIX = 303,               /* MAXPREFIX  */
    RESTART = 304,                 /* RESTART  */
    ANNOUNCE = 305,                /* ANNOUNCE  */
    REFRESH = 306,                 /* REFRESH  */
    AS4BYTE = 307,                 /* AS4BYTE  */
    CONNECTRETRY = 308,            /* CONNECTRETRY  */
    ENHANCED = 309,                /* ENHANCED  */
    ADDPATH = 310,                 /* ADDPATH  */
    EXTENDED = 311,                /* EXTENDED  */
    SEND = 312,                    /* SEND  */
    RECV = 313,                    /* RECV  */
    PLUS = 314,                    /* PLUS  */
    POLICY = 315,                  /* POLICY  */
    ROLE = 316,                    /* ROLE  */
    GRACEFUL = 317,                /* GRACEFUL  */
    NOTIFICATION = 318,            /* NOTIFICATION  */
    MESSAGE = 319,                 /* MESSAGE  */
    DEMOTE = 320,                  /* DEMOTE  */
    ENFORCE = 321,                 /* ENFORCE  */
    NEIGHBORAS = 322,              /* NEIGHBORAS  */
    ASOVERRIDE = 323,              /* ASOVERRIDE  */
    REFLECTOR = 324,               /* REFLECTOR  */
    DEPEND = 325,                  /* DEPEND  */
    DOWN = 326,                    /* DOWN  */
    DUMP = 327,                    /* DUMP  */
    IN = 328,                      /* IN  */
    OUT = 329,                     /* OUT  */
    SOCKET = 330,                  /* SOCKET  */
    RESTRICTED = 331,              /* RESTRICTED  */
    LOG = 332,                     /* LOG  */
    TRANSPARENT = 333,             /* TRANSPARENT  */
    FILTERED = 334,                /* FILTERED  */
    TCP = 335,                     /* TCP  */
    MD5SIG = 336,                  /* MD5SIG  */
    PASSWORD = 337,                /* PASSWORD  */
    KEY = 338,                     /* KEY  */
    TTLSECURITY = 339,             /* TTLSECURITY  */
    ALLOW = 340,                   /* ALLOW  */
    DENY = 341,                    /* DENY  */
    MATCH = 342,                   /* MATCH  */
    QUICK = 343,                   /* QUICK  */
    FROM = 344,                    /* FROM  */
    TO = 345,                      /* TO  */
    ANY = 346,                     /* ANY  */
    CONNECTED = 347,               /* CONNECTED  */
    STATIC = 348,                  /* STATIC  */
    COMMUNITY = 349,               /* COMMUNITY  */
    EXTCOMMUNITY = 350,            /* EXTCOMMUNITY  */
    LARGECOMMUNITY = 351,          /* LARGECOMMUNITY  */
    DELETE = 352,                  /* DELETE  */
    MAXCOMMUNITIES = 353,          /* MAXCOMMUNITIES  */
    MAXEXTCOMMUNITIES = 354,       /* MAXEXTCOMMUNITIES  */
    MAXLARGECOMMUNITIES = 355,     /* MAXLARGECOMMUNITIES  */
    PREFIX = 356,                  /* PREFIX  */
    PREFIXLEN = 357,               /* PREFIXLEN  */
    PREFIXSET = 358,               /* PREFIXSET  */
    ASPASET = 359,                 /* ASPASET  */
    ROASET = 360,                  /* ROASET  */
    ORIGINSET = 361,               /* ORIGINSET  */
    OVS = 362,                     /* OVS  */
    AVS = 363,                     /* AVS  */
    EXPIRES = 364,                 /* EXPIRES  */
    ASSET = 365,                   /* ASSET  */
    SOURCEAS = 366,                /* SOURCEAS  */
    TRANSITAS = 367,               /* TRANSITAS  */
    PEERAS = 368,                  /* PEERAS  */
    PROVIDERAS = 369,              /* PROVIDERAS  */
    CUSTOMERAS = 370,              /* CUSTOMERAS  */
    MAXASLEN = 371,                /* MAXASLEN  */
    MAXASSEQ = 372,                /* MAXASSEQ  */
    SET = 373,                     /* SET  */
    LOCALPREF = 374,               /* LOCALPREF  */
    MED = 375,                     /* MED  */
    METRIC = 376,                  /* METRIC  */
    NEXTHOP = 377,                 /* NEXTHOP  */
    REJECT = 378,                  /* REJECT  */
    BLACKHOLE = 379,               /* BLACKHOLE  */
    NOMODIFY = 380,                /* NOMODIFY  */
    SELF = 381,                    /* SELF  */
    PREPEND_SELF = 382,            /* PREPEND_SELF  */
    PREPEND_PEER = 383,            /* PREPEND_PEER  */
    PFTABLE = 384,                 /* PFTABLE  */
    WEIGHT = 385,                  /* WEIGHT  */
    RTLABEL = 386,                 /* RTLABEL  */
    ORIGIN = 387,                  /* ORIGIN  */
    PRIORITY = 388,                /* PRIORITY  */
    ERROR = 389,                   /* ERROR  */
    INCLUDE = 390,                 /* INCLUDE  */
    IPSEC = 391,                   /* IPSEC  */
    ESP = 392,                     /* ESP  */
    AH = 393,                      /* AH  */
    SPI = 394,                     /* SPI  */
    IKE = 395,                     /* IKE  */
    IPV4 = 396,                    /* IPV4  */
    IPV6 = 397,                    /* IPV6  */
    EVPN = 398,                    /* EVPN  */
    QUALIFY = 399,                 /* QUALIFY  */
    VIA = 400,                     /* VIA  */
    NE = 401,                      /* NE  */
    LE = 402,                      /* LE  */
    GE = 403,                      /* GE  */
    XRANGE = 404,                  /* XRANGE  */
    LONGER = 405,                  /* LONGER  */
    MAXLEN = 406,                  /* MAXLEN  */
    MAX = 407,                     /* MAX  */
    STRING = 408,                  /* STRING  */
    NUMBER = 409                   /* NUMBER  */
  };
  typedef enum yytokentype yytoken_kind_t;
#endif
/* Token kinds.  */
#define YYEMPTY -2
#define YYEOF 0
#define YYerror 256
#define YYUNDEF 257
#define AS 258
#define ROUTERID 259
#define HOLDTIME 260
#define YMIN 261
#define LISTEN 262
#define ON 263
#define FIBUPDATE 264
#define FIBPRIORITY 265
#define RTABLE 266
#define NONE 267
#define UNICAST 268
#define VPN 269
#define RD 270
#define EXPORT 271
#define EXPORTTRGT 272
#define IMPORTTRGT 273
#define DEFAULTROUTE 274
#define RDE 275
#define RIB 276
#define EVALUATE 277
#define IGNORE 278
#define COMPARE 279
#define RTR 280
#define PORT 281
#define MINVERSION 282
#define STALETIME 283
#define GROUP 284
#define NEIGHBOR 285
#define NETWORK 286
#define EBGP 287
#define IBGP 288
#define FLOWSPEC 289
#define PROTO 290
#define FLAGS 291
#define FRAGMENT 292
#define TOS 293
#define LENGTH 294
#define ICMPTYPE 295
#define CODE 296
#define LOCALAS 297
#define REMOTEAS 298
#define DESCR 299
#define LOCALADDR 300
#define MULTIHOP 301
#define PASSIVE 302
#define MAXPREFIX 303
#define RESTART 304
#define ANNOUNCE 305
#define REFRESH 306
#define AS4BYTE 307
#define CONNECTRETRY 308
#define ENHANCED 309
#define ADDPATH 310
#define EXTENDED 311
#define SEND 312
#define RECV 313
#define PLUS 314
#define POLICY 315
#define ROLE 316
#define GRACEFUL 317
#define NOTIFICATION 318
#define MESSAGE 319
#define DEMOTE 320
#define ENFORCE 321
#define NEIGHBORAS 322
#define ASOVERRIDE 323
#define REFLECTOR 324
#define DEPEND 325
#define DOWN 326
#define DUMP 327
#define IN 328
#define OUT 329
#define SOCKET 330
#define RESTRICTED 331
#define LOG 332
#define TRANSPARENT 333
#define FILTERED 334
#define TCP 335
#define MD5SIG 336
#define PASSWORD 337
#define KEY 338
#define TTLSECURITY 339
#define ALLOW 340
#define DENY 341
#define MATCH 342
#define QUICK 343
#define FROM 344
#define TO 345
#define ANY 346
#define CONNECTED 347
#define STATIC 348
#define COMMUNITY 349
#define EXTCOMMUNITY 350
#define LARGECOMMUNITY 351
#define DELETE 352
#define MAXCOMMUNITIES 353
#define MAXEXTCOMMUNITIES 354
#define MAXLARGECOMMUNITIES 355
#define PREFIX 356
#define PREFIXLEN 357
#define PREFIXSET 358
#define ASPASET 359
#define ROASET 360
#define ORIGINSET 361
#define OVS 362
#define AVS 363
#define EXPIRES 364
#define ASSET 365
#define SOURCEAS 366
#define TRANSITAS 367
#define PEERAS 368
#define PROVIDERAS 369
#define CUSTOMERAS 370
#define MAXASLEN 371
#define MAXASSEQ 372
#define SET 373
#define LOCALPREF 374
#define MED 375
#define METRIC 376
#define NEXTHOP 377
#define REJECT 378
#define BLACKHOLE 379
#define NOMODIFY 380
#define SELF 381
#define PREPEND_SELF 382
#define PREPEND_PEER 383
#define PFTABLE 384
#define WEIGHT 385
#define RTLABEL 386
#define ORIGIN 387
#define PRIORITY 388
#define ERROR 389
#define INCLUDE 390
#define IPSEC 391
#define ESP 392
#define AH 393
#define SPI 394
#define IKE 395
#define IPV4 396
#define IPV6 397
#define EVPN 398
#define QUALIFY 399
#define VIA 400
#define NE 401
#define LE 402
#define GE 403
#define XRANGE 404
#define LONGER 405
#define MAXLEN 406
#define MAX 407
#define STRING 408
#define NUMBER 409

/* Value type.  */


extern YYSTYPE yylval;


int yyparse (void);



/* Symbol kind.  */
enum yysymbol_kind_t
{
  YYSYMBOL_YYEMPTY = -2,
  YYSYMBOL_YYEOF = 0,                      /* "end of file"  */
  YYSYMBOL_YYerror = 1,                    /* error  */
  YYSYMBOL_YYUNDEF = 2,                    /* "invalid token"  */
  YYSYMBOL_AS = 3,                         /* AS  */
  YYSYMBOL_ROUTERID = 4,                   /* ROUTERID  */
  YYSYMBOL_HOLDTIME = 5,                   /* HOLDTIME  */
  YYSYMBOL_YMIN = 6,                       /* YMIN  */
  YYSYMBOL_LISTEN = 7,                     /* LISTEN  */
  YYSYMBOL_ON = 8,                         /* ON  */
  YYSYMBOL_FIBUPDATE = 9,                  /* FIBUPDATE  */
  YYSYMBOL_FIBPRIORITY = 10,               /* FIBPRIORITY  */
  YYSYMBOL_RTABLE = 11,                    /* RTABLE  */
  YYSYMBOL_NONE = 12,                      /* NONE  */
  YYSYMBOL_UNICAST = 13,                   /* UNICAST  */
  YYSYMBOL_VPN = 14,                       /* VPN  */
  YYSYMBOL_RD = 15,                        /* RD  */
  YYSYMBOL_EXPORT = 16,                    /* EXPORT  */
  YYSYMBOL_EXPORTTRGT = 17,                /* EXPORTTRGT  */
  YYSYMBOL_IMPORTTRGT = 18,                /* IMPORTTRGT  */
  YYSYMBOL_DEFAULTROUTE = 19,              /* DEFAULTROUTE  */
  YYSYMBOL_RDE = 20,                       /* RDE  */
  YYSYMBOL_RIB = 21,                       /* RIB  */
  YYSYMBOL_EVALUATE = 22,                  /* EVALUATE  */
  YYSYMBOL_IGNORE = 23,                    /* IGNORE  */
  YYSYMBOL_COMPARE = 24,                   /* COMPARE  */
  YYSYMBOL_RTR = 25,                       /* RTR  */
  YYSYMBOL_PORT = 26,                      /* PORT  */
  YYSYMBOL_MINVERSION = 27,                /* MINVERSION  */
  YYSYMBOL_STALETIME = 28,                 /* STALETIME  */
  YYSYMBOL_GROUP = 29,                     /* GROUP  */
  YYSYMBOL_NEIGHBOR = 30,                  /* NEIGHBOR  */
  YYSYMBOL_NETWORK = 31,                   /* NETWORK  */
  YYSYMBOL_EBGP = 32,                      /* EBGP  */
  YYSYMBOL_IBGP = 33,                      /* IBGP  */
  YYSYMBOL_FLOWSPEC = 34,                  /* FLOWSPEC  */
  YYSYMBOL_PROTO = 35,                     /* PROTO  */
  YYSYMBOL_FLAGS = 36,                     /* FLAGS  */
  YYSYMBOL_FRAGMENT = 37,                  /* FRAGMENT  */
  YYSYMBOL_TOS = 38,                       /* TOS  */
  YYSYMBOL_LENGTH = 39,                    /* LENGTH  */
  YYSYMBOL_ICMPTYPE = 40,                  /* ICMPTYPE  */
  YYSYMBOL_CODE = 41,                      /* CODE  */
  YYSYMBOL_LOCALAS = 42,                   /* LOCALAS  */
  YYSYMBOL_REMOTEAS = 43,                  /* REMOTEAS  */
  YYSYMBOL_DESCR = 44,                     /* DESCR  */
  YYSYMBOL_LOCALADDR = 45,                 /* LOCALADDR  */
  YYSYMBOL_MULTIHOP = 46,                  /* MULTIHOP  */
  YYSYMBOL_PASSIVE = 47,                   /* PASSIVE  */
  YYSYMBOL_MAXPREFIX = 48,                 /* MAXPREFIX  */
  YYSYMBOL_RESTART = 49,                   /* RESTART  */
  YYSYMBOL_ANNOUNCE = 50,                  /* ANNOUNCE  */
  YYSYMBOL_REFRESH = 51,                   /* REFRESH  */
  YYSYMBOL_AS4BYTE = 52,                   /* AS4BYTE  */
  YYSYMBOL_CONNECTRETRY = 53,              /* CONNECTRETRY  */
  YYSYMBOL_ENHANCED = 54,                  /* ENHANCED  */
  YYSYMBOL_ADDPATH = 55,                   /* ADDPATH  */
  YYSYMBOL_EXTENDED = 56,                  /* EXTENDED  */
  YYSYMBOL_SEND = 57,                      /* SEND  */
  YYSYMBOL_RECV = 58,                      /* RECV  */
  YYSYMBOL_PLUS = 59,                      /* PLUS  */
  YYSYMBOL_POLICY = 60,                    /* POLICY  */
  YYSYMBOL_ROLE = 61,                      /* ROLE  */
  YYSYMBOL_GRACEFUL = 62,                  /* GRACEFUL  */
  YYSYMBOL_NOTIFICATION = 63,              /* NOTIFICATION  */
  YYSYMBOL_MESSAGE = 64,                   /* MESSAGE  */
  YYSYMBOL_DEMOTE = 65,                    /* DEMOTE  */
  YYSYMBOL_ENFORCE = 66,                   /* ENFORCE  */
  YYSYMBOL_NEIGHBORAS = 67,                /* NEIGHBORAS  */
  YYSYMBOL_ASOVERRIDE = 68,                /* ASOVERRIDE  */
  YYSYMBOL_REFLECTOR = 69,                 /* REFLECTOR  */
  YYSYMBOL_DEPEND = 70,                    /* DEPEND  */
  YYSYMBOL_DOWN = 71,                      /* DOWN  */
  YYSYMBOL_DUMP = 72,                      /* DUMP  */
  YYSYMBOL_IN = 73,                        /* IN  */
  YYSYMBOL_OUT = 74,                       /* OUT  */
  YYSYMBOL_SOCKET = 75,                    /* SOCKET  */
  YYSYMBOL_RESTRICTED = 76,                /* RESTRICTED  */
  YYSYMBOL_LOG = 77,                       /* LOG  */
  YYSYMBOL_TRANSPARENT = 78,               /* TRANSPARENT  */
  YYSYMBOL_FILTERED = 79,                  /* FILTERED  */
  YYSYMBOL_TCP = 80,                       /* TCP  */
  YYSYMBOL_MD5SIG = 81,                    /* MD5SIG  */
  YYSYMBOL_PASSWORD = 82,                  /* PASSWORD  */
  YYSYMBOL_KEY = 83,                       /* KEY  */
  YYSYMBOL_TTLSECURITY = 84,               /* TTLSECURITY  */
  YYSYMBOL_ALLOW = 85,                     /* ALLOW  */
  YYSYMBOL_DENY = 86,                      /* DENY  */
  YYSYMBOL_MATCH = 87,                     /* MATCH  */
  YYSYMBOL_QUICK = 88,                     /* QUICK  */
  YYSYMBOL_FROM = 89,                      /* FROM  */
  YYSYMBOL_TO = 90,                        /* TO  */
  YYSYMBOL_ANY = 91,                       /* ANY  */
  YYSYMBOL_CONNECTED = 92,                 /* CONNECTED  */
  YYSYMBOL_STATIC = 93,                    /* STATIC  */
  YYSYMBOL_COMMUNITY = 94,                 /* COMMUNITY  */
  YYSYMBOL_EXTCOMMUNITY = 95,              /* EXTCOMMUNITY  */
  YYSYMBOL_LARGECOMMUNITY = 96,            /* LARGECOMMUNITY  */
  YYSYMBOL_DELETE = 97,                    /* DELETE  */
  YYSYMBOL_MAXCOMMUNITIES = 98,            /* MAXCOMMUNITIES  */
  YYSYMBOL_MAXEXTCOMMUNITIES = 99,         /* MAXEXTCOMMUNITIES  */
  YYSYMBOL_MAXLARGECOMMUNITIES = 100,      /* MAXLARGECOMMUNITIES  */
  YYSYMBOL_PREFIX = 101,                   /* PREFIX  */
  YYSYMBOL_PREFIXLEN = 102,                /* PREFIXLEN  */
  YYSYMBOL_PREFIXSET = 103,                /* PREFIXSET  */
  YYSYMBOL_ASPASET = 104,                  /* ASPASET  */
  YYSYMBOL_ROASET = 105,                   /* ROASET  */
  YYSYMBOL_ORIGINSET = 106,                /* ORIGINSET  */
  YYSYMBOL_OVS = 107,                      /* OVS  */
  YYSYMBOL_AVS = 108,                      /* AVS  */
  YYSYMBOL_EXPIRES = 109,                  /* EXPIRES  */
  YYSYMBOL_ASSET = 110,                    /* ASSET  */
  YYSYMBOL_SOURCEAS = 111,                 /* SOURCEAS  */
  YYSYMBOL_TRANSITAS = 112,                /* TRANSITAS  */
  YYSYMBOL_PEERAS = 113,                   /* PEERAS  */
  YYSYMBOL_PROVIDERAS = 114,               /* PROVIDERAS  */
  YYSYMBOL_CUSTOMERAS = 115,               /* CUSTOMERAS  */
  YYSYMBOL_MAXASLEN = 116,                 /* MAXASLEN  */
  YYSYMBOL_MAXASSEQ = 117,                 /* MAXASSEQ  */
  YYSYMBOL_SET = 118,                      /* SET  */
  YYSYMBOL_LOCALPREF = 119,                /* LOCALPREF  */
  YYSYMBOL_MED = 120,                      /* MED  */
  YYSYMBOL_METRIC = 121,                   /* METRIC  */
  YYSYMBOL_NEXTHOP = 122,                  /* NEXTHOP  */
  YYSYMBOL_REJECT = 123,                   /* REJECT  */
  YYSYMBOL_BLACKHOLE = 124,                /* BLACKHOLE  */
  YYSYMBOL_NOMODIFY = 125,                 /* NOMODIFY  */
  YYSYMBOL_SELF = 126,                     /* SELF  */
  YYSYMBOL_PREPEND_SELF = 127,             /* PREPEND_SELF  */
  YYSYMBOL_PREPEND_PEER = 128,             /* PREPEND_PEER  */
  YYSYMBOL_PFTABLE = 129,                  /* PFTABLE  */
  YYSYMBOL_WEIGHT = 130,                   /* WEIGHT  */
  YYSYMBOL_RTLABEL = 131,                  /* RTLABEL  */
  YYSYMBOL_ORIGIN = 132,                   /* ORIGIN  */
  YYSYMBOL_PRIORITY = 133,                 /* PRIORITY  */
  YYSYMBOL_ERROR = 134,                    /* ERROR  */
  YYSYMBOL_INCLUDE = 135,                  /* INCLUDE  */
  YYSYMBOL_IPSEC = 136,                    /* IPSEC  */
  YYSYMBOL_ESP = 137,                      /* ESP  */
  YYSYMBOL_AH = 138,                       /* AH  */
  YYSYMBOL_SPI = 139,                      /* SPI  */
  YYSYMBOL_IKE = 140,                      /* IKE  */
  YYSYMBOL_IPV4 = 141,                     /* IPV4  */
  YYSYMBOL_IPV6 = 142,                     /* IPV6  */
  YYSYMBOL_EVPN = 143,                     /* EVPN  */
  YYSYMBOL_QUALIFY = 144,                  /* QUALIFY  */
  YYSYMBOL_VIA = 145,                      /* VIA  */
  YYSYMBOL_NE = 146,                       /* NE  */
  YYSYMBOL_LE = 147,                       /* LE  */
  YYSYMBOL_GE = 148,                       /* GE  */
  YYSYMBOL_XRANGE = 149,                   /* XRANGE  */
  YYSYMBOL_LONGER = 150,                   /* LONGER  */
  YYSYMBOL_MAXLEN = 151,                   /* MAXLEN  */
  YYSYMBOL_MAX = 152,                      /* MAX  */
  YYSYMBOL_STRING = 153,                   /* STRING  */
  YYSYMBOL_NUMBER = 154,                   /* NUMBER  */
  YYSYMBOL_155_n_ = 155,                   /* '\n'  */
  YYSYMBOL_156_ = 156,                     /* '='  */
  YYSYMBOL_157_ = 157,                     /* '{'  */
  YYSYMBOL_158_ = 158,                     /* '}'  */
  YYSYMBOL_159_ = 159,                     /* '/'  */
  YYSYMBOL_160_ = 160,                     /* '+'  */
  YYSYMBOL_161_ = 161,                     /* '-'  */
  YYSYMBOL_162_ = 162,                     /* ','  */
  YYSYMBOL_163_ = 163,                     /* '<'  */
  YYSYMBOL_164_ = 164,                     /* '>'  */
  YYSYMBOL_YYACCEPT = 165,                 /* $accept  */
  YYSYMBOL_grammar = 166,                  /* grammar  */
  YYSYMBOL_asnumber = 167,                 /* asnumber  */
  YYSYMBOL_as4number = 168,                /* as4number  */
  YYSYMBOL_as4number_any = 169,            /* as4number_any  */
  YYSYMBOL_string = 170,                   /* string  */
  YYSYMBOL_yesno = 171,                    /* yesno  */
  YYSYMBOL_varset = 172,                   /* varset  */
  YYSYMBOL_include = 173,                  /* include  */
  YYSYMBOL_as_set = 174,                   /* as_set  */
  YYSYMBOL_175_1 = 175,                    /* $@1  */
  YYSYMBOL_as_set_l = 176,                 /* as_set_l  */
  YYSYMBOL_prefixset = 177,                /* prefixset  */
  YYSYMBOL_178_2 = 178,                    /* $@2  */
  YYSYMBOL_prefixset_l = 179,              /* prefixset_l  */
  YYSYMBOL_prefixset_item = 180,           /* prefixset_item  */
  YYSYMBOL_roa_set = 181,                  /* roa_set  */
  YYSYMBOL_182_3 = 182,                    /* $@3  */
  YYSYMBOL_origin_set = 183,               /* origin_set  */
  YYSYMBOL_184_4 = 184,                    /* $@4  */
  YYSYMBOL_expires = 185,                  /* expires  */
  YYSYMBOL_roa_set_l = 186,                /* roa_set_l  */
  YYSYMBOL_aspa_set = 187,                 /* aspa_set  */
  YYSYMBOL_aspa_set_l = 188,               /* aspa_set_l  */
  YYSYMBOL_aspa_elm = 189,                 /* aspa_elm  */
  YYSYMBOL_aspa_tas_l = 190,               /* aspa_tas_l  */
  YYSYMBOL_aspa_tas = 191,                 /* aspa_tas  */
  YYSYMBOL_rtr = 192,                      /* rtr  */
  YYSYMBOL_193_5 = 193,                    /* $@5  */
  YYSYMBOL_rtropt_l = 194,                 /* rtropt_l  */
  YYSYMBOL_rtropt = 195,                   /* rtropt  */
  YYSYMBOL_conf_main = 196,                /* conf_main  */
  YYSYMBOL_rib = 197,                      /* rib  */
  YYSYMBOL_198_6 = 198,                    /* $@6  */
  YYSYMBOL_ribopts = 199,                  /* ribopts  */
  YYSYMBOL_fibupdate = 200,                /* fibupdate  */
  YYSYMBOL_mrtdump = 201,                  /* mrtdump  */
  YYSYMBOL_network = 202,                  /* network  */
  YYSYMBOL_flowspec = 203,                 /* flowspec  */
  YYSYMBOL_204_7 = 204,                    /* $@7  */
  YYSYMBOL_proto = 205,                    /* proto  */
  YYSYMBOL_proto_list = 206,               /* proto_list  */
  YYSYMBOL_proto_item = 207,               /* proto_item  */
  YYSYMBOL_from = 208,                     /* from  */
  YYSYMBOL_209_8 = 209,                    /* $@8  */
  YYSYMBOL_to = 210,                       /* to  */
  YYSYMBOL_211_9 = 211,                    /* $@9  */
  YYSYMBOL_ipportspec = 212,               /* ipportspec  */
  YYSYMBOL_ipspec = 213,                   /* ipspec  */
  YYSYMBOL_portspec = 214,                 /* portspec  */
  YYSYMBOL_port_list = 215,                /* port_list  */
  YYSYMBOL_port_item = 216,                /* port_item  */
  YYSYMBOL_port = 217,                     /* port  */
  YYSYMBOL_flow_rules = 218,               /* flow_rules  */
  YYSYMBOL_flow_rules_l = 219,             /* flow_rules_l  */
  YYSYMBOL_flowrule = 220,                 /* flowrule  */
  YYSYMBOL_221_10 = 221,                   /* $@10  */
  YYSYMBOL_222_11 = 222,                   /* $@11  */
  YYSYMBOL_flags = 223,                    /* flags  */
  YYSYMBOL_flag = 224,                     /* flag  */
  YYSYMBOL_icmpspec = 225,                 /* icmpspec  */
  YYSYMBOL_icmp_list = 226,                /* icmp_list  */
  YYSYMBOL_icmp_item = 227,                /* icmp_item  */
  YYSYMBOL_icmptype = 228,                 /* icmptype  */
  YYSYMBOL_tos = 229,                      /* tos  */
  YYSYMBOL_lengthspec = 230,               /* lengthspec  */
  YYSYMBOL_length_list = 231,              /* length_list  */
  YYSYMBOL_length_item = 232,              /* length_item  */
  YYSYMBOL_length = 233,                   /* length  */
  YYSYMBOL_inout = 234,                    /* inout  */
  YYSYMBOL_restricted = 235,               /* restricted  */
  YYSYMBOL_address = 236,                  /* address  */
  YYSYMBOL_prefix = 237,                   /* prefix  */
  YYSYMBOL_addrspec = 238,                 /* addrspec  */
  YYSYMBOL_optnumber = 239,                /* optnumber  */
  YYSYMBOL_l3vpn = 240,                    /* l3vpn  */
  YYSYMBOL_241_12 = 241,                   /* $@12  */
  YYSYMBOL_l3vpnopts_l = 242,              /* l3vpnopts_l  */
  YYSYMBOL_l3vpnopts = 243,                /* l3vpnopts  */
  YYSYMBOL_neighbor = 244,                 /* neighbor  */
  YYSYMBOL_245_13 = 245,                   /* $@13  */
  YYSYMBOL_246_14 = 246,                   /* $@14  */
  YYSYMBOL_group = 247,                    /* group  */
  YYSYMBOL_248_15 = 248,                   /* $@15  */
  YYSYMBOL_groupopts_l = 249,              /* groupopts_l  */
  YYSYMBOL_addpathextra = 250,             /* addpathextra  */
  YYSYMBOL_addpathmax = 251,               /* addpathmax  */
  YYSYMBOL_peeropts_h = 252,               /* peeropts_h  */
  YYSYMBOL_peeropts_l = 253,               /* peeropts_l  */
  YYSYMBOL_peeropts = 254,                 /* peeropts  */
  YYSYMBOL_restart = 255,                  /* restart  */
  YYSYMBOL_af = 256,                       /* af  */
  YYSYMBOL_safi = 257,                     /* safi  */
  YYSYMBOL_nettype = 258,                  /* nettype  */
  YYSYMBOL_authconf = 259,                 /* authconf  */
  YYSYMBOL_espah = 260,                    /* espah  */
  YYSYMBOL_encspec = 261,                  /* encspec  */
  YYSYMBOL_filterrule = 262,               /* filterrule  */
  YYSYMBOL_action = 263,                   /* action  */
  YYSYMBOL_quick = 264,                    /* quick  */
  YYSYMBOL_direction = 265,                /* direction  */
  YYSYMBOL_filter_rib_h = 266,             /* filter_rib_h  */
  YYSYMBOL_filter_rib_l = 267,             /* filter_rib_l  */
  YYSYMBOL_filter_rib = 268,               /* filter_rib  */
  YYSYMBOL_filter_peer_h = 269,            /* filter_peer_h  */
  YYSYMBOL_filter_peer_l = 270,            /* filter_peer_l  */
  YYSYMBOL_filter_peer = 271,              /* filter_peer  */
  YYSYMBOL_filter_prefix_h = 272,          /* filter_prefix_h  */
  YYSYMBOL_filter_prefix_m = 273,          /* filter_prefix_m  */
  YYSYMBOL_filter_prefix_l = 274,          /* filter_prefix_l  */
  YYSYMBOL_filter_prefix = 275,            /* filter_prefix  */
  YYSYMBOL_filter_as_h = 276,              /* filter_as_h  */
  YYSYMBOL_filter_as_t_l = 277,            /* filter_as_t_l  */
  YYSYMBOL_filter_as_t = 278,              /* filter_as_t  */
  YYSYMBOL_filter_as_l_h = 279,            /* filter_as_l_h  */
  YYSYMBOL_filter_as_l = 280,              /* filter_as_l  */
  YYSYMBOL_filter_as = 281,                /* filter_as  */
  YYSYMBOL_filter_match_h = 282,           /* filter_match_h  */
  YYSYMBOL_283_16 = 283,                   /* $@16  */
  YYSYMBOL_filter_match = 284,             /* filter_match  */
  YYSYMBOL_filter_elm = 285,               /* filter_elm  */
  YYSYMBOL_prefixlenop = 286,              /* prefixlenop  */
  YYSYMBOL_filter_as_type = 287,           /* filter_as_type  */
  YYSYMBOL_filter_set = 288,               /* filter_set  */
  YYSYMBOL_filter_set_l = 289,             /* filter_set_l  */
  YYSYMBOL_community = 290,                /* community  */
  YYSYMBOL_delete = 291,                   /* delete  */
  YYSYMBOL_enforce = 292,                  /* enforce  */
  YYSYMBOL_yesnoenforce = 293,             /* yesnoenforce  */
  YYSYMBOL_filter_set_opt = 294,           /* filter_set_opt  */
  YYSYMBOL_origincode = 295,               /* origincode  */
  YYSYMBOL_validity = 296,                 /* validity  */
  YYSYMBOL_aspa_validity = 297,            /* aspa_validity  */
  YYSYMBOL_optnl = 298,                    /* optnl  */
  YYSYMBOL_comma = 299,                    /* comma  */
  YYSYMBOL_unaryop = 300,                  /* unaryop  */
  YYSYMBOL_equalityop = 301,               /* equalityop  */
  YYSYMBOL_binaryop = 302                  /* binaryop  */
};
typedef enum yysymbol_kind_t yysymbol_kind_t;




#ifdef short
# undef short
#endif

/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
   <limits.h> and (if available) <stdint.h> are included
   so that the code can choose integer types of a good width.  */

#ifndef __PTRDIFF_MAX__
# include <limits.h> /* INFRINGES ON USER NAME SPACE */
# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
#  include <stdint.h> /* INFRINGES ON USER NAME SPACE */
#  define YY_STDINT_H
# endif
#endif

/* Narrow types that promote to a signed type and that can represent a
   signed or unsigned integer of at least N bits.  In tables they can
   save space and decrease cache pressure.  Promoting to a signed type
   helps avoid bugs in integer arithmetic.  */

#ifdef __INT_LEAST8_MAX__
typedef __INT_LEAST8_TYPE__ yytype_int8;
#elif defined YY_STDINT_H
typedef int_least8_t yytype_int8;
#else
typedef signed char yytype_int8;
#endif

#ifdef __INT_LEAST16_MAX__
typedef __INT_LEAST16_TYPE__ yytype_int16;
#elif defined YY_STDINT_H
typedef int_least16_t yytype_int16;
#else
typedef short yytype_int16;
#endif

/* Work around bug in HP-UX 11.23, which defines these macros
   incorrectly for preprocessor constants.  This workaround can likely
   be removed in 2023, as HPE has promised support for HP-UX 11.23
   (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
   <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>.  */
#ifdef __hpux
# undef UINT_LEAST8_MAX
# undef UINT_LEAST16_MAX
# define UINT_LEAST8_MAX 255
# define UINT_LEAST16_MAX 65535
#endif

#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
typedef __UINT_LEAST8_TYPE__ yytype_uint8;
#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
       && UINT_LEAST8_MAX <= INT_MAX)
typedef uint_least8_t yytype_uint8;
#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
typedef unsigned char yytype_uint8;
#else
typedef short yytype_uint8;
#endif

#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
typedef __UINT_LEAST16_TYPE__ yytype_uint16;
#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
       && UINT_LEAST16_MAX <= INT_MAX)
typedef uint_least16_t yytype_uint16;
#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
typedef unsigned short yytype_uint16;
#else
typedef int yytype_uint16;
#endif

#ifndef YYPTRDIFF_T
# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
#  define YYPTRDIFF_T __PTRDIFF_TYPE__
#  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
# elif defined PTRDIFF_MAX
#  ifndef ptrdiff_t
#   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
#  endif
#  define YYPTRDIFF_T ptrdiff_t
#  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
# else
#  define YYPTRDIFF_T long
#  define YYPTRDIFF_MAXIMUM LONG_MAX
# endif
#endif

#ifndef YYSIZE_T
# ifdef __SIZE_TYPE__
#  define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
#  define YYSIZE_T size_t
# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
#  define YYSIZE_T size_t
# else
#  define YYSIZE_T unsigned
# endif
#endif

#define YYSIZE_MAXIMUM                                  \
  YY_CAST (YYPTRDIFF_T,                                 \
           (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
            ? YYPTRDIFF_MAXIMUM                         \
            : YY_CAST (YYSIZE_T, -1)))

#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))


/* Stored state numbers (used for stacks). */
typedef yytype_int16 yy_state_t;

/* State numbers in computations.  */
typedef int yy_state_fast_t;

#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
#  if ENABLE_NLS
#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
#  endif
# endif
# ifndef YY_
#  define YY_(Msgid) Msgid
# endif
#endif


#ifndef YY_ATTRIBUTE_PURE
# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
#  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
# else
#  define YY_ATTRIBUTE_PURE
# endif
#endif

#ifndef YY_ATTRIBUTE_UNUSED
# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
#  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
# else
#  define YY_ATTRIBUTE_UNUSED
# endif
#endif

/* Suppress unused-variable warnings by "using" E.  */
#if ! defined lint || defined __GNUC__
# define YY_USE(E) ((void) (E))
#else
# define YY_USE(E) /* empty */
#endif

/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
    _Pragma ("GCC diagnostic push")                                     \
    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
# else
#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \
    _Pragma ("GCC diagnostic push")                                     \
    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# endif
# define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
    _Pragma ("GCC diagnostic pop")
#else
# define YY_INITIAL_VALUE(Value) Value
#endif
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif

#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
# define YY_IGNORE_USELESS_CAST_BEGIN                          \
    _Pragma ("GCC diagnostic push")                            \
    _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
# define YY_IGNORE_USELESS_CAST_END            \
    _Pragma ("GCC diagnostic pop")
#endif
#ifndef YY_IGNORE_USELESS_CAST_BEGIN
# define YY_IGNORE_USELESS_CAST_BEGIN
# define YY_IGNORE_USELESS_CAST_END
#endif


#define YY_ASSERT(E) ((void) (0 && (E)))

#if !defined yyoverflow

/* The parser invokes alloca or malloc; define the necessary symbols.  */

# ifdef YYSTACK_USE_ALLOCA
#  if YYSTACK_USE_ALLOCA
#   ifdef __GNUC__
#    define YYSTACK_ALLOC __builtin_alloca
#   elif defined __BUILTIN_VA_ARG_INCR
#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
#   elif defined _AIX
#    define YYSTACK_ALLOC __alloca
#   elif defined _MSC_VER
#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
#    define alloca _alloca
#   else
#    define YYSTACK_ALLOC alloca
#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
#     ifndef EXIT_SUCCESS
#      define EXIT_SUCCESS 0
#     endif
#    endif
#   endif
#  endif
# endif

# ifdef YYSTACK_ALLOC
   /* Pacify GCC's 'empty if-body' warning.  */
#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
#  ifndef YYSTACK_ALLOC_MAXIMUM
    /* The OS might guarantee only one guard page at the bottom of the stack,
       and a page size can be as small as 4096 bytes.  So we cannot safely
       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
       to allow for a few compiler-allocated temporary stack slots.  */
#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
#  endif
# else
#  define YYSTACK_ALLOC YYMALLOC
#  define YYSTACK_FREE YYFREE
#  ifndef YYSTACK_ALLOC_MAXIMUM
#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
#  endif
#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
       && ! ((defined YYMALLOC || defined malloc) \
             && (defined YYFREE || defined free)))
#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
#   ifndef EXIT_SUCCESS
#    define EXIT_SUCCESS 0
#   endif
#  endif
#  ifndef YYMALLOC
#   define YYMALLOC malloc
#   if ! defined malloc && ! defined EXIT_SUCCESS
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
#   endif
#  endif
#  ifndef YYFREE
#   define YYFREE free
#   if ! defined free && ! defined EXIT_SUCCESS
void free (void *); /* INFRINGES ON USER NAME SPACE */
#   endif
#  endif
# endif
#endif /* !defined yyoverflow */

#if (! defined yyoverflow \
     && (! defined __cplusplus \
         || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))

/* A type that is properly aligned for any stack member.  */
union yyalloc
{
  yy_state_t yyss_alloc;
  YYSTYPE yyvs_alloc;
};

/* The size of the maximum gap between one aligned stack and the next.  */
# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)

/* The size of an array large to enough to hold all stacks, each with
   N elements.  */
# define YYSTACK_BYTES(N) \
     ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
      + YYSTACK_GAP_MAXIMUM)

# define YYCOPY_NEEDED 1

/* Relocate STACK from its old location to the new one.  The
   local variables YYSIZE and YYSTACKSIZE give the old and new number of
   elements in the stack, and YYPTR gives the new location of the
   stack.  Advance YYPTR to a properly aligned location for the next
   stack.  */
# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
    do                                                                  \
      {                                                                 \
        YYPTRDIFF_T yynewbytes;                                         \
        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
        Stack = &yyptr->Stack_alloc;                                    \
        yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
        yyptr += yynewbytes / YYSIZEOF (*yyptr);                        \
      }                                                                 \
    while (0)

#endif

#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from SRC to DST.  The source and destination do
   not overlap.  */
# ifndef YYCOPY
#  if defined __GNUC__ && 1 < __GNUC__
#   define YYCOPY(Dst, Src, Count) \
      __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
#  else
#   define YYCOPY(Dst, Src, Count)              \
      do                                        \
        {                                       \
          YYPTRDIFF_T yyi;                      \
          for (yyi = 0; yyi < (Count); yyi++)   \
            (Dst)[yyi] = (Src)[yyi];            \
        }                                       \
      while (0)
#  endif
# endif
#endif /* !YYCOPY_NEEDED */

/* YYFINAL -- State number of the termination state.  */
#define YYFINAL  2
/* YYLAST -- Last index in YYTABLE.  */
#define YYLAST   986

/* YYNTOKENS -- Number of terminals.  */
#define YYNTOKENS  165
/* YYNNTS -- Number of nonterminals.  */
#define YYNNTS  138
/* YYNRULES -- Number of rules.  */
#define YYNRULES  420
/* YYNSTATES -- Number of states.  */
#define YYNSTATES  772

/* YYMAXUTOK -- Last valid token kind.  */
#define YYMAXUTOK   409


/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
   as returned by yylex, with out-of-bounds checking.  */
#define YYTRANSLATE(YYX)                                \
  (0 <= (YYX) && (YYX) <= YYMAXUTOK                     \
   ? YY_CAST (yysymbol_kind_t, yytranslate[YYX])        \
   : YYSYMBOL_YYUNDEF)

/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
   as returned by yylex.  */
static const yytype_uint8 yytranslate[] =
{
       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     155,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,   160,   162,   161,     2,   159,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     163,   156,   164,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,   157,     2,   158,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
     115,   116,   117,   118,   119,   120,   121,   122,   123,   124,
     125,   126,   127,   128,   129,   130,   131,   132,   133,   134,
     135,   136,   137,   138,   139,   140,   141,   142,   143,   144,
     145,   146,   147,   148,   149,   150,   151,   152,   153,   154
};

#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
static const yytype_int16 yyrline[] =
{
       0,   299,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,   313,   314,   315,   316,
     317,   318,   321,   332,   364,   374,   401,   406,   412,   415,
     430,   458,   473,   473,   487,   495,   496,   498,   498,   508,
     518,   532,   548,   565,   565,   570,   573,   573,   587,   599,
     602,   610,   620,   632,   633,   636,   637,   640,   657,   658,
     665,   671,   679,   688,   688,   700,   701,   704,   715,   723,
     726,   734,   740,   747,   751,   758,   766,   774,   782,   796,
     810,   817,   828,   834,   840,   849,   877,   909,   919,   929,
     942,   955,   963,   976,   992,   999,  1015,  1015,  1025,  1026,
    1035,  1044,  1045,  1053,  1083,  1104,  1133,  1152,  1175,  1195,
    1195,  1224,  1225,  1228,  1233,  1240,  1252,  1261,  1261,  1267,
    1267,  1273,  1274,  1275,  1278,  1279,  1285,  1286,  1289,  1290,
    1293,  1297,  1301,  1307,  1315,  1325,  1326,  1329,  1330,  1333,
    1334,  1335,  1335,  1338,  1338,  1341,  1342,  1345,  1346,  1353,
    1368,  1372,  1376,  1379,  1389,  1390,  1393,  1394,  1397,  1402,
    1420,  1434,  1446,  1455,  1475,  1484,  1485,  1488,  1489,  1492,
    1496,  1500,  1506,  1514,  1515,  1518,  1519,  1522,  1543,  1561,
    1581,  1588,  1591,  1592,  1595,  1595,  1640,  1641,  1642,  1643,
    1646,  1664,  1682,  1700,  1706,  1709,  1710,  1709,  1763,  1763,
    1795,  1796,  1797,  1798,  1799,  1802,  1803,  1813,  1814,  1824,
    1825,  1826,  1829,  1830,  1831,  1832,  1835,  1838,  1845,  1849,
    1860,  1873,  1883,  1890,  1893,  1896,  1907,  1923,  1931,  1939,
    1947,  1969,  1975,  1978,  1981,  1984,  1987,  1990,  2003,  2051,
    2054,  2057,  2061,  2080,  2083,  2086,  2089,  2095,  2101,  2116,
    2124,  2132,  2136,  2139,  2146,  2158,  2159,  2169,  2185,  2197,
    2221,  2227,  2238,  2244,  2247,  2262,  2263,  2273,  2274,  2277,
    2278,  2279,  2280,  2283,  2284,  2287,  2300,  2310,  2317,  2392,
    2393,  2396,  2399,  2432,  2459,  2460,  2461,  2464,  2465,  2468,
    2469,  2472,  2473,  2474,  2476,  2477,  2483,  2505,  2506,  2509,
    2510,  2516,  2523,  2543,  2550,  2571,  2577,  2585,  2600,  2615,
    2616,  2619,  2620,  2621,  2633,  2634,  2640,  2655,  2656,  2659,
    2660,  2672,  2676,  2683,  2706,  2707,  2708,  2721,  2722,  2728,
    2736,  2742,  2750,  2764,  2767,  2767,  2775,  2776,  2779,  2792,
    2799,  2811,  2823,  2842,  2864,  2883,  2899,  2911,  2923,  2931,
    2938,  2988,  3008,  3016,  3026,  3027,  3033,  3044,  3087,  3103,
    3104,  3105,  3106,  3109,  3110,  3117,  3120,  3125,  3134,  3135,
    3138,  3139,  3142,  3143,  3146,  3147,  3150,  3165,  3175,  3185,
    3200,  3210,  3220,  3235,  3245,  3255,  3270,  3280,  3290,  3297,
    3302,  3307,  3312,  3317,  3327,  3337,  3342,  3369,  3383,  3411,
    3429,  3445,  3453,  3468,  3483,  3498,  3499,  3502,  3503,  3504,
    3505,  3508,  3509,  3510,  3511,  3512,  3513,  3516,  3517,  3520,
    3521
};
#endif

/** Accessing symbol of state STATE.  */
#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])

#if YYDEBUG || 0
/* The user-facing name of the symbol whose (internal) number is
   YYSYMBOL.  No bounds checking.  */
static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;

/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
static const char *const yytname[] =
{
  "\"end of file\"", "error", "\"invalid token\"", "AS", "ROUTERID",
  "HOLDTIME", "YMIN", "LISTEN", "ON", "FIBUPDATE", "FIBPRIORITY", "RTABLE",
  "NONE", "UNICAST", "VPN", "RD", "EXPORT", "EXPORTTRGT", "IMPORTTRGT",
  "DEFAULTROUTE", "RDE", "RIB", "EVALUATE", "IGNORE", "COMPARE", "RTR",
  "PORT", "MINVERSION", "STALETIME", "GROUP", "NEIGHBOR", "NETWORK",
  "EBGP", "IBGP", "FLOWSPEC", "PROTO", "FLAGS", "FRAGMENT", "TOS",
  "LENGTH", "ICMPTYPE", "CODE", "LOCALAS", "REMOTEAS", "DESCR",
  "LOCALADDR", "MULTIHOP", "PASSIVE", "MAXPREFIX", "RESTART", "ANNOUNCE",
  "REFRESH", "AS4BYTE", "CONNECTRETRY", "ENHANCED", "ADDPATH", "EXTENDED",
  "SEND", "RECV", "PLUS", "POLICY", "ROLE", "GRACEFUL", "NOTIFICATION",
  "MESSAGE", "DEMOTE", "ENFORCE", "NEIGHBORAS", "ASOVERRIDE", "REFLECTOR",
  "DEPEND", "DOWN", "DUMP", "IN", "OUT", "SOCKET", "RESTRICTED", "LOG",
  "TRANSPARENT", "FILTERED", "TCP", "MD5SIG", "PASSWORD", "KEY",
  "TTLSECURITY", "ALLOW", "DENY", "MATCH", "QUICK", "FROM", "TO", "ANY",
  "CONNECTED", "STATIC", "COMMUNITY", "EXTCOMMUNITY", "LARGECOMMUNITY",
  "DELETE", "MAXCOMMUNITIES", "MAXEXTCOMMUNITIES", "MAXLARGECOMMUNITIES",
  "PREFIX", "PREFIXLEN", "PREFIXSET", "ASPASET", "ROASET", "ORIGINSET",
  "OVS", "AVS", "EXPIRES", "ASSET", "SOURCEAS", "TRANSITAS", "PEERAS",
  "PROVIDERAS", "CUSTOMERAS", "MAXASLEN", "MAXASSEQ", "SET", "LOCALPREF",
  "MED", "METRIC", "NEXTHOP", "REJECT", "BLACKHOLE", "NOMODIFY", "SELF",
  "PREPEND_SELF", "PREPEND_PEER", "PFTABLE", "WEIGHT", "RTLABEL", "ORIGIN",
  "PRIORITY", "ERROR", "INCLUDE", "IPSEC", "ESP", "AH", "SPI", "IKE",
  "IPV4", "IPV6", "EVPN", "QUALIFY", "VIA", "NE", "LE", "GE", "XRANGE",
  "LONGER", "MAXLEN", "MAX", "STRING", "NUMBER", "'\\n'", "'='", "'{'",
  "'}'", "'/'", "'+'", "'-'", "','", "'<'", "'>'", "$accept", "grammar",
  "asnumber", "as4number", "as4number_any", "string", "yesno", "varset",
  "include", "as_set", "$@1", "as_set_l", "prefixset", "$@2",
  "prefixset_l", "prefixset_item", "roa_set", "$@3", "origin_set", "$@4",
  "expires", "roa_set_l", "aspa_set", "aspa_set_l", "aspa_elm",
  "aspa_tas_l", "aspa_tas", "rtr", "$@5", "rtropt_l", "rtropt",
  "conf_main", "rib", "$@6", "ribopts", "fibupdate", "mrtdump", "network",
  "flowspec", "$@7", "proto", "proto_list", "proto_item", "from", "$@8",
  "to", "$@9", "ipportspec", "ipspec", "portspec", "port_list",
  "port_item", "port", "flow_rules", "flow_rules_l", "flowrule", "$@10",
  "$@11", "flags", "flag", "icmpspec", "icmp_list", "icmp_item",
  "icmptype", "tos", "lengthspec", "length_list", "length_item", "length",
  "inout", "restricted", "address", "prefix", "addrspec", "optnumber",
  "l3vpn", "$@12", "l3vpnopts_l", "l3vpnopts", "neighbor", "$@13", "$@14",
  "group", "$@15", "groupopts_l", "addpathextra", "addpathmax",
  "peeropts_h", "peeropts_l", "peeropts", "restart", "af", "safi",
  "nettype", "authconf", "espah", "encspec", "filterrule", "action",
  "quick", "direction", "filter_rib_h", "filter_rib_l", "filter_rib",
  "filter_peer_h", "filter_peer_l", "filter_peer", "filter_prefix_h",
  "filter_prefix_m", "filter_prefix_l", "filter_prefix", "filter_as_h",
  "filter_as_t_l", "filter_as_t", "filter_as_l_h", "filter_as_l",
  "filter_as", "filter_match_h", "$@16", "filter_match", "filter_elm",
  "prefixlenop", "filter_as_type", "filter_set", "filter_set_l",
  "community", "delete", "enforce", "yesnoenforce", "filter_set_opt",
  "origincode", "validity", "aspa_validity", "optnl", "comma", "unaryop",
  "equalityop", "binaryop", YY_NULLPTR
};

static const char *
yysymbol_name (yysymbol_kind_t yysymbol)
{
  return yytname[yysymbol];
}
#endif

#define YYPACT_NINF (-581)

#define yypact_value_is_default(Yyn) \
  ((Yyn) == YYPACT_NINF)

#define YYTABLE_NINF (-408)

#define yytable_value_is_error(Yyn) \
  0

/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
   STATE-NUM.  */
static const yytype_int16 yypact[] =
{
    -581,   727,  -581,   -82,   229,   -77,    26,    71,   -72,   -65,
     -46,   -58,    64,   -77,   -25,   -48,   111,   249,   -20,    12,
     -30,    -6,   -72,  -581,  -581,  -581,    13,    -2,    25,    19,
      59,    54,   108,    87,    68,  -581,    96,   117,   136,   151,
     154,   168,   175,   195,   199,   212,   245,   255,   282,   286,
     309,   252,   313,   317,   213,  -581,  -581,  -581,  -581,   178,
    -581,  -581,   258,  -581,   -77,  -581,  -581,  -581,  -581,   411,
     281,   297,   437,   375,   344,  -581,  -581,   321,   323,  -581,
    -581,   349,   354,   385,   177,  -581,  -581,   369,    18,   451,
    -581,  -581,   388,   398,   398,   401,   402,   415,   -72,  -581,
     -48,  -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,
    -581,  -581,  -581,  -581,  -581,  -581,   264,  -581,  -581,  -581,
     540,  -581,  -581,   537,   413,   429,  -581,   414,  -581,  -581,
     420,  -581,   421,   385,   417,   425,   257,  -581,  -581,  -581,
     427,   431,   385,   239,   430,  -581,  -581,   432,   434,  -581,
    -581,   398,   398,   -45,   410,   398,   398,   436,  -581,   321,
     349,  -581,  -581,  -581,   114,   340,   304,  -581,   511,    40,
    -581,   398,  -581,  -581,  -581,  -581,  -581,  -581,   494,  -581,
     134,   144,   185,   298,   438,   440,   442,   220,   443,   444,
     398,   494,  -581,   385,   385,  -581,   133,  -581,  -581,   345,
     306,   163,  -581,  -581,  -581,  -581,  -581,   385,   239,  -581,
    -581,   445,  -581,  -581,   432,   446,  -581,   229,  -581,   -31,
    -581,  -581,   353,   447,   449,  -581,   452,  -581,   398,  -581,
    -581,  -581,    39,  -581,  -581,  -581,   453,  -581,   -72,   448,
     578,  -581,  -581,   183,   504,  -581,   -42,  -581,   454,   457,
    -581,   458,   460,  -581,   461,   462,  -581,  -581,  -581,  -581,
    -581,  -581,  -581,  -581,  -581,   463,   464,  -581,  -581,  -581,
     697,   450,  -581,  -581,  -581,  -581,   398,  -581,   -37,   -37,
    -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,   398,  -581,
    -581,  -581,  -581,   -62,   465,  -581,  -581,   398,  -581,   560,
      15,    15,  -581,  -581,   432,  -581,  -581,   353,   512,   398,
     468,   455,   505,   514,    92,   -49,  -581,   353,  -581,   362,
     831,  -581,   473,   229,   475,  -581,  -581,  -581,   398,  -581,
     -38,  -581,  -581,  -581,   621,  -581,   304,   478,   481,   -77,
     554,   381,   398,  -581,  -581,   483,    37,   295,   614,   484,
     304,   485,   229,   229,   -48,   -77,   487,  -581,   488,   206,
      22,   492,    48,   -72,   -77,   638,   497,   498,   499,   -72,
     -72,   274,   543,  -581,  -581,   602,  -581,   500,   503,  -581,
     507,   508,  -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,
      92,  -581,  -581,   382,  -581,  -581,   510,  -581,   506,  -581,
     319,  -581,  -581,   465,  -581,   384,   386,   279,  -581,  -581,
     640,  -581,  -581,  -581,    92,  -581,   513,   550,   519,   398,
    -581,  -581,   362,   521,   353,   348,  -581,   515,  -581,    92,
    -581,  -581,  -581,    92,  -581,   522,   -59,  -581,  -581,  -581,
      28,   385,    45,    21,  -581,  -581,  -581,  -581,  -581,   459,
    -581,  -581,     9,    83,  -581,   527,  -581,  -581,  -581,   529,
    -581,  -581,  -581,   178,  -581,   321,  -581,  -581,    58,   -11,
     -11,   -11,   617,   486,    -8,   -11,   620,   618,   299,  -581,
    -581,  -581,   -72,   -72,  -581,  -581,   532,  -581,   482,  -581,
    -581,  -581,   398,  -581,   -72,  -581,  -581,  -581,  -581,  -581,
     528,   697,    92,  -581,  -581,   510,    92,  -581,  -581,    92,
    -581,  -581,  -581,   398,  -581,  -581,   -62,   304,   279,   530,
     353,  -581,   533,  -581,   512,  -581,   576,   -62,   538,  -581,
     544,   545,   362,   628,  -581,   546,   473,    92,  -581,  -581,
    -581,    -3,   547,   553,   555,   218,   557,   558,   561,   562,
    -581,  -581,  -581,   559,   563,     7,   -49,   -49,    95,  -581,
    -581,  -581,    45,  -581,   146,   565,   536,   -72,   566,   568,
     569,  -581,  -581,  -581,   571,   -48,   -48,  -581,   577,  -581,
    -581,  -581,  -581,  -581,   570,   674,  -581,  -581,  -581,  -581,
    -581,  -581,   -11,   580,   -11,   -11,   -11,  -581,   -72,  -581,
    -581,  -581,  -581,  -581,  -581,   618,  -581,  -581,  -581,   697,
    -581,  -581,  -581,   581,   382,  -581,   582,   319,   585,   384,
     292,   304,  -581,  -581,  -581,  -581,   398,  -581,   362,   575,
    -581,  -581,  -581,  -581,   589,  -581,  -581,   590,  -581,  -581,
     591,    28,   595,   597,  -581,  -581,  -581,   254,   -49,  -581,
     -49,  -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,
    -581,  -581,   201,  -581,  -581,  -581,   600,  -581,  -581,   181,
     -62,  -581,   362,  -581,  -581,  -581,  -581,   601,   606,  -581,
     321,   321,   608,  -581,  -581,  -581,   676,  -581,  -581,  -581,
    -581,  -581,    92,  -581,  -581,  -581,  -581,  -581,  -581,    92,
    -581,  -581,   362,   512,  -581,  -581,  -581,  -581,  -581,  -581,
    -581,   353,   605,   329,  -581,  -581,  -581,   398,  -581,    95,
    -581,   127,   609,   330,  -581,   362,  -581,  -581,  -581,   607,
     612,   616,   611,   613,   292,   249,    92,  -581,  -581,   335,
    -581,   353,  -581,  -581,   359,  -581,   127,  -581,   619,  -581,
     622,   618,  -581,  -581,  -581,  -581,   615,   362,   254,  -581,
     181,  -581,   624,  -581,  -581,  -581,  -581,  -581,  -581,   625,
    -581,  -581
};

/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
   Performed when YYTABLE does not specify something else to do.  Zero
   means the default is an error.  */
static const yytype_int16 yydefact[] =
{
       2,     0,     1,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   284,   285,   286,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     3,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,   287,    21,    23,    22,    24,    72,
     177,    74,     0,    75,     0,    29,    81,    80,    93,     0,
       0,     0,     0,     0,    62,    77,    28,   198,     0,   267,
     268,     0,     0,   363,     0,   109,    94,     0,     0,   175,
      84,    82,     0,   405,   405,     0,     0,     0,     0,    31,
       0,     4,     5,     6,     7,     8,    10,     9,    11,    16,
      12,    15,    13,    14,    17,    18,     0,    19,    20,   288,
     291,    73,    76,    78,     0,    96,    90,     0,    87,    88,
       0,    27,     0,   363,     0,     0,     0,   104,   274,   273,
       0,     0,   363,   135,     0,   173,   174,   182,     0,   176,
      95,   405,   405,     0,    43,   405,   405,     0,    83,    30,
     177,   180,   181,   196,     0,     0,     0,   184,     0,   101,
      89,   405,   200,   105,   178,   179,   395,   368,   370,   369,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     405,   370,   364,   363,   363,   108,     0,   141,   143,     0,
       0,     0,   117,   119,   147,   139,   140,   363,   136,   137,
     145,     0,   183,    85,   182,    37,   406,     0,    54,   405,
      55,    45,     0,    46,    32,    92,   211,   296,   405,   292,
     289,   290,     0,   134,   133,    79,     0,    91,     0,     0,
       0,    97,    98,     0,     0,   371,     0,   376,     0,     0,
     379,     0,     0,   382,     0,     0,   390,   389,   391,   392,
     388,   393,   394,   396,   385,     0,     0,   397,   402,   401,
       0,     0,   106,   107,   115,   116,   405,   111,     0,     0,
     163,   164,   148,   412,   413,   415,   172,   411,   405,   414,
     416,   146,   165,   169,     0,   161,   162,   405,   154,   158,
       0,     0,   110,   138,   182,   103,    39,     0,    49,   405,
     408,     0,     0,     0,   407,   354,    48,     0,    34,     0,
       0,   197,     0,     0,     0,   305,   306,   301,   405,   302,
     334,   297,   186,   102,   101,   100,     0,     0,     0,     0,
       0,     0,   405,    65,    71,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,   223,     0,     0,
       0,     0,     0,     0,   256,     0,   224,     0,     0,     0,
       0,     0,     0,   201,   199,     0,   255,     0,     0,   251,
       0,     0,   377,   378,   380,   381,   383,   384,   386,   387,
     407,   367,   398,     0,   152,   153,     0,   142,   151,   144,
       0,   420,   419,     0,   170,     0,     0,     0,   124,   118,
     121,   125,   120,    86,   407,    40,     0,     0,   409,   405,
      53,    56,     0,     0,     0,     0,   355,     0,    42,   407,
      25,    26,    35,   407,   212,     0,   405,   294,   303,   304,
       0,   363,     0,     0,    99,    69,    70,    67,    68,     0,
     279,   280,     0,     0,   204,     0,   227,   244,   245,     0,
     226,   263,   229,   217,   216,   219,   220,   222,   265,     0,
       0,     0,     0,     0,     0,     0,     0,   372,     0,   243,
     242,   259,     0,     0,   248,   257,     0,   225,     0,   261,
     260,   252,   405,   253,     0,   221,   203,   202,   400,   399,
       0,     0,   407,   113,   150,     0,   407,   167,   171,   407,
     156,   159,   160,   405,   123,   126,   130,     0,     0,     0,
       0,    50,     0,   410,    49,    44,     0,     0,     0,   356,
       0,     0,     0,     0,   210,     0,     0,   407,   299,   283,
     359,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     360,   361,   362,     0,     0,     0,   354,   354,     0,   338,
     339,   317,   335,   336,     0,     0,     0,     0,     0,     0,
       0,   187,   185,   194,     0,     0,     0,   277,     0,    64,
      66,   228,   264,   218,     0,   265,   249,   375,   374,   234,
     232,   236,     0,     0,     0,     0,     0,   239,     0,   373,
     231,   269,   270,   271,   272,   372,   247,   246,   258,     0,
     262,   365,   366,     0,     0,   149,     0,     0,     0,     0,
       0,     0,   131,   122,    38,    41,   405,    51,     0,     0,
     357,    47,    33,    36,     0,   213,   209,     0,   293,   295,
       0,     0,     0,     0,   345,   346,   347,     0,   354,   309,
     354,   351,   403,   352,   404,   353,   340,   341,   349,   348,
     307,   308,   407,   319,   337,   330,     0,   418,   417,     0,
     329,   321,     0,   342,   189,   193,   190,     0,     0,   188,
     275,   276,     0,   266,   250,   233,   205,   237,   240,   241,
     235,   230,   407,   112,   114,   166,   168,   155,   157,   407,
     128,   132,     0,    49,   358,   215,   214,   298,   300,   344,
     343,     0,     0,   407,   314,   316,   350,   405,   318,     0,
     323,     0,     0,   407,   327,     0,   331,   191,   192,     0,
       0,   207,     0,     0,     0,    60,   407,    58,    52,   407,
     310,     0,   409,   320,   407,   322,     0,   332,     0,   206,
       0,   372,   254,   127,   129,    61,     0,     0,   312,   315,
     325,   328,   281,   208,   238,    57,    59,   313,   326,     0,
     278,   282
};

/* YYPGOTO[NTERM-NUM].  */
static const yytype_int16 yypgoto[] =
{
    -581,  -581,     8,  -153,  -310,   -95,    -5,  -581,  -581,  -581,
    -581,  -581,  -581,  -581,  -581,  -291,  -581,  -581,  -581,  -581,
    -498,   467,  -581,  -581,   470,  -581,    17,  -581,  -581,  -581,
     322,  -581,  -581,  -581,  -581,   456,   769,   336,  -581,  -581,
    -581,  -581,  -383,  -581,  -581,  -581,  -581,   493,  -581,   267,
    -581,  -580,  -162,  -581,  -581,   579,  -581,  -581,   509,  -346,
    -581,  -581,  -385,  -581,  -581,  -581,  -581,  -387,  -225,   337,
    -581,     2,   -16,  -581,  -167,  -581,  -581,  -581,  -581,   551,
    -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,  -581,  -296,
     211,   -15,  -581,  -581,  -215,  -581,  -581,  -581,  -581,  -581,
    -581,  -581,  -581,  -304,  -581,  -581,  -415,  -581,    42,    86,
    -526,  -581,  -581,  -529,    38,    80,  -543,  -581,  -581,  -581,
     241,  -512,  -581,  -119,   197,  -365,   629,  -578,  -350,  -128,
    -581,  -581,  -581,   -93,  -213,  -189,  -581,  -481
};

/* YYDEFGOTO[NTERM-NUM].  */
static const yytype_int16 yydefgoto[] =
{
       0,     1,   431,    59,   670,    77,   588,    36,    37,    38,
     319,   433,    39,   307,   414,   313,    40,   222,    41,   317,
     417,   314,    42,   219,   220,   736,   737,    43,   130,   342,
     343,    44,    45,   169,   241,   242,   376,    47,    48,   143,
     204,   502,   277,   205,   300,   206,   301,   409,   410,   514,
     699,   515,   516,   207,   208,   209,   278,   279,   397,   398,
     210,   509,   298,   299,   282,   291,   506,   292,   293,   148,
     150,   329,   315,   163,   213,    49,   236,   443,   574,    50,
      51,   226,    52,   132,   244,   731,   751,   321,   533,   378,
     586,    84,   605,   142,   379,   452,   770,    53,    54,   120,
     232,   165,   436,   229,   330,   537,   331,   559,   712,   713,
     714,   560,   662,   561,   722,   723,   724,   441,   442,   562,
     563,   428,   564,   137,   390,   191,   246,   600,   589,   391,
     269,   653,   655,   153,   424,   517,   672,   403
};

/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
   positive, shift that token.  If negative, reduce the rule whose
   number is the opposite.  If YYTABLE_NINF, syntax error.  */
static const yytype_int16 yytable[] =
{
      83,   154,    85,    66,   235,   159,   312,    61,   192,   432,
     503,   294,    58,   507,   173,    74,   415,    91,   437,   649,
     510,   671,   566,   195,   435,   538,   627,   691,   344,   663,
     567,   323,    62,    87,   479,   621,   568,   658,   569,   570,
     700,   407,   323,   455,   660,   661,   629,   305,   540,   238,
     504,   239,    16,   425,   394,   587,   595,   324,   215,   216,
     325,   326,   223,   224,   308,   380,   123,   121,   324,   404,
     217,   325,   326,    55,   272,   273,    60,   565,   243,    64,
    -333,    65,   145,   146,  -407,    70,    71,   401,   302,    67,
     482,   145,   146,   158,  -407,    69,   309,   270,   540,   402,
     162,   426,   427,   310,   642,    76,   408,   584,    68,   336,
     337,   381,   524,   218,   596,   483,   395,  -333,   161,   327,
     590,   591,   396,    89,   309,   597,   311,   338,   339,    75,
     327,   310,   585,   526,    86,   322,   715,   413,   716,   177,
     541,   179,    65,   542,   543,   544,   545,    90,   546,   577,
     643,   547,   548,   549,   754,    93,   550,   551,   552,   615,
      60,   553,   554,   340,   240,    88,    92,   555,    81,    82,
     438,   147,    95,   764,   445,   480,   571,   501,   508,   572,
      63,    60,    94,   393,    72,   260,   556,   557,   461,   725,
     743,   456,    60,    65,   665,   400,   328,   565,    97,   463,
     464,   520,   558,   761,   405,   738,   550,   551,   552,   336,
     337,   294,    96,   665,    78,   759,   418,    73,    98,   341,
     532,   423,   633,   536,   100,    58,   708,   338,   339,   625,
     696,   694,   639,   333,   698,   440,   528,   637,   344,   375,
      99,   579,   685,   493,   687,   688,   689,   309,   665,   453,
    -405,   101,    79,    80,   310,   469,   666,   470,   471,   465,
     472,   473,   474,   340,    81,    82,   475,   227,   476,   138,
     139,   228,   102,   667,   196,   197,   198,   199,   200,   201,
     430,    57,   116,   668,   411,   411,   274,   275,   247,   614,
     276,   103,   667,   617,   248,   249,   619,   500,   250,   430,
      57,   119,   668,   669,   251,   252,   104,   457,   140,   105,
     141,   601,   602,   603,   458,   375,   295,   296,   703,   341,
     297,   519,   539,   106,   641,   176,   523,   667,   202,   203,
     107,    58,    57,   604,   430,    57,   530,   668,   721,   253,
     531,   448,   176,   535,   478,   254,   255,    79,    80,   477,
     108,   177,   178,   179,   109,   622,   717,   466,   484,   718,
      58,    58,   726,   310,   490,   491,   485,   110,   177,   178,
     179,    81,    82,   612,   264,   647,   180,   181,   182,   183,
     265,   266,    56,    57,   184,   185,   186,   187,   188,   189,
      79,    80,   735,   180,   181,   182,   183,   128,   129,   609,
     111,   184,   185,   186,   187,   188,   189,    81,    82,   613,
     112,   711,   122,   616,   190,   747,   618,   160,    82,   124,
     620,   256,   257,   258,   259,   283,   284,   285,   294,   230,
     231,   492,   233,   234,   125,   287,   513,   113,   283,   284,
     285,   114,   289,   290,   640,   233,   234,   735,   287,   719,
     126,    60,   283,   284,   285,   289,   290,   233,   234,   701,
     286,   127,   287,   288,   115,   283,   284,   285,   117,   289,
     290,   583,   118,   286,   131,   287,   133,   606,   607,   501,
     680,   681,   289,   290,   717,   717,   734,  -311,  -324,   610,
     717,   310,   310,   758,   283,   284,   285,   310,   280,   281,
     741,   -63,   527,   136,   287,   345,    81,    82,   134,   346,
     746,   289,   290,   135,   717,   430,    57,   760,   450,   451,
     347,   310,   144,   757,   348,   349,   741,   149,   375,   648,
     350,   746,   351,   702,  -195,   274,   275,   295,   296,   511,
     512,   575,   576,   593,   594,   151,   352,   353,   354,   355,
     356,   357,   358,   152,   359,   145,   146,   659,   155,   156,
     157,   164,   675,   166,   168,   360,   167,   170,   221,   361,
     362,   174,   363,   364,   365,   366,   367,   171,   172,   175,
     193,   368,   369,   211,   340,   194,   212,   214,   370,   225,
     237,   245,   261,   690,   262,   263,   267,   268,   304,   732,
     335,   406,   334,   392,   306,   316,   733,   318,   382,   320,
     332,   383,   384,   420,   385,   386,   387,   388,   389,   286,
     217,   416,   371,   419,   742,   422,   227,   372,   439,   634,
     238,   648,   446,   346,   447,   449,   459,   460,   454,   462,
     341,   467,   468,   756,   347,   481,   486,   495,   348,   349,
     487,   488,   489,   494,   350,   496,   351,    65,   497,   373,
     498,   499,   374,   395,   522,   505,   518,   521,   592,   529,
     352,   353,   354,   355,   356,   357,   358,  -406,   359,   525,
     534,   581,   582,   598,   599,   608,   611,   628,   624,   360,
     626,   674,   630,   361,   362,   648,   363,   364,   365,   366,
     367,   644,   631,   632,   638,   368,   369,   645,   340,   646,
     650,   651,   370,   656,   652,   654,   682,   657,   673,   676,
     755,   677,   678,   584,   683,   648,   679,     2,     3,   704,
       4,     5,     6,   686,     7,   730,     8,     9,    10,   693,
     695,    11,   648,   697,   705,   706,   371,    12,   709,   707,
     710,   372,    13,   720,   727,    14,    15,  -195,    16,   728,
     748,    17,   729,   740,   341,   176,   749,   745,   750,   752,
      46,   753,   762,   765,   766,   580,   763,   769,   771,   573,
      18,    65,   421,   635,   429,   623,   636,   303,   399,   578,
     444,   177,   178,   179,   412,   377,   684,   739,   768,    19,
     767,   744,    20,   664,    21,    22,   692,     0,     0,     0,
       0,     0,    23,    24,    25,     0,   180,   181,   182,   183,
     271,     0,     0,     0,   184,   185,   186,   187,   188,   189,
      26,    27,    28,    29,     0,     0,   346,    30,     0,     0,
       0,     0,     0,     0,     0,     0,     0,   347,     0,    31,
      32,   348,   349,     0,     0,     0,     0,   350,     0,   351,
       0,     0,    33,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,   352,   353,   354,   355,   356,   357,   358,
      34,   359,    35,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   360,     0,     0,     0,   361,   362,     0,   363,
     364,   365,   366,   367,     0,     0,     0,     0,   368,   369,
       0,   340,     0,     0,     0,   370,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   371,
       0,     0,     0,     0,   372,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,   341,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,    65,     0,   434
};

static const yytype_int16 yycheck[] =
{
      16,    94,    17,     8,   166,   100,   219,     5,   136,   319,
     393,   200,     4,   400,   133,    13,   307,    22,   322,   545,
     405,   564,     1,   142,   320,   440,   524,   605,   243,   558,
       9,     3,     6,    21,    12,   516,    15,    30,    17,    18,
     620,    26,     3,     6,   556,   557,   527,   214,     3,     9,
     396,    11,    31,   102,    91,    66,    64,    29,   151,   152,
      32,    33,   155,   156,   217,   107,    64,    59,    29,   294,
     115,    32,    33,   155,   193,   194,   153,   442,   171,     8,
     118,   153,    73,    74,   115,    21,    22,   149,   207,   154,
      42,    73,    74,    98,   153,   153,   155,   190,     3,   161,
     116,   150,   151,   162,   107,   153,    91,    49,   154,    26,
      27,   153,   422,   158,   122,    67,   153,   155,   116,    91,
     470,   471,   159,   153,   155,   475,   219,    44,    45,   154,
      91,   162,    74,   424,   154,   228,   648,   304,   650,    94,
      95,    96,   153,    98,    99,   100,   101,   153,   103,   140,
     153,   106,   107,   108,   734,   157,   111,   112,   113,   505,
     153,   116,   117,    80,   169,   153,   153,   122,   153,   154,
     323,   153,   153,   751,   336,   153,   155,   390,   403,   158,
     154,   153,   157,   276,   120,   183,   141,   142,   350,   670,
     719,   154,   153,   153,    67,   288,   157,   562,   144,   352,
     353,   414,   157,   746,   297,   703,   111,   112,   113,    26,
      27,   400,   153,    67,   103,   741,   309,   153,   110,   136,
     433,   314,   532,   436,   156,   217,   641,    44,    45,   520,
     617,   614,   536,   238,   619,   328,   425,   533,   453,   244,
     153,   158,   592,   371,   594,   595,   596,   155,    67,   342,
     158,   155,   141,   142,   162,    49,   110,    51,    52,   354,
      54,    55,    56,    80,   153,   154,    60,   153,    62,    92,
      93,   157,   155,   146,    35,    36,    37,    38,    39,    40,
     153,   154,    30,   156,   300,   301,   153,   154,   154,   502,
     157,   155,   146,   506,   160,   161,   509,   390,   154,   153,
     154,    88,   156,   157,   160,   161,   155,    12,   131,   155,
     133,    12,    13,    14,    19,   320,   153,   154,   628,   136,
     157,   414,   441,   155,   537,    68,   419,   146,    89,    90,
     155,   323,   154,    34,   153,   154,   429,   156,   157,   154,
     433,   339,    68,   436,   359,   160,   161,   141,   142,   143,
     155,    94,    95,    96,   155,   517,   155,   355,   363,   158,
     352,   353,   672,   162,   369,   370,   364,   155,    94,    95,
      96,   153,   154,   501,   154,   157,   119,   120,   121,   122,
     160,   161,   153,   154,   127,   128,   129,   130,   131,   132,
     141,   142,   702,   119,   120,   121,   122,    22,    23,   492,
     155,   127,   128,   129,   130,   131,   132,   153,   154,   502,
     155,   157,   154,   506,   157,   725,   509,   153,   154,     8,
     513,   123,   124,   125,   126,   146,   147,   148,   617,    89,
      90,   157,   153,   154,   153,   156,   157,   155,   146,   147,
     148,   155,   163,   164,   537,   153,   154,   757,   156,   662,
     153,   153,   146,   147,   148,   163,   164,   153,   154,   621,
     154,    24,   156,   157,   155,   146,   147,   148,   155,   163,
     164,   463,   155,   154,   153,   156,   153,   482,   483,   692,
     575,   576,   163,   164,   155,   155,   699,   158,   158,   494,
     155,   162,   162,   158,   146,   147,   148,   162,   153,   154,
     713,   157,   154,   118,   156,     1,   153,   154,   159,     5,
     723,   163,   164,   159,   155,   153,   154,   158,   137,   138,
      16,   162,   153,   736,    20,    21,   739,    76,   533,   545,
      26,   744,    28,   626,    30,   153,   154,   153,   154,   153,
     154,    82,    83,    57,    58,   157,    42,    43,    44,    45,
      46,    47,    48,   155,    50,    73,    74,   555,   157,   157,
     145,    21,   567,    26,   135,    61,   153,   153,   158,    65,
      66,   154,    68,    69,    70,    71,    72,   157,   157,   154,
     153,    77,    78,   153,    80,   154,   154,   153,    84,   153,
      79,    97,   154,   598,   154,   153,   153,   153,   153,   692,
      22,    41,   154,   153,   158,   158,   699,   158,   154,   157,
     157,   154,   154,   158,   154,   154,   154,   154,   154,   154,
     115,   109,   118,   155,   717,   111,   153,   123,   153,     1,
       9,   647,   154,     5,   153,    81,    22,   153,   155,   154,
     136,   154,   154,   736,    16,   153,     8,    45,    20,    21,
     153,   153,   153,   110,    26,   155,    28,   153,   155,   155,
     153,   153,   158,   153,   114,   159,    26,   154,    51,   154,
      42,    43,    44,    45,    46,    47,    48,   158,    50,   158,
     158,   154,   153,    63,    66,   153,   158,   111,   158,    61,
     157,   155,   154,    65,    66,   711,    68,    69,    70,    71,
      72,   154,   158,   158,   158,    77,    78,   154,    80,   154,
     153,   153,    84,   154,   153,   153,   139,   154,   153,   153,
     735,   153,   153,    49,   154,   741,   155,     0,     1,   154,
       3,     4,     5,   153,     7,    59,     9,    10,    11,   158,
     158,    14,   758,   158,   155,   155,   118,    20,   153,   158,
     153,   123,    25,   153,   153,    28,    29,    30,    31,   153,
     153,    34,   154,   158,   136,    68,   154,   158,   152,   158,
       1,   158,   153,   158,   757,   453,   154,   153,   153,   443,
      53,   153,   312,   155,   317,   518,   158,   208,   279,   452,
     334,    94,    95,    96,   301,   244,   585,   711,   760,    72,
     758,   721,    75,   562,    77,    78,   609,    -1,    -1,    -1,
      -1,    -1,    85,    86,    87,    -1,   119,   120,   121,   122,
     191,    -1,    -1,    -1,   127,   128,   129,   130,   131,   132,
     103,   104,   105,   106,    -1,    -1,     5,   110,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    16,    -1,   122,
     123,    20,    21,    -1,    -1,    -1,    -1,    26,    -1,    28,
      -1,    -1,   135,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    42,    43,    44,    45,    46,    47,    48,
     153,    50,   155,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    61,    -1,    -1,    -1,    65,    66,    -1,    68,
      69,    70,    71,    72,    -1,    -1,    -1,    -1,    77,    78,
      -1,    80,    -1,    -1,    -1,    84,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   118,
      -1,    -1,    -1,    -1,   123,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,   136,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,   153,    -1,   155
};

/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
   state STATE-NUM.  */
static const yytype_int16 yystos[] =
{
       0,   166,     0,     1,     3,     4,     5,     7,     9,    10,
      11,    14,    20,    25,    28,    29,    31,    34,    53,    72,
      75,    77,    78,    85,    86,    87,   103,   104,   105,   106,
     110,   122,   123,   135,   153,   155,   172,   173,   174,   177,
     181,   183,   187,   192,   196,   197,   201,   202,   203,   240,
     244,   245,   247,   262,   263,   155,   153,   154,   167,   168,
     153,   236,     6,   154,     8,   153,   171,   154,   154,   153,
      21,    22,   120,   153,   236,   154,   153,   170,   103,   141,
     142,   153,   154,   237,   256,   256,   154,    21,   153,   153,
     153,   171,   153,   157,   157,   153,   153,   144,   110,   153,
     156,   155,   155,   155,   155,   155,   155,   155,   155,   155,
     155,   155,   155,   155,   155,   155,    30,   155,   155,    88,
     264,   167,   154,   236,     8,   153,   153,    24,    22,    23,
     193,   153,   248,   153,   159,   159,   118,   288,    92,    93,
     131,   133,   258,   204,   153,    73,    74,   153,   234,    76,
     235,   157,   155,   298,   298,   157,   157,   145,   171,   170,
     153,   236,   237,   238,    21,   266,    26,   153,   135,   198,
     153,   157,   157,   288,   154,   154,    68,    94,    95,    96,
     119,   120,   121,   122,   127,   128,   129,   130,   131,   132,
     157,   290,   294,   153,   154,   288,    35,    36,    37,    38,
      39,    40,    89,    90,   205,   208,   210,   218,   219,   220,
     225,   153,   154,   239,   153,   298,   298,   115,   158,   188,
     189,   158,   182,   298,   298,   153,   246,   153,   157,   268,
      89,    90,   265,   153,   154,   217,   241,    79,     9,    11,
     171,   199,   200,   298,   249,    97,   291,   154,   160,   161,
     154,   160,   161,   154,   160,   161,   123,   124,   125,   126,
     236,   154,   154,   153,   154,   160,   161,   153,   153,   295,
     298,   291,   288,   288,   153,   154,   157,   207,   221,   222,
     153,   154,   229,   146,   147,   148,   154,   156,   157,   163,
     164,   230,   232,   233,   300,   153,   154,   157,   227,   228,
     209,   211,   288,   220,   153,   239,   158,   178,   168,   155,
     162,   298,   299,   180,   186,   237,   158,   184,   158,   175,
     157,   252,   298,     3,    29,    32,    33,    91,   157,   236,
     269,   271,   157,   171,   154,    22,    26,    27,    44,    45,
      80,   136,   194,   195,   259,     1,     5,    16,    20,    21,
      26,    28,    42,    43,    44,    45,    46,    47,    48,    50,
      61,    65,    66,    68,    69,    70,    71,    72,    77,    78,
      84,   118,   123,   155,   158,   171,   201,   244,   254,   259,
     107,   153,   154,   154,   154,   154,   154,   154,   154,   154,
     289,   294,   153,   298,    91,   153,   159,   223,   224,   223,
     298,   149,   161,   302,   233,   298,    41,    26,    91,   212,
     213,   237,   212,   239,   179,   180,   109,   185,   298,   155,
     158,   189,   111,   298,   299,   102,   150,   151,   286,   186,
     153,   167,   169,   176,   155,   254,   267,   268,   168,   153,
     298,   282,   283,   242,   200,   217,   154,   153,   236,    81,
     137,   138,   260,   298,   155,     6,   154,    12,    19,    22,
     153,   217,   154,   168,   168,   170,   236,   154,   154,    49,
      51,    52,    54,    55,    56,    60,    62,   143,   256,    12,
     153,   153,    42,    67,   171,   236,     8,   153,   153,   153,
     171,   171,   157,   294,   110,    45,   155,   155,   153,   153,
     298,   299,   206,   207,   224,   159,   231,   232,   233,   226,
     227,   153,   154,   157,   214,   216,   217,   300,    26,   298,
     299,   154,   114,   298,   169,   158,   180,   154,   300,   154,
     298,   298,   299,   253,   158,   298,   299,   270,   271,   288,
       3,    95,    98,    99,   100,   101,   103,   106,   107,   108,
     111,   112,   113,   116,   117,   122,   141,   142,   157,   272,
     276,   278,   284,   285,   287,   290,     1,     9,    15,    17,
      18,   155,   158,   202,   243,    82,    83,   140,   234,   158,
     195,   154,   153,   167,    49,    74,   255,    66,   171,   293,
     293,   293,    51,    57,    58,    64,   122,   293,    63,    66,
     292,    12,    13,    14,    34,   257,   171,   171,   153,   298,
     171,   158,   294,   298,   299,   224,   298,   299,   298,   299,
     298,   302,   217,   214,   158,   180,   157,   185,   111,   302,
     154,   158,   158,   169,     1,   155,   158,   254,   158,   268,
     298,   299,   107,   153,   154,   154,   154,   157,   237,   275,
     153,   153,   153,   296,   153,   297,   154,   154,    30,   236,
     286,   286,   277,   278,   285,    67,   110,   146,   156,   157,
     169,   281,   301,   153,   155,   171,   153,   153,   153,   155,
     170,   170,   139,   154,   255,   293,   153,   293,   293,   293,
     171,   292,   289,   158,   207,   158,   232,   158,   227,   215,
     216,   217,   298,   169,   154,   155,   155,   158,   271,   153,
     153,   157,   273,   274,   275,   286,   286,   155,   158,   299,
     153,   157,   279,   280,   281,   302,   169,   153,   153,   154,
      59,   250,   298,   298,   299,   169,   190,   191,   185,   274,
     158,   299,   298,   278,   280,   158,   299,   169,   153,   154,
     152,   251,   158,   158,   216,   256,   298,   299,   158,   275,
     158,   281,   153,   154,   292,   158,   191,   273,   279,   153,
     261,   153
};

/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.  */
static const yytype_int16 yyr1[] =
{
       0,   165,   166,   166,   166,   166,   166,   166,   166,   166,
     166,   166,   166,   166,   166,   166,   166,   166,   166,   166,
     166,   166,   167,   168,   168,   169,   169,   170,   170,   171,
     172,   173,   175,   174,   174,   176,   176,   178,   177,   177,
     179,   179,   180,   182,   181,   181,   184,   183,   183,   185,
     185,   186,   186,   187,   187,   188,   188,   189,   190,   190,
     191,   191,   192,   193,   192,   194,   194,   195,   195,   195,
     195,   195,   196,   196,   196,   196,   196,   196,   196,   196,
     196,   196,   196,   196,   196,   196,   196,   196,   196,   196,
     196,   196,   196,   196,   196,   196,   198,   197,   199,   199,
     199,   200,   200,   201,   202,   202,   202,   202,   202,   204,
     203,   205,   205,   206,   206,   207,   207,   209,   208,   211,
     210,   212,   212,   212,   213,   213,   214,   214,   215,   215,
     216,   216,   216,   217,   217,   218,   218,   219,   219,   220,
     220,   221,   220,   222,   220,   220,   220,   220,   220,   223,
     223,   223,   223,   224,   225,   225,   226,   226,   227,   227,
     227,   228,   228,   229,   229,   230,   230,   231,   231,   232,
     232,   232,   233,   234,   234,   235,   235,   236,   237,   237,
     238,   238,   239,   239,   241,   240,   242,   242,   242,   242,
     243,   243,   243,   243,   243,   245,   246,   244,   248,   247,
     249,   249,   249,   249,   249,   250,   250,   251,   251,   252,
     252,   252,   253,   253,   253,   253,   254,   254,   254,   254,
     254,   254,   254,   254,   254,   254,   254,   254,   254,   254,
     254,   254,   254,   254,   254,   254,   254,   254,   254,   254,
     254,   254,   254,   254,   254,   254,   254,   254,   254,   254,
     254,   254,   254,   254,   254,   254,   254,   254,   254,   254,
     254,   254,   254,   254,   254,   255,   255,   256,   256,   257,
     257,   257,   257,   258,   258,   259,   259,   259,   259,   260,
     260,   261,   261,   262,   263,   263,   263,   264,   264,   265,
     265,   266,   266,   266,   267,   267,   268,   269,   269,   270,
     270,   271,   271,   271,   271,   271,   271,   272,   272,   272,
     272,   273,   273,   273,   274,   274,   275,   276,   276,   277,
     277,   278,   278,   278,   279,   279,   279,   280,   280,   281,
     281,   281,   281,   282,   283,   282,   284,   284,   285,   285,
     285,   285,   285,   285,   285,   285,   285,   285,   285,   285,
     285,   285,   285,   285,   286,   286,   286,   286,   286,   287,
     287,   287,   287,   288,   288,   288,   289,   289,   290,   290,
     291,   291,   292,   292,   293,   293,   294,   294,   294,   294,
     294,   294,   294,   294,   294,   294,   294,   294,   294,   294,
     294,   294,   294,   294,   294,   294,   294,   294,   294,   294,
     294,   294,   295,   296,   297,   298,   298,   299,   299,   299,
     299,   300,   300,   300,   300,   300,   300,   301,   301,   302,
     302
};

/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.  */
static const yytype_int8 yyr2[] =
{
       0,     2,     0,     2,     3,     3,     3,     3,     3,     3,
       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
       3,     3,     1,     1,     1,     1,     1,     2,     1,     1,
       3,     2,     0,     8,     5,     1,     3,     0,     8,     5,
       1,     3,     2,     0,     7,     4,     0,     8,     5,     0,
       2,     4,     6,     6,     4,     1,     3,     9,     1,     3,
       1,     2,     2,     0,     8,     1,     3,     2,     2,     2,
       2,     1,     2,     3,     2,     2,     3,     2,     3,     5,
       2,     2,     2,     3,     2,     4,     6,     3,     3,     4,
       3,     5,     4,     2,     2,     3,     0,     5,     1,     3,
       2,     0,     2,     5,     3,     4,     5,     5,     4,     0,
       5,     2,     6,     1,     3,     1,     1,     0,     3,     0,
       3,     1,     3,     2,     1,     1,     1,     5,     1,     3,
       1,     2,     3,     1,     1,     0,     1,     1,     2,     1,
       1,     0,     3,     0,     3,     1,     2,     1,     2,     3,
       2,     1,     1,     1,     2,     6,     1,     3,     1,     3,
       3,     1,     1,     1,     1,     1,     5,     1,     3,     1,
       2,     3,     1,     1,     1,     0,     1,     1,     3,     3,
       1,     1,     0,     1,     0,     8,     0,     2,     3,     3,
       2,     3,     3,     2,     1,     0,     0,     5,     0,     6,
       0,     2,     3,     3,     3,     0,     2,     0,     2,     4,
       3,     0,     0,     2,     3,     3,     2,     2,     3,     2,
       2,     2,     2,     1,     1,     2,     2,     2,     3,     2,
       4,     3,     3,     4,     3,     4,     3,     4,     7,     3,
       4,     4,     2,     2,     2,     2,     3,     3,     2,     3,
       4,     1,     2,     2,     6,     1,     1,     2,     3,     2,
       2,     2,     3,     2,     3,     0,     2,     1,     1,     1,
       1,     1,     1,     1,     1,     4,     4,     3,     8,     1,
       1,     0,     2,     7,     1,     1,     1,     0,     1,     1,
       1,     0,     2,     6,     1,     3,     1,     1,     5,     1,
       3,     1,     1,     2,     2,     1,     1,     2,     2,     2,
       4,     1,     3,     4,     1,     3,     2,     1,     3,     1,
       3,     2,     4,     3,     1,     3,     4,     1,     3,     1,
       1,     2,     3,     0,     0,     2,     1,     2,     1,     1,
       2,     2,     2,     3,     3,     2,     2,     2,     2,     2,
       3,     2,     2,     2,     0,     1,     2,     3,     4,     1,
       1,     1,     1,     0,     2,     6,     3,     1,     1,     1,
       0,     1,     0,     1,     1,     1,     2,     3,     3,     2,
       3,     3,     2,     3,     3,     2,     3,     3,     2,     2,
       2,     2,     2,     2,     2,     1,     2,     2,     3,     4,
       4,     2,     1,     1,     1,     0,     2,     0,     1,     2,
       3,     1,     1,     1,     1,     1,     1,     1,     1,     1,
       1
};


enum { YYENOMEM = -2 };

#define yyerrok         (yyerrstatus = 0)
#define yyclearin       (yychar = YYEMPTY)

#define YYACCEPT        goto yyacceptlab
#define YYABORT         goto yyabortlab
#define YYERROR         goto yyerrorlab
#define YYNOMEM         goto yyexhaustedlab


#define YYRECOVERING()  (!!yyerrstatus)

#define YYBACKUP(Token, Value)                                    \
  do                                                              \
    if (yychar == YYEMPTY)                                        \
      {                                                           \
        yychar = (Token);                                         \
        yylval = (Value);                                         \
        YYPOPSTACK (yylen);                                       \
        yystate = *yyssp;                                         \
        goto yybackup;                                            \
      }                                                           \
    else                                                          \
      {                                                           \
        yyerror (YY_("syntax error: cannot back up")); \
        YYERROR;                                                  \
      }                                                           \
  while (0)

/* Backward compatibility with an undocumented macro.
   Use YYerror or YYUNDEF. */
#define YYERRCODE YYUNDEF


/* Enable debugging if requested.  */
#if YYDEBUG

# ifndef YYFPRINTF
#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
#  define YYFPRINTF fprintf
# endif

# define YYDPRINTF(Args)                        \
do {                                            \
  if (yydebug)                                  \
    YYFPRINTF Args;                             \
} while (0)




# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                    \
do {                                                                      \
  if (yydebug)                                                            \
    {                                                                     \
      YYFPRINTF (stderr, "%s ", Title);                                   \
      yy_symbol_print (stderr,                                            \
                  Kind, Value); \
      YYFPRINTF (stderr, "\n");                                           \
    }                                                                     \
} while (0)


/*-----------------------------------.
| Print this symbol's value on YYO.  |
`-----------------------------------*/

static void
yy_symbol_value_print (FILE *yyo,
                       yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
{
  FILE *yyoutput = yyo;
  YY_USE (yyoutput);
  if (!yyvaluep)
    return;
  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
  YY_USE (yykind);
  YY_IGNORE_MAYBE_UNINITIALIZED_END
}


/*---------------------------.
| Print this symbol on YYO.  |
`---------------------------*/

static void
yy_symbol_print (FILE *yyo,
                 yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
{
  YYFPRINTF (yyo, "%s %s (",
             yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));

  yy_symbol_value_print (yyo, yykind, yyvaluep);
  YYFPRINTF (yyo, ")");
}

/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included).                                                   |
`------------------------------------------------------------------*/

static void
yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
{
  YYFPRINTF (stderr, "Stack now");
  for (; yybottom <= yytop; yybottom++)
    {
      int yybot = *yybottom;
      YYFPRINTF (stderr, " %d", yybot);
    }
  YYFPRINTF (stderr, "\n");
}

# define YY_STACK_PRINT(Bottom, Top)                            \
do {                                                            \
  if (yydebug)                                                  \
    yy_stack_print ((Bottom), (Top));                           \
} while (0)


/*------------------------------------------------.
| Report that the YYRULE is going to be reduced.  |
`------------------------------------------------*/

static void
yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
                 int yyrule)
{
  int yylno = yyrline[yyrule];
  int yynrhs = yyr2[yyrule];
  int yyi;
  YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
             yyrule - 1, yylno);
  /* The symbols being reduced.  */
  for (yyi = 0; yyi < yynrhs; yyi++)
    {
      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
      yy_symbol_print (stderr,
                       YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
                       &yyvsp[(yyi + 1) - (yynrhs)]);
      YYFPRINTF (stderr, "\n");
    }
}

# define YY_REDUCE_PRINT(Rule)          \
do {                                    \
  if (yydebug)                          \
    yy_reduce_print (yyssp, yyvsp, Rule); \
} while (0)

/* Nonzero means print parse trace.  It is left uninitialized so that
   multiple parsers can coexist.  */
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args) ((void) 0)
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */


/* YYINITDEPTH -- initial size of the parser's stacks.  */
#ifndef YYINITDEPTH
# define YYINITDEPTH 200
#endif

/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
   if the built-in stack extension method is used).

   Do not make this value too large; the results are undefined if
   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
   evaluated with infinite-precision integer arithmetic.  */

#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif






/*-----------------------------------------------.
| Release the memory associated to this symbol.  |
`-----------------------------------------------*/

static void
yydestruct (const char *yymsg,
            yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
{
  YY_USE (yyvaluep);
  if (!yymsg)
    yymsg = "Deleting";
  YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);

  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
  YY_USE (yykind);
  YY_IGNORE_MAYBE_UNINITIALIZED_END
}


/* Lookahead token kind.  */
int yychar;

/* The semantic value of the lookahead symbol.  */
YYSTYPE yylval;
/* Number of syntax errors so far.  */
int yynerrs;




/*----------.
| yyparse.  |
`----------*/

int
yyparse (void)
{
    yy_state_fast_t yystate = 0;
    /* Number of tokens to shift before error messages enabled.  */
    int yyerrstatus = 0;

    /* Refer to the stacks through separate pointers, to allow yyoverflow
       to reallocate them elsewhere.  */

    /* Their size.  */
    YYPTRDIFF_T yystacksize = YYINITDEPTH;

    /* The state stack: array, bottom, top.  */
    yy_state_t yyssa[YYINITDEPTH];
    yy_state_t *yyss = yyssa;
    yy_state_t *yyssp = yyss;

    /* The semantic value stack: array, bottom, top.  */
    YYSTYPE yyvsa[YYINITDEPTH];
    YYSTYPE *yyvs = yyvsa;
    YYSTYPE *yyvsp = yyvs;

  int yyn;
  /* The return value of yyparse.  */
  int yyresult;
  /* Lookahead symbol kind.  */
  yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
  /* The variables used to return semantic value and location from the
     action routines.  */
  YYSTYPE yyval;



#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))

  /* The number of symbols on the RHS of the reduced rule.
     Keep to zero when no symbol should be popped.  */
  int yylen = 0;

  YYDPRINTF ((stderr, "Starting parse\n"));

  yychar = YYEMPTY; /* Cause a token to be read.  */

  goto yysetstate;


/*------------------------------------------------------------.
| yynewstate -- push a new state, which is found in yystate.  |
`------------------------------------------------------------*/
yynewstate:
  /* In all cases, when you get here, the value and location stacks
     have just been pushed.  So pushing a state here evens the stacks.  */
  yyssp++;


/*--------------------------------------------------------------------.
| yysetstate -- set current state (the top of the stack) to yystate.  |
`--------------------------------------------------------------------*/
yysetstate:
  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
  YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
  YY_IGNORE_USELESS_CAST_BEGIN
  *yyssp = YY_CAST (yy_state_t, yystate);
  YY_IGNORE_USELESS_CAST_END
  YY_STACK_PRINT (yyss, yyssp);

  if (yyss + yystacksize - 1 <= yyssp)
#if !defined yyoverflow && !defined YYSTACK_RELOCATE
    YYNOMEM;
#else
    {
      /* Get the current used size of the three stacks, in elements.  */
      YYPTRDIFF_T yysize = yyssp - yyss + 1;

# if defined yyoverflow
      {
        /* Give user a chance to reallocate the stack.  Use copies of
           these so that the &'s don't force the real ones into
           memory.  */
        yy_state_t *yyss1 = yyss;
        YYSTYPE *yyvs1 = yyvs;

        /* Each stack pointer address is followed by the size of the
           data in use in that stack, in bytes.  This used to be a
           conditional around just the two extra args, but that might
           be undefined if yyoverflow is a macro.  */
        yyoverflow (YY_("memory exhausted"),
                    &yyss1, yysize * YYSIZEOF (*yyssp),
                    &yyvs1, yysize * YYSIZEOF (*yyvsp),
                    &yystacksize);
        yyss = yyss1;
        yyvs = yyvs1;
      }
# else /* defined YYSTACK_RELOCATE */
      /* Extend the stack our own way.  */
      if (YYMAXDEPTH <= yystacksize)
        YYNOMEM;
      yystacksize *= 2;
      if (YYMAXDEPTH < yystacksize)
        yystacksize = YYMAXDEPTH;

      {
        yy_state_t *yyss1 = yyss;
        union yyalloc *yyptr =
          YY_CAST (union yyalloc *,
                   YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
        if (! yyptr)
          YYNOMEM;
        YYSTACK_RELOCATE (yyss_alloc, yyss);
        YYSTACK_RELOCATE (yyvs_alloc, yyvs);
#  undef YYSTACK_RELOCATE
        if (yyss1 != yyssa)
          YYSTACK_FREE (yyss1);
      }
# endif

      yyssp = yyss + yysize - 1;
      yyvsp = yyvs + yysize - 1;

      YY_IGNORE_USELESS_CAST_BEGIN
      YYDPRINTF ((stderr, "Stack size increased to %ld\n",
                  YY_CAST (long, yystacksize)));
      YY_IGNORE_USELESS_CAST_END

      if (yyss + yystacksize - 1 <= yyssp)
        YYABORT;
    }
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */


  if (yystate == YYFINAL)
    YYACCEPT;

  goto yybackup;


/*-----------.
| yybackup.  |
`-----------*/
yybackup:
  /* Do appropriate processing given the current state.  Read a
     lookahead token if we need one and don't already have one.  */

  /* First try to decide what to do without reference to lookahead token.  */
  yyn = yypact[yystate];
  if (yypact_value_is_default (yyn))
    goto yydefault;

  /* Not known => get a lookahead token if don't already have one.  */

  /* YYCHAR is either empty, or end-of-input, or a valid lookahead.  */
  if (yychar == YYEMPTY)
    {
      YYDPRINTF ((stderr, "Reading a token\n"));
      yychar = yylex ();
    }

  if (yychar <= YYEOF)
    {
      yychar = YYEOF;
      yytoken = YYSYMBOL_YYEOF;
      YYDPRINTF ((stderr, "Now at end of input.\n"));
    }
  else if (yychar == YYerror)
    {
      /* The scanner already issued an error message, process directly
         to error recovery.  But do not keep the error token as
         lookahead, it is too special and may lead us to an endless
         loop in error recovery. */
      yychar = YYUNDEF;
      yytoken = YYSYMBOL_YYerror;
      goto yyerrlab1;
    }
  else
    {
      yytoken = YYTRANSLATE (yychar);
      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
    }

  /* If the proper action on seeing token YYTOKEN is to reduce or to
     detect an error, take that action.  */
  yyn += yytoken;
  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
    goto yydefault;
  yyn = yytable[yyn];
  if (yyn <= 0)
    {
      if (yytable_value_is_error (yyn))
        goto yyerrlab;
      yyn = -yyn;
      goto yyreduce;
    }

  /* Count tokens shifted since error; after three, turn off error
     status.  */
  if (yyerrstatus)
    yyerrstatus--;

  /* Shift the lookahead token.  */
  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
  yystate = yyn;
  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
  *++yyvsp = yylval;
  YY_IGNORE_MAYBE_UNINITIALIZED_END

  /* Discard the shifted token.  */
  yychar = YYEMPTY;
  goto yynewstate;


/*-----------------------------------------------------------.
| yydefault -- do the default action for the current state.  |
`-----------------------------------------------------------*/
yydefault:
  yyn = yydefact[yystate];
  if (yyn == 0)
    goto yyerrlab;
  goto yyreduce;


/*-----------------------------.
| yyreduce -- do a reduction.  |
`-----------------------------*/
yyreduce:
  /* yyn is the number of a rule to reduce with.  */
  yylen = yyr2[yyn];

  /* If YYLEN is nonzero, implement the default value of the action:
     '$$ = $1'.

     Otherwise, the following line sets YYVAL to garbage.
     This behavior is undocumented and Bison
     users should not rely upon it.  Assigning to YYVAL
     unconditionally makes the parser a bit smaller, and it avoids a
     GCC warning that YYVAL may be used uninitialized.  */
  yyval = yyvsp[1-yylen];


  YY_REDUCE_PRINT (yyn);
  switch (yyn)
    {
  case 21: /* grammar: grammar error '\n'  */
#line 318 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { file->errors++; }
#line 2543 "parse.c"
    break;

  case 22: /* asnumber: NUMBER  */
#line 321 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			/*
			 * According to iana 65535 and 4294967295 are reserved
			 * but enforcing this is not duty of the parser.
			 */
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > UINT_MAX) {
				yyerror("AS too big: max %u", UINT_MAX);
				YYERROR;
			}
		}
#line 2558 "parse.c"
    break;

  case 23: /* as4number: STRING  */
#line 332 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			const char	*errstr;
			char		*dot;
			uint32_t	 uvalh = 0, uval;

			if ((dot = strchr((yyvsp[0].v.string), '.')) != NULL) {
				*dot++ = '\0';
				uvalh = strtonum((yyvsp[0].v.string), 0, USHRT_MAX, &errstr);
				if (errstr) {
					yyerror("number %s is %s", (yyvsp[0].v.string), errstr);
					free((yyvsp[0].v.string));
					YYERROR;
				}
				uval = strtonum(dot, 0, USHRT_MAX, &errstr);
				if (errstr) {
					yyerror("number %s is %s", dot, errstr);
					free((yyvsp[0].v.string));
					YYERROR;
				}
				free((yyvsp[0].v.string));
			} else {
				yyerror("AS %s is bad", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (uvalh == 0 && (uval == AS_TRANS || uval == 0)) {
				yyerror("AS %u is reserved and may not be used",
				    uval);
				YYERROR;
			}
			(yyval.v.number) = uval | (uvalh << 16);
		}
#line 2595 "parse.c"
    break;

  case 24: /* as4number: asnumber  */
#line 364 "../../../openbgpd-portable/src/bgpd/parse.y"
                           {
			if ((yyvsp[0].v.number) == AS_TRANS || (yyvsp[0].v.number) == 0) {
				yyerror("AS %u is reserved and may not be used",
				    (uint32_t)(yyvsp[0].v.number));
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 2608 "parse.c"
    break;

  case 25: /* as4number_any: STRING  */
#line 374 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			const char	*errstr;
			char		*dot;
			uint32_t	 uvalh = 0, uval;

			if ((dot = strchr((yyvsp[0].v.string), '.')) != NULL) {
				*dot++ = '\0';
				uvalh = strtonum((yyvsp[0].v.string), 0, USHRT_MAX, &errstr);
				if (errstr) {
					yyerror("number %s is %s", (yyvsp[0].v.string), errstr);
					free((yyvsp[0].v.string));
					YYERROR;
				}
				uval = strtonum(dot, 0, USHRT_MAX, &errstr);
				if (errstr) {
					yyerror("number %s is %s", dot, errstr);
					free((yyvsp[0].v.string));
					YYERROR;
				}
				free((yyvsp[0].v.string));
			} else {
				yyerror("AS %s is bad", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			(yyval.v.number) = uval | (uvalh << 16);
		}
#line 2640 "parse.c"
    break;

  case 26: /* as4number_any: asnumber  */
#line 401 "../../../openbgpd-portable/src/bgpd/parse.y"
                           {
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 2648 "parse.c"
    break;

  case 27: /* string: string STRING  */
#line 406 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (asprintf(&(yyval.v.string), "%s %s", (yyvsp[-1].v.string), (yyvsp[0].v.string)) == -1)
				fatal("string: asprintf");
			free((yyvsp[-1].v.string));
			free((yyvsp[0].v.string));
		}
#line 2659 "parse.c"
    break;

  case 29: /* yesno: STRING  */
#line 415 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (!strcmp((yyvsp[0].v.string), "yes"))
				(yyval.v.number) = 1;
			else if (!strcmp((yyvsp[0].v.string), "no"))
				(yyval.v.number) = 0;
			else {
				yyerror("syntax error, "
				    "either yes or no expected");
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 2677 "parse.c"
    break;

  case 30: /* varset: STRING '=' string  */
#line 430 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			char *s = (yyvsp[-2].v.string);
			if (strlen((yyvsp[-2].v.string)) >= MACRO_NAME_LEN) {
				yyerror("macro name to long, max %d characters",
				    MACRO_NAME_LEN - 1);
				free((yyvsp[-2].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			do {
				if (isalnum((unsigned char)*s) || *s == '_')
					continue;
				yyerror("macro name can only contain "
					    "alphanumerics and '_'");
				free((yyvsp[-2].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			} while (*++s);

			if (cmd_opts & BGPD_OPT_VERBOSE)
				printf("%s = \"%s\"\n", (yyvsp[-2].v.string), (yyvsp[0].v.string));
			if (symset((yyvsp[-2].v.string), (yyvsp[0].v.string), 0) == -1)
				fatal("cannot store variable");
			free((yyvsp[-2].v.string));
			free((yyvsp[0].v.string));
		}
#line 2708 "parse.c"
    break;

  case 31: /* include: INCLUDE STRING  */
#line 458 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			struct file	*nfile;

			if ((nfile = pushfile((yyvsp[0].v.string), 1)) == NULL) {
				yyerror("failed to include file %s", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));

			file = nfile;
			lungetc('\n');
		}
#line 2726 "parse.c"
    break;

  case 32: /* $@1: %empty  */
#line 473 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (strlen((yyvsp[-2].v.string)) >= SET_NAME_LEN) {
				yyerror("as-set name %s too long", (yyvsp[-2].v.string));
				free((yyvsp[-2].v.string));
				YYERROR;
			}
			if (new_as_set((yyvsp[-2].v.string)) != 0) {
				free((yyvsp[-2].v.string));
				YYERROR;
			}
			free((yyvsp[-2].v.string));
		}
#line 2743 "parse.c"
    break;

  case 33: /* as_set: ASSET STRING '{' optnl $@1 as_set_l optnl '}'  */
#line 484 "../../../openbgpd-portable/src/bgpd/parse.y"
                                     {
			done_as_set();
		}
#line 2751 "parse.c"
    break;

  case 34: /* as_set: ASSET STRING '{' optnl '}'  */
#line 487 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (new_as_set((yyvsp[-3].v.string)) != 0) {
				free((yyvsp[-3].v.string));
				YYERROR;
			}
			free((yyvsp[-3].v.string));
		}
#line 2763 "parse.c"
    break;

  case 35: /* as_set_l: as4number_any  */
#line 495 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { add_as_set((yyvsp[0].v.number)); }
#line 2769 "parse.c"
    break;

  case 36: /* as_set_l: as_set_l comma as4number_any  */
#line 496 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { add_as_set((yyvsp[0].v.number)); }
#line 2775 "parse.c"
    break;

  case 37: /* $@2: %empty  */
#line 498 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			if ((curpset = new_prefix_set((yyvsp[-2].v.string), 0)) == NULL) {
				free((yyvsp[-2].v.string));
				YYERROR;
			}
			free((yyvsp[-2].v.string));
		}
#line 2787 "parse.c"
    break;

  case 38: /* prefixset: PREFIXSET STRING '{' optnl $@2 prefixset_l optnl '}'  */
#line 504 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			SIMPLEQ_INSERT_TAIL(&conf->prefixsets, curpset, entry);
			curpset = NULL;
		}
#line 2796 "parse.c"
    break;

  case 39: /* prefixset: PREFIXSET STRING '{' optnl '}'  */
#line 508 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			if ((curpset = new_prefix_set((yyvsp[-3].v.string), 0)) == NULL) {
				free((yyvsp[-3].v.string));
				YYERROR;
			}
			free((yyvsp[-3].v.string));
			SIMPLEQ_INSERT_TAIL(&conf->prefixsets, curpset, entry);
			curpset = NULL;
		}
#line 2810 "parse.c"
    break;

  case 40: /* prefixset_l: prefixset_item  */
#line 518 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct prefixset_item	*psi;
			if ((yyvsp[0].v.prefixset_item)->p.op != OP_NONE)
				curpset->sflags |= PREFIXSET_FLAG_OPS;
			psi = RB_INSERT(prefixset_tree, &curpset->psitems, (yyvsp[0].v.prefixset_item));
			if (psi != NULL) {
				if (cmd_opts & BGPD_OPT_VERBOSE2)
					log_warnx("warning: duplicate entry in "
					    "prefixset \"%s\" for %s/%u",
					    curpset->name,
					    log_addr(&(yyvsp[0].v.prefixset_item)->p.addr), (yyvsp[0].v.prefixset_item)->p.len);
				free((yyvsp[0].v.prefixset_item));
			}
		}
#line 2829 "parse.c"
    break;

  case 41: /* prefixset_l: prefixset_l comma prefixset_item  */
#line 532 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct prefixset_item	*psi;
			if ((yyvsp[0].v.prefixset_item)->p.op != OP_NONE)
				curpset->sflags |= PREFIXSET_FLAG_OPS;
			psi = RB_INSERT(prefixset_tree, &curpset->psitems, (yyvsp[0].v.prefixset_item));
			if (psi != NULL) {
				if (cmd_opts & BGPD_OPT_VERBOSE2)
					log_warnx("warning: duplicate entry in "
					    "prefixset \"%s\" for %s/%u",
					    curpset->name,
					    log_addr(&(yyvsp[0].v.prefixset_item)->p.addr), (yyvsp[0].v.prefixset_item)->p.len);
				free((yyvsp[0].v.prefixset_item));
			}
		}
#line 2848 "parse.c"
    break;

  case 42: /* prefixset_item: prefix prefixlenop  */
#line 548 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			if ((yyvsp[0].v.prefixlen).op != OP_NONE && (yyvsp[0].v.prefixlen).op != OP_RANGE) {
				yyerror("unsupported prefixlen operation in "
				    "prefix-set");
				YYERROR;
			}
			if (((yyval.v.prefixset_item) = calloc(1, sizeof(*(yyval.v.prefixset_item)))) == NULL)
				fatal(NULL);
			memcpy(&(yyval.v.prefixset_item)->p.addr, &(yyvsp[-1].v.prefix).prefix, sizeof((yyval.v.prefixset_item)->p.addr));
			(yyval.v.prefixset_item)->p.len = (yyvsp[-1].v.prefix).len;
			if (merge_prefixspec(&(yyval.v.prefixset_item)->p, &(yyvsp[0].v.prefixlen)) == -1) {
				free((yyval.v.prefixset_item));
				YYERROR;
			}
		}
#line 2868 "parse.c"
    break;

  case 43: /* $@3: %empty  */
#line 565 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			curroatree = &conf->roa;
		}
#line 2876 "parse.c"
    break;

  case 44: /* roa_set: ROASET '{' optnl $@3 roa_set_l optnl '}'  */
#line 567 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			curroatree = NULL;
		}
#line 2884 "parse.c"
    break;

  case 46: /* $@4: %empty  */
#line 573 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			if ((curoset = new_prefix_set((yyvsp[-2].v.string), 1)) == NULL) {
				free((yyvsp[-2].v.string));
				YYERROR;
			}
			curroatree = &curoset->roaitems;
			noexpires = 1;
			free((yyvsp[-2].v.string));
		}
#line 2898 "parse.c"
    break;

  case 47: /* origin_set: ORIGINSET STRING '{' optnl $@4 roa_set_l optnl '}'  */
#line 581 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			SIMPLEQ_INSERT_TAIL(&conf->originsets, curoset, entry);
			curoset = NULL;
			curroatree = NULL;
			noexpires = 0;
		}
#line 2909 "parse.c"
    break;

  case 48: /* origin_set: ORIGINSET STRING '{' optnl '}'  */
#line 587 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                {
			if ((curoset = new_prefix_set((yyvsp[-3].v.string), 1)) == NULL) {
				free((yyvsp[-3].v.string));
				YYERROR;
			}
			free((yyvsp[-3].v.string));
			SIMPLEQ_INSERT_TAIL(&conf->originsets, curoset, entry);
			curoset = NULL;
			curroatree = NULL;
		}
#line 2924 "parse.c"
    break;

  case 49: /* expires: %empty  */
#line 599 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			(yyval.v.number) = 0;
		}
#line 2932 "parse.c"
    break;

  case 50: /* expires: EXPIRES NUMBER  */
#line 602 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (noexpires) {
				yyerror("syntax error, expires not allowed");
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 2944 "parse.c"
    break;

  case 51: /* roa_set_l: prefixset_item SOURCEAS as4number_any expires  */
#line 610 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                        {
			if ((yyvsp[-3].v.prefixset_item)->p.len_min != (yyvsp[-3].v.prefixset_item)->p.len) {
				yyerror("unsupported prefixlen operation in "
				    "roa-set");
				free((yyvsp[-3].v.prefixset_item));
				YYERROR;
			}
			add_roa_set((yyvsp[-3].v.prefixset_item), (yyvsp[-1].v.number), (yyvsp[-3].v.prefixset_item)->p.len_max, (yyvsp[0].v.number));
			free((yyvsp[-3].v.prefixset_item));
		}
#line 2959 "parse.c"
    break;

  case 52: /* roa_set_l: roa_set_l comma prefixset_item SOURCEAS as4number_any expires  */
#line 620 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                                {
			if ((yyvsp[-3].v.prefixset_item)->p.len_min != (yyvsp[-3].v.prefixset_item)->p.len) {
				yyerror("unsupported prefixlen operation in "
				    "roa-set");
				free((yyvsp[-3].v.prefixset_item));
				YYERROR;
			}
			add_roa_set((yyvsp[-3].v.prefixset_item), (yyvsp[-1].v.number), (yyvsp[-3].v.prefixset_item)->p.len_max, (yyvsp[0].v.number));
			free((yyvsp[-3].v.prefixset_item));
		}
#line 2974 "parse.c"
    break;

  case 57: /* aspa_elm: CUSTOMERAS as4number expires PROVIDERAS '{' optnl aspa_tas_l optnl '}'  */
#line 641 "../../../openbgpd-portable/src/bgpd/parse.y"
                                         {
			int rv;
			struct aspa_tas_l *a, *n;

			rv = merge_aspa_set((yyvsp[-7].v.number), (yyvsp[-2].v.aspa_elm), (yyvsp[-6].v.number));

			for (a = (yyvsp[-2].v.aspa_elm); a != NULL; a = n) {
				n = a->next;
				free(a);
			}

			if (rv == -1)
				YYERROR;
		}
#line 2993 "parse.c"
    break;

  case 58: /* aspa_tas_l: aspa_tas  */
#line 657 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { (yyval.v.aspa_elm) = (yyvsp[0].v.aspa_elm); }
#line 2999 "parse.c"
    break;

  case 59: /* aspa_tas_l: aspa_tas_l comma aspa_tas  */
#line 658 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			(yyvsp[0].v.aspa_elm)->next = (yyvsp[-2].v.aspa_elm);
			(yyvsp[0].v.aspa_elm)->num = (yyvsp[-2].v.aspa_elm)->num + 1;
			(yyval.v.aspa_elm) = (yyvsp[0].v.aspa_elm);
		}
#line 3009 "parse.c"
    break;

  case 60: /* aspa_tas: as4number_any  */
#line 665 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (((yyval.v.aspa_elm) = calloc(1, sizeof(*(yyval.v.aspa_elm)))) == NULL)
				fatal(NULL);
			(yyval.v.aspa_elm)->as = (yyvsp[0].v.number);
			(yyval.v.aspa_elm)->num = 1;
		}
#line 3020 "parse.c"
    break;

  case 61: /* aspa_tas: as4number_any af  */
#line 671 "../../../openbgpd-portable/src/bgpd/parse.y"
                                   {
			if (((yyval.v.aspa_elm) = calloc(1, sizeof(*(yyval.v.aspa_elm)))) == NULL)
				fatal(NULL);
			(yyval.v.aspa_elm)->as = (yyvsp[-1].v.number);
			(yyval.v.aspa_elm)->num = 1;
		}
#line 3031 "parse.c"
    break;

  case 62: /* rtr: RTR address  */
#line 679 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			currtr = get_rtr(&(yyvsp[0].v.addr));
			currtr->remote_port = RTR_PORT;
			if (insert_rtr(currtr) == -1) {
				free(currtr);
				YYERROR;
			}
			currtr = NULL;
		}
#line 3045 "parse.c"
    break;

  case 63: /* $@5: %empty  */
#line 688 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			currtr = get_rtr(&(yyvsp[0].v.addr));
			currtr->remote_port = RTR_PORT;
		}
#line 3054 "parse.c"
    break;

  case 64: /* rtr: RTR address $@5 '{' optnl rtropt_l optnl '}'  */
#line 691 "../../../openbgpd-portable/src/bgpd/parse.y"
                                               {
			if (insert_rtr(currtr) == -1) {
				free(currtr);
				YYERROR;
			}
			currtr = NULL;
		}
#line 3066 "parse.c"
    break;

  case 67: /* rtropt: DESCR STRING  */
#line 704 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (strlcpy(currtr->descr, (yyvsp[0].v.string),
			    sizeof(currtr->descr)) >=
			    sizeof(currtr->descr)) {
				yyerror("descr \"%s\" too long: max %zu",
				    (yyvsp[0].v.string), sizeof(currtr->descr) - 1);
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3082 "parse.c"
    break;

  case 68: /* rtropt: LOCALADDR address  */
#line 715 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.addr).aid != currtr->remote_addr.aid) {
				yyerror("Bad address family %s for "
				    "local-addr", aid2str((yyvsp[0].v.addr).aid));
				YYERROR;
			}
			currtr->local_addr = (yyvsp[0].v.addr);
		}
#line 3095 "parse.c"
    break;

  case 69: /* rtropt: PORT port  */
#line 723 "../../../openbgpd-portable/src/bgpd/parse.y"
                            {
			currtr->remote_port = (yyvsp[0].v.number);
		}
#line 3103 "parse.c"
    break;

  case 70: /* rtropt: MINVERSION NUMBER  */
#line 726 "../../../openbgpd-portable/src/bgpd/parse.y"
                                    {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > RTR_MAX_VERSION) {
				yyerror("min-version must be between %u and %u",
				    0, RTR_MAX_VERSION);
				YYERROR;
			}
			currtr->min_version = (yyvsp[0].v.number);
		}
#line 3116 "parse.c"
    break;

  case 71: /* rtropt: authconf  */
#line 734 "../../../openbgpd-portable/src/bgpd/parse.y"
                           {
			if (merge_auth_conf(&currtr->auth, &(yyvsp[0].v.authconf)) == 0)
				YYERROR;
		}
#line 3125 "parse.c"
    break;

  case 72: /* conf_main: AS as4number  */
#line 740 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			conf->as = (yyvsp[0].v.number);
			if ((yyvsp[0].v.number) > USHRT_MAX)
				conf->short_as = AS_TRANS;
			else
				conf->short_as = (yyvsp[0].v.number);
		}
#line 3137 "parse.c"
    break;

  case 73: /* conf_main: AS as4number asnumber  */
#line 747 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			conf->as = (yyvsp[-1].v.number);
			conf->short_as = (yyvsp[0].v.number);
		}
#line 3146 "parse.c"
    break;

  case 74: /* conf_main: ROUTERID address  */
#line 751 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.addr).aid != AID_INET) {
				yyerror("router-id must be an IPv4 address");
				YYERROR;
			}
			conf->bgpid = ntohl((yyvsp[0].v.addr).v4.s_addr);
		}
#line 3158 "parse.c"
    break;

  case 75: /* conf_main: HOLDTIME NUMBER  */
#line 758 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < MIN_HOLDTIME || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("holdtime must be between %u and %u",
				    MIN_HOLDTIME, USHRT_MAX);
				YYERROR;
			}
			conf->holdtime = (yyvsp[0].v.number);
		}
#line 3171 "parse.c"
    break;

  case 76: /* conf_main: HOLDTIME YMIN NUMBER  */
#line 766 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < MIN_HOLDTIME || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("holdtime must be between %u and %u",
				    MIN_HOLDTIME, USHRT_MAX);
				YYERROR;
			}
			conf->min_holdtime = (yyvsp[0].v.number);
		}
#line 3184 "parse.c"
    break;

  case 77: /* conf_main: STALETIME NUMBER  */
#line 774 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < MIN_HOLDTIME || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("staletime must be between %u and %u",
				    MIN_HOLDTIME, USHRT_MAX);
				YYERROR;
			}
			conf->staletime = (yyvsp[0].v.number);
		}
#line 3197 "parse.c"
    break;

  case 78: /* conf_main: LISTEN ON address  */
#line 782 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			struct listen_addr	*la;
			struct sockaddr		*sa;

			if ((la = calloc(1, sizeof(struct listen_addr))) ==
			    NULL)
				fatal("parse conf_main listen on calloc");

			la->fd = -1;
			la->reconf = RECONF_REINIT;
			sa = addr2sa(&(yyvsp[0].v.addr), BGP_PORT, &la->sa_len);
			memcpy(&la->sa, sa, la->sa_len);
			TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
		}
#line 3216 "parse.c"
    break;

  case 79: /* conf_main: LISTEN ON address PORT port  */
#line 796 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			struct listen_addr	*la;
			struct sockaddr		*sa;

			if ((la = calloc(1, sizeof(struct listen_addr))) ==
			    NULL)
				fatal("parse conf_main listen on calloc");

			la->fd = -1;
			la->reconf = RECONF_REINIT;
			sa = addr2sa(&(yyvsp[-2].v.addr), (yyvsp[0].v.number), &la->sa_len);
			memcpy(&la->sa, sa, la->sa_len);
			TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
		}
#line 3235 "parse.c"
    break;

  case 80: /* conf_main: FIBPRIORITY NUMBER  */
#line 810 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (!kr_check_prio((yyvsp[0].v.number))) {
				yyerror("fib-priority %lld out of range", (yyvsp[0].v.number));
				YYERROR;
			}
			conf->fib_priority = (yyvsp[0].v.number);
		}
#line 3247 "parse.c"
    break;

  case 81: /* conf_main: FIBUPDATE yesno  */
#line 817 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			struct rde_rib *rr;
			rr = find_rib("Loc-RIB");
			if (rr == NULL)
				fatalx("RTABLE cannot find the main RIB!");

			if ((yyvsp[0].v.number) == 0)
				rr->flags |= F_RIB_NOFIBSYNC;
			else
				rr->flags &= ~F_RIB_NOFIBSYNC;
		}
#line 3263 "parse.c"
    break;

  case 82: /* conf_main: TRANSPARENT yesno  */
#line 828 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) == 1)
				conf->flags |= BGPD_FLAG_DECISION_TRANS_AS;
			else
				conf->flags &= ~BGPD_FLAG_DECISION_TRANS_AS;
		}
#line 3274 "parse.c"
    break;

  case 83: /* conf_main: REJECT ASSET yesno  */
#line 834 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) == 1)
				conf->flags &= ~BGPD_FLAG_PERMIT_AS_SET;
			else
				conf->flags |= BGPD_FLAG_PERMIT_AS_SET;
		}
#line 3285 "parse.c"
    break;

  case 84: /* conf_main: LOG STRING  */
#line 840 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (!strcmp((yyvsp[0].v.string), "updates"))
				conf->log |= BGPD_LOG_UPDATES;
			else {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3299 "parse.c"
    break;

  case 85: /* conf_main: DUMP STRING STRING optnumber  */
#line 849 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			int action;

			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad timeout");
				free((yyvsp[-2].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if (!strcmp((yyvsp[-2].v.string), "table"))
				action = MRT_TABLE_DUMP;
			else if (!strcmp((yyvsp[-2].v.string), "table-mp"))
				action = MRT_TABLE_DUMP_MP;
			else if (!strcmp((yyvsp[-2].v.string), "table-v2"))
				action = MRT_TABLE_DUMP_V2;
			else {
				yyerror("unknown mrt dump type");
				free((yyvsp[-2].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-2].v.string));
			if (add_mrtconfig(action, (yyvsp[-1].v.string), (yyvsp[0].v.number), NULL, NULL) == -1) {
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-1].v.string));
		}
#line 3332 "parse.c"
    break;

  case 86: /* conf_main: DUMP RIB STRING STRING STRING optnumber  */
#line 877 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                        {
			int action;

			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad timeout");
				free((yyvsp[-3].v.string));
				free((yyvsp[-2].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if (!strcmp((yyvsp[-2].v.string), "table"))
				action = MRT_TABLE_DUMP;
			else if (!strcmp((yyvsp[-2].v.string), "table-mp"))
				action = MRT_TABLE_DUMP_MP;
			else if (!strcmp((yyvsp[-2].v.string), "table-v2"))
				action = MRT_TABLE_DUMP_V2;
			else {
				yyerror("unknown mrt dump type");
				free((yyvsp[-3].v.string));
				free((yyvsp[-2].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-2].v.string));
			if (add_mrtconfig(action, (yyvsp[-1].v.string), (yyvsp[0].v.number), NULL, (yyvsp[-3].v.string)) == -1) {
				free((yyvsp[-3].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-3].v.string));
			free((yyvsp[-1].v.string));
		}
#line 3369 "parse.c"
    break;

  case 87: /* conf_main: RDE STRING EVALUATE  */
#line 909 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (!strcmp((yyvsp[-1].v.string), "route-age"))
				conf->flags |= BGPD_FLAG_DECISION_ROUTEAGE;
			else {
				yyerror("unknown route decision type");
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-1].v.string));
		}
#line 3384 "parse.c"
    break;

  case 88: /* conf_main: RDE STRING IGNORE  */
#line 919 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (!strcmp((yyvsp[-1].v.string), "route-age"))
				conf->flags &= ~BGPD_FLAG_DECISION_ROUTEAGE;
			else {
				yyerror("unknown route decision type");
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-1].v.string));
		}
#line 3399 "parse.c"
    break;

  case 89: /* conf_main: RDE MED COMPARE STRING  */
#line 929 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (!strcmp((yyvsp[0].v.string), "always"))
				conf->flags |= BGPD_FLAG_DECISION_MED_ALWAYS;
			else if (!strcmp((yyvsp[0].v.string), "strict"))
				conf->flags &= ~BGPD_FLAG_DECISION_MED_ALWAYS;
			else {
				yyerror("rde med compare: "
				    "unknown setting \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3417 "parse.c"
    break;

  case 90: /* conf_main: RDE EVALUATE STRING  */
#line 942 "../../../openbgpd-portable/src/bgpd/parse.y"
                                      {
			if (!strcmp((yyvsp[0].v.string), "all"))
				conf->flags |= BGPD_FLAG_DECISION_ALL_PATHS;
			else if (!strcmp((yyvsp[0].v.string), "default"))
				conf->flags &= ~BGPD_FLAG_DECISION_ALL_PATHS;
			else {
				yyerror("rde evaluate: "
				    "unknown setting \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3435 "parse.c"
    break;

  case 91: /* conf_main: RDE RIB STRING INCLUDE FILTERED  */
#line 955 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                  {
			if (strcmp((yyvsp[-2].v.string), "Loc-RIB") != 0) {
				yyerror("include filtered only supported in "
				    "Loc-RIB");
				YYERROR;
			}
			conf->filtered_in_locrib = 1;
		}
#line 3448 "parse.c"
    break;

  case 92: /* conf_main: NEXTHOP QUALIFY VIA STRING  */
#line 963 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (!strcmp((yyvsp[0].v.string), "bgp"))
				conf->flags |= BGPD_FLAG_NEXTHOP_BGP;
			else if (!strcmp((yyvsp[0].v.string), "default"))
				conf->flags |= BGPD_FLAG_NEXTHOP_DEFAULT;
			else {
				yyerror("nexthop depend on: "
				    "unknown setting \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3466 "parse.c"
    break;

  case 93: /* conf_main: RTABLE NUMBER  */
#line 976 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			struct rde_rib *rr;
			if ((yyvsp[0].v.number) > RT_TABLEID_MAX) {
				yyerror("rtable %llu too big: max %u", (yyvsp[0].v.number),
				    RT_TABLEID_MAX);
				YYERROR;
			}
			if (!ktable_exists((yyvsp[0].v.number), NULL)) {
				yyerror("rtable id %lld does not exist", (yyvsp[0].v.number));
				YYERROR;
			}
			rr = find_rib("Loc-RIB");
			if (rr == NULL)
				fatalx("RTABLE cannot find the main RIB!");
			rr->rtableid = (yyvsp[0].v.number);
		}
#line 3487 "parse.c"
    break;

  case 94: /* conf_main: CONNECTRETRY NUMBER  */
#line 992 "../../../openbgpd-portable/src/bgpd/parse.y"
                                      {
			if ((yyvsp[0].v.number) > USHRT_MAX || (yyvsp[0].v.number) < 1) {
				yyerror("invalid connect-retry");
				YYERROR;
			}
			conf->connectretry = (yyvsp[0].v.number);
		}
#line 3499 "parse.c"
    break;

  case 95: /* conf_main: SOCKET STRING restricted  */
#line 999 "../../../openbgpd-portable/src/bgpd/parse.y"
                                           {
			if (strlen((yyvsp[-1].v.string)) >=
			    sizeof(((struct sockaddr_un *)0)->sun_path)) {
				yyerror("socket path too long");
				YYERROR;
			}
			if ((yyvsp[0].v.number)) {
				free(conf->rcsock);
				conf->rcsock = (yyvsp[-1].v.string);
			} else {
				free(conf->csock);
				conf->csock = (yyvsp[-1].v.string);
			}
		}
#line 3518 "parse.c"
    break;

  case 96: /* $@6: %empty  */
#line 1015 "../../../openbgpd-portable/src/bgpd/parse.y"
                                 {
			if ((currib = add_rib((yyvsp[0].v.string))) == NULL) {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3530 "parse.c"
    break;

  case 97: /* rib: RDE RIB STRING $@6 ribopts  */
#line 1021 "../../../openbgpd-portable/src/bgpd/parse.y"
                          {
			currib = NULL;
		}
#line 3538 "parse.c"
    break;

  case 99: /* ribopts: RTABLE NUMBER fibupdate  */
#line 1026 "../../../openbgpd-portable/src/bgpd/parse.y"
                                          {
			if ((yyvsp[-1].v.number) > RT_TABLEID_MAX) {
				yyerror("rtable %llu too big: max %u", (yyvsp[-1].v.number),
				    RT_TABLEID_MAX);
				YYERROR;
			}
			if (rib_add_fib(currib, (yyvsp[-1].v.number)) == -1)
				YYERROR;
		}
#line 3552 "parse.c"
    break;

  case 100: /* ribopts: yesno EVALUATE  */
#line 1035 "../../../openbgpd-portable/src/bgpd/parse.y"
                                 {
			if ((yyvsp[-1].v.number)) {
				yyerror("bad rde rib definition");
				YYERROR;
			}
			currib->flags |= F_RIB_NOEVALUATE;
		}
#line 3564 "parse.c"
    break;

  case 102: /* fibupdate: FIBUPDATE yesno  */
#line 1045 "../../../openbgpd-portable/src/bgpd/parse.y"
                                  {
			if ((yyvsp[0].v.number) == 0)
				currib->flags |= F_RIB_NOFIBSYNC;
			else
				currib->flags &= ~F_RIB_NOFIBSYNC;
		}
#line 3575 "parse.c"
    break;

  case 103: /* mrtdump: DUMP STRING inout STRING optnumber  */
#line 1053 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			int action;

			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad timeout");
				free((yyvsp[-3].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if (!strcmp((yyvsp[-3].v.string), "all"))
				action = (yyvsp[-2].v.number) ? MRT_ALL_IN : MRT_ALL_OUT;
			else if (!strcmp((yyvsp[-3].v.string), "updates"))
				action = (yyvsp[-2].v.number) ? MRT_UPDATE_IN : MRT_UPDATE_OUT;
			else {
				yyerror("unknown mrt msg dump type");
				free((yyvsp[-3].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if (add_mrtconfig(action, (yyvsp[-1].v.string), (yyvsp[0].v.number), curpeer, NULL) ==
			    -1) {
				free((yyvsp[-3].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-3].v.string));
			free((yyvsp[-1].v.string));
		}
#line 3608 "parse.c"
    break;

  case 104: /* network: NETWORK prefix filter_set  */
#line 1083 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			struct network	*n, *m;

			if ((n = calloc(1, sizeof(struct network))) == NULL)
				fatal("new_network");
			memcpy(&n->net.prefix, &(yyvsp[-1].v.prefix).prefix,
			    sizeof(n->net.prefix));
			n->net.prefixlen = (yyvsp[-1].v.prefix).len;
			filterset_move((yyvsp[0].v.filter_set_head), &n->net.attrset);
			free((yyvsp[0].v.filter_set_head));
			TAILQ_FOREACH(m, netconf, entry) {
				if (n->net.type == m->net.type &&
				    n->net.prefixlen == m->net.prefixlen &&
				    prefix_compare(&n->net.prefix,
				    &m->net.prefix, n->net.prefixlen) == 0)
					yyerror("duplicate prefix "
					    "in network statement");
			}

			TAILQ_INSERT_TAIL(netconf, n, entry);
		}
#line 3634 "parse.c"
    break;

  case 105: /* network: NETWORK PREFIXSET STRING filter_set  */
#line 1104 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct prefixset *ps;
			struct network	*n;
			if ((ps = find_prefixset((yyvsp[-1].v.string), &conf->prefixsets))
			    == NULL) {
				yyerror("prefix-set '%s' not defined", (yyvsp[-1].v.string));
				free((yyvsp[-1].v.string));
				filterset_free((yyvsp[0].v.filter_set_head));
				free((yyvsp[0].v.filter_set_head));
				YYERROR;
			}
			if (ps->sflags & PREFIXSET_FLAG_OPS) {
				yyerror("prefix-set %s has prefixlen operators "
				    "and cannot be used in network statements.",
				    ps->name);
				free((yyvsp[-1].v.string));
				filterset_free((yyvsp[0].v.filter_set_head));
				free((yyvsp[0].v.filter_set_head));
				YYERROR;
			}
			if ((n = calloc(1, sizeof(struct network))) == NULL)
				fatal("new_network");
			strlcpy(n->net.psname, ps->name, sizeof(n->net.psname));
			filterset_move((yyvsp[0].v.filter_set_head), &n->net.attrset);
			n->net.type = NETWORK_PREFIXSET;
			TAILQ_INSERT_TAIL(netconf, n, entry);
			free((yyvsp[-1].v.string));
			free((yyvsp[0].v.filter_set_head));
		}
#line 3668 "parse.c"
    break;

  case 106: /* network: NETWORK af RTLABEL STRING filter_set  */
#line 1133 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct network	*n;

			if ((n = calloc(1, sizeof(struct network))) == NULL)
				fatal("new_network");
			if (afi2aid((yyvsp[-3].v.number), SAFI_UNICAST, &n->net.prefix.aid) ==
			    -1) {
				yyerror("unknown address family");
				filterset_free((yyvsp[0].v.filter_set_head));
				free((yyvsp[0].v.filter_set_head));
				YYERROR;
			}
			n->net.type = NETWORK_RTLABEL;
			n->net.rtlabel = rtlabel_name2id((yyvsp[-1].v.string));
			filterset_move((yyvsp[0].v.filter_set_head), &n->net.attrset);
			free((yyvsp[0].v.filter_set_head));

			TAILQ_INSERT_TAIL(netconf, n, entry);
		}
#line 3692 "parse.c"
    break;

  case 107: /* network: NETWORK af PRIORITY NUMBER filter_set  */
#line 1152 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct network	*n;
			if (!kr_check_prio((yyvsp[-1].v.number))) {
				yyerror("priority %lld out of range", (yyvsp[-1].v.number));
				YYERROR;
			}

			if ((n = calloc(1, sizeof(struct network))) == NULL)
				fatal("new_network");
			if (afi2aid((yyvsp[-3].v.number), SAFI_UNICAST, &n->net.prefix.aid) ==
			    -1) {
				yyerror("unknown address family");
				filterset_free((yyvsp[0].v.filter_set_head));
				free((yyvsp[0].v.filter_set_head));
				YYERROR;
			}
			n->net.type = NETWORK_PRIORITY;
			n->net.priority = (yyvsp[-1].v.number);
			filterset_move((yyvsp[0].v.filter_set_head), &n->net.attrset);
			free((yyvsp[0].v.filter_set_head));

			TAILQ_INSERT_TAIL(netconf, n, entry);
		}
#line 3720 "parse.c"
    break;

  case 108: /* network: NETWORK af nettype filter_set  */
#line 1175 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			struct network	*n;

			if ((n = calloc(1, sizeof(struct network))) == NULL)
				fatal("new_network");
			if (afi2aid((yyvsp[-2].v.number), SAFI_UNICAST, &n->net.prefix.aid) ==
			    -1) {
				yyerror("unknown address family");
				filterset_free((yyvsp[0].v.filter_set_head));
				free((yyvsp[0].v.filter_set_head));
				YYERROR;
			}
			n->net.type = (yyvsp[-1].v.number) ? NETWORK_STATIC : NETWORK_CONNECTED;
			filterset_move((yyvsp[0].v.filter_set_head), &n->net.attrset);
			free((yyvsp[0].v.filter_set_head));

			TAILQ_INSERT_TAIL(netconf, n, entry);
		}
#line 3743 "parse.c"
    break;

  case 109: /* $@7: %empty  */
#line 1195 "../../../openbgpd-portable/src/bgpd/parse.y"
                              {
			if ((curflow = calloc(1, sizeof(*curflow))) == NULL)
				fatal("new_flowspec");
			curflow->aid = (yyvsp[0].v.number);
		}
#line 3753 "parse.c"
    break;

  case 110: /* flowspec: FLOWSPEC af $@7 flow_rules filter_set  */
#line 1199 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			struct flowspec_config *f;

			f = flow_to_flowspec(curflow);
			if (f == NULL) {
				yyerror("out of memory");
				free((yyvsp[0].v.filter_set_head));
				flow_free(curflow);
				curflow = NULL;
				YYERROR;
			}
			filterset_move((yyvsp[0].v.filter_set_head), &f->attrset);
			free((yyvsp[0].v.filter_set_head));
			flow_free(curflow);
			curflow = NULL;

			if (RB_INSERT(flowspec_tree, &conf->flowspecs, f) !=
			    NULL) {
				yyerror("duplicate flowspec definition");
				flowspec_free(f);
				YYERROR;
			}
		}
#line 3781 "parse.c"
    break;

  case 113: /* proto_list: proto_item  */
#line 1228 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			curflow->type = FLOWSPEC_TYPE_PROTO;
			if (push_unary_numop(OP_EQ, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 3791 "parse.c"
    break;

  case 114: /* proto_list: proto_list comma proto_item  */
#line 1233 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			curflow->type = FLOWSPEC_TYPE_PROTO;
			if (push_unary_numop(OP_EQ, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 3801 "parse.c"
    break;

  case 115: /* proto_item: STRING  */
#line 1240 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct protoent *p;

			p = getprotobyname((yyvsp[0].v.string));
			if (p == NULL) {
				yyerror("unknown protocol %s", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			(yyval.v.number) = p->p_proto;
			free((yyvsp[0].v.string));
		}
#line 3818 "parse.c"
    break;

  case 116: /* proto_item: NUMBER  */
#line 1252 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 255) {
				yyerror("protocol outside range");
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 3830 "parse.c"
    break;

  case 117: /* $@8: %empty  */
#line 1261 "../../../openbgpd-portable/src/bgpd/parse.y"
                       {
			curflow->type = FLOWSPEC_TYPE_SRC_PORT;
			curflow->addr_type = FLOWSPEC_TYPE_SOURCE;
		}
#line 3839 "parse.c"
    break;

  case 119: /* $@9: %empty  */
#line 1267 "../../../openbgpd-portable/src/bgpd/parse.y"
                     {
			curflow->type = FLOWSPEC_TYPE_DST_PORT;
			curflow->addr_type = FLOWSPEC_TYPE_DEST;
		}
#line 3848 "parse.c"
    break;

  case 125: /* ipspec: prefix  */
#line 1279 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_prefix(&(yyvsp[0].v.prefix).prefix, (yyvsp[0].v.prefix).len) == -1)
				YYERROR;
		}
#line 3857 "parse.c"
    break;

  case 130: /* port_item: port  */
#line 1293 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_unary_numop(OP_EQ, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 3866 "parse.c"
    break;

  case 131: /* port_item: unaryop port  */
#line 1297 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_unary_numop((yyvsp[-1].v.u8), (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 3875 "parse.c"
    break;

  case 132: /* port_item: port binaryop port  */
#line 1301 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_binary_numop((yyvsp[-1].v.u8), (yyvsp[-2].v.number), (yyvsp[0].v.number)))
				YYERROR;
		}
#line 3884 "parse.c"
    break;

  case 133: /* port: NUMBER  */
#line 1307 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 1 || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("port must be between %u and %u",
				    1, USHRT_MAX);
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 3897 "parse.c"
    break;

  case 134: /* port: STRING  */
#line 1315 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.number) = getservice((yyvsp[0].v.string))) == -1) {
				yyerror("unknown port '%s'", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3910 "parse.c"
    break;

  case 141: /* $@10: %empty  */
#line 1335 "../../../openbgpd-portable/src/bgpd/parse.y"
                        {
			curflow->type = FLOWSPEC_TYPE_TCP_FLAGS;
		}
#line 3918 "parse.c"
    break;

  case 143: /* $@11: %empty  */
#line 1338 "../../../openbgpd-portable/src/bgpd/parse.y"
                           {
			curflow->type = FLOWSPEC_TYPE_FRAG;
		}
#line 3926 "parse.c"
    break;

  case 146: /* flowrule: LENGTH lengthspec  */
#line 1342 "../../../openbgpd-portable/src/bgpd/parse.y"
                                    {
			curflow->type = FLOWSPEC_TYPE_PKT_LEN;
		}
#line 3934 "parse.c"
    break;

  case 148: /* flowrule: TOS tos  */
#line 1346 "../../../openbgpd-portable/src/bgpd/parse.y"
                          {
			curflow->type = FLOWSPEC_TYPE_DSCP;
			if (push_unary_numop(OP_EQ, (yyvsp[0].v.number) >> 2) == -1)
				YYERROR;
		}
#line 3944 "parse.c"
    break;

  case 149: /* flags: flag '/' flag  */
#line 1353 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyvsp[-2].v.number) & (yyvsp[0].v.number)) != (yyvsp[-2].v.number)) {
				yyerror("bad flag combination, "
				    "check bit not in mask");
				YYERROR;
			}
			if (push_binop(FLOWSPEC_OP_BIT_MATCH, (yyvsp[-2].v.number)) == -1)
				YYERROR;
			/* check if extra mask op is needed */
			if ((yyvsp[0].v.number) & ~(yyvsp[-2].v.number)) {
				if (push_binop(FLOWSPEC_OP_BIT_NOT |
				    FLOWSPEC_OP_AND, (yyvsp[0].v.number) & ~(yyvsp[-2].v.number)) == -1)
					YYERROR;
			}
		}
#line 3964 "parse.c"
    break;

  case 150: /* flags: '/' flag  */
#line 1368 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_binop(FLOWSPEC_OP_BIT_NOT, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 3973 "parse.c"
    break;

  case 151: /* flags: flag  */
#line 1372 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_binop(0, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 3982 "parse.c"
    break;

  case 153: /* flag: STRING  */
#line 1379 "../../../openbgpd-portable/src/bgpd/parse.y"
                         {
			if (((yyval.v.number) = parse_flags((yyvsp[0].v.string))) < 0) {
				yyerror("bad flags %s", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 3995 "parse.c"
    break;

  case 158: /* icmp_item: icmptype  */
#line 1397 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			curflow->type = FLOWSPEC_TYPE_ICMP_TYPE;
			if (push_unary_numop(OP_EQ, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 4005 "parse.c"
    break;

  case 159: /* icmp_item: icmptype CODE STRING  */
#line 1402 "../../../openbgpd-portable/src/bgpd/parse.y"
                                       {
			int code;

			if ((code = geticmpcodebyname((yyvsp[-2].v.number), (yyvsp[0].v.string), curflow->aid)) ==
			    -1) {
				yyerror("unknown icmp-code %s", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));

			curflow->type = FLOWSPEC_TYPE_ICMP_TYPE;
			if (push_unary_numop(OP_EQ, (yyvsp[-2].v.number)) == -1)
				YYERROR;
			curflow->type = FLOWSPEC_TYPE_ICMP_CODE;
			if (push_unary_numop(OP_EQ, code) == -1)
				YYERROR;
		}
#line 4028 "parse.c"
    break;

  case 160: /* icmp_item: icmptype CODE NUMBER  */
#line 1420 "../../../openbgpd-portable/src/bgpd/parse.y"
                                       {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 255) {
				yyerror("illegal icmp-code %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			curflow->type = FLOWSPEC_TYPE_ICMP_TYPE;
			if (push_unary_numop(OP_EQ, (yyvsp[-2].v.number)) == -1)
				YYERROR;
			curflow->type = FLOWSPEC_TYPE_ICMP_CODE;
			if (push_unary_numop(OP_EQ, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 4045 "parse.c"
    break;

  case 161: /* icmptype: STRING  */
#line 1434 "../../../openbgpd-portable/src/bgpd/parse.y"
                         {
			int type;

			if ((type = geticmptypebyname((yyvsp[0].v.string), curflow->aid)) ==
			    -1) {
				yyerror("unknown icmp-type %s", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			(yyval.v.number) = type;
			free((yyvsp[0].v.string));
		}
#line 4062 "parse.c"
    break;

  case 162: /* icmptype: NUMBER  */
#line 1446 "../../../openbgpd-portable/src/bgpd/parse.y"
                         {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 255) {
				yyerror("illegal icmp-type %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 4074 "parse.c"
    break;

  case 163: /* tos: STRING  */
#line 1455 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			int val;
			char *end;

			if (map_tos((yyvsp[0].v.string), &val))
				(yyval.v.number) = val;
			else if ((yyvsp[0].v.string)[0] == '0' && (yyvsp[0].v.string)[1] == 'x') {
				errno = 0;
				(yyval.v.number) = strtoul((yyvsp[0].v.string), &end, 16);
				if (errno || *end != '\0')
					(yyval.v.number) = 256;
			} else
				(yyval.v.number) = 256;
			if ((yyval.v.number) < 0 || (yyval.v.number) > 255) {
				yyerror("illegal tos value %s", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 4099 "parse.c"
    break;

  case 164: /* tos: NUMBER  */
#line 1475 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyval.v.number) < 0 || (yyval.v.number) > 255) {
				yyerror("illegal tos value %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 4111 "parse.c"
    break;

  case 169: /* length_item: length  */
#line 1492 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_unary_numop(OP_EQ, (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 4120 "parse.c"
    break;

  case 170: /* length_item: unaryop length  */
#line 1496 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_unary_numop((yyvsp[-1].v.u8), (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 4129 "parse.c"
    break;

  case 171: /* length_item: length binaryop length  */
#line 1500 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (push_binary_numop((yyvsp[-1].v.u8), (yyvsp[-2].v.number), (yyvsp[0].v.number)) == -1)
				YYERROR;
		}
#line 4138 "parse.c"
    break;

  case 172: /* length: NUMBER  */
#line 1506 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyval.v.number) < 0 || (yyval.v.number) > USHRT_MAX) {
				yyerror("illegal ptk length value %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 4150 "parse.c"
    break;

  case 173: /* inout: IN  */
#line 1514 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 1; }
#line 4156 "parse.c"
    break;

  case 174: /* inout: OUT  */
#line 1515 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 0; }
#line 4162 "parse.c"
    break;

  case 175: /* restricted: %empty  */
#line 1518 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 0; }
#line 4168 "parse.c"
    break;

  case 176: /* restricted: RESTRICTED  */
#line 1519 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 1; }
#line 4174 "parse.c"
    break;

  case 177: /* address: STRING  */
#line 1522 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			uint8_t	len;

			if (!host((yyvsp[0].v.string), &(yyval.v.addr), &len)) {
				yyerror("could not parse address spec \"%s\"",
				    (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));

			if (((yyval.v.addr).aid == AID_INET && len != 32) ||
			    ((yyval.v.addr).aid == AID_INET6 && len != 128)) {
				/* unreachable */
				yyerror("got prefixlen %u, expected %u",
				    len, (yyval.v.addr).aid == AID_INET ? 32 : 128);
				YYERROR;
			}
		}
#line 4198 "parse.c"
    break;

  case 178: /* prefix: STRING '/' NUMBER  */
#line 1543 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			char	*s;
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 128) {
				yyerror("bad prefixlen %lld", (yyvsp[0].v.number));
				free((yyvsp[-2].v.string));
				YYERROR;
			}
			if (asprintf(&s, "%s/%lld", (yyvsp[-2].v.string), (yyvsp[0].v.number)) == -1)
				fatal(NULL);
			free((yyvsp[-2].v.string));

			if (!host(s, &(yyval.v.prefix).prefix, &(yyval.v.prefix).len)) {
				yyerror("could not parse address \"%s\"", s);
				free(s);
				YYERROR;
			}
			free(s);
		}
#line 4221 "parse.c"
    break;

  case 179: /* prefix: NUMBER '/' NUMBER  */
#line 1561 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			char	*s;

			/* does not match IPv6 */
			if ((yyvsp[-2].v.number) < 0 || (yyvsp[-2].v.number) > 255 || (yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 32) {
				yyerror("bad prefix %lld/%lld", (yyvsp[-2].v.number), (yyvsp[0].v.number));
				YYERROR;
			}
			if (asprintf(&s, "%lld/%lld", (yyvsp[-2].v.number), (yyvsp[0].v.number)) == -1)
				fatal(NULL);

			if (!host(s, &(yyval.v.prefix).prefix, &(yyval.v.prefix).len)) {
				yyerror("could not parse address \"%s\"", s);
				free(s);
				YYERROR;
			}
			free(s);
		}
#line 4244 "parse.c"
    break;

  case 180: /* addrspec: address  */
#line 1581 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			memcpy(&(yyval.v.prefix).prefix, &(yyvsp[0].v.addr), sizeof(struct bgpd_addr));
			if ((yyval.v.prefix).prefix.aid == AID_INET)
				(yyval.v.prefix).len = 32;
			else
				(yyval.v.prefix).len = 128;
		}
#line 4256 "parse.c"
    break;

  case 182: /* optnumber: %empty  */
#line 1591 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        { (yyval.v.number) = 0; }
#line 4262 "parse.c"
    break;

  case 184: /* $@12: %empty  */
#line 1595 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			u_int rdomain, label;

			if (get_mpe_config((yyvsp[0].v.string), &rdomain, &label) == -1) {
				if ((cmd_opts & BGPD_OPT_NOACTION) == 0) {
					yyerror("troubles getting config of %s",
					    (yyvsp[0].v.string));
					free((yyvsp[0].v.string));
					free((yyvsp[-2].v.string));
					YYERROR;
				}
			}

			if (!(curvpn = calloc(1, sizeof(struct l3vpn))))
				fatal(NULL);
			strlcpy(curvpn->ifmpe, (yyvsp[0].v.string), IFNAMSIZ);

			if (strlcpy(curvpn->descr, (yyvsp[-2].v.string),
			    sizeof(curvpn->descr)) >=
			    sizeof(curvpn->descr)) {
				yyerror("descr \"%s\" too long: max %zu",
				    (yyvsp[-2].v.string), sizeof(curvpn->descr) - 1);
				free((yyvsp[-2].v.string));
				free((yyvsp[0].v.string));
				free(curvpn);
				curvpn = NULL;
				YYERROR;
			}
			free((yyvsp[-2].v.string));
			free((yyvsp[0].v.string));

			TAILQ_INIT(&curvpn->import);
			TAILQ_INIT(&curvpn->export);
			TAILQ_INIT(&curvpn->net_l);
			curvpn->label = label;
			curvpn->rtableid = rdomain;
			netconf = &curvpn->net_l;
		}
#line 4305 "parse.c"
    break;

  case 185: /* l3vpn: VPN STRING ON STRING $@12 '{' l3vpnopts_l '}'  */
#line 1632 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			/* insert into list */
			SIMPLEQ_INSERT_TAIL(&conf->l3vpns, curvpn, entry);
			curvpn = NULL;
			netconf = &conf->networks;
		}
#line 4316 "parse.c"
    break;

  case 190: /* l3vpnopts: RD STRING  */
#line 1646 "../../../openbgpd-portable/src/bgpd/parse.y"
                            {
			struct community	ext;

			memset(&ext, 0, sizeof(ext));
			if (parseextcommunity(&ext, "rt", (yyvsp[0].v.string)) == -1) {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
			/*
			 * RD is almost encoded like an ext-community,
			 * but only almost so convert here.
			 */
			if (community_to_rd(&ext, &curvpn->rd) == -1) {
				yyerror("bad encoding of rd");
				YYERROR;
			}
		}
#line 4339 "parse.c"
    break;

  case 191: /* l3vpnopts: EXPORTTRGT STRING STRING  */
#line 1664 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			struct filter_set	*set;

			if ((set = calloc(1, sizeof(struct filter_set))) ==
			    NULL)
				fatal(NULL);
			set->type = ACTION_SET_COMMUNITY;
			if (parseextcommunity(&set->action.community,
			    (yyvsp[-1].v.string), (yyvsp[0].v.string)) == -1) {
				free((yyvsp[0].v.string));
				free((yyvsp[-1].v.string));
				free(set);
				YYERROR;
			}
			free((yyvsp[0].v.string));
			free((yyvsp[-1].v.string));
			TAILQ_INSERT_TAIL(&curvpn->export, set, entry);
		}
#line 4362 "parse.c"
    break;

  case 192: /* l3vpnopts: IMPORTTRGT STRING STRING  */
#line 1682 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			struct filter_set	*set;

			if ((set = calloc(1, sizeof(struct filter_set))) ==
			    NULL)
				fatal(NULL);
			set->type = ACTION_SET_COMMUNITY;
			if (parseextcommunity(&set->action.community,
			    (yyvsp[-1].v.string), (yyvsp[0].v.string)) == -1) {
				free((yyvsp[0].v.string));
				free((yyvsp[-1].v.string));
				free(set);
				YYERROR;
			}
			free((yyvsp[0].v.string));
			free((yyvsp[-1].v.string));
			TAILQ_INSERT_TAIL(&curvpn->import, set, entry);
		}
#line 4385 "parse.c"
    break;

  case 193: /* l3vpnopts: FIBUPDATE yesno  */
#line 1700 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) == 0)
				curvpn->flags |= F_RIB_NOFIBSYNC;
			else
				curvpn->flags &= ~F_RIB_NOFIBSYNC;
		}
#line 4396 "parse.c"
    break;

  case 195: /* $@13: %empty  */
#line 1709 "../../../openbgpd-portable/src/bgpd/parse.y"
                  { curpeer = new_peer(); }
#line 4402 "parse.c"
    break;

  case 196: /* $@14: %empty  */
#line 1710 "../../../openbgpd-portable/src/bgpd/parse.y"
                                      {
			memcpy(&curpeer->conf.remote_addr, &(yyvsp[0].v.prefix).prefix,
			    sizeof(curpeer->conf.remote_addr));
			curpeer->conf.remote_masklen = (yyvsp[0].v.prefix).len;
			if (((yyvsp[0].v.prefix).prefix.aid == AID_INET && (yyvsp[0].v.prefix).len != 32) ||
			    ((yyvsp[0].v.prefix).prefix.aid == AID_INET6 && (yyvsp[0].v.prefix).len != 128))
				curpeer->conf.template = 1;
			if (get_id(curpeer)) {
				yyerror("get_id failed");
				YYERROR;
			}
		}
#line 4419 "parse.c"
    break;

  case 197: /* neighbor: $@13 NEIGHBOR addrspec $@14 peeropts_h  */
#line 1722 "../../../openbgpd-portable/src/bgpd/parse.y"
                               {
			uint8_t		aid;

			if (curpeer_filter[0] != NULL)
				TAILQ_INSERT_TAIL(peerfilter_l,
				    curpeer_filter[0], entry);
			if (curpeer_filter[1] != NULL)
				TAILQ_INSERT_TAIL(peerfilter_l,
				    curpeer_filter[1], entry);
			curpeer_filter[0] = NULL;
			curpeer_filter[1] = NULL;

			/*
			 * Check if any MP capa is set, if none is set and
			 * and the default AID was not disabled via none then
			 * enable it. Finally fixup the disabled AID.
			 */
			for (aid = AID_MIN; aid < AID_MAX; aid++) {
				if (curpeer->conf.capabilities.mp[aid] > 0)
					break;
			}
			if (aid == AID_MAX &&
			    curpeer->conf.capabilities.mp[
			    curpeer->conf.remote_addr.aid] != -1)
				curpeer->conf.capabilities.mp[
				    curpeer->conf.remote_addr.aid] = 1;
			for (aid = AID_MIN; aid < AID_MAX; aid++) {
				if (curpeer->conf.capabilities.mp[aid] == -1)
					curpeer->conf.capabilities.mp[aid] = 0;
			}

			if (neighbor_consistent(curpeer) == -1) {
				free(curpeer);
				YYERROR;
			}
			if (RB_INSERT(peer_head, new_peers, curpeer) != NULL)
				fatalx("%s: peer tree is corrupt", __func__);
			curpeer = curgroup;
		}
#line 4463 "parse.c"
    break;

  case 198: /* $@15: %empty  */
#line 1763 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			curgroup = curpeer = new_group();
			if (strlcpy(curgroup->conf.group, (yyvsp[0].v.string),
			    sizeof(curgroup->conf.group)) >=
			    sizeof(curgroup->conf.group)) {
				yyerror("group name \"%s\" too long: max %zu",
				    (yyvsp[0].v.string), sizeof(curgroup->conf.group) - 1);
				free((yyvsp[0].v.string));
				free(curgroup);
				YYERROR;
			}
			free((yyvsp[0].v.string));
			if (get_id(curgroup)) {
				yyerror("get_id failed");
				free(curgroup);
				YYERROR;
			}
		}
#line 4486 "parse.c"
    break;

  case 199: /* group: GROUP string $@15 '{' groupopts_l '}'  */
#line 1780 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (curgroup_filter[0] != NULL)
				TAILQ_INSERT_TAIL(groupfilter_l,
				    curgroup_filter[0], entry);
			if (curgroup_filter[1] != NULL)
				TAILQ_INSERT_TAIL(groupfilter_l,
				    curgroup_filter[1], entry);
			curgroup_filter[0] = NULL;
			curgroup_filter[1] = NULL;

			free(curgroup);
			curgroup = NULL;
		}
#line 4504 "parse.c"
    break;

  case 205: /* addpathextra: %empty  */
#line 1802 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        { (yyval.v.number) = 0; }
#line 4510 "parse.c"
    break;

  case 206: /* addpathextra: PLUS NUMBER  */
#line 1803 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < 1 || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("additional paths must be between "
				    "%u and %u", 1, USHRT_MAX);
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 4523 "parse.c"
    break;

  case 207: /* addpathmax: %empty  */
#line 1813 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        { (yyval.v.number) = 0; }
#line 4529 "parse.c"
    break;

  case 208: /* addpathmax: MAX NUMBER  */
#line 1814 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < 1 || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("maximum additional paths must be "
				    "between %u and %u", 1, USHRT_MAX);
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 4542 "parse.c"
    break;

  case 216: /* peeropts: REMOTEAS as4number  */
#line 1835 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			curpeer->conf.remote_as = (yyvsp[0].v.number);
		}
#line 4550 "parse.c"
    break;

  case 217: /* peeropts: LOCALAS as4number  */
#line 1838 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			curpeer->conf.local_as = (yyvsp[0].v.number);
			if ((yyvsp[0].v.number) > USHRT_MAX)
				curpeer->conf.local_short_as = AS_TRANS;
			else
				curpeer->conf.local_short_as = (yyvsp[0].v.number);
		}
#line 4562 "parse.c"
    break;

  case 218: /* peeropts: LOCALAS as4number asnumber  */
#line 1845 "../../../openbgpd-portable/src/bgpd/parse.y"
                                             {
			curpeer->conf.local_as = (yyvsp[-1].v.number);
			curpeer->conf.local_short_as = (yyvsp[0].v.number);
		}
#line 4571 "parse.c"
    break;

  case 219: /* peeropts: DESCR string  */
#line 1849 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (strlcpy(curpeer->conf.descr, (yyvsp[0].v.string),
			    sizeof(curpeer->conf.descr)) >=
			    sizeof(curpeer->conf.descr)) {
				yyerror("descr \"%s\" too long: max %zu",
				    (yyvsp[0].v.string), sizeof(curpeer->conf.descr) - 1);
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 4587 "parse.c"
    break;

  case 220: /* peeropts: LOCALADDR address  */
#line 1860 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.addr).aid == AID_INET)
				memcpy(&curpeer->conf.local_addr_v4, &(yyvsp[0].v.addr),
				    sizeof(curpeer->conf.local_addr_v4));
			else if ((yyvsp[0].v.addr).aid == AID_INET6)
				memcpy(&curpeer->conf.local_addr_v6, &(yyvsp[0].v.addr),
				    sizeof(curpeer->conf.local_addr_v6));
			else {
				yyerror("Unsupported address family %s for "
				    "local-addr", aid2str((yyvsp[0].v.addr).aid));
				YYERROR;
			}
		}
#line 4605 "parse.c"
    break;

  case 221: /* peeropts: yesno LOCALADDR  */
#line 1873 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[-1].v.number)) {
				yyerror("bad local-address definition");
				YYERROR;
			}
			memset(&curpeer->conf.local_addr_v4, 0,
			    sizeof(curpeer->conf.local_addr_v4));
			memset(&curpeer->conf.local_addr_v6, 0,
			    sizeof(curpeer->conf.local_addr_v6));
		}
#line 4620 "parse.c"
    break;

  case 222: /* peeropts: MULTIHOP NUMBER  */
#line 1883 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < 2 || (yyvsp[0].v.number) > 255) {
				yyerror("invalid multihop distance %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			curpeer->conf.distance = (yyvsp[0].v.number);
		}
#line 4632 "parse.c"
    break;

  case 223: /* peeropts: PASSIVE  */
#line 1890 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			curpeer->conf.passive = 1;
		}
#line 4640 "parse.c"
    break;

  case 224: /* peeropts: DOWN  */
#line 1893 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			curpeer->conf.down = 1;
		}
#line 4648 "parse.c"
    break;

  case 225: /* peeropts: DOWN STRING  */
#line 1896 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			curpeer->conf.down = 1;
			if (strlcpy(curpeer->conf.reason, (yyvsp[0].v.string),
				sizeof(curpeer->conf.reason)) >=
				sizeof(curpeer->conf.reason)) {
				    yyerror("shutdown reason too long");
				    free((yyvsp[0].v.string));
				    YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 4664 "parse.c"
    break;

  case 226: /* peeropts: RIB STRING  */
#line 1907 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (!find_rib((yyvsp[0].v.string))) {
				yyerror("rib \"%s\" does not exist.", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (strlcpy(curpeer->conf.rib, (yyvsp[0].v.string),
			    sizeof(curpeer->conf.rib)) >=
			    sizeof(curpeer->conf.rib)) {
				yyerror("rib name \"%s\" too long: max %zu",
				    (yyvsp[0].v.string), sizeof(curpeer->conf.rib) - 1);
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 4685 "parse.c"
    break;

  case 227: /* peeropts: HOLDTIME NUMBER  */
#line 1923 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < MIN_HOLDTIME || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("holdtime must be between %u and %u",
				    MIN_HOLDTIME, USHRT_MAX);
				YYERROR;
			}
			curpeer->conf.holdtime = (yyvsp[0].v.number);
		}
#line 4698 "parse.c"
    break;

  case 228: /* peeropts: HOLDTIME YMIN NUMBER  */
#line 1931 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < MIN_HOLDTIME || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("holdtime must be between %u and %u",
				    MIN_HOLDTIME, USHRT_MAX);
				YYERROR;
			}
			curpeer->conf.min_holdtime = (yyvsp[0].v.number);
		}
#line 4711 "parse.c"
    break;

  case 229: /* peeropts: STALETIME NUMBER  */
#line 1939 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < MIN_HOLDTIME || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("staletime must be between %u and %u",
				    MIN_HOLDTIME, USHRT_MAX);
				YYERROR;
			}
			curpeer->conf.staletime = (yyvsp[0].v.number);
		}
#line 4724 "parse.c"
    break;

  case 230: /* peeropts: ANNOUNCE af safi enforce  */
#line 1947 "../../../openbgpd-portable/src/bgpd/parse.y"
                                           {
			uint8_t		aid, safi;
			uint16_t	afi;

			if ((yyvsp[-1].v.number) == SAFI_NONE) {
				for (aid = AID_MIN; aid < AID_MAX; aid++) {
					if (aid2afi(aid, &afi, &safi) == -1 ||
					    afi != (yyvsp[-2].v.number))
						continue;
					curpeer->conf.capabilities.mp[aid] = -1;
				}
			} else {
				if (afi2aid((yyvsp[-2].v.number), (yyvsp[-1].v.number), &aid) == -1) {
					yyerror("unknown AFI/SAFI pair");
					YYERROR;
				}
				if ((yyvsp[0].v.number))
					curpeer->conf.capabilities.mp[aid] = 2;
				else
					curpeer->conf.capabilities.mp[aid] = 1;
			}
		}
#line 4751 "parse.c"
    break;

  case 231: /* peeropts: ANNOUNCE EVPN enforce  */
#line 1969 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number))
				curpeer->conf.capabilities.mp[AID_EVPN] = 2;
			else
				curpeer->conf.capabilities.mp[AID_EVPN] = 1;
		}
#line 4762 "parse.c"
    break;

  case 232: /* peeropts: ANNOUNCE REFRESH yesnoenforce  */
#line 1975 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			curpeer->conf.capabilities.refresh = (yyvsp[0].v.number);
		}
#line 4770 "parse.c"
    break;

  case 233: /* peeropts: ANNOUNCE ENHANCED REFRESH yesnoenforce  */
#line 1978 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                         {
			curpeer->conf.capabilities.enhanced_rr = (yyvsp[0].v.number);
		}
#line 4778 "parse.c"
    break;

  case 234: /* peeropts: ANNOUNCE RESTART yesnoenforce  */
#line 1981 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			curpeer->conf.capabilities.grestart.restart = (yyvsp[0].v.number);
		}
#line 4786 "parse.c"
    break;

  case 235: /* peeropts: ANNOUNCE GRACEFUL NOTIFICATION yesno  */
#line 1984 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                       {
			curpeer->conf.capabilities.grestart.grnotification = (yyvsp[0].v.number);
		}
#line 4794 "parse.c"
    break;

  case 236: /* peeropts: ANNOUNCE AS4BYTE yesnoenforce  */
#line 1987 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			curpeer->conf.capabilities.as4byte = (yyvsp[0].v.number);
		}
#line 4802 "parse.c"
    break;

  case 237: /* peeropts: ANNOUNCE ADDPATH RECV yesnoenforce  */
#line 1990 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                     {
			int8_t *ap = curpeer->conf.capabilities.add_path;
			uint8_t i;

			for (i = AID_MIN; i < AID_MAX; i++) {
				if ((yyvsp[0].v.number)) {
					if ((yyvsp[0].v.number) == 2)
						ap[i] |= CAPA_AP_RECV_ENFORCE;
					ap[i] |= CAPA_AP_RECV;
				} else
					ap[i] &= ~CAPA_AP_RECV;
			}
		}
#line 4820 "parse.c"
    break;

  case 238: /* peeropts: ANNOUNCE ADDPATH SEND STRING addpathextra addpathmax enforce  */
#line 2003 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                               {
			int8_t *ap = curpeer->conf.capabilities.add_path;
			enum addpath_mode mode;
			u_int8_t i;

			if (!strcmp((yyvsp[-3].v.string), "no")) {
				free((yyvsp[-3].v.string));
				if ((yyvsp[-2].v.number) != 0 || (yyvsp[-1].v.number) != 0 || (yyvsp[0].v.number) != 0) {
					yyerror("no additional option allowed "
					    "for 'add-path send no'");
					YYERROR;
				}
				mode = ADDPATH_EVAL_NONE;
			} else if (!strcmp((yyvsp[-3].v.string), "all")) {
				free((yyvsp[-3].v.string));
				if ((yyvsp[-2].v.number) != 0 || (yyvsp[-1].v.number) != 0) {
					yyerror("no additional option allowed "
					    "for 'add-path send all'");
					YYERROR;
				}
				mode = ADDPATH_EVAL_ALL;
			} else if (!strcmp((yyvsp[-3].v.string), "best")) {
				free((yyvsp[-3].v.string));
				mode = ADDPATH_EVAL_BEST;
			} else if (!strcmp((yyvsp[-3].v.string), "ecmp")) {
				free((yyvsp[-3].v.string));
				mode = ADDPATH_EVAL_ECMP;
			} else if (!strcmp((yyvsp[-3].v.string), "as-wide-best")) {
				free((yyvsp[-3].v.string));
				mode = ADDPATH_EVAL_AS_WIDE;
			} else {
				yyerror("announce add-path send: "
				    "unknown mode \"%s\"", (yyvsp[-3].v.string));
				free((yyvsp[-3].v.string));
				YYERROR;
			}
			for (i = AID_MIN; i < AID_MAX; i++) {
				if (mode != ADDPATH_EVAL_NONE) {
					if ((yyvsp[0].v.number))
						ap[i] |= CAPA_AP_SEND_ENFORCE;
					ap[i] |= CAPA_AP_SEND;
				} else
					ap[i] &= ~CAPA_AP_SEND;
			}
			curpeer->conf.eval.mode = mode;
			curpeer->conf.eval.extrapaths = (yyvsp[-2].v.number);
			curpeer->conf.eval.maxpaths = (yyvsp[-1].v.number);
		}
#line 4873 "parse.c"
    break;

  case 239: /* peeropts: ANNOUNCE POLICY yesnoenforce  */
#line 2051 "../../../openbgpd-portable/src/bgpd/parse.y"
                                               {
			curpeer->conf.capabilities.policy = (yyvsp[0].v.number);
		}
#line 4881 "parse.c"
    break;

  case 240: /* peeropts: ANNOUNCE EXTENDED MESSAGE yesnoenforce  */
#line 2054 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                         {
			curpeer->conf.capabilities.ext_msg = (yyvsp[0].v.number);
		}
#line 4889 "parse.c"
    break;

  case 241: /* peeropts: ANNOUNCE EXTENDED NEXTHOP yesnoenforce  */
#line 2057 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                         {
			curpeer->conf.capabilities.ext_nh[AID_VPN_IPv4] =
			    curpeer->conf.capabilities.ext_nh[AID_INET] = (yyvsp[0].v.number);
		}
#line 4898 "parse.c"
    break;

  case 242: /* peeropts: ROLE STRING  */
#line 2061 "../../../openbgpd-portable/src/bgpd/parse.y"
                              {
			if (strcmp((yyvsp[0].v.string), "provider") == 0) {
				curpeer->conf.role = ROLE_PROVIDER;
			} else if (strcmp((yyvsp[0].v.string), "rs") == 0) {
				curpeer->conf.role = ROLE_RS;
			} else if (strcmp((yyvsp[0].v.string), "rs-client") == 0) {
				curpeer->conf.role = ROLE_RS_CLIENT;
			} else if (strcmp((yyvsp[0].v.string), "customer") == 0) {
				curpeer->conf.role = ROLE_CUSTOMER;
			} else if (strcmp((yyvsp[0].v.string), "peer") == 0) {
				curpeer->conf.role = ROLE_PEER;
			} else {
				yyerror("syntax error, one of none, provider, "
				    "rs, rs-client, customer, peer expected");
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 4922 "parse.c"
    break;

  case 243: /* peeropts: ROLE NONE  */
#line 2080 "../../../openbgpd-portable/src/bgpd/parse.y"
                            {
			curpeer->conf.role = ROLE_NONE;
		}
#line 4930 "parse.c"
    break;

  case 244: /* peeropts: EXPORT NONE  */
#line 2083 "../../../openbgpd-portable/src/bgpd/parse.y"
                              {
			curpeer->conf.export_type = EXPORT_NONE;
		}
#line 4938 "parse.c"
    break;

  case 245: /* peeropts: EXPORT DEFAULTROUTE  */
#line 2086 "../../../openbgpd-portable/src/bgpd/parse.y"
                                      {
			curpeer->conf.export_type = EXPORT_DEFAULT_ROUTE;
		}
#line 4946 "parse.c"
    break;

  case 246: /* peeropts: ENFORCE NEIGHBORAS yesno  */
#line 2089 "../../../openbgpd-portable/src/bgpd/parse.y"
                                           {
			if ((yyvsp[0].v.number))
				curpeer->conf.enforce_as = ENFORCE_AS_ON;
			else
				curpeer->conf.enforce_as = ENFORCE_AS_OFF;
		}
#line 4957 "parse.c"
    break;

  case 247: /* peeropts: ENFORCE LOCALAS yesno  */
#line 2095 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number))
				curpeer->conf.enforce_local_as = ENFORCE_AS_ON;
			else
				curpeer->conf.enforce_local_as = ENFORCE_AS_OFF;
		}
#line 4968 "parse.c"
    break;

  case 248: /* peeropts: ASOVERRIDE yesno  */
#line 2101 "../../../openbgpd-portable/src/bgpd/parse.y"
                                   {
			if ((yyvsp[0].v.number)) {
				struct filter_rule	*r;
				struct filter_set	*s;

				if ((s = calloc(1, sizeof(struct filter_set)))
				    == NULL)
					fatal(NULL);
				s->type = ACTION_SET_AS_OVERRIDE;

				r = get_rule(s->type);
				if (merge_filterset(&r->set, s) == -1)
					YYERROR;
			}
		}
#line 4988 "parse.c"
    break;

  case 249: /* peeropts: MAXPREFIX NUMBER restart  */
#line 2116 "../../../openbgpd-portable/src/bgpd/parse.y"
                                           {
			if ((yyvsp[-1].v.number) < 0 || (yyvsp[-1].v.number) > UINT_MAX) {
				yyerror("bad maximum number of prefixes");
				YYERROR;
			}
			curpeer->conf.max_prefix = (yyvsp[-1].v.number);
			curpeer->conf.max_prefix_restart = (yyvsp[0].v.number);
		}
#line 5001 "parse.c"
    break;

  case 250: /* peeropts: MAXPREFIX NUMBER OUT restart  */
#line 2124 "../../../openbgpd-portable/src/bgpd/parse.y"
                                               {
			if ((yyvsp[-2].v.number) < 0 || (yyvsp[-2].v.number) > UINT_MAX) {
				yyerror("bad maximum number of prefixes");
				YYERROR;
			}
			curpeer->conf.max_out_prefix = (yyvsp[-2].v.number);
			curpeer->conf.max_out_prefix_restart = (yyvsp[0].v.number);
		}
#line 5014 "parse.c"
    break;

  case 251: /* peeropts: authconf  */
#line 2132 "../../../openbgpd-portable/src/bgpd/parse.y"
                           {
			if (merge_auth_conf(&curpeer->auth_conf, &(yyvsp[0].v.authconf)) == 0)
				YYERROR;
		}
#line 5023 "parse.c"
    break;

  case 252: /* peeropts: TTLSECURITY yesno  */
#line 2136 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			curpeer->conf.ttlsec = (yyvsp[0].v.number);
		}
#line 5031 "parse.c"
    break;

  case 253: /* peeropts: SET filter_set_opt  */
#line 2139 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			struct filter_rule	*r;

			r = get_rule((yyvsp[0].v.filter_set)->type);
			if (merge_filterset(&r->set, (yyvsp[0].v.filter_set)) == -1)
				YYERROR;
		}
#line 5043 "parse.c"
    break;

  case 254: /* peeropts: SET '{' optnl filter_set_l optnl '}'  */
#line 2146 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct filter_rule	*r;
			struct filter_set	*s;

			while ((s = TAILQ_FIRST((yyvsp[-2].v.filter_set_head))) != NULL) {
				TAILQ_REMOVE((yyvsp[-2].v.filter_set_head), s, entry);
				r = get_rule(s->type);
				if (merge_filterset(&r->set, s) == -1)
					YYERROR;
			}
			free((yyvsp[-2].v.filter_set_head));
		}
#line 5060 "parse.c"
    break;

  case 256: /* peeropts: REFLECTOR  */
#line 2159 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((conf->flags & BGPD_FLAG_REFLECTOR) &&
			    conf->clusterid != 0) {
				yyerror("only one route reflector "
				    "cluster allowed");
				YYERROR;
			}
			conf->flags |= BGPD_FLAG_REFLECTOR;
			curpeer->conf.reflector_client = 1;
		}
#line 5075 "parse.c"
    break;

  case 257: /* peeropts: REFLECTOR address  */
#line 2169 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.addr).aid != AID_INET) {
				yyerror("route reflector cluster-id must be "
				    "an IPv4 address");
				YYERROR;
			}
			if ((conf->flags & BGPD_FLAG_REFLECTOR) &&
			    conf->clusterid != ntohl((yyvsp[0].v.addr).v4.s_addr)) {
				yyerror("only one route reflector "
				    "cluster allowed");
				YYERROR;
			}
			conf->flags |= BGPD_FLAG_REFLECTOR;
			curpeer->conf.reflector_client = 1;
			conf->clusterid = ntohl((yyvsp[0].v.addr).v4.s_addr);
		}
#line 5096 "parse.c"
    break;

  case 258: /* peeropts: DEPEND ON STRING  */
#line 2185 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (strlcpy(curpeer->conf.if_depend, (yyvsp[0].v.string),
			    sizeof(curpeer->conf.if_depend)) >=
			    sizeof(curpeer->conf.if_depend)) {
				yyerror("interface name \"%s\" too long: "
				    "max %zu", (yyvsp[0].v.string),
				    sizeof(curpeer->conf.if_depend) - 1);
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 5113 "parse.c"
    break;

  case 259: /* peeropts: DEMOTE STRING  */
#line 2197 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
#ifdef HAVE_CARP
			if (strlcpy(curpeer->conf.demote_group, (yyvsp[0].v.string),
			    sizeof(curpeer->conf.demote_group)) >=
			    sizeof(curpeer->conf.demote_group)) {
				yyerror("demote group name \"%s\" too long: "
				    "max %zu", (yyvsp[0].v.string),
				    sizeof(curpeer->conf.demote_group) - 1);
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
			if (carp_demote_init(curpeer->conf.demote_group,
			    cmd_opts & BGPD_OPT_FORCE_DEMOTE) == -1) {
				yyerror("error initializing group \"%s\"",
				    curpeer->conf.demote_group);
				YYERROR;
			}
#else
			yyerror("carp demote not supported");
			free((yyvsp[0].v.string));
			YYERROR;
#endif
		}
#line 5142 "parse.c"
    break;

  case 260: /* peeropts: TRANSPARENT yesno  */
#line 2221 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) == 1)
				curpeer->conf.flags |= PEERFLAG_TRANS_AS;
			else
				curpeer->conf.flags &= ~PEERFLAG_TRANS_AS;
		}
#line 5153 "parse.c"
    break;

  case 261: /* peeropts: LOG STRING  */
#line 2227 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (!strcmp((yyvsp[0].v.string), "updates"))
				curpeer->conf.flags |= PEERFLAG_LOG_UPDATES;
			else if (!strcmp((yyvsp[0].v.string), "no"))
				curpeer->conf.flags &= ~PEERFLAG_LOG_UPDATES;
			else {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 5169 "parse.c"
    break;

  case 262: /* peeropts: REJECT ASSET yesno  */
#line 2238 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) == 1)
				curpeer->conf.flags &= ~PEERFLAG_PERMIT_AS_SET;
			else
				curpeer->conf.flags |= PEERFLAG_PERMIT_AS_SET;
		}
#line 5180 "parse.c"
    break;

  case 263: /* peeropts: PORT port  */
#line 2244 "../../../openbgpd-portable/src/bgpd/parse.y"
                            {
			curpeer->conf.remote_port = (yyvsp[0].v.number);
		}
#line 5188 "parse.c"
    break;

  case 264: /* peeropts: RDE EVALUATE STRING  */
#line 2247 "../../../openbgpd-portable/src/bgpd/parse.y"
                                      {
			if (!strcmp((yyvsp[0].v.string), "all"))
				curpeer->conf.flags |= PEERFLAG_EVALUATE_ALL;
			else if (!strcmp((yyvsp[0].v.string), "default"))
				curpeer->conf.flags &= ~PEERFLAG_EVALUATE_ALL;
			else {
				yyerror("rde evaluate: "
				    "unknown setting \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 5206 "parse.c"
    break;

  case 265: /* restart: %empty  */
#line 2262 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        { (yyval.v.number) = 0; }
#line 5212 "parse.c"
    break;

  case 266: /* restart: RESTART NUMBER  */
#line 2263 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < 1 || (yyvsp[0].v.number) > USHRT_MAX) {
				yyerror("restart out of range. 1 to %u minutes",
				    USHRT_MAX);
				YYERROR;
			}
			(yyval.v.number) = (yyvsp[0].v.number);
		}
#line 5225 "parse.c"
    break;

  case 267: /* af: IPV4  */
#line 2273 "../../../openbgpd-portable/src/bgpd/parse.y"
                        { (yyval.v.number) = AFI_IPv4; }
#line 5231 "parse.c"
    break;

  case 268: /* af: IPV6  */
#line 2274 "../../../openbgpd-portable/src/bgpd/parse.y"
                        { (yyval.v.number) = AFI_IPv6; }
#line 5237 "parse.c"
    break;

  case 269: /* safi: NONE  */
#line 2277 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = SAFI_NONE; }
#line 5243 "parse.c"
    break;

  case 270: /* safi: UNICAST  */
#line 2278 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = SAFI_UNICAST; }
#line 5249 "parse.c"
    break;

  case 271: /* safi: VPN  */
#line 2279 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = SAFI_MPLSVPN; }
#line 5255 "parse.c"
    break;

  case 272: /* safi: FLOWSPEC  */
#line 2280 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = SAFI_FLOWSPEC; }
#line 5261 "parse.c"
    break;

  case 273: /* nettype: STATIC  */
#line 2283 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 1; }
#line 5267 "parse.c"
    break;

  case 274: /* nettype: CONNECTED  */
#line 2284 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 0; }
#line 5273 "parse.c"
    break;

  case 275: /* authconf: TCP MD5SIG PASSWORD string  */
#line 2287 "../../../openbgpd-portable/src/bgpd/parse.y"
                                             {
			memset(&(yyval.v.authconf), 0, sizeof((yyval.v.authconf)));
			if (strlcpy((yyval.v.authconf).md5key, (yyvsp[0].v.string), sizeof((yyval.v.authconf).md5key)) >=
			    sizeof((yyval.v.authconf).md5key)) {
				yyerror("tcp md5sig password too long: max %zu",
				    sizeof((yyval.v.authconf).md5key) - 1);
				free((yyvsp[0].v.string));
				YYERROR;
			}
			(yyval.v.authconf).method = AUTH_MD5SIG;
			(yyval.v.authconf).md5key_len = strlen((yyvsp[0].v.string));
			free((yyvsp[0].v.string));
		}
#line 5291 "parse.c"
    break;

  case 276: /* authconf: TCP MD5SIG KEY string  */
#line 2300 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			memset(&(yyval.v.authconf), 0, sizeof((yyval.v.authconf)));
			if (str2key((yyvsp[0].v.string), (yyval.v.authconf).md5key, sizeof((yyval.v.authconf).md5key)) == -1) {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			(yyval.v.authconf).method = AUTH_MD5SIG;
			(yyval.v.authconf).md5key_len = strlen((yyvsp[0].v.string)) / 2;
			free((yyvsp[0].v.string));
		}
#line 5306 "parse.c"
    break;

  case 277: /* authconf: IPSEC espah IKE  */
#line 2310 "../../../openbgpd-portable/src/bgpd/parse.y"
                                  {
			memset(&(yyval.v.authconf), 0, sizeof((yyval.v.authconf)));
			if ((yyvsp[-1].v.number))
				(yyval.v.authconf).method = AUTH_IPSEC_IKE_ESP;
			else
				(yyval.v.authconf).method = AUTH_IPSEC_IKE_AH;
		}
#line 5318 "parse.c"
    break;

  case 278: /* authconf: IPSEC espah inout SPI NUMBER STRING STRING encspec  */
#line 2317 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                     {
			enum auth_alg	auth_alg;
			uint8_t		keylen;

			memset(&(yyval.v.authconf), 0, sizeof((yyval.v.authconf)));
			if (!strcmp((yyvsp[-2].v.string), "sha1")) {
				auth_alg = AUTH_AALG_SHA1HMAC;
				keylen = 20;
			} else if (!strcmp((yyvsp[-2].v.string), "md5")) {
				auth_alg = AUTH_AALG_MD5HMAC;
				keylen = 16;
			} else {
				yyerror("unknown auth algorithm \"%s\"", (yyvsp[-2].v.string));
				free((yyvsp[-2].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			free((yyvsp[-2].v.string));

			if (strlen((yyvsp[-1].v.string)) / 2 != keylen) {
				yyerror("auth key len: must be %u bytes, "
				    "is %zu bytes", keylen, strlen((yyvsp[-1].v.string)) / 2);
				free((yyvsp[-1].v.string));
				YYERROR;
			}

			if ((yyvsp[-6].v.number))
				(yyval.v.authconf).method = AUTH_IPSEC_MANUAL_ESP;
			else {
				if ((yyvsp[0].v.encspec).enc_alg) {
					yyerror("\"ipsec ah\" doesn't take "
					    "encryption keys");
					free((yyvsp[-1].v.string));
					YYERROR;
				}
				(yyval.v.authconf).method = AUTH_IPSEC_MANUAL_AH;
			}

			if ((yyvsp[-3].v.number) <= SPI_RESERVED_MAX || (yyvsp[-3].v.number) > UINT_MAX) {
				yyerror("bad spi number %lld", (yyvsp[-3].v.number));
				free((yyvsp[-1].v.string));
				YYERROR;
			}

			if ((yyvsp[-5].v.number) == 1) {
				if (str2key((yyvsp[-1].v.string), (yyval.v.authconf).auth_key_in,
				    sizeof((yyval.v.authconf).auth_key_in)) == -1) {
					free((yyvsp[-1].v.string));
					YYERROR;
				}
				(yyval.v.authconf).spi_in = (yyvsp[-3].v.number);
				(yyval.v.authconf).auth_alg_in = auth_alg;
				(yyval.v.authconf).enc_alg_in = (yyvsp[0].v.encspec).enc_alg;
				memcpy(&(yyval.v.authconf).enc_key_in, &(yyvsp[0].v.encspec).enc_key,
				    sizeof((yyval.v.authconf).enc_key_in));
				(yyval.v.authconf).enc_keylen_in = (yyvsp[0].v.encspec).enc_key_len;
				(yyval.v.authconf).auth_keylen_in = keylen;
			} else {
				if (str2key((yyvsp[-1].v.string), (yyval.v.authconf).auth_key_out,
				    sizeof((yyval.v.authconf).auth_key_out)) == -1) {
					free((yyvsp[-1].v.string));
					YYERROR;
				}
				(yyval.v.authconf).spi_out = (yyvsp[-3].v.number);
				(yyval.v.authconf).auth_alg_out = auth_alg;
				(yyval.v.authconf).enc_alg_out = (yyvsp[0].v.encspec).enc_alg;
				memcpy(&(yyval.v.authconf).enc_key_out, &(yyvsp[0].v.encspec).enc_key,
				    sizeof((yyval.v.authconf).enc_key_out));
				(yyval.v.authconf).enc_keylen_out = (yyvsp[0].v.encspec).enc_key_len;
				(yyval.v.authconf).auth_keylen_out = keylen;
			}
			free((yyvsp[-1].v.string));
		}
#line 5396 "parse.c"
    break;

  case 279: /* espah: ESP  */
#line 2392 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 1; }
#line 5402 "parse.c"
    break;

  case 280: /* espah: AH  */
#line 2393 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 0; }
#line 5408 "parse.c"
    break;

  case 281: /* encspec: %empty  */
#line 2396 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			memset(&(yyval.v.encspec), 0, sizeof((yyval.v.encspec)));
		}
#line 5416 "parse.c"
    break;

  case 282: /* encspec: STRING STRING  */
#line 2399 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			memset(&(yyval.v.encspec), 0, sizeof((yyval.v.encspec)));
			if (!strcmp((yyvsp[-1].v.string), "3des") || !strcmp((yyvsp[-1].v.string), "3des-cbc")) {
				(yyval.v.encspec).enc_alg = AUTH_EALG_3DESCBC;
				(yyval.v.encspec).enc_key_len = 21; /* XXX verify */
			} else if (!strcmp((yyvsp[-1].v.string), "aes") ||
			    !strcmp((yyvsp[-1].v.string), "aes-128-cbc")) {
				(yyval.v.encspec).enc_alg = AUTH_EALG_AES;
				(yyval.v.encspec).enc_key_len = 16;
			} else {
				yyerror("unknown enc algorithm \"%s\"", (yyvsp[-1].v.string));
				free((yyvsp[-1].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[-1].v.string));

			if (strlen((yyvsp[0].v.string)) / 2 != (yyval.v.encspec).enc_key_len) {
				yyerror("enc key length wrong: should be %u "
				    "bytes, is %zu bytes",
				    (yyval.v.encspec).enc_key_len * 2, strlen((yyvsp[0].v.string)));
				free((yyvsp[0].v.string));
				YYERROR;
			}

			if (str2key((yyvsp[0].v.string), (yyval.v.encspec).enc_key, sizeof((yyval.v.encspec).enc_key)) == -1) {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 5452 "parse.c"
    break;

  case 283: /* filterrule: action quick filter_rib_h direction filter_peer_h filter_match_h filter_set  */
#line 2434 "../../../openbgpd-portable/src/bgpd/parse.y"
                {
			struct filter_rule	 r;
			struct filter_rib_l	 *rb, *rbnext;

			memset(&r, 0, sizeof(r));
			r.action = (yyvsp[-6].v.u8);
			r.quick = (yyvsp[-5].v.u8);
			r.dir = (yyvsp[-3].v.u8);
			if ((yyvsp[-4].v.filter_rib)) {
				if (r.dir != DIR_IN) {
					yyerror("rib only allowed on \"from\" "
					    "rules.");

					for (rb = (yyvsp[-4].v.filter_rib); rb != NULL; rb = rbnext) {
						rbnext = rb->next;
						free(rb);
					}
					YYERROR;
				}
			}
			if (expand_rule(&r, (yyvsp[-4].v.filter_rib), (yyvsp[-2].v.filter_peers), &(yyvsp[-1].v.filter_match), (yyvsp[0].v.filter_set_head)) == -1)
				YYERROR;
		}
#line 5480 "parse.c"
    break;

  case 284: /* action: ALLOW  */
#line 2459 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = ACTION_ALLOW; }
#line 5486 "parse.c"
    break;

  case 285: /* action: DENY  */
#line 2460 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = ACTION_DENY; }
#line 5492 "parse.c"
    break;

  case 286: /* action: MATCH  */
#line 2461 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = ACTION_NONE; }
#line 5498 "parse.c"
    break;

  case 287: /* quick: %empty  */
#line 2464 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = 0; }
#line 5504 "parse.c"
    break;

  case 288: /* quick: QUICK  */
#line 2465 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = 1; }
#line 5510 "parse.c"
    break;

  case 289: /* direction: FROM  */
#line 2468 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = DIR_IN; }
#line 5516 "parse.c"
    break;

  case 290: /* direction: TO  */
#line 2469 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = DIR_OUT; }
#line 5522 "parse.c"
    break;

  case 291: /* filter_rib_h: %empty  */
#line 2472 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { (yyval.v.filter_rib) = NULL; }
#line 5528 "parse.c"
    break;

  case 292: /* filter_rib_h: RIB filter_rib  */
#line 2473 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { (yyval.v.filter_rib) = (yyvsp[0].v.filter_rib); }
#line 5534 "parse.c"
    break;

  case 293: /* filter_rib_h: RIB '{' optnl filter_rib_l optnl '}'  */
#line 2474 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_rib) = (yyvsp[-2].v.filter_rib); }
#line 5540 "parse.c"
    break;

  case 294: /* filter_rib_l: filter_rib  */
#line 2476 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { (yyval.v.filter_rib) = (yyvsp[0].v.filter_rib); }
#line 5546 "parse.c"
    break;

  case 295: /* filter_rib_l: filter_rib_l comma filter_rib  */
#line 2477 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			(yyvsp[0].v.filter_rib)->next = (yyvsp[-2].v.filter_rib);
			(yyval.v.filter_rib) = (yyvsp[0].v.filter_rib);
		}
#line 5555 "parse.c"
    break;

  case 296: /* filter_rib: STRING  */
#line 2483 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (!find_rib((yyvsp[0].v.string))) {
				yyerror("rib \"%s\" does not exist.", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (((yyval.v.filter_rib) = calloc(1, sizeof(struct filter_rib_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_rib)->next = NULL;
			if (strlcpy((yyval.v.filter_rib)->name, (yyvsp[0].v.string), sizeof((yyval.v.filter_rib)->name)) >=
			    sizeof((yyval.v.filter_rib)->name)) {
				yyerror("rib name \"%s\" too long: "
				    "max %zu", (yyvsp[0].v.string), sizeof((yyval.v.filter_rib)->name) - 1);
				free((yyvsp[0].v.string));
				free((yyval.v.filter_rib));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 5580 "parse.c"
    break;

  case 298: /* filter_peer_h: '{' optnl filter_peer_l optnl '}'  */
#line 2506 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_peers) = (yyvsp[-2].v.filter_peers); }
#line 5586 "parse.c"
    break;

  case 299: /* filter_peer_l: filter_peer  */
#line 2509 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_peers) = (yyvsp[0].v.filter_peers); }
#line 5592 "parse.c"
    break;

  case 300: /* filter_peer_l: filter_peer_l comma filter_peer  */
#line 2510 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			(yyvsp[0].v.filter_peers)->next = (yyvsp[-2].v.filter_peers);
			(yyval.v.filter_peers) = (yyvsp[0].v.filter_peers);
		}
#line 5601 "parse.c"
    break;

  case 301: /* filter_peer: ANY  */
#line 2516 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (((yyval.v.filter_peers) = calloc(1, sizeof(struct filter_peers_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_peers)->p.peerid = (yyval.v.filter_peers)->p.groupid = 0;
			(yyval.v.filter_peers)->next = NULL;
		}
#line 5613 "parse.c"
    break;

  case 302: /* filter_peer: address  */
#line 2523 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			struct peer *p;

			if (((yyval.v.filter_peers) = calloc(1, sizeof(struct filter_peers_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_peers)->p.remote_as = (yyval.v.filter_peers)->p.groupid = (yyval.v.filter_peers)->p.peerid = 0;
			(yyval.v.filter_peers)->next = NULL;
			RB_FOREACH(p, peer_head, new_peers)
				if (!memcmp(&p->conf.remote_addr,
				    &(yyvsp[0].v.addr), sizeof(p->conf.remote_addr))) {
					(yyval.v.filter_peers)->p.peerid = p->conf.id;
					break;
				}
			if ((yyval.v.filter_peers)->p.peerid == 0) {
				yyerror("no such peer: %s", log_addr(&(yyvsp[0].v.addr)));
				free((yyval.v.filter_peers));
				YYERROR;
			}
		}
#line 5638 "parse.c"
    break;

  case 303: /* filter_peer: AS as4number  */
#line 2543 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (((yyval.v.filter_peers) = calloc(1, sizeof(struct filter_peers_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_peers)->p.groupid = (yyval.v.filter_peers)->p.peerid = 0;
			(yyval.v.filter_peers)->p.remote_as = (yyvsp[0].v.number);
		}
#line 5650 "parse.c"
    break;

  case 304: /* filter_peer: GROUP STRING  */
#line 2550 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			struct peer *p;

			if (((yyval.v.filter_peers) = calloc(1, sizeof(struct filter_peers_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_peers)->p.remote_as = (yyval.v.filter_peers)->p.peerid = 0;
			(yyval.v.filter_peers)->next = NULL;
			RB_FOREACH(p, peer_head, new_peers)
				if (!strcmp(p->conf.group, (yyvsp[0].v.string))) {
					(yyval.v.filter_peers)->p.groupid = p->conf.groupid;
					break;
				}
			if ((yyval.v.filter_peers)->p.groupid == 0) {
				yyerror("no such group: \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				free((yyval.v.filter_peers));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 5676 "parse.c"
    break;

  case 305: /* filter_peer: EBGP  */
#line 2571 "../../../openbgpd-portable/src/bgpd/parse.y"
                       {
			if (((yyval.v.filter_peers) = calloc(1, sizeof(struct filter_peers_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_peers)->p.ebgp = 1;
		}
#line 5687 "parse.c"
    break;

  case 306: /* filter_peer: IBGP  */
#line 2577 "../../../openbgpd-portable/src/bgpd/parse.y"
                       {
			if (((yyval.v.filter_peers) = calloc(1, sizeof(struct filter_peers_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_peers)->p.ibgp = 1;
		}
#line 5698 "parse.c"
    break;

  case 307: /* filter_prefix_h: IPV4 prefixlenop  */
#line 2585 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                         {
			if ((yyvsp[0].v.prefixlen).op == OP_NONE) {
				(yyvsp[0].v.prefixlen).op = OP_RANGE;
				(yyvsp[0].v.prefixlen).len_min = 0;
				(yyvsp[0].v.prefixlen).len_max = -1;
			}
			if (((yyval.v.filter_prefix) = calloc(1, sizeof(struct filter_prefix_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_prefix)->p.addr.aid = AID_INET;
			if (merge_prefixspec(&(yyval.v.filter_prefix)->p, &(yyvsp[0].v.prefixlen)) == -1) {
				free((yyval.v.filter_prefix));
				YYERROR;
			}
		}
#line 5718 "parse.c"
    break;

  case 308: /* filter_prefix_h: IPV6 prefixlenop  */
#line 2600 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			if ((yyvsp[0].v.prefixlen).op == OP_NONE) {
				(yyvsp[0].v.prefixlen).op = OP_RANGE;
				(yyvsp[0].v.prefixlen).len_min = 0;
				(yyvsp[0].v.prefixlen).len_max = -1;
			}
			if (((yyval.v.filter_prefix) = calloc(1, sizeof(struct filter_prefix_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_prefix)->p.addr.aid = AID_INET6;
			if (merge_prefixspec(&(yyval.v.filter_prefix)->p, &(yyvsp[0].v.prefixlen)) == -1) {
				free((yyval.v.filter_prefix));
				YYERROR;
			}
		}
#line 5738 "parse.c"
    break;

  case 309: /* filter_prefix_h: PREFIX filter_prefix  */
#line 2615 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_prefix) = (yyvsp[0].v.filter_prefix); }
#line 5744 "parse.c"
    break;

  case 310: /* filter_prefix_h: PREFIX '{' filter_prefix_m '}'  */
#line 2616 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_prefix) = (yyvsp[-1].v.filter_prefix); }
#line 5750 "parse.c"
    break;

  case 312: /* filter_prefix_m: '{' filter_prefix_l '}'  */
#line 2620 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_prefix) = (yyvsp[-1].v.filter_prefix); }
#line 5756 "parse.c"
    break;

  case 313: /* filter_prefix_m: '{' filter_prefix_l '}' filter_prefix_m  */
#line 2622 "../../../openbgpd-portable/src/bgpd/parse.y"
                {
			struct filter_prefix_l	*p;

			/* merge, both can be lists */
			for (p = (yyvsp[-2].v.filter_prefix); p != NULL && p->next != NULL; p = p->next)
				;	/* nothing */
			if (p != NULL)
				p->next = (yyvsp[0].v.filter_prefix);
			(yyval.v.filter_prefix) = (yyvsp[-2].v.filter_prefix);
		}
#line 5771 "parse.c"
    break;

  case 314: /* filter_prefix_l: filter_prefix  */
#line 2633 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { (yyval.v.filter_prefix) = (yyvsp[0].v.filter_prefix); }
#line 5777 "parse.c"
    break;

  case 315: /* filter_prefix_l: filter_prefix_l comma filter_prefix  */
#line 2634 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			(yyvsp[0].v.filter_prefix)->next = (yyvsp[-2].v.filter_prefix);
			(yyval.v.filter_prefix) = (yyvsp[0].v.filter_prefix);
		}
#line 5786 "parse.c"
    break;

  case 316: /* filter_prefix: prefix prefixlenop  */
#line 2640 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			if (((yyval.v.filter_prefix) = calloc(1, sizeof(struct filter_prefix_l))) ==
			    NULL)
				fatal(NULL);
			memcpy(&(yyval.v.filter_prefix)->p.addr, &(yyvsp[-1].v.prefix).prefix,
			    sizeof((yyval.v.filter_prefix)->p.addr));
			(yyval.v.filter_prefix)->p.len = (yyvsp[-1].v.prefix).len;

			if (merge_prefixspec(&(yyval.v.filter_prefix)->p, &(yyvsp[0].v.prefixlen)) == -1) {
				free((yyval.v.filter_prefix));
				YYERROR;
			}
		}
#line 5804 "parse.c"
    break;

  case 318: /* filter_as_h: '{' filter_as_t_l '}'  */
#line 2656 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                { (yyval.v.filter_as) = (yyvsp[-1].v.filter_as); }
#line 5810 "parse.c"
    break;

  case 320: /* filter_as_t_l: filter_as_t_l comma filter_as_t  */
#line 2660 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                {
			struct filter_as_l	*a;

			/* merge, both can be lists */
			for (a = (yyvsp[-2].v.filter_as); a != NULL && a->next != NULL; a = a->next)
				;	/* nothing */
			if (a != NULL)
				a->next = (yyvsp[0].v.filter_as);
			(yyval.v.filter_as) = (yyvsp[-2].v.filter_as);
		}
#line 5825 "parse.c"
    break;

  case 321: /* filter_as_t: filter_as_type filter_as  */
#line 2672 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                                {
			(yyval.v.filter_as) = (yyvsp[0].v.filter_as);
			(yyval.v.filter_as)->a.type = (yyvsp[-1].v.u8);
		}
#line 5834 "parse.c"
    break;

  case 322: /* filter_as_t: filter_as_type '{' filter_as_l_h '}'  */
#line 2676 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			struct filter_as_l	*a;

			(yyval.v.filter_as) = (yyvsp[-1].v.filter_as);
			for (a = (yyval.v.filter_as); a != NULL; a = a->next)
				a->a.type = (yyvsp[-3].v.u8);
		}
#line 5846 "parse.c"
    break;

  case 323: /* filter_as_t: filter_as_type ASSET STRING  */
#line 2683 "../../../openbgpd-portable/src/bgpd/parse.y"
                                              {
			if (as_sets_lookup(&conf->as_sets, (yyvsp[0].v.string)) == NULL) {
				yyerror("as-set \"%s\" not defined", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (((yyval.v.filter_as) = calloc(1, sizeof(struct filter_as_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_as)->a.type = (yyvsp[-2].v.u8);
			(yyval.v.filter_as)->a.flags = AS_FLAG_AS_SET_NAME;
			if (strlcpy((yyval.v.filter_as)->a.name, (yyvsp[0].v.string), sizeof((yyval.v.filter_as)->a.name)) >=
			    sizeof((yyval.v.filter_as)->a.name)) {
				yyerror("as-set name \"%s\" too long: "
				    "max %zu", (yyvsp[0].v.string), sizeof((yyval.v.filter_as)->a.name) - 1);
				free((yyvsp[0].v.string));
				free((yyval.v.filter_as));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 5872 "parse.c"
    break;

  case 325: /* filter_as_l_h: '{' filter_as_l '}'  */
#line 2707 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_as) = (yyvsp[-1].v.filter_as); }
#line 5878 "parse.c"
    break;

  case 326: /* filter_as_l_h: '{' filter_as_l '}' filter_as_l_h  */
#line 2709 "../../../openbgpd-portable/src/bgpd/parse.y"
                {
			struct filter_as_l	*a;

			/* merge, both can be lists */
			for (a = (yyvsp[-2].v.filter_as); a != NULL && a->next != NULL; a = a->next)
				;	/* nothing */
			if (a != NULL)
				a->next = (yyvsp[0].v.filter_as);
			(yyval.v.filter_as) = (yyvsp[-2].v.filter_as);
		}
#line 5893 "parse.c"
    break;

  case 328: /* filter_as_l: filter_as_l comma filter_as  */
#line 2722 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			(yyvsp[0].v.filter_as)->next = (yyvsp[-2].v.filter_as);
			(yyval.v.filter_as) = (yyvsp[0].v.filter_as);
		}
#line 5902 "parse.c"
    break;

  case 329: /* filter_as: as4number_any  */
#line 2728 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (((yyval.v.filter_as) = calloc(1, sizeof(struct filter_as_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_as)->a.as_min = (yyvsp[0].v.number);
			(yyval.v.filter_as)->a.as_max = (yyvsp[0].v.number);
			(yyval.v.filter_as)->a.op = OP_EQ;
		}
#line 5915 "parse.c"
    break;

  case 330: /* filter_as: NEIGHBORAS  */
#line 2736 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (((yyval.v.filter_as) = calloc(1, sizeof(struct filter_as_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_as)->a.flags = AS_FLAG_NEIGHBORAS;
		}
#line 5926 "parse.c"
    break;

  case 331: /* filter_as: equalityop as4number_any  */
#line 2742 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_as) = calloc(1, sizeof(struct filter_as_l))) ==
			    NULL)
				fatal(NULL);
			(yyval.v.filter_as)->a.op = (yyvsp[-1].v.u8);
			(yyval.v.filter_as)->a.as_min = (yyvsp[0].v.number);
			(yyval.v.filter_as)->a.as_max = (yyvsp[0].v.number);
		}
#line 5939 "parse.c"
    break;

  case 332: /* filter_as: as4number_any binaryop as4number_any  */
#line 2750 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                       {
			if (((yyval.v.filter_as) = calloc(1, sizeof(struct filter_as_l))) ==
			    NULL)
				fatal(NULL);
			if ((yyvsp[-2].v.number) >= (yyvsp[0].v.number)) {
				yyerror("start AS is bigger than end");
				YYERROR;
			}
			(yyval.v.filter_as)->a.op = (yyvsp[-1].v.u8);
			(yyval.v.filter_as)->a.as_min = (yyvsp[-2].v.number);
			(yyval.v.filter_as)->a.as_max = (yyvsp[0].v.number);
		}
#line 5956 "parse.c"
    break;

  case 333: /* filter_match_h: %empty  */
#line 2764 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			memset(&(yyval.v.filter_match), 0, sizeof((yyval.v.filter_match)));
		}
#line 5964 "parse.c"
    break;

  case 334: /* $@16: %empty  */
#line 2767 "../../../openbgpd-portable/src/bgpd/parse.y"
                  {
			memset(&fmopts, 0, sizeof(fmopts));
		}
#line 5972 "parse.c"
    break;

  case 335: /* filter_match_h: $@16 filter_match  */
#line 2770 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			memcpy(&(yyval.v.filter_match), &fmopts, sizeof((yyval.v.filter_match)));
		}
#line 5980 "parse.c"
    break;

  case 338: /* filter_elm: filter_prefix_h  */
#line 2779 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (fmopts.prefix_l != NULL) {
				yyerror("\"prefix\" already specified");
				YYERROR;
			}
			if (fmopts.m.prefixset.name[0] != '\0') {
				yyerror("\"prefix-set\" already specified, "
				    "cannot be used with \"prefix\" in the "
				    "same filter rule");
				YYERROR;
			}
			fmopts.prefix_l = (yyvsp[0].v.filter_prefix);
		}
#line 5998 "parse.c"
    break;

  case 339: /* filter_elm: filter_as_h  */
#line 2792 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (fmopts.as_l != NULL) {
				yyerror("AS filters already specified");
				YYERROR;
			}
			fmopts.as_l = (yyvsp[0].v.filter_as);
		}
#line 6010 "parse.c"
    break;

  case 340: /* filter_elm: MAXASLEN NUMBER  */
#line 2799 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (fmopts.m.aslen.type != ASLEN_NONE) {
				yyerror("AS length filters already specified");
				YYERROR;
			}
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > UINT_MAX) {
				yyerror("bad max-as-len %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			fmopts.m.aslen.type = ASLEN_MAX;
			fmopts.m.aslen.aslen = (yyvsp[0].v.number);
		}
#line 6027 "parse.c"
    break;

  case 341: /* filter_elm: MAXASSEQ NUMBER  */
#line 2811 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (fmopts.m.aslen.type != ASLEN_NONE) {
				yyerror("AS length filters already specified");
				YYERROR;
			}
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > UINT_MAX) {
				yyerror("bad max-as-seq %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			fmopts.m.aslen.type = ASLEN_SEQ;
			fmopts.m.aslen.aslen = (yyvsp[0].v.number);
		}
#line 6044 "parse.c"
    break;

  case 342: /* filter_elm: community STRING  */
#line 2823 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			int i;
			for (i = 0; i < MAX_COMM_MATCH; i++) {
				if (fmopts.m.community[i].flags == 0)
					break;
			}
			if (i >= MAX_COMM_MATCH) {
				yyerror("too many \"community\" filters "
				    "specified");
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (parsecommunity(&fmopts.m.community[i], (yyvsp[-1].v.u8), (yyvsp[0].v.string)) ==
			    -1) {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6068 "parse.c"
    break;

  case 343: /* filter_elm: EXTCOMMUNITY STRING STRING  */
#line 2842 "../../../openbgpd-portable/src/bgpd/parse.y"
                                             {
			int i;
			for (i = 0; i < MAX_COMM_MATCH; i++) {
				if (fmopts.m.community[i].flags == 0)
					break;
			}
			if (i >= MAX_COMM_MATCH) {
				yyerror("too many \"community\" filters "
				    "specified");
				free((yyvsp[-1].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (parseextcommunity(&fmopts.m.community[i],
			    (yyvsp[-1].v.string), (yyvsp[0].v.string)) == -1) {
				free((yyvsp[-1].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[-1].v.string));
			free((yyvsp[0].v.string));
		}
#line 6095 "parse.c"
    break;

  case 344: /* filter_elm: EXTCOMMUNITY OVS STRING  */
#line 2864 "../../../openbgpd-portable/src/bgpd/parse.y"
                                          {
			int i;
			for (i = 0; i < MAX_COMM_MATCH; i++) {
				if (fmopts.m.community[i].flags == 0)
					break;
			}
			if (i >= MAX_COMM_MATCH) {
				yyerror("too many \"community\" filters "
				    "specified");
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (parseextcommunity(&fmopts.m.community[i],
			    "ovs", (yyvsp[0].v.string)) == -1) {
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6119 "parse.c"
    break;

  case 345: /* filter_elm: MAXCOMMUNITIES NUMBER  */
#line 2883 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT16_MAX) {
				yyerror("bad max-comunities %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (fmopts.m.maxcomm != 0) {
				yyerror("%s already specified",
				    "max-communities");
				YYERROR;
			}
			/*
			 * Offset by 1 since 0 means not used.
			 * The match function then uses >= to compensate.
			 */
			fmopts.m.maxcomm = (yyvsp[0].v.number) + 1;
		}
#line 6140 "parse.c"
    break;

  case 346: /* filter_elm: MAXEXTCOMMUNITIES NUMBER  */
#line 2899 "../../../openbgpd-portable/src/bgpd/parse.y"
                                           {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT16_MAX) {
				yyerror("bad max-ext-communities %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (fmopts.m.maxextcomm != 0) {
				yyerror("%s already specified",
				    "max-ext-communities");
				YYERROR;
			}
			fmopts.m.maxextcomm = (yyvsp[0].v.number) + 1;
		}
#line 6157 "parse.c"
    break;

  case 347: /* filter_elm: MAXLARGECOMMUNITIES NUMBER  */
#line 2911 "../../../openbgpd-portable/src/bgpd/parse.y"
                                             {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT16_MAX) {
				yyerror("bad max-large-communities %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (fmopts.m.maxlargecomm != 0) {
				yyerror("%s already specified",
				    "max-large-communities");
				YYERROR;
			}
			fmopts.m.maxlargecomm = (yyvsp[0].v.number) + 1;
		}
#line 6174 "parse.c"
    break;

  case 348: /* filter_elm: NEXTHOP address  */
#line 2923 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (fmopts.m.nexthop.flags) {
				yyerror("nexthop already specified");
				YYERROR;
			}
			fmopts.m.nexthop.addr = (yyvsp[0].v.addr);
			fmopts.m.nexthop.flags = FILTER_NEXTHOP_ADDR;
		}
#line 6187 "parse.c"
    break;

  case 349: /* filter_elm: NEXTHOP NEIGHBOR  */
#line 2931 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (fmopts.m.nexthop.flags) {
				yyerror("nexthop already specified");
				YYERROR;
			}
			fmopts.m.nexthop.flags = FILTER_NEXTHOP_NEIGHBOR;
		}
#line 6199 "parse.c"
    break;

  case 350: /* filter_elm: PREFIXSET STRING prefixlenop  */
#line 2938 "../../../openbgpd-portable/src/bgpd/parse.y"
                                               {
			struct prefixset *ps;
			if (fmopts.prefix_l != NULL) {
				yyerror("\"prefix\" already specified, cannot "
				    "be used with \"prefix-set\" in the same "
				    "filter rule");
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if (fmopts.m.prefixset.name[0] != '\0') {
				yyerror("prefix-set filter already specified");
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if ((ps = find_prefixset((yyvsp[-1].v.string), &conf->prefixsets))
			    == NULL) {
				yyerror("prefix-set '%s' not defined", (yyvsp[-1].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if (strlcpy(fmopts.m.prefixset.name, (yyvsp[-1].v.string),
			    sizeof(fmopts.m.prefixset.name)) >=
			    sizeof(fmopts.m.prefixset.name)) {
				yyerror("prefix-set name too long");
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if (!((yyvsp[0].v.prefixlen).op == OP_NONE ||
			    ((yyvsp[0].v.prefixlen).op == OP_RANGE &&
			     (yyvsp[0].v.prefixlen).len_min == -1 && (yyvsp[0].v.prefixlen).len_max == -1))) {
				yyerror("prefix-sets can only use option "
				    "or-longer");
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if ((yyvsp[0].v.prefixlen).op == OP_RANGE &&
			    ps->sflags & PREFIXSET_FLAG_OPS) {
				yyerror("prefix-set %s contains prefixlen "
				    "operators and cannot be used with an "
				    "or-longer filter", (yyvsp[-1].v.string));
				free((yyvsp[-1].v.string));
				YYERROR;
			}
			if ((yyvsp[0].v.prefixlen).op == OP_RANGE && (yyvsp[0].v.prefixlen).len_min == -1 &&
			    (yyvsp[0].v.prefixlen).len_min == -1)
				fmopts.m.prefixset.flags |=
				    PREFIXSET_FLAG_LONGER;
			fmopts.m.prefixset.flags |= PREFIXSET_FLAG_FILTER;
			free((yyvsp[-1].v.string));
		}
#line 6254 "parse.c"
    break;

  case 351: /* filter_elm: ORIGINSET STRING  */
#line 2988 "../../../openbgpd-portable/src/bgpd/parse.y"
                                   {
			if (fmopts.m.originset.name[0] != '\0') {
				yyerror("origin-set filter already specified");
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (find_prefixset((yyvsp[0].v.string), &conf->originsets) == NULL) {
				yyerror("origin-set '%s' not defined", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			if (strlcpy(fmopts.m.originset.name, (yyvsp[0].v.string),
			    sizeof(fmopts.m.originset.name)) >=
			    sizeof(fmopts.m.originset.name)) {
				yyerror("origin-set name too long");
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6279 "parse.c"
    break;

  case 352: /* filter_elm: OVS validity  */
#line 3008 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (fmopts.m.ovs.is_set) {
				yyerror("ovs filter already specified");
				YYERROR;
			}
			fmopts.m.ovs.validity = (yyvsp[0].v.number);
			fmopts.m.ovs.is_set = 1;
		}
#line 6292 "parse.c"
    break;

  case 353: /* filter_elm: AVS aspa_validity  */
#line 3016 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (fmopts.m.avs.is_set) {
				yyerror("avs filter already specified");
				YYERROR;
			}
			fmopts.m.avs.validity = (yyvsp[0].v.number);
			fmopts.m.avs.is_set = 1;
		}
#line 6305 "parse.c"
    break;

  case 354: /* prefixlenop: %empty  */
#line 3026 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        { memset(&(yyval.v.prefixlen), 0, sizeof((yyval.v.prefixlen))); }
#line 6311 "parse.c"
    break;

  case 355: /* prefixlenop: LONGER  */
#line 3027 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			memset(&(yyval.v.prefixlen), 0, sizeof((yyval.v.prefixlen)));
			(yyval.v.prefixlen).op = OP_RANGE;
			(yyval.v.prefixlen).len_min = -1;
			(yyval.v.prefixlen).len_max = -1;
		}
#line 6322 "parse.c"
    break;

  case 356: /* prefixlenop: MAXLEN NUMBER  */
#line 3033 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			memset(&(yyval.v.prefixlen), 0, sizeof((yyval.v.prefixlen)));
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 128) {
				yyerror("prefixlen must be >= 0 and <= 128");
				YYERROR;
			}

			(yyval.v.prefixlen).op = OP_RANGE;
			(yyval.v.prefixlen).len_min = -1;
			(yyval.v.prefixlen).len_max = (yyvsp[0].v.number);
		}
#line 6338 "parse.c"
    break;

  case 357: /* prefixlenop: PREFIXLEN unaryop NUMBER  */
#line 3044 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			int min, max;

			memset(&(yyval.v.prefixlen), 0, sizeof((yyval.v.prefixlen)));
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 128) {
				yyerror("prefixlen must be >= 0 and <= 128");
				YYERROR;
			}
			/*
			 * convert the unary operation into the equivalent
			 * range check
			 */
			(yyval.v.prefixlen).op = OP_RANGE;

			switch ((yyvsp[-1].v.u8)) {
			case OP_NE:
				(yyval.v.prefixlen).op = (yyvsp[-1].v.u8);
			case OP_EQ:
				min = max = (yyvsp[0].v.number);
				break;
			case OP_LT:
				if ((yyvsp[0].v.number) == 0) {
					yyerror("prefixlen must be > 0");
					YYERROR;
				}
				(yyvsp[0].v.number) -= 1;
			case OP_LE:
				min = -1;
				max = (yyvsp[0].v.number);
				break;
			case OP_GT:
				(yyvsp[0].v.number) += 1;
			case OP_GE:
				min = (yyvsp[0].v.number);
				max = -1;
				break;
			default:
				yyerror("unknown prefixlen operation");
				YYERROR;
			}
			(yyval.v.prefixlen).len_min = min;
			(yyval.v.prefixlen).len_max = max;
		}
#line 6386 "parse.c"
    break;

  case 358: /* prefixlenop: PREFIXLEN NUMBER binaryop NUMBER  */
#line 3087 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			memset(&(yyval.v.prefixlen), 0, sizeof((yyval.v.prefixlen)));
			if ((yyvsp[-2].v.number) < 0 || (yyvsp[-2].v.number) > 128 || (yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 128) {
				yyerror("prefixlen must be < 128");
				YYERROR;
			}
			if ((yyvsp[-2].v.number) > (yyvsp[0].v.number)) {
				yyerror("start prefixlen is bigger than end");
				YYERROR;
			}
			(yyval.v.prefixlen).op = (yyvsp[-1].v.u8);
			(yyval.v.prefixlen).len_min = (yyvsp[-2].v.number);
			(yyval.v.prefixlen).len_max = (yyvsp[0].v.number);
		}
#line 6405 "parse.c"
    break;

  case 359: /* filter_as_type: AS  */
#line 3103 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = AS_ALL; }
#line 6411 "parse.c"
    break;

  case 360: /* filter_as_type: SOURCEAS  */
#line 3104 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = AS_SOURCE; }
#line 6417 "parse.c"
    break;

  case 361: /* filter_as_type: TRANSITAS  */
#line 3105 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = AS_TRANSIT; }
#line 6423 "parse.c"
    break;

  case 362: /* filter_as_type: PEERAS  */
#line 3106 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = AS_PEER; }
#line 6429 "parse.c"
    break;

  case 363: /* filter_set: %empty  */
#line 3109 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.filter_set_head) = NULL; }
#line 6435 "parse.c"
    break;

  case 364: /* filter_set: SET filter_set_opt  */
#line 3110 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (((yyval.v.filter_set_head) = calloc(1, sizeof(struct filter_set_head))) ==
			    NULL)
				fatal(NULL);
			TAILQ_INIT((yyval.v.filter_set_head));
			TAILQ_INSERT_TAIL((yyval.v.filter_set_head), (yyvsp[0].v.filter_set), entry);
		}
#line 6447 "parse.c"
    break;

  case 365: /* filter_set: SET '{' optnl filter_set_l optnl '}'  */
#line 3117 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        { (yyval.v.filter_set_head) = (yyvsp[-2].v.filter_set_head); }
#line 6453 "parse.c"
    break;

  case 366: /* filter_set_l: filter_set_l comma filter_set_opt  */
#line 3120 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                        {
			(yyval.v.filter_set_head) = (yyvsp[-2].v.filter_set_head);
			if (merge_filterset((yyval.v.filter_set_head), (yyvsp[0].v.filter_set)) == 1)
				YYERROR;
		}
#line 6463 "parse.c"
    break;

  case 367: /* filter_set_l: filter_set_opt  */
#line 3125 "../../../openbgpd-portable/src/bgpd/parse.y"
                                 {
			if (((yyval.v.filter_set_head) = calloc(1, sizeof(struct filter_set_head))) ==
			    NULL)
				fatal(NULL);
			TAILQ_INIT((yyval.v.filter_set_head));
			TAILQ_INSERT_TAIL((yyval.v.filter_set_head), (yyvsp[0].v.filter_set), entry);
		}
#line 6475 "parse.c"
    break;

  case 368: /* community: COMMUNITY  */
#line 3134 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        { (yyval.v.u8) = COMMUNITY_TYPE_BASIC; }
#line 6481 "parse.c"
    break;

  case 369: /* community: LARGECOMMUNITY  */
#line 3135 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        { (yyval.v.u8) = COMMUNITY_TYPE_LARGE; }
#line 6487 "parse.c"
    break;

  case 370: /* delete: %empty  */
#line 3138 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = 0; }
#line 6493 "parse.c"
    break;

  case 371: /* delete: DELETE  */
#line 3139 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = 1; }
#line 6499 "parse.c"
    break;

  case 372: /* enforce: %empty  */
#line 3142 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 0; }
#line 6505 "parse.c"
    break;

  case 373: /* enforce: ENFORCE  */
#line 3143 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 2; }
#line 6511 "parse.c"
    break;

  case 374: /* yesnoenforce: yesno  */
#line 3146 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = (yyvsp[0].v.number); }
#line 6517 "parse.c"
    break;

  case 375: /* yesnoenforce: ENFORCE  */
#line 3147 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.number) = 2; }
#line 6523 "parse.c"
    break;

  case 376: /* filter_set_opt: LOCALPREF NUMBER  */
#line 3150 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < -INT_MAX || (yyvsp[0].v.number) > UINT_MAX) {
				yyerror("bad localpref %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			if ((yyvsp[0].v.number) >= 0) {
				(yyval.v.filter_set)->type = ACTION_SET_LOCALPREF;
				(yyval.v.filter_set)->action.metric = (yyvsp[0].v.number);
			} else {
				(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_LOCALPREF;
				(yyval.v.filter_set)->action.relative = (yyvsp[0].v.number);
			}
		}
#line 6543 "parse.c"
    break;

  case 377: /* filter_set_opt: LOCALPREF '+' NUMBER  */
#line 3165 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad localpref +%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_LOCALPREF;
			(yyval.v.filter_set)->action.relative = (yyvsp[0].v.number);
		}
#line 6558 "parse.c"
    break;

  case 378: /* filter_set_opt: LOCALPREF '-' NUMBER  */
#line 3175 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad localpref -%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_LOCALPREF;
			(yyval.v.filter_set)->action.relative = -(yyvsp[0].v.number);
		}
#line 6573 "parse.c"
    break;

  case 379: /* filter_set_opt: MED NUMBER  */
#line 3185 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < -INT_MAX || (yyvsp[0].v.number) > UINT_MAX) {
				yyerror("bad metric %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			if ((yyvsp[0].v.number) >= 0) {
				(yyval.v.filter_set)->type = ACTION_SET_MED;
				(yyval.v.filter_set)->action.metric = (yyvsp[0].v.number);
			} else {
				(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_MED;
				(yyval.v.filter_set)->action.relative = (yyvsp[0].v.number);
			}
		}
#line 6593 "parse.c"
    break;

  case 380: /* filter_set_opt: MED '+' NUMBER  */
#line 3200 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad metric +%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_MED;
			(yyval.v.filter_set)->action.relative = (yyvsp[0].v.number);
		}
#line 6608 "parse.c"
    break;

  case 381: /* filter_set_opt: MED '-' NUMBER  */
#line 3210 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad metric -%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_MED;
			(yyval.v.filter_set)->action.relative = -(yyvsp[0].v.number);
		}
#line 6623 "parse.c"
    break;

  case 382: /* filter_set_opt: METRIC NUMBER  */
#line 3220 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {	/* alias for MED */
			if ((yyvsp[0].v.number) < -INT_MAX || (yyvsp[0].v.number) > UINT_MAX) {
				yyerror("bad metric %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			if ((yyvsp[0].v.number) >= 0) {
				(yyval.v.filter_set)->type = ACTION_SET_MED;
				(yyval.v.filter_set)->action.metric = (yyvsp[0].v.number);
			} else {
				(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_MED;
				(yyval.v.filter_set)->action.relative = (yyvsp[0].v.number);
			}
		}
#line 6643 "parse.c"
    break;

  case 383: /* filter_set_opt: METRIC '+' NUMBER  */
#line 3235 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad metric +%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_MED;
			(yyval.v.filter_set)->action.metric = (yyvsp[0].v.number);
		}
#line 6658 "parse.c"
    break;

  case 384: /* filter_set_opt: METRIC '-' NUMBER  */
#line 3245 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad metric -%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_MED;
			(yyval.v.filter_set)->action.relative = -(yyvsp[0].v.number);
		}
#line 6673 "parse.c"
    break;

  case 385: /* filter_set_opt: WEIGHT NUMBER  */
#line 3255 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < -INT_MAX || (yyvsp[0].v.number) > UINT_MAX) {
				yyerror("bad weight %lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			if ((yyvsp[0].v.number) > 0) {
				(yyval.v.filter_set)->type = ACTION_SET_WEIGHT;
				(yyval.v.filter_set)->action.metric = (yyvsp[0].v.number);
			} else {
				(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_WEIGHT;
				(yyval.v.filter_set)->action.relative = (yyvsp[0].v.number);
			}
		}
#line 6693 "parse.c"
    break;

  case 386: /* filter_set_opt: WEIGHT '+' NUMBER  */
#line 3270 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad weight +%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_WEIGHT;
			(yyval.v.filter_set)->action.relative = (yyvsp[0].v.number);
		}
#line 6708 "parse.c"
    break;

  case 387: /* filter_set_opt: WEIGHT '-' NUMBER  */
#line 3280 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > INT_MAX) {
				yyerror("bad weight -%lld", (yyvsp[0].v.number));
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_RELATIVE_WEIGHT;
			(yyval.v.filter_set)->action.relative = -(yyvsp[0].v.number);
		}
#line 6723 "parse.c"
    break;

  case 388: /* filter_set_opt: NEXTHOP address  */
#line 3290 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_NEXTHOP;
			memcpy(&(yyval.v.filter_set)->action.nexthop, &(yyvsp[0].v.addr),
			    sizeof((yyval.v.filter_set)->action.nexthop));
		}
#line 6735 "parse.c"
    break;

  case 389: /* filter_set_opt: NEXTHOP BLACKHOLE  */
#line 3297 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_NEXTHOP_BLACKHOLE;
		}
#line 6745 "parse.c"
    break;

  case 390: /* filter_set_opt: NEXTHOP REJECT  */
#line 3302 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_NEXTHOP_REJECT;
		}
#line 6755 "parse.c"
    break;

  case 391: /* filter_set_opt: NEXTHOP NOMODIFY  */
#line 3307 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_NEXTHOP_NOMODIFY;
		}
#line 6765 "parse.c"
    break;

  case 392: /* filter_set_opt: NEXTHOP SELF  */
#line 3312 "../../../openbgpd-portable/src/bgpd/parse.y"
                                        {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_NEXTHOP_SELF;
		}
#line 6775 "parse.c"
    break;

  case 393: /* filter_set_opt: PREPEND_SELF NUMBER  */
#line 3317 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 128) {
				yyerror("bad number of prepends");
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_PREPEND_SELF;
			(yyval.v.filter_set)->action.prepend = (yyvsp[0].v.number);
		}
#line 6790 "parse.c"
    break;

  case 394: /* filter_set_opt: PREPEND_PEER NUMBER  */
#line 3327 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if ((yyvsp[0].v.number) < 0 || (yyvsp[0].v.number) > 128) {
				yyerror("bad number of prepends");
				YYERROR;
			}
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_PREPEND_PEER;
			(yyval.v.filter_set)->action.prepend = (yyvsp[0].v.number);
		}
#line 6805 "parse.c"
    break;

  case 395: /* filter_set_opt: ASOVERRIDE  */
#line 3337 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_AS_OVERRIDE;
		}
#line 6815 "parse.c"
    break;

  case 396: /* filter_set_opt: PFTABLE STRING  */
#line 3342 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_PFTABLE;
			if (!(cmd_opts & BGPD_OPT_NOACTION) &&
			    pftable_exists((yyvsp[0].v.string)) != 0) {
				yyerror("pftable name does not exist");
				free((yyvsp[0].v.string));
				free((yyval.v.filter_set));
				YYERROR;
			}
			if (strlcpy((yyval.v.filter_set)->action.pftable, (yyvsp[0].v.string),
			    sizeof((yyval.v.filter_set)->action.pftable)) >=
			    sizeof((yyval.v.filter_set)->action.pftable)) {
				yyerror("pftable name too long");
				free((yyvsp[0].v.string));
				free((yyval.v.filter_set));
				YYERROR;
			}
			if (pftable_add((yyvsp[0].v.string)) != 0) {
				yyerror("Couldn't register table");
				free((yyvsp[0].v.string));
				free((yyval.v.filter_set));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6847 "parse.c"
    break;

  case 397: /* filter_set_opt: RTLABEL STRING  */
#line 3369 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_RTLABEL;
			if (strlcpy((yyval.v.filter_set)->action.rtlabel, (yyvsp[0].v.string),
			    sizeof((yyval.v.filter_set)->action.rtlabel)) >=
			    sizeof((yyval.v.filter_set)->action.rtlabel)) {
				yyerror("rtlabel name too long");
				free((yyvsp[0].v.string));
				free((yyval.v.filter_set));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6866 "parse.c"
    break;

  case 398: /* filter_set_opt: community delete STRING  */
#line 3383 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                {
			uint8_t f1, f2, f3;

			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			if ((yyvsp[-1].v.u8))
				(yyval.v.filter_set)->type = ACTION_DEL_COMMUNITY;
			else
				(yyval.v.filter_set)->type = ACTION_SET_COMMUNITY;

			if (parsecommunity(&(yyval.v.filter_set)->action.community, (yyvsp[-2].v.u8), (yyvsp[0].v.string)) ==
			    -1) {
				free((yyvsp[0].v.string));
				free((yyval.v.filter_set));
				YYERROR;
			}
			free((yyvsp[0].v.string));
			/* Don't allow setting of any match */
			f1 = (yyval.v.filter_set)->action.community.flags >> 8;
			f2 = (yyval.v.filter_set)->action.community.flags >> 16;
			f3 = (yyval.v.filter_set)->action.community.flags >> 24;
			if (!(yyvsp[-1].v.u8) && (f1 == COMMUNITY_ANY ||
			    f2 == COMMUNITY_ANY || f3 == COMMUNITY_ANY)) {
				yyerror("'*' is not allowed in set community");
				free((yyval.v.filter_set));
				YYERROR;
			}
		}
#line 6899 "parse.c"
    break;

  case 399: /* filter_set_opt: EXTCOMMUNITY delete STRING STRING  */
#line 3411 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                    {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			if ((yyvsp[-2].v.u8))
				(yyval.v.filter_set)->type = ACTION_DEL_COMMUNITY;
			else
				(yyval.v.filter_set)->type = ACTION_SET_COMMUNITY;

			if (parseextcommunity(&(yyval.v.filter_set)->action.community,
			    (yyvsp[-1].v.string), (yyvsp[0].v.string)) == -1) {
				free((yyvsp[-1].v.string));
				free((yyvsp[0].v.string));
				free((yyval.v.filter_set));
				YYERROR;
			}
			free((yyvsp[-1].v.string));
			free((yyvsp[0].v.string));
		}
#line 6922 "parse.c"
    break;

  case 400: /* filter_set_opt: EXTCOMMUNITY delete OVS STRING  */
#line 3429 "../../../openbgpd-portable/src/bgpd/parse.y"
                                                 {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			if ((yyvsp[-2].v.u8))
				(yyval.v.filter_set)->type = ACTION_DEL_COMMUNITY;
			else
				(yyval.v.filter_set)->type = ACTION_SET_COMMUNITY;

			if (parseextcommunity(&(yyval.v.filter_set)->action.community,
			    "ovs", (yyvsp[0].v.string)) == -1) {
				free((yyvsp[0].v.string));
				free((yyval.v.filter_set));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6943 "parse.c"
    break;

  case 401: /* filter_set_opt: ORIGIN origincode  */
#line 3445 "../../../openbgpd-portable/src/bgpd/parse.y"
                                    {
			if (((yyval.v.filter_set) = calloc(1, sizeof(struct filter_set))) == NULL)
				fatal(NULL);
			(yyval.v.filter_set)->type = ACTION_SET_ORIGIN;
			(yyval.v.filter_set)->action.origin = (yyvsp[0].v.number);
		}
#line 6954 "parse.c"
    break;

  case 402: /* origincode: STRING  */
#line 3453 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (!strcmp((yyvsp[0].v.string), "egp"))
				(yyval.v.number) = ORIGIN_EGP;
			else if (!strcmp((yyvsp[0].v.string), "igp"))
				(yyval.v.number) = ORIGIN_IGP;
			else if (!strcmp((yyvsp[0].v.string), "incomplete"))
				(yyval.v.number) = ORIGIN_INCOMPLETE;
			else {
				yyerror("unknown origin \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6973 "parse.c"
    break;

  case 403: /* validity: STRING  */
#line 3468 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (!strcmp((yyvsp[0].v.string), "not-found"))
				(yyval.v.number) = ROA_NOTFOUND;
			else if (!strcmp((yyvsp[0].v.string), "invalid"))
				(yyval.v.number) = ROA_INVALID;
			else if (!strcmp((yyvsp[0].v.string), "valid"))
				(yyval.v.number) = ROA_VALID;
			else {
				yyerror("unknown roa validity \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 6992 "parse.c"
    break;

  case 404: /* aspa_validity: STRING  */
#line 3483 "../../../openbgpd-portable/src/bgpd/parse.y"
                                {
			if (!strcmp((yyvsp[0].v.string), "unknown"))
				(yyval.v.number) = ASPA_UNKNOWN;
			else if (!strcmp((yyvsp[0].v.string), "invalid"))
				(yyval.v.number) = ASPA_INVALID;
			else if (!strcmp((yyvsp[0].v.string), "valid"))
				(yyval.v.number) = ASPA_VALID;
			else {
				yyerror("unknown aspa validity \"%s\"", (yyvsp[0].v.string));
				free((yyvsp[0].v.string));
				YYERROR;
			}
			free((yyvsp[0].v.string));
		}
#line 7011 "parse.c"
    break;

  case 411: /* unaryop: '='  */
#line 3508 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_EQ; }
#line 7017 "parse.c"
    break;

  case 412: /* unaryop: NE  */
#line 3509 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_NE; }
#line 7023 "parse.c"
    break;

  case 413: /* unaryop: LE  */
#line 3510 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_LE; }
#line 7029 "parse.c"
    break;

  case 414: /* unaryop: '<'  */
#line 3511 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_LT; }
#line 7035 "parse.c"
    break;

  case 415: /* unaryop: GE  */
#line 3512 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_GE; }
#line 7041 "parse.c"
    break;

  case 416: /* unaryop: '>'  */
#line 3513 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_GT; }
#line 7047 "parse.c"
    break;

  case 417: /* equalityop: '='  */
#line 3516 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_EQ; }
#line 7053 "parse.c"
    break;

  case 418: /* equalityop: NE  */
#line 3517 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_NE; }
#line 7059 "parse.c"
    break;

  case 419: /* binaryop: '-'  */
#line 3520 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_RANGE; }
#line 7065 "parse.c"
    break;

  case 420: /* binaryop: XRANGE  */
#line 3521 "../../../openbgpd-portable/src/bgpd/parse.y"
                                { (yyval.v.u8) = OP_XRANGE; }
#line 7071 "parse.c"
    break;


#line 7075 "parse.c"

      default: break;
    }
  /* User semantic actions sometimes alter yychar, and that requires
     that yytoken be updated with the new translation.  We take the
     approach of translating immediately before every use of yytoken.
     One alternative is translating here after every semantic action,
     but that translation would be missed if the semantic action invokes
     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
     incorrect destructor might then be invoked immediately.  In the
     case of YYERROR or YYBACKUP, subsequent parser actions might lead
     to an incorrect destructor call or verbose syntax error message
     before the lookahead is translated.  */
  YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);

  YYPOPSTACK (yylen);
  yylen = 0;

  *++yyvsp = yyval;

  /* Now 'shift' the result of the reduction.  Determine what state
     that goes to, based on the state we popped back to and the rule
     number reduced by.  */
  {
    const int yylhs = yyr1[yyn] - YYNTOKENS;
    const int yyi = yypgoto[yylhs] + *yyssp;
    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
               ? yytable[yyi]
               : yydefgoto[yylhs]);
  }

  goto yynewstate;


/*--------------------------------------.
| yyerrlab -- here on detecting error.  |
`--------------------------------------*/
yyerrlab:
  /* Make sure we have latest lookahead translation.  See comments at
     user semantic actions for why this is necessary.  */
  yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
  /* If not already recovering from an error, report this error.  */
  if (!yyerrstatus)
    {
      ++yynerrs;
      yyerror (YY_("syntax error"));
    }

  if (yyerrstatus == 3)
    {
      /* If just tried and failed to reuse lookahead token after an
         error, discard it.  */

      if (yychar <= YYEOF)
        {
          /* Return failure if at end of input.  */
          if (yychar == YYEOF)
            YYABORT;
        }
      else
        {
          yydestruct ("Error: discarding",
                      yytoken, &yylval);
          yychar = YYEMPTY;
        }
    }

  /* Else will try to reuse lookahead token after shifting the error
     token.  */
  goto yyerrlab1;


/*---------------------------------------------------.
| yyerrorlab -- error raised explicitly by YYERROR.  |
`---------------------------------------------------*/
yyerrorlab:
  /* Pacify compilers when the user code never invokes YYERROR and the
     label yyerrorlab therefore never appears in user code.  */
  if (0)
    YYERROR;
  ++yynerrs;

  /* Do not reclaim the symbols of the rule whose action triggered
     this YYERROR.  */
  YYPOPSTACK (yylen);
  yylen = 0;
  YY_STACK_PRINT (yyss, yyssp);
  yystate = *yyssp;
  goto yyerrlab1;


/*-------------------------------------------------------------.
| yyerrlab1 -- common code for both syntax error and YYERROR.  |
`-------------------------------------------------------------*/
yyerrlab1:
  yyerrstatus = 3;      /* Each real token shifted decrements this.  */

  /* Pop stack until we find a state that shifts the error token.  */
  for (;;)
    {
      yyn = yypact[yystate];
      if (!yypact_value_is_default (yyn))
        {
          yyn += YYSYMBOL_YYerror;
          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
            {
              yyn = yytable[yyn];
              if (0 < yyn)
                break;
            }
        }

      /* Pop the current state because it cannot handle the error token.  */
      if (yyssp == yyss)
        YYABORT;


      yydestruct ("Error: popping",
                  YY_ACCESSING_SYMBOL (yystate), yyvsp);
      YYPOPSTACK (1);
      yystate = *yyssp;
      YY_STACK_PRINT (yyss, yyssp);
    }

  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
  *++yyvsp = yylval;
  YY_IGNORE_MAYBE_UNINITIALIZED_END


  /* Shift the error token.  */
  YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);

  yystate = yyn;
  goto yynewstate;


/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here.  |
`-------------------------------------*/
yyacceptlab:
  yyresult = 0;
  goto yyreturnlab;


/*-----------------------------------.
| yyabortlab -- YYABORT comes here.  |
`-----------------------------------*/
yyabortlab:
  yyresult = 1;
  goto yyreturnlab;


/*-----------------------------------------------------------.
| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here.  |
`-----------------------------------------------------------*/
yyexhaustedlab:
  yyerror (YY_("memory exhausted"));
  yyresult = 2;
  goto yyreturnlab;


/*----------------------------------------------------------.
| yyreturnlab -- parsing is finished, clean up and return.  |
`----------------------------------------------------------*/
yyreturnlab:
  if (yychar != YYEMPTY)
    {
      /* Make sure we have latest lookahead translation.  See comments at
         user semantic actions for why this is necessary.  */
      yytoken = YYTRANSLATE (yychar);
      yydestruct ("Cleanup: discarding lookahead",
                  yytoken, &yylval);
    }
  /* Do not reclaim the symbols of the rule whose action triggered
     this YYABORT or YYACCEPT.  */
  YYPOPSTACK (yylen);
  YY_STACK_PRINT (yyss, yyssp);
  while (yyssp != yyss)
    {
      yydestruct ("Cleanup: popping",
                  YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
      YYPOPSTACK (1);
    }
#ifndef yyoverflow
  if (yyss != yyssa)
    YYSTACK_FREE (yyss);
#endif

  return yyresult;
}

#line 3524 "../../../openbgpd-portable/src/bgpd/parse.y"


struct keywords {
	const char	*k_name;
	int		 k_val;
};

int
yyerror(const char *fmt, ...)
{
	va_list		 ap;
	char		*msg;

	file->errors++;
	va_start(ap, fmt);
	if (vasprintf(&msg, fmt, ap) == -1)
		fatalx("yyerror vasprintf");
	va_end(ap);
	logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
	free(msg);
	return (0);
}

int
kw_cmp(const void *k, const void *e)
{
	return (strcmp(k, ((const struct keywords *)e)->k_name));
}

int
lookup(char *s)
{
	/* this has to be sorted always */
	static const struct keywords keywords[] = {
		{ "AS",			AS },
		{ "EVPN",		EVPN },
		{ "IPv4",		IPV4 },
		{ "IPv6",		IPV6 },
		{ "add-path",		ADDPATH },
		{ "ah",			AH },
		{ "allow",		ALLOW },
		{ "announce",		ANNOUNCE },
		{ "any",		ANY },
		{ "as-4byte",		AS4BYTE },
		{ "as-override",	ASOVERRIDE },
		{ "as-set",		ASSET },
		{ "aspa-set",		ASPASET },
		{ "avs",		AVS },
		{ "blackhole",		BLACKHOLE },
		{ "community",		COMMUNITY },
		{ "compare",		COMPARE },
		{ "connect-retry",	CONNECTRETRY },
		{ "connected",		CONNECTED },
		{ "customer-as",	CUSTOMERAS },
		{ "default-route",	DEFAULTROUTE },
		{ "delete",		DELETE },
		{ "demote",		DEMOTE },
		{ "deny",		DENY },
		{ "depend",		DEPEND },
		{ "descr",		DESCR },
		{ "down",		DOWN },
		{ "dump",		DUMP },
		{ "ebgp",		EBGP },
		{ "enforce",		ENFORCE },
		{ "enhanced",		ENHANCED },
		{ "esp",		ESP },
		{ "evaluate",		EVALUATE },
		{ "expires",		EXPIRES },
		{ "export",		EXPORT },
		{ "export-target",	EXPORTTRGT },
		{ "ext-community",	EXTCOMMUNITY },
		{ "extended",		EXTENDED },
		{ "fib-priority",	FIBPRIORITY },
		{ "fib-update",		FIBUPDATE },
		{ "filtered",		FILTERED },
		{ "flags",		FLAGS },
		{ "flowspec",		FLOWSPEC },
		{ "fragment",		FRAGMENT },
		{ "from",		FROM },
		{ "graceful",		GRACEFUL },
		{ "group",		GROUP },
		{ "holdtime",		HOLDTIME },
		{ "ibgp",		IBGP },
		{ "ignore",		IGNORE },
		{ "ike",		IKE },
		{ "import-target",	IMPORTTRGT },
		{ "in",			IN },
		{ "include",		INCLUDE },
		{ "inet",		IPV4 },
		{ "inet6",		IPV6 },
		{ "ipsec",		IPSEC },
		{ "key",		KEY },
		{ "large-community",	LARGECOMMUNITY },
		{ "listen",		LISTEN },
		{ "local-address",	LOCALADDR },
		{ "local-as",		LOCALAS },
		{ "localpref",		LOCALPREF },
		{ "log",		LOG },
		{ "match",		MATCH },
		{ "max",		MAX },
		{ "max-as-len",		MAXASLEN },
		{ "max-as-seq",		MAXASSEQ },
		{ "max-communities",	MAXCOMMUNITIES },
		{ "max-ext-communities",	MAXEXTCOMMUNITIES },
		{ "max-large-communities",	MAXLARGECOMMUNITIES },
		{ "max-prefix",		MAXPREFIX },
		{ "maxlen",		MAXLEN },
		{ "md5sig",		MD5SIG },
		{ "med",		MED },
		{ "message",		MESSAGE },
		{ "metric",		METRIC },
		{ "min",		YMIN },
		{ "min-version",	MINVERSION },
		{ "multihop",		MULTIHOP },
		{ "neighbor",		NEIGHBOR },
		{ "neighbor-as",	NEIGHBORAS },
		{ "network",		NETWORK },
		{ "nexthop",		NEXTHOP },
		{ "no-modify",		NOMODIFY },
		{ "none",		NONE },
		{ "notification",	NOTIFICATION },
		{ "on",			ON },
		{ "or-longer",		LONGER },
		{ "origin",		ORIGIN },
		{ "origin-set",		ORIGINSET },
		{ "out",		OUT },
		{ "ovs",		OVS },
		{ "passive",		PASSIVE },
		{ "password",		PASSWORD },
		{ "peer-as",		PEERAS },
		{ "pftable",		PFTABLE },
		{ "plus",		PLUS },
		{ "policy",		POLICY },
		{ "port",		PORT },
		{ "prefix",		PREFIX },
		{ "prefix-set",		PREFIXSET },
		{ "prefixlen",		PREFIXLEN },
		{ "prepend-neighbor",	PREPEND_PEER },
		{ "prepend-self",	PREPEND_SELF },
		{ "priority",		PRIORITY },
		{ "proto",		PROTO },
		{ "provider-as",	PROVIDERAS },
		{ "qualify",		QUALIFY },
		{ "quick",		QUICK },
		{ "rd",			RD },
		{ "rde",		RDE },
		{ "recv",		RECV },
		{ "refresh",		REFRESH },
		{ "reject",		REJECT },
		{ "remote-as",		REMOTEAS },
		{ "restart",		RESTART },
		{ "restricted",		RESTRICTED },
		{ "rib",		RIB },
		{ "roa-set",		ROASET },
		{ "role",		ROLE },
		{ "route-reflector",	REFLECTOR },
		{ "router-id",		ROUTERID },
		{ "rtable",		RTABLE },
		{ "rtlabel",		RTLABEL },
		{ "rtr",		RTR },
		{ "self",		SELF },
		{ "send",		SEND },
		{ "set",		SET },
		{ "socket",		SOCKET },
		{ "source-as",		SOURCEAS },
		{ "spi",		SPI },
		{ "staletime",		STALETIME },
		{ "static",		STATIC },
		{ "tcp",		TCP },
		{ "to",			TO },
		{ "tos",		TOS },
		{ "transit-as",		TRANSITAS },
		{ "transparent-as",	TRANSPARENT },
		{ "ttl-security",	TTLSECURITY },
		{ "unicast",		UNICAST },
		{ "via",		VIA },
		{ "vpn",		VPN },
		{ "weight",		WEIGHT },
	};
	const struct keywords	*p;

	p = bsearch(s, keywords, nitems(keywords), sizeof(keywords[0]), kw_cmp);

	if (p)
		return (p->k_val);
	else
		return (STRING);
}

#define START_EXPAND	1
#define DONE_EXPAND	2

static int	expanding;

int
igetc(void)
{
	int	c;

	while (1) {
		if (file->ungetpos > 0)
			c = file->ungetbuf[--file->ungetpos];
		else
			c = getc(file->stream);

		if (c == START_EXPAND)
			expanding = 1;
		else if (c == DONE_EXPAND)
			expanding = 0;
		else
			break;
	}
	return (c);
}

int
lgetc(int quotec)
{
	int		c, next;

	if (quotec) {
		if ((c = igetc()) == EOF) {
			yyerror("reached end of file while parsing "
			    "quoted string");
			if (file == topfile || popfile() == EOF)
				return (EOF);
			return (quotec);
		}
		return (c);
	}

	while ((c = igetc()) == '\\') {
		next = igetc();
		if (next != '\n') {
			c = next;
			break;
		}
		yylval.lineno = file->lineno;
		file->lineno++;
	}

	if (c == EOF) {
		/*
		 * Fake EOL when hit EOF for the first time. This gets line
		 * count right if last line in included file is syntactically
		 * invalid and has no newline.
		 */
		if (file->eof_reached == 0) {
			file->eof_reached = 1;
			return ('\n');
		}
		while (c == EOF) {
			if (file == topfile || popfile() == EOF)
				return (EOF);
			c = igetc();
		}
	}
	return (c);
}

void
lungetc(int c)
{
	if (c == EOF)
		return;

	if (file->ungetpos >= file->ungetsize) {
		void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
		if (p == NULL)
			err(1, "lungetc");
		file->ungetbuf = p;
		file->ungetsize *= 2;
	}
	file->ungetbuf[file->ungetpos++] = c;
}

int
findeol(void)
{
	int	c;

	/* skip to either EOF or the first real EOL */
	while (1) {
		c = lgetc(0);
		if (c == '\n') {
			file->lineno++;
			break;
		}
		if (c == EOF)
			break;
	}
	return (ERROR);
}

int
expand_macro(void)
{
	char	 buf[MACRO_NAME_LEN];
	char	*p, *val;
	int	 c;

	p = buf;
	while (1) {
		if ((c = lgetc('$')) == EOF)
			return (ERROR);
		if (p + 1 >= buf + sizeof(buf) - 1) {
			yyerror("macro name too long");
			return (ERROR);
		}
		if (isalnum(c) || c == '_') {
			*p++ = c;
			continue;
		}
		*p = '\0';
		lungetc(c);
		break;
	}
	val = symget(buf);
	if (val == NULL) {
		yyerror("macro '%s' not defined", buf);
		return (ERROR);
	}
	p = val + strlen(val) - 1;
	lungetc(DONE_EXPAND);
	while (p >= val) {
		lungetc((unsigned char)*p);
		p--;
	}
	lungetc(START_EXPAND);
	return (0);
}

int
yylex(void)
{
	char	 buf[8096];
	char	*p;
	int	 quotec, next, c;
	int	 token;

top:
	p = buf;
	while ((c = lgetc(0)) == ' ' || c == '\t')
		; /* nothing */

	yylval.lineno = file->lineno;
	if (c == '#')
		while ((c = lgetc(0)) != '\n' && c != EOF)
			; /* nothing */
	if (c == '$' && !expanding) {
		c = expand_macro();
		if (c != 0)
			return (c);
		goto top;
	}

	switch (c) {
	case '\'':
	case '"':
		quotec = c;
		while (1) {
			if ((c = lgetc(quotec)) == EOF)
				return (0);
			if (c == '\n') {
				file->lineno++;
				continue;
			} else if (c == '\\') {
				if ((next = lgetc(quotec)) == EOF)
					return (0);
				if (next == quotec || next == ' ' ||
				    next == '\t')
					c = next;
				else if (next == '\n') {
					file->lineno++;
					continue;
				} else
					lungetc(next);
			} else if (c == quotec) {
				*p = '\0';
				break;
			} else if (c == '\0') {
				yyerror("syntax error: unterminated quote");
				return (findeol());
			}
			if (p + 1 >= buf + sizeof(buf) - 1) {
				yyerror("string too long");
				return (findeol());
			}
			*p++ = c;
		}
		yylval.v.string = strdup(buf);
		if (yylval.v.string == NULL)
			fatal("yylex: strdup");
		return (STRING);
	case '!':
		next = lgetc(0);
		if (next == '=')
			return (NE);
		lungetc(next);
		break;
	case '<':
		next = lgetc(0);
		if (next == '=')
			return (LE);
		lungetc(next);
		break;
	case '>':
		next = lgetc(0);
		if (next == '<')
			return (XRANGE);
		else if (next == '=')
			return (GE);
		lungetc(next);
		break;
	}

#define allowed_to_end_number(x) \
	(isspace(x) || x == ')' || x == ',' || x == '/' || x == '}' || x == '=')

	if (c == '-' || isdigit(c)) {
		do {
			*p++ = c;
			if ((size_t)(p-buf) >= sizeof(buf)) {
				yyerror("string too long");
				return (findeol());
			}
		} while ((c = lgetc(0)) != EOF && isdigit(c));
		lungetc(c);
		if (p == buf + 1 && buf[0] == '-')
			goto nodigits;
		if (c == EOF || allowed_to_end_number(c)) {
			const char *errstr = NULL;

			*p = '\0';
			yylval.v.number = strtonum(buf, LLONG_MIN,
			    LLONG_MAX, &errstr);
			if (errstr) {
				yyerror("\"%s\" invalid number: %s",
				    buf, errstr);
				return (findeol());
			}
			return (NUMBER);
		} else {
nodigits:
			while (p > buf + 1)
				lungetc((unsigned char)*--p);
			c = (unsigned char)*--p;
			if (c == '-')
				return (c);
		}
	}

#define allowed_in_string(x) \
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
	x != '{' && x != '}' && x != '<' && x != '>' && \
	x != '!' && x != '=' && x != '/' && x != '#' && \
	x != ','))

	if (isalnum(c) || c == ':' || c == '_' || c == '*') {
		do {
			if (c == '$' && !expanding) {
				c = expand_macro();
				if (c != 0)
					return (c);
			} else
				*p++ = c;

			if ((size_t)(p-buf) >= sizeof(buf)) {
				yyerror("string too long");
				return (findeol());
			}
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
		lungetc(c);
		*p = '\0';
		if ((token = lookup(buf)) == STRING)
			if ((yylval.v.string = strdup(buf)) == NULL)
				fatal("yylex: strdup");
		return (token);
	}
	if (c == '\n') {
		yylval.lineno = file->lineno;
		file->lineno++;
	}
	if (c == EOF)
		return (0);
	return (c);
}

int
check_file_secrecy(int fd, const char *fname)
{
	struct stat	st;

	if (fstat(fd, &st)) {
		log_warn("cannot stat %s", fname);
		return (-1);
	}
	return (0);
}

struct file *
pushfile(const char *name, int secret)
{
	struct file	*nfile;

	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
		log_warn("%s", __func__);
		return (NULL);
	}
	if ((nfile->name = strdup(name)) == NULL) {
		log_warn("%s", __func__);
		free(nfile);
		return (NULL);
	}
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
		log_warn("%s: %s", __func__, nfile->name);
		free(nfile->name);
		free(nfile);
		return (NULL);
	}
	if (secret &&
	    check_file_secrecy(fileno(nfile->stream), nfile->name)) {
		fclose(nfile->stream);
		free(nfile->name);
		free(nfile);
		return (NULL);
	}
	nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
	nfile->ungetsize = 16;
	nfile->ungetbuf = malloc(nfile->ungetsize);
	if (nfile->ungetbuf == NULL) {
		log_warn("%s", __func__);
		fclose(nfile->stream);
		free(nfile->name);
		free(nfile);
		return (NULL);
	}
	TAILQ_INSERT_TAIL(&files, nfile, entry);
	return (nfile);
}

int
popfile(void)
{
	struct file	*prev;

	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
		prev->errors += file->errors;

	TAILQ_REMOVE(&files, file, entry);
	fclose(file->stream);
	free(file->name);
	free(file->ungetbuf);
	free(file);
	file = prev;
	return (file ? 0 : EOF);
}

static void
init_config(struct bgpd_config *c)
{
	u_int rdomid;

	c->min_holdtime = MIN_HOLDTIME;
	c->holdtime = INTERVAL_HOLD;
	c->staletime = INTERVAL_STALE;
	c->connectretry = INTERVAL_CONNECTRETRY;
	c->bgpid = get_bgpid();
	c->fib_priority = kr_default_prio();
	c->default_tableid = getrtable();
	if (!ktable_exists(c->default_tableid, &rdomid))
		fatalx("current routing table %u does not exist",
		    c->default_tableid);
	if (rdomid != c->default_tableid)
		fatalx("current routing table %u is not a routing domain",
		    c->default_tableid);

	if (asprintf(&c->csock, "%s.%d", SOCKET_NAME, c->default_tableid) == -1)
		fatal(NULL);
}

struct bgpd_config *
parse_config(const char *filename, struct peer_head *ph,
    struct rtr_config_head *rh)
{
	struct sym		*sym, *next;
	struct rde_rib		*rr;
	struct network		*n;
	int			 errors = 0;

	conf = new_config();
	init_config(conf);

	if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL)
		fatal(NULL);
	if ((peerfilter_l = calloc(1, sizeof(struct filter_head))) == NULL)
		fatal(NULL);
	if ((groupfilter_l = calloc(1, sizeof(struct filter_head))) == NULL)
		fatal(NULL);
	TAILQ_INIT(filter_l);
	TAILQ_INIT(peerfilter_l);
	TAILQ_INIT(groupfilter_l);

	curpeer = NULL;
	curgroup = NULL;

	cur_peers = ph;
	cur_rtrs = rh;
	new_peers = &conf->peers;
	netconf = &conf->networks;

	if ((rr = add_rib("Adj-RIB-In")) == NULL)
		fatal("add_rib failed");
	rr->flags = F_RIB_NOFIB | F_RIB_NOEVALUATE;
	if ((rr = add_rib("Loc-RIB")) == NULL)
		fatal("add_rib failed");
	rib_add_fib(rr, conf->default_tableid);
	rr->flags = F_RIB_LOCAL;

	if ((file = pushfile(filename, 1)) == NULL)
		goto errors;
	topfile = file;

	yyparse();
	errors = file->errors;
	popfile();

	/* check that we dont try to announce our own routes */
	TAILQ_FOREACH(n, netconf, entry)
		if (n->net.priority == conf->fib_priority) {
			errors++;
			logit(LOG_CRIT, "network priority %d == fib-priority "
			    "%d is not allowed.",
			    n->net.priority, conf->fib_priority);
		}

	/* Free macros and check which have not been used. */
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
		if ((cmd_opts & BGPD_OPT_VERBOSE2) && !sym->used)
			fprintf(stderr, "warning: macro \"%s\" not "
			    "used\n", sym->nam);
		if (!sym->persist) {
			free(sym->nam);
			free(sym->val);
			TAILQ_REMOVE(&symhead, sym, entry);
			free(sym);
		}
	}

	if (!conf->as) {
		log_warnx("configuration error: AS not given");
		errors++;
	}

	/* clear the globals */
	curpeer = NULL;
	curgroup = NULL;
	cur_peers = NULL;
	new_peers = NULL;
	netconf = NULL;
	curflow = NULL;

	if (errors) {
errors:
		while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) {
			SIMPLEQ_REMOVE_HEAD(&ribnames, entry);
			free(rr);
		}

		filterlist_free(filter_l);
		filterlist_free(peerfilter_l);
		filterlist_free(groupfilter_l);

		free_config(conf);
		return (NULL);
	}

	/* Create default listeners if none where specified. */
	if (TAILQ_EMPTY(conf->listen_addrs)) {
		struct listen_addr *la;

		if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
			fatal("setup_listeners calloc");
		la->fd = -1;
		la->flags = DEFAULT_LISTENER;
		la->reconf = RECONF_REINIT;
		la->sa_len = sizeof(struct sockaddr_in);
		((struct sockaddr_in *)&la->sa)->sin_family = AF_INET;
		((struct sockaddr_in *)&la->sa)->sin_addr.s_addr =
		    htonl(INADDR_ANY);
		((struct sockaddr_in *)&la->sa)->sin_port = htons(BGP_PORT);
		TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);

		if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
			fatal("setup_listeners calloc");
		la->fd = -1;
		la->flags = DEFAULT_LISTENER;
		la->reconf = RECONF_REINIT;
		la->sa_len = sizeof(struct sockaddr_in6);
		((struct sockaddr_in6 *)&la->sa)->sin6_family = AF_INET6;
		((struct sockaddr_in6 *)&la->sa)->sin6_port = htons(BGP_PORT);
		TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
	}

	/* update clusterid in case it was not set explicitly */
	if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
		conf->clusterid = conf->bgpid;

	/*
	 * Concatenate filter list and static group and peer filtersets
	 * together. Static group sets come first then peer sets
	 * last normal filter rules.
	 */
	TAILQ_CONCAT(conf->filters, groupfilter_l, entry);
	TAILQ_CONCAT(conf->filters, peerfilter_l, entry);
	TAILQ_CONCAT(conf->filters, filter_l, entry);

	optimize_filters(conf->filters);

	free(filter_l);
	free(peerfilter_l);
	free(groupfilter_l);

	return (conf);
}

int
symset(const char *nam, const char *val, int persist)
{
	struct sym	*sym;

	TAILQ_FOREACH(sym, &symhead, entry) {
		if (strcmp(nam, sym->nam) == 0)
			break;
	}

	if (sym != NULL) {
		if (sym->persist == 1)
			return (0);
		else {
			free(sym->nam);
			free(sym->val);
			TAILQ_REMOVE(&symhead, sym, entry);
			free(sym);
		}
	}
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
		return (-1);

	sym->nam = strdup(nam);
	if (sym->nam == NULL) {
		free(sym);
		return (-1);
	}
	sym->val = strdup(val);
	if (sym->val == NULL) {
		free(sym->nam);
		free(sym);
		return (-1);
	}
	sym->used = 0;
	sym->persist = persist;
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
	return (0);
}

int
cmdline_symset(char *s)
{
	char	*sym, *val;
	int	ret;

	if ((val = strrchr(s, '=')) == NULL)
		return (-1);
	sym = strndup(s, val - s);
	if (sym == NULL)
		fatal("%s: strndup", __func__);
	ret = symset(sym, val + 1, 1);
	free(sym);

	return (ret);
}

char *
symget(const char *nam)
{
	struct sym	*sym;

	TAILQ_FOREACH(sym, &symhead, entry) {
		if (strcmp(nam, sym->nam) == 0) {
			sym->used = 1;
			return (sym->val);
		}
	}
	return (NULL);
}

static int
cmpcommunity(struct community *a, struct community *b)
{
	if (a->flags > b->flags)
		return 1;
	if (a->flags < b->flags)
		return -1;
	if (a->data1 > b->data1)
		return 1;
	if (a->data1 < b->data1)
		return -1;
	if (a->data2 > b->data2)
		return 1;
	if (a->data2 < b->data2)
		return -1;
	if (a->data3 > b->data3)
		return 1;
	if (a->data3 < b->data3)
		return -1;
	return 0;
}

static int
getcommunity(char *s, int large, uint32_t *val, uint32_t *flag)
{
	long long	 max = USHRT_MAX;
	const char	*errstr;

	*flag = 0;
	*val = 0;
	if (strcmp(s, "*") == 0) {
		*flag = COMMUNITY_ANY;
		return 0;
	} else if (strcmp(s, "neighbor-as") == 0) {
		*flag = COMMUNITY_NEIGHBOR_AS;
		return 0;
	} else if (strcmp(s, "local-as") == 0) {
		*flag = COMMUNITY_LOCAL_AS;
		return 0;
	}
	if (large)
		max = UINT_MAX;
	*val = strtonum(s, 0, max, &errstr);
	if (errstr) {
		yyerror("Community %s is %s (max: %lld)", s, errstr, max);
		return -1;
	}
	return 0;
}

static void
setcommunity(struct community *c, uint32_t as, uint32_t data,
    uint32_t asflag, uint32_t dataflag)
{
	c->flags = COMMUNITY_TYPE_BASIC;
	c->flags |= asflag << 8;
	c->flags |= dataflag << 16;
	c->data1 = as;
	c->data2 = data;
	c->data3 = 0;
}

static int
parselargecommunity(struct community *c, char *s)
{
	char *p, *q;
	uint32_t dflag1, dflag2, dflag3;

	if ((p = strchr(s, ':')) == NULL) {
		yyerror("Bad community syntax");
		return (-1);
	}
	*p++ = 0;

	if ((q = strchr(p, ':')) == NULL) {
		yyerror("Bad community syntax");
		return (-1);
	}
	*q++ = 0;

	if (getcommunity(s, 1, &c->data1, &dflag1) == -1 ||
	    getcommunity(p, 1, &c->data2, &dflag2) == -1 ||
	    getcommunity(q, 1, &c->data3, &dflag3) == -1)
		return (-1);
	c->flags = COMMUNITY_TYPE_LARGE;
	c->flags |= dflag1 << 8;
	c->flags |= dflag2 << 16;
	c->flags |= dflag3 << 24;
	return (0);
}

int
parsecommunity(struct community *c, int type, char *s)
{
	char *p;
	uint32_t as, data, asflag, dataflag;

	if (type == COMMUNITY_TYPE_LARGE)
		return parselargecommunity(c, s);

	/* Well-known communities */
	if (strcasecmp(s, "GRACEFUL_SHUTDOWN") == 0) {
		setcommunity(c, COMMUNITY_WELLKNOWN,
		    COMMUNITY_GRACEFUL_SHUTDOWN, 0, 0);
		return (0);
	} else if (strcasecmp(s, "NO_EXPORT") == 0) {
		setcommunity(c, COMMUNITY_WELLKNOWN,
		    COMMUNITY_NO_EXPORT, 0, 0);
		return (0);
	} else if (strcasecmp(s, "NO_ADVERTISE") == 0) {
		setcommunity(c, COMMUNITY_WELLKNOWN,
		    COMMUNITY_NO_ADVERTISE, 0, 0);
		return (0);
	} else if (strcasecmp(s, "NO_EXPORT_SUBCONFED") == 0) {
		setcommunity(c, COMMUNITY_WELLKNOWN,
		    COMMUNITY_NO_EXPSUBCONFED, 0, 0);
		return (0);
	} else if (strcasecmp(s, "NO_PEER") == 0) {
		setcommunity(c, COMMUNITY_WELLKNOWN,
		    COMMUNITY_NO_PEER, 0, 0);
		return (0);
	} else if (strcasecmp(s, "BLACKHOLE") == 0) {
		setcommunity(c, COMMUNITY_WELLKNOWN,
		    COMMUNITY_BLACKHOLE, 0, 0);
		return (0);
	}

	if ((p = strchr(s, ':')) == NULL) {
		yyerror("Bad community syntax");
		return (-1);
	}
	*p++ = 0;

	if (getcommunity(s, 0, &as, &asflag) == -1 ||
	    getcommunity(p, 0, &data, &dataflag) == -1)
		return (-1);
	setcommunity(c, as, data, asflag, dataflag);
	return (0);
}

static int
parsesubtype(char *name, int *type, int *subtype)
{
	const struct ext_comm_pairs *cp;
	int found = 0;

	for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
		if (strcmp(name, cp->subname) == 0) {
			if (found == 0) {
				*type = cp->type;
				*subtype = cp->subtype;
			}
			found++;
		}
	}
	if (found > 1)
		*type = -1;
	return (found);
}

static int
parseextvalue(int type, char *s, uint32_t *v, uint32_t *flag)
{
	const char	*errstr;
	char		*p;
	struct in_addr	 ip;
	uint32_t	 uvalh, uval;

	if (type != -1) {
		/* nothing */
	} else if (strcmp(s, "neighbor-as") == 0) {
		*flag = COMMUNITY_NEIGHBOR_AS;
		*v = 0;
		return EXT_COMMUNITY_TRANS_TWO_AS;
	} else if (strcmp(s, "local-as") == 0) {
		*flag = COMMUNITY_LOCAL_AS;
		*v = 0;
		return EXT_COMMUNITY_TRANS_TWO_AS;
	} else if ((p = strchr(s, '.')) == NULL) {
		/* AS_PLAIN number (4 or 2 byte) */
		strtonum(s, 0, USHRT_MAX, &errstr);
		if (errstr == NULL)
			type = EXT_COMMUNITY_TRANS_TWO_AS;
		else
			type = EXT_COMMUNITY_TRANS_FOUR_AS;
	} else if (strchr(p + 1, '.') == NULL) {
		/* AS_DOT number (4-byte) */
		type = EXT_COMMUNITY_TRANS_FOUR_AS;
	} else {
		/* more than one dot -> IP address */
		type = EXT_COMMUNITY_TRANS_IPV4;
	}

	switch (type & EXT_COMMUNITY_VALUE) {
	case EXT_COMMUNITY_TRANS_TWO_AS:
		uval = strtonum(s, 0, USHRT_MAX, &errstr);
		if (errstr) {
			yyerror("Bad ext-community %s is %s", s, errstr);
			return (-1);
		}
		*v = uval;
		break;
	case EXT_COMMUNITY_TRANS_FOUR_AS:
		if ((p = strchr(s, '.')) == NULL) {
			uval = strtonum(s, 0, UINT_MAX, &errstr);
			if (errstr) {
				yyerror("Bad ext-community %s is %s", s,
				    errstr);
				return (-1);
			}
			*v = uval;
			break;
		}
		*p++ = '\0';
		uvalh = strtonum(s, 0, USHRT_MAX, &errstr);
		if (errstr) {
			yyerror("Bad ext-community %s is %s", s, errstr);
			return (-1);
		}
		uval = strtonum(p, 0, USHRT_MAX, &errstr);
		if (errstr) {
			yyerror("Bad ext-community %s is %s", p, errstr);
			return (-1);
		}
		*v = uval | (uvalh << 16);
		break;
	case EXT_COMMUNITY_TRANS_IPV4:
		if (inet_pton(AF_INET, s, &ip) != 1) {
			yyerror("Bad ext-community %s not parseable", s);
			return (-1);
		}
		*v = ntohl(ip.s_addr);
		break;
	default:
		fatalx("%s: unexpected type %d", __func__, type);
	}
	return (type);
}

int
parseextcommunity(struct community *c, char *t, char *s)
{
	const struct ext_comm_pairs *cp;
	char		*p, *ep;
	uint64_t	 ullval;
	uint32_t	 uval, uval2, dflag1 = 0, dflag2 = 0;
	int		 type = 0, subtype = 0;

	if (strcmp(t, "*") == 0 && strcmp(s, "*") == 0) {
		c->flags = COMMUNITY_TYPE_EXT;
		c->flags |= COMMUNITY_ANY << 24;
		return (0);
	}
	if (parsesubtype(t, &type, &subtype) == 0) {
		yyerror("Bad ext-community unknown type");
		return (-1);
	}

	switch (type) {
	case EXT_COMMUNITY_TRANS_TWO_AS:
	case EXT_COMMUNITY_TRANS_FOUR_AS:
	case EXT_COMMUNITY_TRANS_IPV4:
	case EXT_COMMUNITY_GEN_TWO_AS:
	case EXT_COMMUNITY_GEN_FOUR_AS:
	case EXT_COMMUNITY_GEN_IPV4:
	case -1:
		if (strcmp(s, "*") == 0) {
			dflag1 = COMMUNITY_ANY;
			break;
		}
		if ((p = strchr(s, ':')) == NULL) {
			yyerror("Bad ext-community %s", s);
			return (-1);
		}
		*p++ = '\0';
		if ((type = parseextvalue(type, s, &uval, &dflag1)) == -1)
			return (-1);

		switch (type) {
		case EXT_COMMUNITY_TRANS_TWO_AS:
		case EXT_COMMUNITY_GEN_TWO_AS:
			if (getcommunity(p, 1, &uval2, &dflag2) == -1)
				return (-1);
			break;
		case EXT_COMMUNITY_TRANS_IPV4:
		case EXT_COMMUNITY_TRANS_FOUR_AS:
		case EXT_COMMUNITY_GEN_IPV4:
		case EXT_COMMUNITY_GEN_FOUR_AS:
			if (getcommunity(p, 0, &uval2, &dflag2) == -1)
				return (-1);
			break;
		default:
			fatalx("parseextcommunity: unexpected result");
		}

		c->data1 = uval;
		c->data2 = uval2;
		break;
	case EXT_COMMUNITY_TRANS_OPAQUE:
	case EXT_COMMUNITY_TRANS_EVPN:
		if (strcmp(s, "*") == 0) {
			dflag1 = COMMUNITY_ANY;
			break;
		}
		errno = 0;
		ullval = strtoull(s, &ep, 0);
		if (s[0] == '\0' || *ep != '\0') {
			yyerror("Bad ext-community bad value");
			return (-1);
		}
		if (errno == ERANGE && ullval > EXT_COMMUNITY_OPAQUE_MAX) {
			yyerror("Bad ext-community value too big");
			return (-1);
		}
		c->data1 = ullval >> 32;
		c->data2 = ullval;
		break;
	case EXT_COMMUNITY_NON_TRANS_OPAQUE:
		if (subtype == EXT_COMMUNITY_SUBTYPE_OVS) {
			if (strcmp(s, "valid") == 0) {
				c->data2 = EXT_COMMUNITY_OVS_VALID;
				break;
			} else if (strcmp(s, "invalid") == 0) {
				c->data2 = EXT_COMMUNITY_OVS_INVALID;
				break;
			} else if (strcmp(s, "not-found") == 0) {
				c->data2 = EXT_COMMUNITY_OVS_NOTFOUND;
				break;
			} else if (strcmp(s, "*") == 0) {
				dflag1 = COMMUNITY_ANY;
				break;
			}
		}
		yyerror("Bad ext-community %s", s);
		return (-1);
	}

	c->data3 = type << 8 | subtype;

	/* special handling of ext-community rt * since type is not known */
	if (dflag1 == COMMUNITY_ANY && type == -1) {
		c->flags = COMMUNITY_TYPE_EXT;
		c->flags |= dflag1 << 8;
		return (0);
	}

	/* verify type/subtype combo */
	for (cp = iana_ext_comms; cp->subname != NULL; cp++) {
		if (cp->type == type && cp->subtype == subtype) {
			c->flags = COMMUNITY_TYPE_EXT;
			c->flags |= dflag1 << 8;
			c->flags |= dflag2 << 16;
			return (0);
		}
	}

	yyerror("Bad ext-community bad format for type");
	return (-1);
}

struct peer *
alloc_peer(void)
{
	struct peer	*p;

	if ((p = calloc(1, sizeof(struct peer))) == NULL)
		fatal("new_peer");

	/* some sane defaults */
	p->state = STATE_NONE;
	p->reconf_action = RECONF_REINIT;
	p->conf.distance = 1;
	p->conf.export_type = EXPORT_UNSET;
	p->conf.capabilities.refresh = 1;
	p->conf.capabilities.grestart.restart = 1;
	p->conf.capabilities.as4byte = 1;
	p->conf.capabilities.policy = 1;
	p->conf.local_as = conf->as;
	p->conf.local_short_as = conf->short_as;
	p->conf.remote_port = BGP_PORT;

	if (conf->flags & BGPD_FLAG_DECISION_TRANS_AS)
		p->conf.flags |= PEERFLAG_TRANS_AS;
	if (conf->flags & BGPD_FLAG_DECISION_ALL_PATHS)
		p->conf.flags |= PEERFLAG_EVALUATE_ALL;
	if (conf->flags & BGPD_FLAG_PERMIT_AS_SET)
		p->conf.flags |= PEERFLAG_PERMIT_AS_SET;

	return (p);
}

struct peer *
new_peer(void)
{
	struct peer		*p;

	p = alloc_peer();

	if (curgroup != NULL) {
		p->conf = curgroup->conf;
		p->auth_conf = curgroup->auth_conf;
		p->conf.groupid = curgroup->conf.id;
	}
	return (p);
}

struct peer *
new_group(void)
{
	return (alloc_peer());
}

int
add_mrtconfig(enum mrt_type type, char *name, int timeout, struct peer *p,
    char *rib)
{
	struct mrt	*m, *n;

	LIST_FOREACH(m, conf->mrt, entry) {
		if ((rib && strcmp(rib, m->rib)) ||
		    (!rib && *m->rib))
			continue;
		if (p == NULL) {
			if (m->peer_id != 0 || m->group_id != 0)
				continue;
		} else {
			if (m->peer_id != p->conf.id ||
			    m->group_id != p->conf.groupid)
				continue;
		}
		if (m->type == type) {
			yyerror("only one mrtdump per type allowed.");
			return (-1);
		}
	}

	if ((n = calloc(1, sizeof(struct mrt_config))) == NULL)
		fatal("add_mrtconfig");

	n->type = type;
	n->state = MRT_STATE_OPEN;
	if (strlcpy(MRT2MC(n)->name, name, sizeof(MRT2MC(n)->name)) >=
	    sizeof(MRT2MC(n)->name)) {
		yyerror("filename \"%s\" too long: max %zu",
		    name, sizeof(MRT2MC(n)->name) - 1);
		free(n);
		return (-1);
	}
	TAILQ_INIT(&MRT2MC(n)->timer);
	MRT2MC(n)->ReopenTimerInterval = timeout;
	if (p != NULL) {
		if (curgroup == p) {
			n->peer_id = 0;
			n->group_id = p->conf.id;
		} else {
			n->peer_id = p->conf.id;
			n->group_id = p->conf.groupid;
		}
	}
	if (rib) {
		if (!find_rib(rib)) {
			yyerror("rib \"%s\" does not exist.", rib);
			free(n);
			return (-1);
		}
		if (strlcpy(n->rib, rib, sizeof(n->rib)) >=
		    sizeof(n->rib)) {
			yyerror("rib name \"%s\" too long: max %zu",
			    name, sizeof(n->rib) - 1);
			free(n);
			return (-1);
		}
	}

	LIST_INSERT_HEAD(conf->mrt, n, entry);

	return (0);
}

struct rde_rib *
add_rib(char *name)
{
	struct rde_rib	*rr;

	if ((rr = find_rib(name)) == NULL) {
		if ((rr = calloc(1, sizeof(*rr))) == NULL) {
			log_warn("add_rib");
			return (NULL);
		}
		if (strlcpy(rr->name, name, sizeof(rr->name)) >=
		    sizeof(rr->name)) {
			yyerror("rib name \"%s\" too long: max %zu",
			    name, sizeof(rr->name) - 1);
			free(rr);
			return (NULL);
		}
		rr->flags = F_RIB_NOFIB;
		SIMPLEQ_INSERT_TAIL(&ribnames, rr, entry);
	}
	return (rr);
}

struct rde_rib *
find_rib(char *name)
{
	struct rde_rib	*rr;

	SIMPLEQ_FOREACH(rr, &ribnames, entry) {
		if (!strcmp(rr->name, name))
			return (rr);
	}
	return (NULL);
}

int
rib_add_fib(struct rde_rib *rr, u_int rtableid)
{
	u_int	rdom;

	if (!ktable_exists(rtableid, &rdom)) {
		yyerror("rtable id %u does not exist", rtableid);
		return (-1);
	}
	/*
	 * conf->default_tableid is also a rdomain because that is checked
	 * in init_config()
	 */
	if (rdom != conf->default_tableid) {
		log_warnx("rtable %u does not belong to rdomain %u",
		    rtableid, conf->default_tableid);
		return (-1);
	}
	rr->rtableid = rtableid;
	rr->flags &= ~F_RIB_NOFIB;
	return (0);
}

struct prefixset *
find_prefixset(char *name, struct prefixset_head *p)
{
	struct prefixset *ps;

	SIMPLEQ_FOREACH(ps, p, entry) {
		if (!strcmp(ps->name, name))
			return (ps);
	}
	return (NULL);
}

int
get_id(struct peer *newpeer)
{
	static uint32_t id = PEER_ID_STATIC_MIN;
	struct peer	*p = NULL;

	/* check if the peer already existed before */
	if (newpeer->conf.remote_addr.aid) {
		/* neighbor */
		if (cur_peers)
			RB_FOREACH(p, peer_head, cur_peers)
				if (p->conf.remote_masklen ==
				    newpeer->conf.remote_masklen &&
				    memcmp(&p->conf.remote_addr,
				    &newpeer->conf.remote_addr,
				    sizeof(p->conf.remote_addr)) == 0)
					break;
		if (p) {
			newpeer->conf.id = p->conf.id;
			return (0);
		}
	} else {
		/* group */
		if (cur_peers)
			RB_FOREACH(p, peer_head, cur_peers)
				if (strcmp(p->conf.group,
				    newpeer->conf.group) == 0)
					break;
		if (p) {
			newpeer->conf.id = p->conf.groupid;
			return (0);
		}
	}

	/* else new one */
	if (id < PEER_ID_STATIC_MAX) {
		newpeer->conf.id = id++;
		return (0);
	}

	return (-1);
}

int
merge_prefixspec(struct filter_prefix *p, struct filter_prefixlen *pl)
{
	uint8_t max_len = 0;

	switch (p->addr.aid) {
	case AID_INET:
	case AID_VPN_IPv4:
		max_len = 32;
		break;
	case AID_INET6:
	case AID_VPN_IPv6:
		max_len = 128;
		break;
	}

	if (pl->op == OP_NONE) {
		p->len_min = p->len_max = p->len;
		return (0);
	}

	if (pl->len_min == -1)
		pl->len_min = 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->len) {
		yyerror("prefixlen %d smaller than prefix, limit %d",
		    pl->len_min, p->len);
		return (-1);
	}

	p->op = pl->op;
	p->len_min = pl->len_min;
	p->len_max = pl->len_max;
	return (0);
}

int
expand_rule(struct filter_rule *rule, struct filter_rib_l *rib,
    struct filter_peers_l *peer, struct filter_match_l *match,
    struct filter_set_head *set)
{
	struct filter_rule	*r;
	struct filter_rib_l	*rb, *rbnext;
	struct filter_peers_l	*p, *pnext;
	struct filter_prefix_l	*prefix, *prefix_next;
	struct filter_as_l	*a, *anext;
	struct filter_set	*s;

	rb = rib;
	do {
		p = peer;
		do {
			a = match->as_l;
			do {
				prefix = match->prefix_l;
				do {
					if ((r = calloc(1,
					    sizeof(struct filter_rule))) ==
						 NULL) {
						log_warn("expand_rule");
						return (-1);
					}

					memcpy(r, rule, sizeof(*r));
					memcpy(&r->match, match,
					    sizeof(struct filter_match));
					filterset_copy(set, &r->set);

					if (rb != NULL)
						strlcpy(r->rib, rb->name,
						    sizeof(r->rib));

					if (p != NULL)
						memcpy(&r->peer, &p->p,
						    sizeof(r->peer));

					if (prefix != NULL)
						memcpy(&r->match.prefix,
						    &prefix->p,
						    sizeof(r->match.prefix));

					if (a != NULL)
						memcpy(&r->match.as, &a->a,
						    sizeof(struct filter_as));

					TAILQ_INSERT_TAIL(filter_l, r, entry);

					if (prefix != NULL)
						prefix = prefix->next;
				} while (prefix != NULL);

				if (a != NULL)
					a = a->next;
			} while (a != NULL);

			if (p != NULL)
				p = p->next;
		} while (p != NULL);

		if (rb != NULL)
			rb = rb->next;
	} while (rb != NULL);

	for (rb = rib; rb != NULL; rb = rbnext) {
		rbnext = rb->next;
		free(rb);
	}

	for (p = peer; p != NULL; p = pnext) {
		pnext = p->next;
		free(p);
	}

	for (a = match->as_l; a != NULL; a = anext) {
		anext = a->next;
		free(a);
	}

	for (prefix = match->prefix_l; prefix != NULL; prefix = prefix_next) {
		prefix_next = prefix->next;
		free(prefix);
	}

	if (set != NULL) {
		while ((s = TAILQ_FIRST(set)) != NULL) {
			TAILQ_REMOVE(set, s, entry);
			free(s);
		}
		free(set);
	}

	return (0);
}

static int
h2i(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	else if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	else
		return -1;
}

int
str2key(char *s, char *dest, size_t max_len)
{
	size_t	i;

	if (strlen(s) / 2 > max_len) {
		yyerror("key too long");
		return (-1);
	}

	if (strlen(s) % 2) {
		yyerror("key must be of even length");
		return (-1);
	}

	for (i = 0; i < strlen(s) / 2; i++) {
		int hi, lo;

		hi = h2i(s[2 * i]);
		lo = h2i(s[2 * i + 1]);
		if (hi == -1 || lo == -1) {
			yyerror("key must be specified in hex");
			return (-1);
		}
		dest[i] = (hi << 4) | lo;
	}

	return (0);
}

int
neighbor_consistent(struct peer *p)
{
	struct bgpd_addr *local_addr;
	struct peer *xp;

	switch (p->conf.remote_addr.aid) {
	case AID_INET:
		local_addr = &p->conf.local_addr_v4;
		break;
	case AID_INET6:
		local_addr = &p->conf.local_addr_v6;
		break;
	default:
		yyerror("Bad address family for remote-addr");
		return (-1);
	}

	/* with any form of ipsec local-address is required */
	if ((p->auth_conf.method == AUTH_IPSEC_IKE_ESP ||
	    p->auth_conf.method == AUTH_IPSEC_IKE_AH ||
	    p->auth_conf.method == AUTH_IPSEC_MANUAL_ESP ||
	    p->auth_conf.method == AUTH_IPSEC_MANUAL_AH) &&
	    local_addr->aid == AID_UNSPEC) {
		yyerror("neighbors with any form of IPsec configured "
		    "need local-address to be specified");
		return (-1);
	}

	/* with static keying we need both directions */
	if ((p->auth_conf.method == AUTH_IPSEC_MANUAL_ESP ||
	    p->auth_conf.method == AUTH_IPSEC_MANUAL_AH) &&
	    (!p->auth_conf.spi_in || !p->auth_conf.spi_out)) {
		yyerror("with manual keyed IPsec, SPIs and keys "
		    "for both directions are required");
		return (-1);
	}

	if (!conf->as) {
		yyerror("AS needs to be given before neighbor definitions");
		return (-1);
	}

	/* set default values if they where undefined */
	p->conf.ebgp = (p->conf.remote_as != conf->as);
	if (p->conf.enforce_as == ENFORCE_AS_UNDEF)
		p->conf.enforce_as = p->conf.ebgp ?
		    ENFORCE_AS_ON : ENFORCE_AS_OFF;
	if (p->conf.enforce_local_as == ENFORCE_AS_UNDEF)
		p->conf.enforce_local_as = ENFORCE_AS_ON;

	if (p->conf.remote_as == 0 && !p->conf.template) {
		yyerror("peer AS may not be zero");
		return (-1);
	}

	/* EBGP neighbors are not allowed in route reflector clusters */
	if (p->conf.reflector_client && p->conf.ebgp) {
		yyerror("EBGP neighbors are not allowed in route "
		    "reflector clusters");
		return (-1);
	}

	/* BGP role and RFC 9234 role are only valid for EBGP neighbors */
	if (!p->conf.ebgp) {
		p->conf.role = ROLE_NONE;
		p->conf.capabilities.policy = 0;
	} else if (p->conf.role == ROLE_NONE) {
		/* no role, no policy capability */
		p->conf.capabilities.policy = 0;
	}

	/* check for duplicate peer definitions */
	RB_FOREACH(xp, peer_head, new_peers)
		if (xp->conf.remote_masklen ==
		    p->conf.remote_masklen &&
		    memcmp(&xp->conf.remote_addr,
		    &p->conf.remote_addr,
		    sizeof(p->conf.remote_addr)) == 0)
			break;
	if (xp != NULL) {
		char *descr = log_fmt_peer(&p->conf);
		yyerror("duplicate %s", descr);
		free(descr);
		return (-1);
	}

	return (0);
}

static void
filterset_add(struct filter_set_head *sh, struct filter_set *s)
{
	struct filter_set	*t;

	TAILQ_FOREACH(t, sh, entry) {
		if (s->type < t->type) {
			TAILQ_INSERT_BEFORE(t, s, entry);
			return;
		}
		if (s->type == t->type) {
			switch (s->type) {
			case ACTION_SET_COMMUNITY:
			case ACTION_DEL_COMMUNITY:
				switch (cmpcommunity(&s->action.community,
				    &t->action.community)) {
				case -1:
					TAILQ_INSERT_BEFORE(t, s, entry);
					return;
				case 0:
					break;
				case 1:
					continue;
				}
				break;
			case ACTION_SET_NEXTHOP:
				/* only last nexthop per AF matters */
				if (s->action.nexthop.aid <
				    t->action.nexthop.aid) {
					TAILQ_INSERT_BEFORE(t, s, entry);
					return;
				} else if (s->action.nexthop.aid ==
				    t->action.nexthop.aid) {
					t->action.nexthop = s->action.nexthop;
					break;
				}
				continue;
			case ACTION_SET_NEXTHOP_BLACKHOLE:
			case ACTION_SET_NEXTHOP_REJECT:
			case ACTION_SET_NEXTHOP_NOMODIFY:
			case ACTION_SET_NEXTHOP_SELF:
				/* set it only once */
				break;
			case ACTION_SET_LOCALPREF:
			case ACTION_SET_MED:
			case ACTION_SET_WEIGHT:
				/* only last set matters */
				t->action.metric = s->action.metric;
				break;
			case ACTION_SET_RELATIVE_LOCALPREF:
			case ACTION_SET_RELATIVE_MED:
			case ACTION_SET_RELATIVE_WEIGHT:
				/* sum all relative numbers */
				t->action.relative += s->action.relative;
				break;
			case ACTION_SET_ORIGIN:
				/* only last set matters */
				t->action.origin = s->action.origin;
				break;
			case ACTION_PFTABLE:
				/* only last set matters */
				strlcpy(t->action.pftable, s->action.pftable,
				    sizeof(t->action.pftable));
				break;
			case ACTION_RTLABEL:
				/* only last set matters */
				strlcpy(t->action.rtlabel, s->action.rtlabel,
				    sizeof(t->action.rtlabel));
				break;
			default:
				break;
			}
			free(s);
			return;
		}
	}

	TAILQ_INSERT_TAIL(sh, s, entry);
}

int
merge_filterset(struct filter_set_head *sh, struct filter_set *s)
{
	struct filter_set	*t;

	TAILQ_FOREACH(t, sh, entry) {
		/*
		 * need to cycle across the full list because even
		 * if types are not equal filterset_cmp() may return 0.
		 */
		if (filterset_cmp(s, t) == 0) {
			if (s->type == ACTION_SET_COMMUNITY)
				yyerror("community is already set");
			else if (s->type == ACTION_DEL_COMMUNITY)
				yyerror("community will already be deleted");
			else
				yyerror("redefining set parameter %s",
				    filterset_name(s->type));
			return (-1);
		}
	}

	filterset_add(sh, s);
	return (0);
}

static int
filter_equal(struct filter_rule *fa, struct filter_rule *fb)
{
	if (fa == NULL || fb == NULL)
		return 0;
	if (fa->action != fb->action || fa->quick != fb->quick ||
	    fa->dir != fb->dir)
		return 0;
	if (memcmp(&fa->peer, &fb->peer, sizeof(fa->peer)))
		return 0;
	if (memcmp(&fa->match, &fb->match, sizeof(fa->match)))
		return 0;

	return 1;
}

/* do a basic optimization by folding equal rules together */
void
optimize_filters(struct filter_head *fh)
{
	struct filter_rule *r, *nr;

	TAILQ_FOREACH_SAFE(r, fh, entry, nr) {
		while (filter_equal(r, nr)) {
			struct filter_set	*t;

			while ((t = TAILQ_FIRST(&nr->set)) != NULL) {
				TAILQ_REMOVE(&nr->set, t, entry);
				filterset_add(&r->set, t);
			}

			TAILQ_REMOVE(fh, nr, entry);
			free(nr);
			nr = TAILQ_NEXT(r, entry);
		}
	}
}

struct filter_rule *
get_rule(enum action_types type)
{
	struct filter_rule	*r;
	int			 out;

	switch (type) {
	case ACTION_SET_PREPEND_SELF:
	case ACTION_SET_NEXTHOP_NOMODIFY:
	case ACTION_SET_NEXTHOP_SELF:
		out = 1;
		break;
	default:
		out = 0;
		break;
	}
	r = (curpeer == curgroup) ? curgroup_filter[out] : curpeer_filter[out];
	if (r == NULL) {
		if ((r = calloc(1, sizeof(struct filter_rule))) == NULL)
			fatal(NULL);
		r->quick = 0;
		r->dir = out ? DIR_OUT : DIR_IN;
		r->action = ACTION_NONE;
		TAILQ_INIT(&r->set);
		if (curpeer == curgroup) {
			/* group */
			r->peer.groupid = curgroup->conf.id;
			curgroup_filter[out] = r;
		} else {
			/* peer */
			r->peer.peerid = curpeer->conf.id;
			curpeer_filter[out] = r;
		}
	}
	return (r);
}

struct set_table *curset;
static int
new_as_set(char *name)
{
	struct as_set *aset;

	if (as_sets_lookup(&conf->as_sets, name) != NULL) {
		yyerror("as-set \"%s\" already exists", name);
		return -1;
	}

	aset = as_sets_new(&conf->as_sets, name, 0, sizeof(uint32_t));
	if (aset == NULL)
		fatal(NULL);

	curset = aset->set;
	return 0;
}

static void
add_as_set(uint32_t as)
{
	if (curset == NULL)
		fatalx("%s: bad mojo jojo", __func__);

	if (set_add(curset, &as, 1) != 0)
		fatal(NULL);
}

static void
done_as_set(void)
{
	curset = NULL;
}

static struct prefixset *
new_prefix_set(char *name, int is_roa)
{
	const char *type = "prefix-set";
	struct prefixset_head *sets = &conf->prefixsets;
	struct prefixset *pset;

	if (is_roa) {
		type = "origin-set";
		sets = &conf->originsets;
	}

	if (find_prefixset(name, sets) != NULL) {
		yyerror("%s \"%s\" already exists", type, name);
		return NULL;
	}
	if ((pset = calloc(1, sizeof(*pset))) == NULL)
		fatal("prefixset");
	if (strlcpy(pset->name, name, sizeof(pset->name)) >=
	    sizeof(pset->name)) {
		yyerror("%s \"%s\" too long: max %zu", type,
		    name, sizeof(pset->name) - 1);
		free(pset);
		return NULL;
	}
	RB_INIT(&pset->psitems);
	RB_INIT(&pset->roaitems);
	return pset;
}

static void
add_roa_set(struct prefixset_item *npsi, uint32_t as, uint8_t max,
    time_t expires)
{
	struct roa *roa, *r;

	if ((roa = calloc(1, sizeof(*roa))) == NULL)
		fatal("add_roa_set");

	roa->aid = npsi->p.addr.aid;
	roa->prefixlen = npsi->p.len;
	roa->maxlen = max;
	roa->asnum = as;
	roa->expires = expires;
	switch (roa->aid) {
	case AID_INET:
		roa->prefix.inet = npsi->p.addr.v4;
		break;
	case AID_INET6:
		roa->prefix.inet6 = npsi->p.addr.v6;
		break;
	default:
		fatalx("Bad address family for roa_set address");
	}

	r = RB_INSERT(roa_tree, curroatree, roa);
	if (r != NULL) {
		/* just ignore duplicates */
		if (r->expires != 0 && expires != 0 && expires > r->expires)
			r->expires = expires;
		free(roa);
	}
}

static struct rtr_config *
get_rtr(struct bgpd_addr *addr)
{
	struct rtr_config *n;

	n = calloc(1, sizeof(*n));
	if (n == NULL) {
		yyerror("out of memory");
		return NULL;
	}

	n->remote_addr = *addr;
	strlcpy(n->descr, log_addr(addr), sizeof(currtr->descr));

	return n;
}

static int
insert_rtr(struct rtr_config *new)
{
	static uint32_t id;
	struct rtr_config *r;

	if (id == UINT32_MAX) {
		yyerror("out of rtr session IDs");
		return -1;
	}

	SIMPLEQ_FOREACH(r, &conf->rtrs, entry)
		if (memcmp(&r->remote_addr, &new->remote_addr,
		    sizeof(r->remote_addr)) == 0 &&
		    r->remote_port == new->remote_port) {
			yyerror("duplicate rtr session to %s:%u",
			    log_addr(&new->remote_addr), new->remote_port);
			return -1;
		}

	if (cur_rtrs)
		SIMPLEQ_FOREACH(r, cur_rtrs, entry)
			if (memcmp(&r->remote_addr, &new->remote_addr,
			    sizeof(r->remote_addr)) == 0 &&
			    r->remote_port == new->remote_port) {
				new->id = r->id;
				break;
			}

	if (new->id == 0)
		new->id = ++id;

	SIMPLEQ_INSERT_TAIL(&conf->rtrs, new, entry);

	return 0;
}

static int
merge_aspa_set(uint32_t as, struct aspa_tas_l *tas, time_t expires)
{
	struct aspa_set	*aspa, needle = { .as = as };
	uint32_t i, num, *newtas;

	aspa = RB_FIND(aspa_tree, &conf->aspa, &needle);
	if (aspa == NULL) {
		if ((aspa = calloc(1, sizeof(*aspa))) == NULL) {
			yyerror("out of memory");
			return -1;
		}
		aspa->as = as;
		aspa->expires = expires;
		RB_INSERT(aspa_tree, &conf->aspa, aspa);
	}

	if (MAX_ASPA_SPAS_COUNT - aspa->num <= tas->num) {
		yyerror("too many providers for customer-as %u", as);
		return -1;
	}
	num = aspa->num + tas->num;
	newtas = recallocarray(aspa->tas, aspa->num, num, sizeof(uint32_t));
	if (newtas == NULL) {
		yyerror("out of memory");
		return -1;
	}
	/* fill starting at the end since the tas list is reversed */
	if (num > 0) {
		for (i = num - 1; tas; tas = tas->next, i--)
			newtas[i] = tas->as;
	}

	aspa->num = num;
	aspa->tas = newtas;

	/* take the longest expiry time, same logic as for ROA entries */
	if (aspa->expires != 0 && expires != 0 && expires > aspa->expires)
		aspa->expires = expires;

	return 0;
}

static int
kw_casecmp(const void *k, const void *e)
{
	return (strcasecmp(k, ((const struct keywords *)e)->k_name));
}

static int
map_tos(char *s, int *val)
{
	/* DiffServ Codepoints and other TOS mappings */
	const struct keywords	 toswords[] = {
		{ "af11",		IPTOS_DSCP_AF11 },
		{ "af12",		IPTOS_DSCP_AF12 },
		{ "af13",		IPTOS_DSCP_AF13 },
		{ "af21",		IPTOS_DSCP_AF21 },
		{ "af22",		IPTOS_DSCP_AF22 },
		{ "af23",		IPTOS_DSCP_AF23 },
		{ "af31",		IPTOS_DSCP_AF31 },
		{ "af32",		IPTOS_DSCP_AF32 },
		{ "af33",		IPTOS_DSCP_AF33 },
		{ "af41",		IPTOS_DSCP_AF41 },
		{ "af42",		IPTOS_DSCP_AF42 },
		{ "af43",		IPTOS_DSCP_AF43 },
		{ "critical",		IPTOS_PREC_CRITIC_ECP },
		{ "cs0",		IPTOS_DSCP_CS0 },
		{ "cs1",		IPTOS_DSCP_CS1 },
		{ "cs2",		IPTOS_DSCP_CS2 },
		{ "cs3",		IPTOS_DSCP_CS3 },
		{ "cs4",		IPTOS_DSCP_CS4 },
		{ "cs5",		IPTOS_DSCP_CS5 },
		{ "cs6",		IPTOS_DSCP_CS6 },
		{ "cs7",		IPTOS_DSCP_CS7 },
		{ "ef",			IPTOS_DSCP_EF },
		{ "inetcontrol",	IPTOS_PREC_INTERNETCONTROL },
		{ "lowdelay",		IPTOS_LOWDELAY },
		{ "netcontrol",		IPTOS_PREC_NETCONTROL },
		{ "reliability",	IPTOS_RELIABILITY },
		{ "throughput",		IPTOS_THROUGHPUT },
		{ "va",			IPTOS_DSCP_VA },
	};
	const struct keywords	*p;

	p = bsearch(s, toswords, nitems(toswords), sizeof(toswords[0]),
	    kw_casecmp);

	if (p) {
		*val = p->k_val;
		return (1);
	}
	return (0);
}

static int
getservice(char *n)
{
	struct servent	*s;

	s = getservbyname(n, "tcp");
	if (s == NULL)
		s = getservbyname(n, "udp");
	if (s == NULL)
		return -1;
	return s->s_port;
}

static int
parse_flags(char *s)
{
	const char *flags = FLOWSPEC_TCP_FLAG_STRING;
	char *p, *q;
	uint8_t f = 0;

	if (curflow->type == FLOWSPEC_TYPE_FRAG) {
		if (curflow->aid == AID_INET)
			flags = FLOWSPEC_FRAG_STRING4;
		else
			flags = FLOWSPEC_FRAG_STRING6;
	}

	for (p = s; *p; p++) {
		if ((q = strchr(flags, *p)) == NULL)
			return -1;
		f |= 1 << (q - flags);
	}
	return (f ? f : 0xff);
}

static void
component_finish(int type, uint8_t *data, int len)
{
	uint8_t *last;
	int i;

	switch (type) {
	case FLOWSPEC_TYPE_DEST:
	case FLOWSPEC_TYPE_SOURCE:
		/* nothing to do */
		return;
	default:
		break;
	}

	i = 0;
	do {
		last = data + i;
		i += FLOWSPEC_OP_LEN(*last) + 1;
	} while (i < len);
	*last |= FLOWSPEC_OP_EOL;
}

static struct flowspec_config *
flow_to_flowspec(struct flowspec_context *ctx)
{
	struct flowspec_config *f;
	int i, len = 0;
	uint8_t aid;

	switch (ctx->aid) {
	case AID_INET:
		aid = AID_FLOWSPECv4;
		break;
	case AID_INET6:
		aid = AID_FLOWSPECv6;
		break;
	default:
		return NULL;
	}

	for (i = FLOWSPEC_TYPE_MIN; i < FLOWSPEC_TYPE_MAX; i++)
		if (ctx->components[i] != NULL)
			len += ctx->complen[i] + 1;

	f = flowspec_alloc(aid, len);
	if (f == NULL)
		return NULL;

	len = 0;
	for (i = FLOWSPEC_TYPE_MIN; i < FLOWSPEC_TYPE_MAX; i++)
		if (ctx->components[i] != NULL) {
			f->flow->data[len++] = i;
			component_finish(i, ctx->components[i],
			    ctx->complen[i]);
			memcpy(f->flow->data + len, ctx->components[i],
			    ctx->complen[i]);
			len += ctx->complen[i];
		}

	return f;
}

static void
flow_free(struct flowspec_context *ctx)
{
	int i;

	for (i = 0; i < FLOWSPEC_TYPE_MAX; i++)
		free(ctx->components[i]);
	free(ctx);
}

static int
push_prefix(struct bgpd_addr *addr, uint8_t len)
{
	void *data;
	uint8_t *comp;
	int complen, l;

	if (curflow->components[curflow->addr_type] != NULL) {
		yyerror("flowspec address already set");
		return -1;
	}

	if (curflow->aid != addr->aid) {
		yyerror("wrong address family for flowspec address");
		return -1;
	}

	switch (curflow->aid) {
	case AID_INET:
		complen = PREFIX_SIZE(len);
		data = &addr->v4;
		break;
	case AID_INET6:
		/* IPv6 includes an offset byte */
		complen = PREFIX_SIZE(len) + 1;
		data = &addr->v6;
		break;
	default:
		yyerror("unsupported address family for flowspec address");
		return -1;
	}
	comp = malloc(complen);
	if (comp == NULL) {
		yyerror("out of memory");
		return -1;
	}

	l = 0;
	comp[l++] = len;
	if (curflow->aid == AID_INET6)
		comp[l++] = 0;
	memcpy(comp + l, data, complen - l);

	curflow->complen[curflow->addr_type] = complen;
	curflow->components[curflow->addr_type] = comp;

	return 0;
}

static int
push_binop(uint8_t binop, long long val)
{
	uint8_t *comp;
	int complen;
	uint8_t u8;

	if (val < 0 || val > 0xff) {
		yyerror("unsupported value for flowspec bin_op");
		return -1;
	}
	u8 = val;

	complen = curflow->complen[curflow->type];
	comp = realloc(curflow->components[curflow->type],
	    complen + 2);
	if (comp == NULL) {
		yyerror("out of memory");
		return -1;
	}

	comp[complen++] = binop;
	comp[complen++] = u8;
	curflow->complen[curflow->type] = complen;
	curflow->components[curflow->type] = comp;

	return 0;
}

static uint8_t
component_numop(enum comp_ops op, int and, int len)
{
	uint8_t flag = 0;

	switch (op) {
	case OP_EQ:
		flag |= FLOWSPEC_OP_NUM_EQ;
		break;
	case OP_NE:
		flag |= FLOWSPEC_OP_NUM_NOT;
		break;
	case OP_LE:
		flag |= FLOWSPEC_OP_NUM_LE;
		break;
	case OP_LT:
		flag |= FLOWSPEC_OP_NUM_LT;
		break;
	case OP_GE:
		flag |= FLOWSPEC_OP_NUM_GE;
		break;
	case OP_GT:
		flag |= FLOWSPEC_OP_NUM_GT;
		break;
	default:
		fatalx("unsupported op");
	}

	switch (len) {
	case 2:
		flag |= 1 << FLOWSPEC_OP_LEN_SHIFT;
		break;
	case 4:
		flag |= 2 << FLOWSPEC_OP_LEN_SHIFT;
		break;
	case 8:
		flag |= 3 << FLOWSPEC_OP_LEN_SHIFT;
		break;
	}

	if (and)
		flag |= FLOWSPEC_OP_AND;

	return flag;
}

static int
push_numop(enum comp_ops op, int and, long long val)
{
	uint8_t *comp;
	void *data;
	uint32_t u32;
	uint16_t u16;
	uint8_t u8;
	int len, complen;

	if (val < 0 || val > 0xffffffff) {
		yyerror("unsupported value for flowspec num_op");
		return -1;
	} else if (val <= 255) {
		len = 1;
		u8 = val;
		data = &u8;
	} else if (val <= 0xffff) {
		len = 2;
		u16 = htons(val);
		data = &u16;
	} else {
		len = 4;
		u32 = htonl(val);
		data = &u32;
	}

	complen = curflow->complen[curflow->type];
	comp = realloc(curflow->components[curflow->type],
	    complen + len + 1);
	if (comp == NULL) {
		yyerror("out of memory");
		return -1;
	}

	comp[complen++] = component_numop(op, and, len);
	memcpy(comp + complen, data, len);
	complen += len;
	curflow->complen[curflow->type] = complen;
	curflow->components[curflow->type] = comp;

	return 0;
}

static int
push_unary_numop(enum comp_ops op, long long val)
{
	return push_numop(op, 0, val);
}

static int
push_binary_numop(enum comp_ops op, long long min, long long max)
{
	switch (op) {
	case OP_RANGE:
		if (push_numop(OP_GE, 0, min) == -1)
			return -1;
		return push_numop(OP_LE, 1, max);
	case OP_XRANGE:
		if (push_numop(OP_LT, 0, min) == -1)
			return -1;
		return push_numop(OP_GT, 0, max);
	default:
		yyerror("unsupported binary flowspec num_op");
		return -1;
	}
}

struct icmptypeent {
	const char *name;
	u_int8_t type;
};

struct icmpcodeent {
	const char *name;
	u_int8_t type;
	u_int8_t code;
};

static const struct icmptypeent icmp_type[] = {
	{ "echoreq",	ICMP_ECHO },
	{ "echorep",	ICMP_ECHOREPLY },
	{ "unreach",	ICMP_UNREACH },
	{ "squench",	ICMP_SOURCEQUENCH },
	{ "redir",	ICMP_REDIRECT },
	{ "althost",	ICMP_ALTHOSTADDR },
	{ "routeradv",	ICMP_ROUTERADVERT },
	{ "routersol",	ICMP_ROUTERSOLICIT },
	{ "timex",	ICMP_TIMXCEED },
	{ "paramprob",	ICMP_PARAMPROB },
	{ "timereq",	ICMP_TSTAMP },
	{ "timerep",	ICMP_TSTAMPREPLY },
	{ "inforeq",	ICMP_IREQ },
	{ "inforep",	ICMP_IREQREPLY },
	{ "maskreq",	ICMP_MASKREQ },
	{ "maskrep",	ICMP_MASKREPLY },
	{ "trace",	ICMP_TRACEROUTE },
	{ "dataconv",	ICMP_DATACONVERR },
	{ "mobredir",	ICMP_MOBILE_REDIRECT },
	{ "ipv6-where",	ICMP_IPV6_WHEREAREYOU },
	{ "ipv6-here",	ICMP_IPV6_IAMHERE },
	{ "mobregreq",	ICMP_MOBILE_REGREQUEST },
	{ "mobregrep",	ICMP_MOBILE_REGREPLY },
	{ "skip",	ICMP_SKIP },
	{ "photuris",	ICMP_PHOTURIS },
};

static const struct icmptypeent icmp6_type[] = {
	{ "unreach",	ICMP6_DST_UNREACH },
	{ "toobig",	ICMP6_PACKET_TOO_BIG },
	{ "timex",	ICMP6_TIME_EXCEEDED },
	{ "paramprob",	ICMP6_PARAM_PROB },
	{ "echoreq",	ICMP6_ECHO_REQUEST },
	{ "echorep",	ICMP6_ECHO_REPLY },
	{ "groupqry",	ICMP6_MEMBERSHIP_QUERY },
	{ "listqry",	MLD_LISTENER_QUERY },
	{ "grouprep",	ICMP6_MEMBERSHIP_REPORT },
	{ "listenrep",	MLD_LISTENER_REPORT },
	{ "groupterm",	ICMP6_MEMBERSHIP_REDUCTION },
	{ "listendone", MLD_LISTENER_DONE },
	{ "routersol",	ND_ROUTER_SOLICIT },
	{ "routeradv",	ND_ROUTER_ADVERT },
	{ "neighbrsol", ND_NEIGHBOR_SOLICIT },
	{ "neighbradv", ND_NEIGHBOR_ADVERT },
	{ "redir",	ND_REDIRECT },
	{ "routrrenum", ICMP6_ROUTER_RENUMBERING },
	{ "wrureq",	ICMP6_WRUREQUEST },
	{ "wrurep",	ICMP6_WRUREPLY },
	{ "fqdnreq",	ICMP6_FQDN_QUERY },
	{ "fqdnrep",	ICMP6_FQDN_REPLY },
	{ "niqry",	ICMP6_NI_QUERY },
	{ "nirep",	ICMP6_NI_REPLY },
	{ "mtraceresp",	MLD_MTRACE_RESP },
	{ "mtrace",	MLD_MTRACE },
	{ "listenrepv2", MLDV2_LISTENER_REPORT },
};

static const struct icmpcodeent icmp_code[] = {
	{ "net-unr",		ICMP_UNREACH,	ICMP_UNREACH_NET },
	{ "host-unr",		ICMP_UNREACH,	ICMP_UNREACH_HOST },
	{ "proto-unr",		ICMP_UNREACH,	ICMP_UNREACH_PROTOCOL },
	{ "port-unr",		ICMP_UNREACH,	ICMP_UNREACH_PORT },
	{ "needfrag",		ICMP_UNREACH,	ICMP_UNREACH_NEEDFRAG },
	{ "srcfail",		ICMP_UNREACH,	ICMP_UNREACH_SRCFAIL },
	{ "net-unk",		ICMP_UNREACH,	ICMP_UNREACH_NET_UNKNOWN },
	{ "host-unk",		ICMP_UNREACH,	ICMP_UNREACH_HOST_UNKNOWN },
	{ "isolate",		ICMP_UNREACH,	ICMP_UNREACH_ISOLATED },
	{ "net-prohib",		ICMP_UNREACH,	ICMP_UNREACH_NET_PROHIB },
	{ "host-prohib",	ICMP_UNREACH,	ICMP_UNREACH_HOST_PROHIB },
	{ "net-tos",		ICMP_UNREACH,	ICMP_UNREACH_TOSNET },
	{ "host-tos",		ICMP_UNREACH,	ICMP_UNREACH_TOSHOST },
	{ "filter-prohib",	ICMP_UNREACH,	ICMP_UNREACH_FILTER_PROHIB },
	{ "host-preced",	ICMP_UNREACH,	ICMP_UNREACH_HOST_PRECEDENCE },
	{ "cutoff-preced",	ICMP_UNREACH,	ICMP_UNREACH_PRECEDENCE_CUTOFF },
	{ "redir-net",		ICMP_REDIRECT,	ICMP_REDIRECT_NET },
	{ "redir-host",		ICMP_REDIRECT,	ICMP_REDIRECT_HOST },
	{ "redir-tos-net",	ICMP_REDIRECT,	ICMP_REDIRECT_TOSNET },
	{ "redir-tos-host",	ICMP_REDIRECT,	ICMP_REDIRECT_TOSHOST },
	{ "normal-adv",		ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NORMAL },
	{ "common-adv",		ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NOROUTE_COMMON },
	{ "transit",		ICMP_TIMXCEED,	ICMP_TIMXCEED_INTRANS },
	{ "reassemb",		ICMP_TIMXCEED,	ICMP_TIMXCEED_REASS },
	{ "badhead",		ICMP_PARAMPROB,	ICMP_PARAMPROB_ERRATPTR },
	{ "optmiss",		ICMP_PARAMPROB,	ICMP_PARAMPROB_OPTABSENT },
	{ "badlen",		ICMP_PARAMPROB,	ICMP_PARAMPROB_LENGTH },
	{ "unknown-ind",	ICMP_PHOTURIS,	ICMP_PHOTURIS_UNKNOWN_INDEX },
	{ "auth-fail",		ICMP_PHOTURIS,	ICMP_PHOTURIS_AUTH_FAILED },
	{ "decrypt-fail",	ICMP_PHOTURIS,	ICMP_PHOTURIS_DECRYPT_FAILED },
};

static const struct icmpcodeent icmp6_code[] = {
	{ "admin-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN },
	{ "noroute-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE },
	{ "beyond-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_BEYONDSCOPE },
	{ "addr-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR },
	{ "port-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT },
	{ "transit", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT },
	{ "reassemb", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY },
	{ "badhead", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER },
	{ "nxthdr", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER },
	{ "redironlink", ND_REDIRECT, ND_REDIRECT_ONLINK },
	{ "redirrouter", ND_REDIRECT, ND_REDIRECT_ROUTER },
};

static int
geticmptypebyname(char *w, uint8_t aid)
{
	size_t	i;

	switch (aid) {
	case AID_INET:
		for (i = 0; i < nitems(icmp_type); i++) {
			if (!strcmp(w, icmp_type[i].name))
				return (icmp_type[i].type);
		}
		break;
	case AID_INET6:
		for (i = 0; i < nitems(icmp6_type); i++) {
			if (!strcmp(w, icmp6_type[i].name))
				return (icmp6_type[i].type);
		}
		break;
	}
	return -1;
}

static int
geticmpcodebyname(u_long type, char *w, uint8_t aid)
{
	size_t	i;

	switch (aid) {
	case AID_INET:
		for (i = 0; i < nitems(icmp_code); i++) {
			if (type == icmp_code[i].type &&
			    !strcmp(w, icmp_code[i].name))
				return (icmp_code[i].code);
		}
		break;
	case AID_INET6:
		for (i = 0; i < nitems(icmp6_code); i++) {
			if (type == icmp6_code[i].type &&
			    !strcmp(w, icmp6_code[i].name))
				return (icmp6_code[i].code);
		}
		break;
	}
	return -1;
}

static int
merge_auth_conf(struct auth_config *to, struct auth_config *from)
{
	if (to->method != 0) {
		/* extra magic for manual ipsec rules */
		if (to->method == from->method &&
		    (to->method == AUTH_IPSEC_MANUAL_ESP ||
		    to->method == AUTH_IPSEC_MANUAL_AH)) {
			if (to->spi_in == 0 && from->spi_in != 0) {
				to->spi_in = from->spi_in;
				to->auth_alg_in = from->auth_alg_in;
				to->enc_alg_in = from->enc_alg_in;
				memcpy(to->enc_key_in, from->enc_key_in,
				    sizeof(to->enc_key_in));
				to->enc_keylen_in = from->enc_keylen_in;
				to->auth_keylen_in = from->auth_keylen_in;
				return 1;
			} else if (to->spi_out == 0 && from->spi_out != 0) {
				to->spi_out = from->spi_out;
				to->auth_alg_out = from->auth_alg_out;
				to->enc_alg_out = from->enc_alg_out;
				memcpy(to->enc_key_out, from->enc_key_out,
				    sizeof(to->enc_key_out));
				to->enc_keylen_out = from->enc_keylen_out;
				to->auth_keylen_out = from->auth_keylen_out;
				return 1;
			}
		}
		yyerror("auth method cannot be redefined");
		return 0;
	}
	*to = *from;
	return 1;
}

