📄 cfparse.y
字号:
} return(0);}static intadd_protoexportlist(exportinfo, bnp) struct yy_exportinfo *exportinfo; struct rpcb *bnp; /* BGP depend */{ struct attr_list *attr; struct ifinfo *ifp; struct rpcb *ibnp; struct ripif *ripif; extern struct ripif *ripifs; for (attr = exportinfo->protolist; attr; attr = attr->next) { struct yy_rtproto *proto; proto = (struct yy_rtproto *)attr->attru.data; switch(proto->type) { case RTP_IFACE: cprint("interface_route(%s) ", proto->rtpu.ifname); if ((ifp = find_if_by_name(proto->rtpu.ifname)) == NULL) { warnx("%s line %d: invalid I/F name: %s", configfilename, attr->line, proto->rtpu.ifname); return(-1); } if (add_protoexport(bnp, attr, RTPROTO_IF, (void *)ifp)) return(-1); break; case RTP_BGP: cprint("BGP(AS: %d) ", proto->rtpu.rtpu_bgp.peeras); if (proto->rtpu.rtpu_bgp.peeras == my_as_number) goto ibgp; if ((ibnp = find_peer_by_as(proto->rtpu.rtpu_bgp.peeras)) == NULL) { warnx("%s line %d: invalid AS number: %d", configfilename, attr->line, proto->rtpu.rtpu_bgp.peeras); return(-1); } if (add_protoexport(bnp, attr, RTPROTO_BGP, (void *)ibnp)) return(-1); break; case RTP_RIP: cprint("RIP "); if (!ripyes || !ripifs) { warnx("%s line %d: RIPng specified but disabled", configfilename, attr->line); return(-1); } ripif = ripifs; while(ripifs) { /* XXX: odd loop */ if (add_protoexport(bnp, attr, RTPROTO_RIP, (void *)ripif)) return(-1); if ((ripif = ripif->rip_next) == ripifs) break; } break; case RTP_IBGP: ibgp: cprint("IBGP "); ibnp = bgb; while(ibnp) { /* XXX: odd loop */ if (ibnp->rp_mode & BGPO_IGP) if (add_protoexport(bnp, attr, RTPROTO_BGP, (void *)ibnp)) return(-1); if ((ibnp = ibnp->rp_next) == bgb) break; } break; default: cprint("unknown or unsupported proto(%d) ", proto->type); break; } } return(0);}static intexport_config(){ struct yy_exportinfo *info; struct sockaddr_in6 *peeraddr; struct rpcb *asp, *bnp; int peeras; cprint("Export config\n"); for (info = yy_exportinfo_head; info; info = info->next) { peeras = info->asnum; peeraddr = &info->peeraddr; if (!IN6_IS_ADDR_UNSPECIFIED(&peeraddr->sin6_addr)) { cprint(" peer addr: %s ", ip6str2(peeraddr)); /* XXX scoped address support */ asp = find_apeer_by_addr(&peeraddr->sin6_addr); if (asp == NULL) { warnx("%s line %d: invalid BGP peer address: " "%s", configfilename, info->line, ip6str2(peeraddr)); return(-1); } /* this check is in fact redundant */ if (peeras > 0 && peeras != asp->rp_as) { warnx("%s line %d: bad peer AS(%d) for %s", configfilename, info->line, peeras, ip6str2(peeraddr)); return(-1); } if (add_protoexportlist(info, asp)) return(-1); cprint("\n"); continue; } for (bnp = bgb; bnp; ) { /* XXX: odd loop... */ if (bnp->rp_as == peeras) { cprint(" peer as: %d (addr: %s) ", peeras, bgp_peerstr(bnp)); if (add_protoexportlist(info, bnp)) return(-1); cprint("\n"); } if ((bnp = bnp->rp_next) == bgb) break; } } return(0);}static intadd_protoaggr(attr, aggregated, ptype, pdata) struct attr_list *attr; struct rt_entry *aggregated; int ptype; void *pdata;{ struct rtproto *rtp = NULL; if ((rtp = malloc(sizeof(*rtp))) == NULL) { warnx("can't allocate space for aggregation"); return(-1); } memset(rtp, 0, sizeof(*rtp)); rtp->rtp_type = ptype; switch(ptype) { case RTPROTO_IF: rtp->rtp_if = (struct ifinfo *)pdata; break; case RTPROTO_BGP: rtp->rtp_bgp = (struct rpcb *)pdata; break; } if (aggregated->rt_aggr.ag_rtp != NULL) { if (find_rtp(rtp, aggregated->rt_aggr.ag_rtp)) { warnx("%s line %d: aggregation doubly defined: %s/%d", configfilename, attr->line, ip6str(&aggregated->rt_ripinfo.rip6_dest, 0), aggregated->rt_ripinfo.rip6_plen); goto bad; } insque(rtp, aggregated->rt_aggr.ag_rtp); } else { rtp->rtp_next = rtp->rtp_prev = rtp; aggregated->rt_aggr.ag_rtp = rtp; } return(0); bad: free(rtp); return(-1);}static intaggr_proto_config(attr, aggregated) struct attr_list *attr; struct rt_entry *aggregated;{ struct yy_rtproto *proto; struct ifinfo *ifp; struct sockaddr_in6 *peeraddr; int peeras; struct rpcb *asp = NULL, *bnp; proto = (struct yy_rtproto *)attr->attru.data; switch(proto->type) { case RTP_IFACE: cprint(" interface_route(%s) ", proto->rtpu.ifname); if ((ifp = find_if_by_name(proto->rtpu.ifname)) == NULL) { warnx("%s line %d: invalid interface name: %s", configfilename, attr->line, proto->rtpu.ifname); return(-1); } if (add_protoaggr(attr, aggregated, RTPROTO_IF, (void *)ifp)) return(-1); break; case RTP_BGP: cprint(" BGP"); peeraddr = &proto->rtpu.rtpu_bgp.peeraddr; peeras = proto->rtpu.rtpu_bgp.peeras; if (peeras > 0) cprint(" AS(%d)", peeras); if (!IN6_IS_ADDR_UNSPECIFIED(&peeraddr->sin6_addr)) { cprint(" peer(%s)", ip6str2(peeraddr)); /* XXX scoped address support */ asp = find_apeer_by_addr(&peeraddr->sin6_addr); if (asp == NULL) { warnx("%s line %d: invalid BGP peer address: " "%s", configfilename, attr->line, ip6str2(peeraddr)); return(-1); } /* this check is in fact redundant */ if (peeras > 0 && peeras != asp->rp_as) { warnx("%s line %d: bad peer AS(%d) for %s", configfilename, attr->line, peeras, ip6str2(peeraddr)); return(-1); } if (add_protoaggr(attr, aggregated, RTPROTO_BGP, (void *)asp)) return(-1); break; } for (bnp = bgb; bnp; ) { /* XXX: odd loop... */ if (bnp->rp_as == peeras) { cprint("\n peer=%s", bgp_peerstr(bnp)); if (add_protoaggr(attr, aggregated, RTPROTO_BGP, (void *)bnp)) return(-1); } if ((bnp = bnp->rp_next) == bgb) break; } break; case RTP_RIP: cprint(" RIP "); warnx("%s line %d: proto RIP can't specified for aggregation " "(sorry)", configfilename, attr->line); return(-1); break; case RTP_IBGP: cprint(" IBGP "); warnx("%s line %d: proto IBGP can't specified for aggregation", configfilename, attr->line); return(-1); break; default: cprint(" unknown proto(%d) ", proto->type); warnx("%s line %d: unkonw proto for aggregation: %d", configfilename, attr->line, proto->type); return(-1); break; } return(0);}static intaggr_explict_config(aggr, aggregated, expl) struct attr_list *aggr; struct rt_entry *aggregated, *expl;{ struct rt_entry *e; struct attr_list *epfx; cprint(" Explicit: "); for (epfx = aggr->attru.list; epfx; epfx = epfx->next) { struct in6_prefix *pfx = &epfx->attru.prefix; cprint("%s/%d ", ip6str2(&pfx->paddr), pfx->plen); if ((e = malloc(sizeof(*e))) == NULL) { warnx("can't allocate space for explict route"); return(-1); } memset(e, 0, sizeof(*e)); e->rt_ripinfo.rip6_dest = pfx->paddr.sin6_addr; /* XXX */ e->rt_ripinfo.rip6_plen = pfx->plen; /* check if this is really aggregatable. */ if (aggregated != aggregatable(e)) { warnx("%s line %d: not aggregatable(%s/%d)", configfilename, aggr->line, ip6str2(&pfx->paddr), pfx->plen); return(-1); } if (aggregated->rt_aggr.ag_explt) { if (find_rte(e, aggregated->rt_aggr.ag_explt)) { warnx("%s line %d: explict prefix (%s/%d) " "doubly defined", configfilename, aggr->line, ip6str2(&pfx->paddr), pfx->plen); return(-1); } insque(e, aggregated->rt_aggr.ag_explt); } else { e->rt_next = e->rt_prev = e; aggregated->rt_aggr.ag_explt = e; } } return(0);}static intaggregate_config(){ struct yy_aggrinfo *info; struct attr_list *attr; struct rt_entry *aggregated; extern struct rt_entry *aggregations; cprint("Aggregation config\n"); for (info = yy_aggr_head; info; info = info->next) { cprint(" prefix: %s/%d\n", ip6str2(&info->prefix.paddr), info->prefix.plen); if ((aggregated = malloc(sizeof(*aggregated))) == NULL) { warnx("can't allocate space for aggregation"); return(-1); } memset(aggregated, 0, sizeof(*aggregated)); aggregated->rt_proto.rtp_type = RTPROTO_AGGR; /* XXX: this would drop scope information */ aggregated->rt_ripinfo.rip6_dest = info->prefix.paddr.sin6_addr; aggregated->rt_ripinfo.rip6_plen = info->prefix.plen; /* canonize the address part */ mask_nclear(&aggregated->rt_ripinfo.rip6_dest, aggregated->rt_ripinfo.rip6_plen); for (attr = info->aggrinfo; attr; attr = attr->next) { switch(attr->code) { case AGGA_PROTO: if (aggr_proto_config(attr, aggregated)) return(-1); break; case AGGA_EXPFX: if (aggr_explict_config(info, aggregated, attr)) return(-1); break; default: cprint(" unkown info(%d)\n", attr->code); break; } cprint("\n"); } if (aggregations) { if (find_rte(aggregated, aggregations)) { warnx("%s line %d: aggregate route doubly " "doubly defined: %s/%d", configfilename, info->line, ip6str(&info->prefix.paddr.sin6_addr, 0), info->prefix.plen); return(-1); } insque(aggregated, aggregations); } else { aggregated->rt_next = aggregated; aggregated->rt_prev = aggregated; aggregations = aggregated; } } return(0);}/* * The followings statics are cleanup fucntions. */static voidattr_cleanup(head) struct attr_list *head;{ struct attr_list *attr, *nattr; for (attr = head; attr; attr = nattr) { nattr = attr->next; switch(attr->type) { case ATTR_STRING: free(attr->attru.str); break; case ATTR_DATA: free(attr->attru.data); break; case ATTR_LIST: attr_cleanup(attr->attru.list); break; default: /* nothing to do */ break; } free(attr); }}static voidstaticconfig_cleanup(head) struct yy_route_entry *head;{ struct yy_route_entry *rte, *nrte; for (rte = head; rte; rte = nrte) { nrte = rte->next; free(rte); }}static voidripconfig_cleanup(head) struct yy_ripifinfo *head;{ struct yy_ripifinfo *info, *ninfo; for (info = head; info; info = ninfo) { ninfo = info->next; attr_cleanup(info->attribute); free(info); }}static voidbgpconfig_cleanup(head) struct yy_bgppeerinfo *head;{ struct yy_bgppeerinfo *info, *ninfo; for (info = head; info; info = ninfo) { ninfo = info->next; attr_cleanup(info->attribute); free(info); }}static voidexportconfig_cleanup(head) struct yy_exportinfo *head;{ struct yy_exportinfo *info, *ninfo; for (info = head; info; info = ninfo) { ninfo = info->next; attr_cleanup(info->protolist); free(info); }}static voidaggrconfig_cleanup(head) struct yy_aggrinfo *head;{ struct yy_aggrinfo *info, *ninfo; for (info = head; info; info = ninfo) { ninfo = info->next; attr_cleanup(info->aggrinfo); free(info); }}static voidconfig_cleanup(){ if (yy_dumpfile) free(yy_dumpfile); staticconfig_cleanup(yy_static_head); ripconfig_cleanup(yy_ripifinfo_head); bgpconfig_cleanup(yy_bgppeer_head); exportconfig_cleanup(yy_exportinfo_head); aggrconfig_cleanup(yy_aggr_head); cf_init(); /* maybe unnecessary, but call it for safety */}/* * Global functions called from outside of the parser. */intcf_post_config(){ param_config(); /* always success */ if (static_config()) return(-1); if (rip_config()) return(-1); if (bgp_config()) return(-1); if (aggregate_config()) return(-1); if (export_config()) return(-1); config_cleanup(); return(0);}/* initialize all temporary variables */voidcf_init(){ yy_debug = 0; yy_asnum = yy_bgpsbsize = yy_holdtime = yy_rrflag = -1; yy_rip = yy_rip_sitelocal = yy_bgp = -1; yy_routerid = yy_clusterid = -1; yy_dumpfile = NULL; yy_static_head = NULL; yy_ripifinfo_head = NULL; yy_bgppeer_head = NULL; yy_exportinfo_head = NULL; yy_aggr_head = NULL; return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -