当前位置: 首页 > Linux

FRR开启EVPN功能

时间:2023-04-07 00:04:06 Linux

介绍frr使用advertise-all-vni命令开启bgp-evpn功能,配置如下:routerbgp7675bgprouter-id192.168.59.128bgpbestpathas-pathmultipath-relaxneighborfabric对等组邻居结构远程作为外部邻居192.168.59.130对等组结构!地址系列l2vpnevpn邻居结构激活广告所有vni出口地址系列!此命令必须配置在l2vpnevpn地址族下。在多个bgp实例的情况下,只有一个bgp实例可以配置此命令,通常是默认的bgp实例。实施分析DEFUN(bgp_evpn_advertise_all_vni,bgp_evpn_advertise_all_vni_cmd,"advertise-all-vni","AdvertiseAlllocalVNIs\n"){structbgp*bgp=VTY_GET_CONTEXT(bgp);结构bgp*bgp_evpn=!NULL_MDCreWt)(;//获取设置了该命令的bgp实例,一般在创建默认bgp实例时设置该值bgp_evpn=bgp_get_evpn();//如果设置了evpn的bgp实例与currentbgpinstance,表示当前bgp为vrf实例,不允许配置。//如果必须配置,使用noadvertise-all-vni取消,设置在指定bgp实例下。if(bgp_evpn&&bgp_evpn!=bgp){vty_out(vty,"%%PleaseunconfigureEVPNinVRF%s\n",bgp_evpn->name);返回CMD_WARNING_CONFIG_FAILED;}/*设置分发所有vni*/evpn_set_advertise_all_vni(bgp);returnCMD_SUCCESS;}/**EVPN(VNI通告)已启用。注册斑马。*/staticvoidevpn_set_advertise_all_vni(structbgp*bgp){bgp->advertise_all_vni=1;//设置全局evpn_bgp为当前bgpbgp_set_evpn(bgp);//通知zebra获取vtep配置的所有vnibgp_zebra_advertise_all_vni(bgp,bgp->advertise_all_vni);}/*设置启用EVPN的BGP实例*/voidbgp_set_evpn(structbgp*bgp){if(bm->bgp_evpn==bgp)//相等,则直接退出return;/*首先,释放我们在实例上持有的引用计数*/if(bm->bgp_evpn)bgp_unlock(bm->bgp_evpn);//设置一个新的bgp实例。bm->bgp_evpn=bgp;/*增加这个新VRF的引用计数*/if(bm->bgp_evpn)bgp_lock(bm->bgp_evpn);}//向zebra发送消息以获取所有vni。intbgp_zebra_advertise_all_vni(structbgp*bgp,intadvertise){structstream*s;/*检查套接字。*/if(!zclient||zclient->sock<0)return0;/*如果Zebra不知道这个实例,不要尝试注册。*/如果(!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))返回0;s=zclient->obuf;stream_reset(s);//通知zebra进程获取所有配置的vnis。zclient_create_header(s,ZEBRA_ADVERTISE_ALL_VNI,bgp->vrf_id);stream_putc(s,广告);/*同时通知当前的BUM处理设置。*只有当设置了'advertise'时,这才是真正相关的。*/stream_putc(s,bgp->vxlan_flood_ctrl);stream_putw_at(s,0,stream_get_endp(s));returnzclient_send_message(zclient);}zebra对这个命令的动作//处理evpnopen请求,会把本地所有的svi发给bgp,每个vxlan段下的fdb表和neighbor表(准确的主机路由)都会发给bgp。voidzebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS){structstream*s=NULL;int广告=0;枚举vxlan_flood_controlflood_ctrl;/*EVPNVRF和当前VRF不匹配(应该通过*bgpd的cli来防止当前VRF是否与VPN一致)*如果不一致,则退出。*/if(is_evpn_enabled()&&!EVPN_ENABLED(zvrf))返回;s=味精;STREAM_GETC(s,广告);STREAM_GETC(s,flood_ctrl);if(IS_ZEBRA_DEBUG_VXLAN)zlog_debug("EVPNVRF%s(%u)VNIAdv%s,当前%s,floodcontrol%u",zvrf_name(zvrf),zvrf_id(zvrf),advertise?"enabled":"disabled",is_evpn_enabled()?"enabled":"disabled",flood_ctrl);//配置相等则直接返回if(zvrf->advertise_all_vni==advertise)return;//设置新的配置zvrf->advertise_all_vni=advertise;if(EVPN_ENABLED(zvrf)){//新的配置是开启zrouter.evpn_vrf=zvrf;//全局只有一个evpnvrf/*注意BUMhandlingbumtrafficprocessing*/zvrf->vxlan_flood_ctrl=flood_ctrl;/*构建VNI哈希表并通知BGP。*/zvni_build_hash_table();/*将所有SVI(L3GW)MAC添加到BGP添加所有l3svi,发送到bgp*/hash_iterate(zvrf->vni_table,zvni_gw_macip_add_for_vni_ha嘘,空);/*读取MACFDB读取fdb信息并发送给bgp*/macfdb_read(zvrf->zns);/*Readneighbors读取邻居信息并发送给bgp*/neigh_read(zvrf->zns);}else{/*清除所有VNI的VTEP-从*内核和空闲条目中卸载。*/hash_iterate(zvrf->vni_table,zvni_cleanup_all,zvrf);/*清除所有l3vnis*/hash_iterate(zrouter.l3vni_table,zl3vni_ULL)_all,N;/*标记为“无EVPNVRF”*/zrouter.evpn_vrf=NULL;}stream_failure:return;}bgp处理zebra返回的消息staticintbgp_zebra_process_local_macip(ZAPI_CALLBACK_ARGS){structstream*s;vni_tvni;结构bgp*bgp;结构ethaddrmac;结构ipaddrip;intipa_len;字符buf[ETHER_ADDR_STRLEN];charbuf1[INET6_ADDRSTRLEN];uint8_t标志=0;uint32_t序号=0;国际状态=0;memset(&ip,0,sizeof(ip));s=zclient->ibuf;vni=stream_getl(s);stream_get(&mac.octet,s,ETH_ALEN);ipa_len=stream_getl(s);if(ipa_len!=0&&ipa_len!=IPV4_MAX_BYTELEN&&ipa_len!=IPV6_MAX_BYTELEN){flog_err(EC_BGP_MACIP_LEN,"%u:RecvMACIP%swithinvalidIPaddrlength%d",vrf_id,(cmd==ZEBRA_MACIP_ADD)?"Add":"删除",ipa_len);返回-1;}如果(ipa_len){ip.ipa_type=(ipa_len==IPV4_MAX_BYTELEN)?IPADDR_V4:IPADDR_V6;stream_get(&ip.ip.addr,s,ipa_len);}if(cmd==ZEBRA_MACIP_ADD){flags=stream_getc(s);seqnum=stream_getl(s);}else{state=stream_getl(s);}bgp=bgp_lookup_by_vrf_id(vrf_id);如果(!bgp)返回0;if(BGP_DEBUG(zebra,ZEBRA))zlog_debug("%u:RecvMACIP%sflags0x%xMAC%sIP%sVNI%useq%ustate%d",vrf_id,(cmd==ZEBRA_MACIP_ADD)?"添加":"Del",flags,prefix_mac2str(&mac,buf,sizeof(buf)),ipaddr2str(&ip,buf1,sizeof(buf1)),vni,seqnum,state);如果(cmd==ZEBRA_MACIP_ADD)返回bgp_evpn_local_macip_add(bgp,vni,&mac,&ip,flags,seqnum);elsereturnbgp_evpn_local_macip_del(bgp,vni,&mac,&ip,state);}/**处理本地MACIP的添加。*publicmac/ipporttype2enabledfreeremote*/intbgp_evpn_local_macip_add(structbgp*bgp,vni_tvni,structethaddr*mac,structipaddr*ip,uint8_tflags,uint32_tseq){pn*bgppev;结构前缀_evpnp;/*VNI哈希查找-应该存在。*/vpn=bgp_evpn_lookup_vni(bgp,vni);if(!vpn||!is_vni_live(vpn)){flog_warn(EC_BGP_EVPN_VPN_VNI,"%u:VNI%u%s到MACIPADD的VNI哈希条目",bgp->vrf_id,vni,vpn?"notlive":“未找到”);返回-1;}/*创建EVPNtype-2路由并检查dule进行处理。*/build_evpn_type2_prefix(&p,mac,ip);如果(update_evpn_route(bgp,vpn,&p,flags,seq)){charbuf[ETHER_ADDR_STRLEN];charbuf2[INET6_ADDRSTRLEN];flog_err(EC_BGP_EVPN_ROUTE_CREATE,"%u:未能创建Type-2路由,VNI%u%sMAC%sIP%s(flags:0x%x)",bgp->vrf_id,vpn->vni,CHECK_FLAG(flags,ZEBRA_MACIP_TYPE_STICKY)?"stickygateway":"",prefix_mac2str(mac,buf,sizeof(buf)),ipaddr2str(ip,buf2,sizeof(buf2)),flags);返回-1;}返回0;}