⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfparse.y

📁 同时支持IPv4和IPv6的BGP协议实现
💻 Y
📖 第 1 页 / 共 4 页
字号:
	}	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 + -