📄 cfparse.y
字号:
/* * Copyright (C) 2000 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */%{#include <sys/types.h>#include <sys/socket.h>#if 0#include <net/if.h>#endif#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <netdb.h>#include <string.h>#include <syslog.h>#include <err.h>#include "include.h"#include "bgp.h"#include "router.h"#include "task.h"#include "rt_table.h"#include "aspath.h"#include "bgp_var.h"#include "in6.h"#include "ripng.h"#include "ripng_var.h"#include "debug.h"#include "cfparse.h"#include "vmbuf.h"#define set_param(var,val,p) \ do {\ if ((var) != -1) {\ yywarn("%s doubly defined(ignore %d)", (p), (val));\ }\ else {\ (var) = val;\ }\ } while(0)#define set_string(var,val,p) \ do {\ if ((var) != NULL) {\ yywarn("%s doubly defined(ignore %s)", (p), (val));\ free(p);\ }\ else {\ (var) = val;\ }\ } while(0)#define cprint if (confcheck) printfstruct in6_prefix { struct sockaddr_in6 paddr; int plen;};struct attr_list { struct attr_list *next; int code; int type; int line; union { char *str; void *data; unsigned int flags; int number; struct sockaddr_in6 in6addr; struct in6_prefix prefix; struct attr_list *list; }attru;};struct yy_route_entry { struct yy_route_entry *next; struct in6_prefix prefix; int gwtype; int line; union { struct sockaddr_in6 gateway; char ifname[IFNAMSIZ]; } reu;};struct yy_ripifinfo { struct yy_ripifinfo *next; char ifname[IFNAMSIZ]; struct attr_list *attribute; int line;};struct yy_bgppeerinfo { struct yy_bgppeerinfo *next; int asnum; u_int32_t routerid; int peertype; /* an ordinal peer or an IBGP cluster client */ struct sockaddr_in6 peeraddr; struct attr_list *attribute; int line;};struct yy_exportinfo { /* XXX: BGP depend */ struct yy_exportinfo *next; int asnum; int line; struct sockaddr_in6 peeraddr; struct attr_list *protolist;};struct yy_aggrinfo { struct yy_aggrinfo *next; struct in6_prefix prefix; struct attr_list *aggrinfo; int line;};struct yy_rtproto { int type; union { struct { int peeras; struct sockaddr_in6 peeraddr; }rtpu_bgp; char ifname[IFNAMSIZ]; }rtpu;};enum {GW_IFACE, GW_ADDR};enum {RIPIFA_DEFAULT, RIPIFA_NORIPIN, RIPIFA_NORIPOUT, RIPIFA_METRICIN, RIPIFA_FILINDEF, RIPIFA_FILOUTDEF, RIPIFA_RESINDEF, RIPIFA_RESOUTDEF, RIPIFA_FILINPFX, RIPIFA_FILOUTPFX, RIPIFA_RESINPFX, RIPIFA_RESOUTPFX, RIPIFA_DESCR, BGPPA_IFNAME, BGPPA_NOSYNC, BGPPA_NEXTHOPSELF, BGPPA_LCLADDR, BGPPA_PREFERENCE, BGPPA_PREPEND, BGPPA_DESCR, BGPPA_FILINDEF, BGPPA_FILOUTDEF, BGPPA_RESINDEF, BGPPA_RESOUTDEF, BGPPA_FILINPFX, BGPPA_FILOUTPFX, BGPPA_RESINPFX, BGPPA_RESOUTPFX, EXPA_PROTO, AGGA_PROTO, AGGA_EXPFX, STATICA_RTE};enum {ATTR_FLAG, ATTR_PREFIX, ATTR_STRING, ATTR_ADDR, ATTR_NUMBER, ATTR_DATA, ATTR_LIST};enum {BGPPEER_NORMAL, BGPPEER_CLIENT}; enum {RTP_IFACE, RTP_BGP, RTP_RIP, RTP_IBGP}; static struct in6_prefix in6pfx_temp; /* XXX */static struct yy_route_entry static_temp; /* XXX */static struct yy_bgppeerinfo bgppeer_temp; /* XXX file global */static struct yy_bgppeerinfo *yy_bgppeer_head;static struct yy_route_entry *yy_static_head;static int yy_debug, yy_asnum, yy_bgpsbsize, yy_holdtime, yy_rrflag, yy_rip, yy_rip_sitelocal;static long yy_routerid, yy_clusterid; /* XXX sizoef(long)? */static int yy_bgp;static char *yy_dumpfile;static struct yy_ripifinfo *yy_ripifinfo_head;static struct yy_exportinfo *yy_exportinfo_head;static struct yy_aggrinfo *yy_aggr_head;extern int lineno;extern int confcheck;extern char *configfilename;extern char *dumpfile;extern u_int32_t bgpIdentifier, clusterId;extern u_int16_t my_as_number, bgpHoldtime;extern byte ripyes, bgpyes, IamRR;extern struct rpcb *bgb;#define DUMPFILENAME "/var/run/bgpd.dump"extern void insque __P((void *, void *)); /* XXX */extern int yylex __P((void));%}%union { unsigned long num; vchar_t val; struct attr_list *attr; struct in6_prefix *prefix; struct yy_bgppeerinfo *bpeer; struct yy_rtproto *rtp;}%token EOS BCL ECL%token YES NO ALL DESCR DESCSTRING IGNORE_END%token NUMBER STRING SLASH%token LOG LOGLEV NOLOGLEV%token LOGASPATH NOLOGASPATH LOGBGPSTATE NOLOGBGPSTATE LOGBGPCONNECT%token NOLOGBGPCONNECT LOGBGPINPUT NOLOGBGPINPUT LOGBGPOUTPUT NOLOGBGPOUTPUT%token LOGBGPROUTE NOLOGBGPROUTE LOGINTERFACE NOLOGINTERFACE LOGINET6%token NOLOGINET6 LOGRIP NOLOGRIP LOGROUTE NOLOGROUTE LOGFILTER NOLOGFILTER%token LOGTIMER NOLOGTIMER%token DUMPFILE%token AUTONOMOUSSYSTEM ROUTERID CLUSTERID HOLDTIME ROUTEREFLECTOR BGPSBSIZE%token INTERFACE IFNAME%token STATIC GATEWAY%token RIP DEFAULT ORIGINATE NORIPIN NORIPOUT SITELOCAL METRICIN%token FILTERIN FILTEROUT RESTRICTIN RESTRICTOUT%token BGP GROUP TYPE INTERNAL EXTERNAL PEER CLIENT PEERAS AS%token SYNCHRONIZATION PREFERENCE PREPEND LCLADDR NEXTHOPSELF NOSYNC%token EXPORT%token AGGREGATE EXPLICIT%token PROTO DIRECT IBGP%type <num> LOGLEV NOLOGLEV NUMBER%type <val> STRING IFNAME DESCSTRING%type <attr> rip_ifattributes peerattributes export_list%type <attr> aggregate_substatements prefix_list%type <prefix> prefix%type <bpeer> peerstatements%type <rtp> protocol%%statements: /* empty */ | statements statement ;statement: logging_statement | param_statement | static_statement | rip_statement | bgp_statement | export_statement | aggregate_statement ;/* logging */logging_statement: LOG log_specs EOS ;log_specs: /* empty */ | log_specs LOGLEV {yy_debug |= $2;} | log_specs NOLOGLEV {yy_debug &= ~($2);} ;param_statement: DUMPFILE STRING EOS { set_string(yy_dumpfile, $2.v, "dumpfile"); } | AUTONOMOUSSYSTEM NUMBER EOS { set_param(yy_asnum, $2, "AS number"); } | BGPSBSIZE NUMBER EOS { set_param(yy_bgpsbsize, $2, "BGP sbsize"); } | ROUTERID STRING EOS { struct in_addr routerid; /* we don't regared -1 as a valid IPv4 address */ if ((inet_aton($2.v, &routerid)) == 0 && routerid.s_addr == (u_int32_t)-1) { yywarn("invalid router ID: %s", $2.v); free($2.v); return(-1); } set_param(yy_routerid, routerid.s_addr, "RouterID"); free($2.v); } | CLUSTERID STRING EOS { struct in_addr clusterid; /* we don't regared -1 as a valid IPv4 address */ if ((inet_aton($2.v, &clusterid)) == 0 && clusterid.s_addr == (u_int32_t)-1) { yywarn("invalid cluster ID: %s", $2.v); free($2.v); return(-1); } set_param(yy_clusterid, clusterid.s_addr, "ClusterID"); free($2.v); } | HOLDTIME NUMBER EOS { if ($2 > 0 && $2 < 3) { yywarn("invalid hold timer value: %d", $2); return(-1); } set_param(yy_holdtime, $2, "holdtime"); } | ROUTEREFLECTOR EOS { set_param(yy_rrflag, 1, "route reflector"); } ;/* Static Route */static_statement: STATIC BCL static_routes ECL EOSstatic_routes: /* empty */ | static_routes static_route ;static_route: prefix GATEWAY STRING EOS { static_temp.prefix = *($1); if (get_in6_addr($3.v, &static_temp.reu.gateway)) { yywarn("bad IPv6 gateway address: %s", $3.v); free($3.v); return(-1); } free($3.v); static_temp.gwtype = GW_ADDR; if (add_static(&static_temp)) return(-1); } | prefix INTERFACE IFNAME EOS { static_temp.prefix = *($1); strncpy(static_temp.reu.ifname, $3.v, sizeof(static_temp.reu.ifname)); free($3.v); static_temp.gwtype = GW_IFACE; if (add_static(&static_temp)) return(-1); } ;/* RIP */rip_statement: RIP YES BCL rip_substatements ECL EOS { if (yy_rip != -1) { yywarn("RIP(yes) doubly defined (ignored)"); return(-1); } yy_rip = 1; } | RIP BCL rip_substatements ECL EOS { if (yy_rip != -1) { yywarn("RIP(yes) doubly defined (ignored)"); return(-1); } yy_rip = 1; } | RIP NO IGNORE_END EOS { if (yy_rip != -1) { yywarn("RIP(no) doubly defined (ignored)"); return(-1); } yy_rip = 0; } ;rip_substatements: /* empty */ | rip_substatements rip_substatement ;rip_substatement: INTERFACE IFNAME rip_ifattributes EOS { struct yy_ripifinfo *ifinfo; ifinfo = add_ripifinfo($2.v); if (ifinfo == NULL) { yywarn("can't add RIP interface: %s", $2.v); free($2.v); return(-1); } else { struct attr_list *p; for (p = (struct attr_list *)ifinfo->attribute; p && p->next; p = p->next) ; if (p) p->next = (void *)$3; else ifinfo->attribute = (void *)$3; } free($2.v); } | SITELOCAL YES EOS { set_param(yy_rip_sitelocal, 1, "RIP site-local"); } | SITELOCAL NO EOS { set_param(yy_rip_sitelocal, 0, "RIP site-local"); } ;rip_ifattributes: { $$ = NULL; } | rip_ifattributes DEFAULT ORIGINATE { if (($$ = add_attribute($1, ATTR_FLAG, RIPIFA_DEFAULT, 0)) == NULL) return(-1); } | rip_ifattributes NORIPIN { if (($$ = add_attribute($1, ATTR_FLAG, RIPIFA_NORIPIN, 0)) == NULL) return(-1); } | rip_ifattributes NORIPOUT { if (($$ = add_attribute($1, ATTR_FLAG, RIPIFA_NORIPOUT, 0)) == NULL) return(-1); } | rip_ifattributes METRICIN NUMBER { int metric = $3; if (metric < 0 || metric >= 16) { yywarn("invalid RIP metric(%d)", metric); return(-1); } if (($$ = add_attribute($1, ATTR_NUMBER, RIPIFA_METRICIN, &metric)) == NULL) return(-1); } | rip_ifattributes FILTERIN DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, RIPIFA_FILINDEF, 0)) == NULL) return(-1); } | rip_ifattributes FILTEROUT DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, RIPIFA_FILOUTDEF, 0)) == NULL) return(-1); } | rip_ifattributes RESTRICTIN DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, RIPIFA_RESINDEF, 0)) == NULL) return(-1); } | rip_ifattributes RESTRICTOUT DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, RIPIFA_RESOUTDEF, 0)) == NULL) return(-1); } | rip_ifattributes FILTERIN prefix { if (($$ = add_attribute($1, ATTR_PREFIX, RIPIFA_FILINPFX, $3)) == NULL) return(-1); } | rip_ifattributes FILTEROUT prefix { if (($$ = add_attribute($1, ATTR_PREFIX, RIPIFA_FILOUTPFX, $3)) == NULL) return(-1); } | rip_ifattributes RESTRICTIN prefix { if (($$ = add_attribute($1, ATTR_PREFIX, RIPIFA_RESINPFX, $3)) == NULL) return(-1); } | rip_ifattributes RESTRICTOUT prefix { if (($$ = add_attribute($1, ATTR_PREFIX, RIPIFA_RESOUTPFX, $3)) == NULL) return(-1); } | rip_ifattributes DESCR DESCSTRING { if (($$ = add_attribute($1, ATTR_STRING, RIPIFA_DESCR, $3.v)) == NULL) return(-1); } ;/* BGP */bgp_statement: BGP YES BCL bgp_substatements ECL EOS { if (yy_bgp != -1) { yywarn("BGP(yes) doubly defined (ignored)"); return(-1); } yy_bgp = 1; } | BGP BCL bgp_substatements ECL EOS { if (yy_bgp != -1) { yywarn("BGP(yes) doubly defined (ignored)"); return(-1); } yy_bgp = 1; } | BGP NO IGNORE_END { if (yy_bgp != -1) { yywarn("BGP(no) doubly defined (ignored)"); return(-1); } yy_bgp = 0; } ;bgp_substatements: /* empty */ | bgp_substatements GROUP TYPE EXTERNAL PEERAS NUMBER BCL peerstatements ECL EOS { if ($6 < 0 || $6 > 65535) { yywarn("bad AS number: %d", $6); return(-1); } if (add_bgppeer($6, 0, $8)) return(-1); /* XXX free? */ } | bgp_substatements GROUP TYPE INTERNAL BCL peerstatements ECL EOS { if (add_bgppeer(-1, 0, $6)) return(-1); } | bgp_substatements GROUP TYPE INTERNAL ROUTERID STRING BCL peerstatements ECL EOS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -