📄 cfparse.y
字号:
{ struct in_addr routerid; if ((inet_aton($6.v, &routerid)) == 0) { yywarn("invalid router ID: %s", $6.v); free($6.v); return(-1); } free($6.v); if (add_bgppeer(-1, routerid.s_addr, $8)) return(-1); } ;peerstatements: PEER STRING peerattributes EOS { memset(&bgppeer_temp, 0, sizeof(bgppeer_temp)); if (get_in6_addr($2.v, &bgppeer_temp.peeraddr)) { yywarn("bad BGP peer address: %s", $2.v); free($2.v); return(-1); } bgppeer_temp.peertype = BGPPEER_NORMAL; bgppeer_temp.attribute = $3; $$ = &bgppeer_temp; } | CLIENT STRING peerattributes EOS { memset(&bgppeer_temp, 0, sizeof(bgppeer_temp)); if (get_in6_addr($2.v, &bgppeer_temp.peeraddr)) { yywarn("bad BGP peer address: %s", $2.v); free($2.v); return(-1); } bgppeer_temp.peertype = BGPPEER_CLIENT; bgppeer_temp.attribute = $3; $$ = &bgppeer_temp; } ;peerattributes: { $$ = NULL; } /* empty */ | peerattributes INTERFACE IFNAME { if (($$ = add_attribute($1, ATTR_STRING, BGPPA_IFNAME, $3.v)) == NULL) { free($3.v); return(-1); } } | peerattributes NOSYNC { if (($$ = add_attribute($1, ATTR_FLAG, BGPPA_NOSYNC, 0)) == NULL) return(-1); } | peerattributes NEXTHOPSELF { if (($$ = add_attribute($1, ATTR_FLAG, BGPPA_NEXTHOPSELF, 0)) == NULL) return(-1); } | peerattributes LCLADDR STRING { struct sockaddr_in6 lcladdr; if (get_in6_addr($3.v, &lcladdr)) { yywarn("bad IPv6 address: %s", $3.v); free($3.v); return(-1); } if (($$ = add_attribute($1, ATTR_ADDR, BGPPA_LCLADDR, &lcladdr)) == NULL) return(-1); } | peerattributes PREFERENCE NUMBER { int pref = $3; if (($$ = add_attribute($1, ATTR_NUMBER, BGPPA_PREFERENCE, (void *)&pref)) == NULL) return(-1); } | peerattributes PREPEND { int pref = BGP_DEF_ASPREPEND; if (($$ = add_attribute($1, ATTR_NUMBER, BGPPA_PREPEND, (void *)&pref)) == NULL) return(-1); } | peerattributes PREPEND NUMBER { int pref = $3; if (($$ = add_attribute($1, ATTR_NUMBER, BGPPA_PREPEND, (void *)&pref)) == NULL) return(-1); } | peerattributes DESCR DESCSTRING { if (($$ = add_attribute($1, ATTR_STRING, BGPPA_DESCR, $3.v)) == NULL) return(-1); } | peerattributes FILTERIN DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, BGPPA_FILINDEF, 0)) == NULL) return(-1); } | peerattributes FILTEROUT DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, BGPPA_FILOUTDEF, 0)) == NULL) return(-1); } | peerattributes RESTRICTIN DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, BGPPA_RESINDEF, 0)) == NULL) return(-1); } | peerattributes RESTRICTOUT DEFAULT { if (($$ = add_attribute($1, ATTR_FLAG, BGPPA_RESOUTDEF, 0)) == NULL) return(-1); } | peerattributes FILTERIN prefix { if (($$ = add_attribute($1, ATTR_PREFIX, BGPPA_FILINPFX, $3)) == NULL) return(-1); } | peerattributes FILTEROUT prefix { if (($$ = add_attribute($1, ATTR_PREFIX, BGPPA_FILOUTPFX, $3)) == NULL) return(-1); } | peerattributes RESTRICTIN prefix { if (($$ = add_attribute($1, ATTR_PREFIX, BGPPA_RESINPFX, $3)) == NULL) return(-1); } | peerattributes RESTRICTOUT prefix { if (($$ = add_attribute($1, ATTR_PREFIX, BGPPA_RESOUTPFX, $3)) == NULL) return(-1); } ;/* export */export_statement: EXPORT PROTO BGP AS NUMBER BCL export_list ECL EOS { if (add_export($5, NULL, $7)) return(-1); /* XXX free? */ } | EXPORT PROTO BGP PEER STRING BCL export_list ECL EOS { struct sockaddr_in6 peeraddr; if (get_in6_addr($5.v, &peeraddr)) { yywarn("bad peer address: %s", $5.v); free($5.v); return(-1); } if (add_export(-1, &peeraddr, $7)) return(-1); } ;export_list: { $$ = NULL; }; /* empty */ | export_list protocol { if (($$ = add_attribute($1, ATTR_DATA, EXPA_PROTO, $2)) == NULL) return(-1); } ;protocol: /* XXX: currently too restrictive */ PROTO DIRECT INTERFACE IFNAME all_block EOS { struct yy_rtproto *p; if ((p = malloc(sizeof(*p))) == NULL) { yywarn("can't allocate memory"); return(-1); } memset(p, 0, sizeof(*p)); if (strlen($4.v) >= sizeof(p->rtpu.ifname)) { yywarn("interface name(%s) is too long", $4.v); free($4.v); return(-1); } p->type = RTP_IFACE; strcpy(p->rtpu.ifname, $4.v); $$ = p; } | PROTO BGP AS NUMBER all_block EOS { struct yy_rtproto *p; if ((p = malloc(sizeof(*p))) == NULL) { yywarn("can't allocate memory"); return(-1); } memset(p, 0, sizeof(*p)); p->type = RTP_BGP; p->rtpu.rtpu_bgp.peeras = $4; $$ = p; } | PROTO BGP PEER STRING all_block EOS { struct yy_rtproto *p; if ((p = malloc(sizeof(*p))) == NULL) { yywarn("can't allocate memory"); free($4.v); return(-1); } memset(p, 0, sizeof(*p)); p->type = RTP_BGP; if (get_in6_addr($4.v, &p->rtpu.rtpu_bgp.peeraddr)) { yywarn("bad peer address: %s", $4.v); free($4.v); return(-1); } free($4.v); $$ = p; } | PROTO RIP all_block EOS { struct yy_rtproto *p; if ((p = malloc(sizeof(*p))) == NULL) { yywarn("can't allocate memory"); return(-1); } memset(p, 0, sizeof(*p)); p->type = RTP_RIP; $$ = p; } | PROTO IBGP all_block EOS { struct yy_rtproto *p; if ((p = malloc(sizeof(*p))) == NULL) { yywarn("can't allocate memory"); return(-1); } memset(p, 0, sizeof(*p)); p->type = RTP_IBGP; $$ = p; } ;/* just for shortcut */all_block: /* do nothing */ /* empty */ | BCL ALL EOS ECL ;/* aggregate */aggregate_statement: AGGREGATE prefix BCL aggregate_substatements ECL EOS { if (add_aggregation($2, $4)) return(-1); };aggregate_substatements: { $$ = NULL; } /* empty */ | aggregate_substatements protocol { if (($$ = add_attribute($1, ATTR_DATA, AGGA_PROTO, $2)) == NULL) return(-1); } | aggregate_substatements EXPLICIT BCL prefix_list ECL EOS { if (($$ = add_attribute($1, ATTR_LIST, AGGA_EXPFX, $4)) == NULL) return(-1); } ;/* prefix */prefix_list: { $$ = NULL; } /* empty */ | prefix_list prefix EOS { if (($$ = add_attribute($1, ATTR_PREFIX, ATTR_PREFIX, $2)) == NULL) return(-1); } ;prefix: STRING { if (get_in6_addr($1.v, &in6pfx_temp.paddr)) { yywarn("bad IPv6 prefix: %s", $1.v); free($1.v); return(-1); } free($1.v); in6pfx_temp.plen = 128; $$ = &in6pfx_temp; } | STRING SLASH NUMBER { if (get_in6_addr($1.v, &in6pfx_temp.paddr)) { yywarn("bad IPv6 prefix: %s", $1.v); free($1.v); return(-1); } if ($3 < 0 || $3 > 128) { yywarn("bad IPv6 prefixlen: %s", $1.v); free($1.v); return(-1); } free($1.v); in6pfx_temp.plen = $3; $$ = &in6pfx_temp; } ;%%static intadd_static(new_rte) struct yy_route_entry *new_rte;{ struct yy_route_entry *rte; /* canonize the address part */ mask_nclear(&new_rte->prefix.paddr.sin6_addr, new_rte->prefix.plen); /* check if duplicated */ for (rte = yy_static_head; rte; rte = rte->next) { if (sa6_equal(&rte->prefix.paddr, &new_rte->prefix.paddr) && rte->prefix.plen == new_rte->prefix.plen) { yywarn("static route doubly defined: %s/%d", ip6str2(&rte->prefix.paddr), rte->prefix.plen); return(-1); } } /* add a new route */ if ((rte = malloc(sizeof(*rte))) == NULL) { warnx("can't allocate space for a static route"); return(-1); } *rte = *new_rte; rte->next = yy_static_head; rte->line = lineno; yy_static_head = rte; return(0);}static intadd_aggregation(prefix, aggrinfo) struct in6_prefix *prefix; struct attr_list *aggrinfo;{ struct yy_aggrinfo *info; /* check if duplicated */ for (info = yy_aggr_head; info; info = info->next) { if (sa6_equal(&info->prefix.paddr, &prefix->paddr) && info->prefix.plen == prefix->plen) { yywarn("aggregate prefix(%s/%d) doulby defined", ip6str2(&prefix->paddr), prefix->plen); return(-1); } } /* allocate a new one */ if ((info = malloc(sizeof(*info))) == NULL) { yywarn("can't allocate memory for aggregation"); return(-1); } memset(info, 0, sizeof(*info)); info->prefix = *prefix; info->aggrinfo = aggrinfo; info->line = lineno; info->next = yy_aggr_head; yy_aggr_head = info; return(0);}static intadd_export(asnum, peer, list) /* XXX BGP depend */ int asnum; struct sockaddr_in6 *peer; struct attr_list *list;{ struct yy_exportinfo *info; /* check if duplicated */ for (info = yy_exportinfo_head; info; info = info->next) { if (asnum >= 0 && info->asnum == asnum) { yywarn("export peer (AS: %d) doubly defined", asnum); return(-1); } if (peer && sa6_equal(peer, &info->peeraddr)) { yywarn("export peer (addr: %s) doubly defined", ip6str2(&info->peeraddr)); return(-1); } } /* allocate a new one */ if ((info = malloc(sizeof(*info))) == NULL) { yywarn("can't allocate memory for export peer"); return(-1); } memset(info, 0, sizeof(*info)); info->asnum = asnum; info->line = lineno; if (peer) info->peeraddr = *peer; info->protolist = list; info->next = yy_exportinfo_head; yy_exportinfo_head = info; return(0);}static intadd_bgppeer(asnum, routerid, peerinfo) int asnum; u_int32_t routerid; struct yy_bgppeerinfo *peerinfo;{ struct yy_bgppeerinfo *info; /* check if duplicated */ for (info = yy_bgppeer_head; info; info = info->next) { if (asnum >= 0 && info->asnum == asnum) { yywarn("BGP peer (AS: %d) doubly defined", asnum); return(-1); } if (routerid && info->routerid == routerid) { yywarn("BGP peer (routerID: %x) doubly defined", ntohl(routerid)); return(-1); } if (sa6_equal(&info->peeraddr, &peerinfo->peeraddr)) { yywarn("BGP peer (addr: %s) doubly defined", ip6str2(&info->peeraddr)); return(-1); } } /* allocate a new one */ if ((info = malloc(sizeof(*info))) == NULL) { yywarn("can't allocate memory for BGP peerinfo"); return(-1); } memset(info, 0, sizeof(*info)); info->asnum = asnum; info->routerid = routerid; info->peertype = peerinfo->peertype; info->peeraddr = peerinfo->peeraddr; info->attribute = peerinfo->attribute; info->line = lineno; info->next = yy_bgppeer_head; yy_bgppeer_head = info; return(0);}static struct yy_ripifinfo *add_ripifinfo(ifname) char *ifname;{ struct yy_ripifinfo *info; if ((info = malloc(sizeof(*info))) == NULL) { yywarn("can't allocate memory for ripifinfo"); return(NULL); } if (strlen(ifname) >= sizeof(info->ifname)) { yywarn("interface name(%s) is too long", ifname); free(info); return(NULL); } memset(info, 0, sizeof(*info)); strcpy(info->ifname, ifname); info->line = lineno; info->next = yy_ripifinfo_head; yy_ripifinfo_head = info; return(info);}static struct attr_list *add_attribute(list, type, code, val) struct attr_list *list; int type, code; void *val;{ struct attr_list *p; if ((p = malloc(sizeof(*p))) == NULL) { yyerror("malloc failed"); return(NULL); } memset((void *)p, 0, sizeof(*p)); p->code = code; p->type = type; p->line = lineno; switch(type) { case ATTR_FLAG: p->attru.flags++; break; case ATTR_PREFIX: p->attru.prefix = *(struct in6_prefix *)val; break; case ATTR_STRING: p->attru.str = (char *)val; break; case ATTR_ADDR: p->attru.in6addr = *(struct sockaddr_in6 *)val; break; case ATTR_NUMBER: p->attru.number = *(int *)val; break; case ATTR_DATA: p->attru.data = val; break; case ATTR_LIST: p->attru.list = (struct attr_list *)val; break; default: /* XXX what do I do? */ yywarn("unknown attribute type(%d)", type); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -