package org.freertr.rtr; import java.util.ArrayList; import java.util.List; import org.freertr.addr.addrIP; import org.freertr.addr.addrIPv4; import org.freertr.addr.addrMac; import org.freertr.addr.addrPrefix; import org.freertr.cfg.cfgAceslst; import org.freertr.cfg.cfgAll; import org.freertr.cfg.cfgIfc; import org.freertr.cfg.cfgInit; import org.freertr.cfg.cfgPlymp; import org.freertr.cfg.cfgPrfxlst; import org.freertr.cfg.cfgProxy; import org.freertr.cfg.cfgRoump; import org.freertr.cfg.cfgRouplc; import org.freertr.cfg.cfgRtr; import org.freertr.cfg.cfgVrf; import org.freertr.clnt.clntWhois; import org.freertr.ifc.ifcDot1ah; import org.freertr.ip.ipCor4; import org.freertr.ip.ipCor6; import org.freertr.ip.ipFwd; import org.freertr.ip.ipFwdIface; import org.freertr.ip.ipFwdTab; import org.freertr.ip.ipRtr; import org.freertr.pack.packHolder; import org.freertr.pipe.pipeLine; import org.freertr.pipe.pipeSide; import org.freertr.prt.prtGenConn; import org.freertr.prt.prtServS; import org.freertr.prt.prtTcp; import org.freertr.tab.tabGen; import org.freertr.tab.tabIndex; import org.freertr.tab.tabIntMatcher; import org.freertr.tab.tabLabel; import org.freertr.tab.tabLabelBier; import org.freertr.tab.tabLabelBierN; import org.freertr.tab.tabLabelEntry; import org.freertr.tab.tabListing; import org.freertr.tab.tabPlcmapN; import org.freertr.tab.tabPrfxlstN; import org.freertr.tab.tabQos; import org.freertr.tab.tabRoute; import org.freertr.tab.tabRouteAttr; import org.freertr.tab.tabRouteEntry; import org.freertr.tab.tabRouteUtil; import org.freertr.tab.tabRtrmapN; import org.freertr.tab.tabRtrplcN; import org.freertr.user.userFormat; import org.freertr.user.userHelping; import org.freertr.util.bits; import org.freertr.util.cmds; import org.freertr.util.debugger; import org.freertr.util.logFil; import org.freertr.util.logger; import org.freertr.util.notifier; import org.freertr.spf.spfCalc; import org.freertr.spf.spfLnkst; import org.freertr.tab.tabRoautNtry; import org.freertr.util.counter; import org.freertr.util.syncInt; /** * border gateway protocol (rfc4271) version 4 * * @author matecsaba */ public class rtrBgp extends ipRtr implements prtServS, Runnable { /** * port to use */ public final static int port = 179; /** * local as number */ public int localAs; /** * address families */ public long addrFams; /** * router id */ public addrIPv4 routerID; /** * safe ebgp */ public boolean safeEbgp; /** * segment routing index */ public int segrouIdx = 0; /** * segment routing maximum */ public int segrouMax = 0; /** * segment routing base */ public int segrouBase = 0; /** * segment routing labels */ protected tabLabelEntry[] segrouLab; /** * bier index */ public int bierIdx = 0; /** * bier subdomain */ public int bierSub = 0; /** * bier length */ public int bierLen = 0; /** * bier maximum */ public int bierMax = 0; /** * bier labels */ protected tabLabelEntry[] bierLab; /** * scan time interval */ public int scanTime; /** * initial delay */ public int scanDelay; /** * recursion depth */ public int recursion; /** * default information originate */ public boolean defRou; /** * restart time */ public int restartTime; /** * long lived restart time */ public int llRestartTime; /** * external distance */ public int distantExt; /** * internal distance */ public int distantInt; /** * local distance */ public int distantLoc; /** * update groups */ public List groups; /** * group minimum */ public int groupMin; /** * group maximum */ public int groupMax; /** * listen configurations */ public tabGen lstnTmp = new tabGen(); /** * list of dynamic neighbors */ protected tabGen lstnNei; /** * route type */ protected final tabRouteAttr.routeType rouTyp; /** * unicast afi */ protected final int afiUni; /** * labeled unicast afi */ protected final int afiLab; /** * classful transport plane afi */ protected final int afiCtp; /** * color aware routing afi */ protected final int afiCar; /** * multicast afi */ protected final int afiMlt; /** * other labeled unicast afi */ protected final int afiOlab; /** * other classful transport plane afi */ protected final int afiOctp; /** * other color aware routing afi */ protected final int afiOcar; /** * other unicast afi */ protected final int afiOuni; /** * other multicast afi */ protected final int afiOmlt; /** * other flowspec afi */ protected final int afiOflw; /** * other srte afi */ protected final int afiOsrt; /** * flow specification afi */ protected final int afiFlw; /** * unicast vpn afi */ protected final int afiVpnU; /** * multicast vpn afi */ protected final int afiVpnM; /** * flowspec vpn afi */ protected final int afiVpnF; /** * other unicast vpn afi */ protected final int afiVpoU; /** * other multicast vpn afi */ protected final int afiVpoM; /** * other flowspec vpn afi */ protected final int afiVpoF; /** * vpls afi */ protected final int afiVpls; /** * mspw afi */ protected final int afiMspw; /** * evpn afi */ protected final int afiEvpn; /** * mdt afi */ protected final int afiMdt; /** * nsh afi */ protected final int afiNsh; /** * rpd afi */ protected final int afiRpd; /** * spf afi */ protected final int afiSpf; /** * rtfilter afi */ protected final int afiRtf; /** * srte afi */ protected final int afiSrte; /** * linkstate afi */ protected final int afiLnks; /** * mvpn afi */ protected final int afiMvpn; /** * other mvpn afi */ protected final int afiMvpo; /** * mtree afi */ protected final int afiMtre; /** * other mtree afi */ protected final int afiMtro; /** * router number */ protected final int rtrNum; /** * other changes trigger full computation */ protected boolean otherTrigger; /** * have route reflector client */ protected boolean have2reflect; /** * next hop tracking route map */ protected tabListing nhtRoumap; /** * next hop tracking route policy */ protected tabListing nhtRouplc; /** * next hop tracking policy map */ protected tabListing nhtPfxlst; /** * flow specification */ protected tabListing flowSpec; /** * link states */ protected tabGen linkStates; /** * install flow specification */ protected boolean flowInst; /** * rpki type configured */ protected tabRouteAttr.routeType rpkiT; /** * rpki number configured */ protected int rpkiN; /** * rpki process */ protected rtrRpki rpkiR; /** * rpki table */ protected tabGen rpkiA = new tabGen(); /** * other rpki table */ protected tabGen rpkiO = new tabGen(); /** * the computed other unicast routes */ public tabRoute computedOuni = new tabRoute("rx"); /** * the computed other multicast routes */ public tabRoute computedOmlt = new tabRoute("rx"); /** * the computed other flowspec routes */ public tabRoute computedOflw = new tabRoute("rx"); /** * the computed other srte routes */ public tabRoute computedOsrt = new tabRoute("rx"); /** * the computed vpnuni routes */ public tabRoute computedVpnU = new tabRoute("rx"); /** * the computed vpnmlt routes */ public tabRoute computedVpnM = new tabRoute("rx"); /** * the computed vpnflw routes */ public tabRoute computedVpnF = new tabRoute("rx"); /** * the computed other vpnuni routes */ public tabRoute computedVpoU = new tabRoute("rx"); /** * the computed other vpnmlt routes */ public tabRoute computedVpoM = new tabRoute("rx"); /** * the computed other vpnflw routes */ public tabRoute computedVpoF = new tabRoute("rx"); /** * the computed vpls routes */ public tabRoute computedVpls = new tabRoute("rx"); /** * the computed mspw routes */ public tabRoute computedMspw = new tabRoute("rx"); /** * the computed evpn routes */ public tabRoute computedEvpn = new tabRoute("rx"); /** * the computed mdt routes */ public tabRoute computedMdt = new tabRoute("rx"); /** * the computed nsh routes */ public tabRoute computedNsh = new tabRoute("rx"); /** * the computed rpd routes */ public tabRoute computedRpd = new tabRoute("rx"); /** * the computed spf routes */ public tabRoute computedSpf = new tabRoute("rx"); /** * the computed rtfilter routes */ public tabRoute computedRtf = new tabRoute("rx"); /** * the computed srte routes */ public tabRoute computedSrte = new tabRoute("rx"); /** * the computed linkstate routes */ public tabRoute computedLnks = new tabRoute("rx"); /** * the computed mvpn routes */ public tabRoute computedMvpn = new tabRoute("rx"); /** * the computed other mvpn routes */ public tabRoute computedMvpo = new tabRoute("rx"); /** * the computed mtree routes */ public tabRoute computedMtre = new tabRoute("rx"); /** * the computed other mtree routes */ public tabRoute computedMtro = new tabRoute("rx"); /** * the changed unicast routes */ public final tabRoute changedUni = new tabRoute("rx"); /** * the changed multicast routes */ public final tabRoute changedMlt = new tabRoute("rx"); /** * the changed other unicast routes */ public final tabRoute changedOuni = new tabRoute("rx"); /** * the changed other multicast routes */ public final tabRoute changedOmlt = new tabRoute("rx"); /** * the changed other flowspec routes */ public final tabRoute changedOflw = new tabRoute("rx"); /** * the changed other srte routes */ public final tabRoute changedOsrt = new tabRoute("rx"); /** * the changed flowspec routes */ public final tabRoute changedFlw = new tabRoute("rx"); /** * the changed vpnuni routes */ public final tabRoute changedVpnU = new tabRoute("rx"); /** * the changed vpnmlt routes */ public final tabRoute changedVpnM = new tabRoute("rx"); /** * the changed vpnflw routes */ public final tabRoute changedVpnF = new tabRoute("rx"); /** * the changed other vpnuni routes */ public final tabRoute changedVpoU = new tabRoute("rx"); /** * the changed other vpnmlt routes */ public final tabRoute changedVpoM = new tabRoute("rx"); /** * the changed other vpnflw routes */ public final tabRoute changedVpoF = new tabRoute("rx"); /** * the changed vpls routes */ public final tabRoute changedVpls = new tabRoute("rx"); /** * the changed mspw routes */ public final tabRoute changedMspw = new tabRoute("rx"); /** * the changed evpn routes */ public final tabRoute changedEvpn = new tabRoute("rx"); /** * the changed mdt routes */ public final tabRoute changedMdt = new tabRoute("rx"); /** * the changed nsh routes */ public final tabRoute changedNsh = new tabRoute("rx"); /** * the changed rpd routes */ public final tabRoute changedRpd = new tabRoute("rx"); /** * the changed spf routes */ public final tabRoute changedSpf = new tabRoute("rx"); /** * the changed rtfilter routes */ public final tabRoute changedRtf = new tabRoute("rx"); /** * the changed srte routes */ public final tabRoute changedSrte = new tabRoute("rx"); /** * the changed linkstate routes */ public final tabRoute changedLnks = new tabRoute("rx"); /** * the changed mvpn routes */ public final tabRoute changedMvpn = new tabRoute("rx"); /** * the changed other mvpn routes */ public final tabRoute changedMvpo = new tabRoute("rx"); /** * the changed mvpn routes */ public final tabRoute changedMtre = new tabRoute("rx"); /** * the changed other mvpn routes */ public final tabRoute changedMtro = new tabRoute("rx"); /** * the newly computed unicast routes */ public tabRoute newlyUni = new tabRoute("bst"); /** * the newly computed multicast routes */ public tabRoute newlyMlt = new tabRoute("bst"); /** * the newly computed other unicast routes */ public tabRoute newlyOuni = new tabRoute("bst"); /** * the newly computed other multicast routes */ public tabRoute newlyOmlt = new tabRoute("bst"); /** * the newly computed other flowspec routes */ public tabRoute newlyOflw = new tabRoute("bst"); /** * the newly computed other srte routes */ public tabRoute newlyOsrt = new tabRoute("bst"); /** * the newly computed flowspec routes */ public tabRoute newlyFlw = new tabRoute("bst"); /** * the newly computed vpnuni routes */ public tabRoute newlyVpnU = new tabRoute("bst"); /** * the newly computed vpnmlt routes */ public tabRoute newlyVpnM = new tabRoute("bst"); /** * the newly computed vpnflw routes */ public tabRoute newlyVpnF = new tabRoute("bst"); /** * the newly computed other vpnuni routes */ public tabRoute newlyVpoU = new tabRoute("bst"); /** * the newly computed other vpnmlt routes */ public tabRoute newlyVpoM = new tabRoute("bst"); /** * the newly computed other vpnflw routes */ public tabRoute newlyVpoF = new tabRoute("bst"); /** * the newly computed vpls routes */ public tabRoute newlyVpls = new tabRoute("bst"); /** * the newly computed mspw routes */ public tabRoute newlyMspw = new tabRoute("bst"); /** * the newly computed evpn routes */ public tabRoute newlyEvpn = new tabRoute("bst"); /** * the newly computed mdt routes */ public tabRoute newlyMdt = new tabRoute("bst"); /** * the newly computed nsh routes */ public tabRoute newlyNsh = new tabRoute("bst"); /** * the newly computed rpd routes */ public tabRoute newlyRpd = new tabRoute("bst"); /** * the newly computed spf routes */ public tabRoute newlySpf = new tabRoute("bst"); /** * the newly computed rtfilter routes */ public tabRoute newlyRtf = new tabRoute("bst"); /** * the newly computed srte routes */ public tabRoute newlySrte = new tabRoute("bst"); /** * the newly computed lnkst routes */ public tabRoute newlyLnks = new tabRoute("bst"); /** * the newly computed mvpn routes */ public tabRoute newlyMvpn = new tabRoute("bst"); /** * the newly computed other mvpn routes */ public tabRoute newlyMvpo = new tabRoute("bst"); /** * the newly computed mtree routes */ public tabRoute newlyMtre = new tabRoute("bst"); /** * the newly computed other mtree routes */ public tabRoute newlyMtro = new tabRoute("bst"); /** * the originated other unicast routes */ public tabRoute origntedOuni = new tabRoute("tx"); /** * the originated other multicast routes */ public tabRoute origntedOmlt = new tabRoute("tx"); /** * the originated other flowspec routes */ public tabRoute origntedOflw = new tabRoute("tx"); /** * the originated other srte routes */ public tabRoute origntedOsrt = new tabRoute("tx"); /** * the originated flowspec routes */ public tabRoute origntedFlw = new tabRoute("tx"); /** * the originated vpnuni routes */ public tabRoute origntedVpnU = new tabRoute("tx"); /** * the originated vpnmlt routes */ public tabRoute origntedVpnM = new tabRoute("tx"); /** * the originated vpnflw routes */ public tabRoute origntedVpnF = new tabRoute("tx"); /** * the originated other vpnuni routes */ public tabRoute origntedVpoU = new tabRoute("tx"); /** * the originated other vpnmlt routes */ public tabRoute origntedVpoM = new tabRoute("tx"); /** * the originated other vpnflw routes */ public tabRoute origntedVpoF = new tabRoute("tx"); /** * the originated vpls routes */ public tabRoute origntedVpls = new tabRoute("tx"); /** * the originated mspw routes */ public tabRoute origntedMspw = new tabRoute("tx"); /** * the originated evpn routes */ public tabRoute origntedEvpn = new tabRoute("tx"); /** * the originated mdt routes */ public tabRoute origntedMdt = new tabRoute("tx"); /** * the originated nsh routes */ public tabRoute origntedNsh = new tabRoute("tx"); /** * the originated rpd routes */ public tabRoute origntedRpd = new tabRoute("tx"); /** * the originated spf routes */ public tabRoute origntedSpf = new tabRoute("tx"); /** * the originated rtfilter routes */ public tabRoute origntedRtf = new tabRoute("tx"); /** * the originated srte routes */ public tabRoute origntedSrte = new tabRoute("tx"); /** * the originated linkstate routes */ public tabRoute origntedLnks = new tabRoute("tx"); /** * the originated mvpn routes */ public tabRoute origntedMvpn = new tabRoute("tx"); /** * the originated other mvpn routes */ public tabRoute origntedMvpo = new tabRoute("tx"); /** * the originated mtree routes */ public tabRoute origntedMtre = new tabRoute("tx"); /** * the originated other mtree routes */ public tabRoute origntedMtro = new tabRoute("tx"); /** * incremental limit */ public int incrLimit; /** * conquer bestpath */ public boolean conquer; /** * flap statistics */ public tabGen flaps; /** * list of monitors */ protected tabGen mons; /** * list of dumps */ protected tabGen dmps; /** * list of neighbors */ protected tabGen neighs; /** * list of templates */ protected tabGen temps; /** * other afi router */ protected rtrBgpOther other; /** * spf afi router */ protected rtrBgpSpf lspf; /** * list of vrfs */ protected tabGen vrfs; /** * list of other vrfs */ protected tabGen ovrfs; /** * list of colors */ protected tabGen clrs; /** * list of other colors */ protected tabGen oclrs; /** * list of vpls */ protected tabGen vpls; /** * list of evpns */ protected tabGen evpn; /** * evpn receiver */ protected rtrBgpEvpnPbb evpnRcv; /** * evpn unicast label */ protected tabLabelEntry evpnUni; /** * evpn multicast label */ protected tabLabelEntry evpnMul; /** * accept statistics */ public final counter accptStat = new counter(); /** * reachability statistics */ public final counter reachabStat = new counter(); /** * unreachability statistics */ public final counter unreachStat = new counter(); /** * message types received */ public final counter[] msgStats = new counter[256]; /** * attribute types received */ public final counter[] attrStats = new counter[256]; /** * full compute last */ public long fullLast; /** * incremental compute last */ public long incrLast; /** * full compute count */ public int fullCount; /** * incremental compute count */ public int incrCount; /** * full compute time */ public int fullTime; /** * incremental compute time */ public int incrTime; /** * changed prefixes current */ public int changedCur; /** * changed prefixes total */ public long changedTot; /** * changed prefixes peak */ public long changedMax; /** * changed prefixes peak */ public long changedPek; /** * the tcp protocol */ public final prtTcp tcpCore; /** * the forwarder protocol */ public final ipFwd fwdCore; /** * the forwarder vrf */ protected cfgVrf vrfCore; /** * notifier for table computation */ protected final notifier compute = new notifier(); /** * computation round */ protected final syncInt compRound = new syncInt(0); /** * need full round */ protected final syncInt needFull = new syncInt(0); private boolean oldAggr; private boolean need2run; /** * create bgp process * * @param forwarder forwarder to update * @param vrfcfg vrf config to use * @param protoT tcp protocol to use * @param id process id */ public rtrBgp(ipFwd forwarder, cfgVrf vrfcfg, prtTcp protoT, int id) { if (debugger.rtrBgpEvnt) { logger.debug("startup"); } vrfCore = vrfcfg; fwdCore = forwarder; tcpCore = protoT; vrfs = new tabGen(); ovrfs = new tabGen(); clrs = new tabGen(); oclrs = new tabGen(); vpls = new tabGen(); evpn = new tabGen(); evpnUni = tabLabel.allocate(tabLabelEntry.owner.evpnPbb); evpnMul = tabLabel.allocate(tabLabelEntry.owner.evpnPbb); evpnRcv = new rtrBgpEvpnPbb(this); evpnUni.setFwdPwe(tabLabelEntry.owner.evpnPbb, fwdCore, evpnRcv, 0, null); evpnMul.setFwdPwe(tabLabelEntry.owner.evpnPbb, fwdCore, evpnRcv, 0, null); routerID = new addrIPv4(); safeEbgp = true; addrFams = rtrBgpParam.mskUni; rtrNum = id; for (int i = 0; i < msgStats.length; i++) { msgStats[i] = new counter(); } for (int i = 0; i < attrStats.length; i++) { attrStats[i] = new counter(); } switch (fwdCore.ipVersion) { case ipCor4.protocolVersion: rouTyp = tabRouteAttr.routeType.bgp4; afiUni = rtrBgpUtil.safiIp4uni; afiLab = rtrBgpUtil.safiIp4lab; afiCtp = rtrBgpUtil.safiIp4ctp; afiCar = rtrBgpUtil.safiIp4car; afiMlt = rtrBgpUtil.safiIp4multi; afiOlab = rtrBgpUtil.safiIp6lab; afiOctp = rtrBgpUtil.safiIp6ctp; afiOcar = rtrBgpUtil.safiIp6car; afiOuni = rtrBgpUtil.safiIp6uni; afiOmlt = rtrBgpUtil.safiIp6multi; afiOflw = rtrBgpUtil.safiIp6flow; afiOsrt = rtrBgpUtil.safiIp6srte; afiFlw = rtrBgpUtil.safiIp4flow; afiVpnU = rtrBgpUtil.safiIp4vpnU; afiVpnM = rtrBgpUtil.safiIp4vpnM; afiVpnF = rtrBgpUtil.safiIp4vpnF; afiVpoU = rtrBgpUtil.safiIp6vpnU; afiVpoM = rtrBgpUtil.safiIp6vpnM; afiVpoF = rtrBgpUtil.safiIp6vpnF; afiVpls = rtrBgpUtil.safiVpls46; afiMspw = rtrBgpUtil.safiMspw46; afiEvpn = rtrBgpUtil.safiEvpn46; afiMdt = rtrBgpUtil.safiIp4mdt; afiNsh = rtrBgpUtil.safiNsh46; afiRpd = rtrBgpUtil.safiRpd46; afiSpf = rtrBgpUtil.safiIp46spf; afiRtf = rtrBgpUtil.safiRtf46; afiLnks = rtrBgpUtil.safiIp46lnks; afiSrte = rtrBgpUtil.safiIp4srte; afiMvpn = rtrBgpUtil.safiIp4mvpn; afiMvpo = rtrBgpUtil.safiIp6mvpn; afiMtre = rtrBgpUtil.safiIp4mtree; afiMtro = rtrBgpUtil.safiIp6mtree; other = new rtrBgpOther(this, vrfCore.fwd6); lspf = new rtrBgpSpf(this); break; case ipCor6.protocolVersion: rouTyp = tabRouteAttr.routeType.bgp6; afiUni = rtrBgpUtil.safiIp6uni; afiLab = rtrBgpUtil.safiIp6lab; afiCtp = rtrBgpUtil.safiIp6ctp; afiCar = rtrBgpUtil.safiIp6car; afiMlt = rtrBgpUtil.safiIp6multi; afiOlab = rtrBgpUtil.safiIp4lab; afiOctp = rtrBgpUtil.safiIp4ctp; afiOcar = rtrBgpUtil.safiIp4car; afiOuni = rtrBgpUtil.safiIp4uni; afiOmlt = rtrBgpUtil.safiIp4multi; afiOflw = rtrBgpUtil.safiIp4flow; afiOsrt = rtrBgpUtil.safiIp4srte; afiFlw = rtrBgpUtil.safiIp6flow; afiVpnU = rtrBgpUtil.safiIp6vpnU; afiVpnM = rtrBgpUtil.safiIp6vpnM; afiVpnF = rtrBgpUtil.safiIp6vpnF; afiVpoU = rtrBgpUtil.safiIp4vpnU; afiVpoM = rtrBgpUtil.safiIp4vpnM; afiVpoF = rtrBgpUtil.safiIp4vpnF; afiVpls = rtrBgpUtil.safiVpls46; afiMspw = rtrBgpUtil.safiMspw46; afiEvpn = rtrBgpUtil.safiEvpn46; afiMdt = rtrBgpUtil.safiIp6mdt; afiNsh = rtrBgpUtil.safiNsh46; afiRpd = rtrBgpUtil.safiRpd46; afiSpf = rtrBgpUtil.safiIp46spf; afiRtf = rtrBgpUtil.safiRtf46; afiLnks = rtrBgpUtil.safiIp46lnks; afiSrte = rtrBgpUtil.safiIp6srte; afiMvpn = rtrBgpUtil.safiIp6mvpn; afiMvpo = rtrBgpUtil.safiIp4mvpn; afiMtre = rtrBgpUtil.safiIp6mtree; afiMtro = rtrBgpUtil.safiIp4mtree; other = new rtrBgpOther(this, vrfCore.fwd4); lspf = new rtrBgpSpf(this); break; default: rouTyp = null; afiUni = 0; afiLab = 0; afiCtp = 0; afiCar = 0; afiMlt = 0; afiOlab = 0; afiOctp = 0; afiOcar = 0; afiOuni = 0; afiOmlt = 0; afiOflw = 0; afiOsrt = 0; afiFlw = 0; afiVpnU = 0; afiVpnM = 0; afiVpnF = 0; afiVpoU = 0; afiVpoM = 0; afiVpoF = 0; afiVpls = 0; afiMspw = 0; afiEvpn = 0; afiMdt = 0; afiNsh = 0; afiRpd = 0; afiSpf = 0; afiRtf = 0; afiLnks = 0; afiSrte = 0; afiMvpn = 0; afiMvpo = 0; afiMtre = 0; afiMtro = 0; other = new rtrBgpOther(this, null); lspf = new rtrBgpSpf(this); break; } incrLimit = 1000; conquer = false; flaps = null; scanTime = 1000; scanDelay = 1000; recursion = 1; restartTime = 60 * 1000; distantExt = 20; distantInt = 200; distantLoc = 200; linkStates = new tabGen(); lstnNei = new tabGen(); neighs = new tabGen(); mons = new tabGen(); dmps = new tabGen(); temps = new tabGen(); routerComputedU = new tabRoute("rx"); routerComputedM = new tabRoute("rx"); routerComputedF = new tabRoute("rx"); routerComputedI = new tabGen>(); needFull.add(1); compRound.add(1); routerCreateComputed(); need2run = true; new Thread(this).start(); fwdCore.routerAdd(this, rouTyp, id); } /** * convert to string * * @return string */ public String toString() { return "bgp on " + fwdCore; } /** * convert safi to mask * * @param safi safi * @return mask */ public long safi2mask(int safi) { if (safi == afiUni) { return rtrBgpParam.mskUni; } if (safi == afiLab) { return rtrBgpParam.mskLab; } if (safi == afiCtp) { return rtrBgpParam.mskCtp; } if (safi == afiCar) { return rtrBgpParam.mskCar; } if (safi == afiMlt) { return rtrBgpParam.mskMlt; } if (safi == afiOlab) { return rtrBgpParam.mskOlab; } if (safi == afiOctp) { return rtrBgpParam.mskOctp; } if (safi == afiOcar) { return rtrBgpParam.mskOcar; } if (safi == afiOuni) { return rtrBgpParam.mskOuni; } if (safi == afiOmlt) { return rtrBgpParam.mskOmlt; } if (safi == afiOflw) { return rtrBgpParam.mskOflw; } if (safi == afiOsrt) { return rtrBgpParam.mskOsrt; } if (safi == afiFlw) { return rtrBgpParam.mskFlw; } if (safi == afiVpnU) { return rtrBgpParam.mskVpnU; } if (safi == afiVpnM) { return rtrBgpParam.mskVpnM; } if (safi == afiVpnF) { return rtrBgpParam.mskVpnF; } if (safi == afiVpoU) { return rtrBgpParam.mskVpoU; } if (safi == afiVpoM) { return rtrBgpParam.mskVpoM; } if (safi == afiVpoF) { return rtrBgpParam.mskVpoF; } if (safi == afiVpls) { return rtrBgpParam.mskVpls; } if (safi == afiMspw) { return rtrBgpParam.mskMspw; } if (safi == afiEvpn) { return rtrBgpParam.mskEvpn; } if (safi == afiMdt) { return rtrBgpParam.mskMdt; } if (safi == afiNsh) { return rtrBgpParam.mskNsh; } if (safi == afiRpd) { return rtrBgpParam.mskRpd; } if (safi == afiSpf) { return rtrBgpParam.mskSpf; } if (safi == afiRtf) { return rtrBgpParam.mskRtf; } if (safi == afiSrte) { return rtrBgpParam.mskSrte; } if (safi == afiLnks) { return rtrBgpParam.mskLnks; } if (safi == afiMvpn) { return rtrBgpParam.mskMvpn; } if (safi == afiMvpo) { return rtrBgpParam.mskMvpo; } if (safi == afiMtre) { return rtrBgpParam.mskMtre; } if (safi == afiMtro) { return rtrBgpParam.mskMtro; } logger.info("unknown safi (" + safi + ") requested"); return -1; } /** * convert mask to safi * * @param mask mask * @return safi */ public int mask2safi(long mask) { if (mask == rtrBgpParam.mskUni) { return afiUni; } if (mask == rtrBgpParam.mskLab) { return afiLab; } if (mask == rtrBgpParam.mskCtp) { return afiCtp; } if (mask == rtrBgpParam.mskCar) { return afiCar; } if (mask == rtrBgpParam.mskMlt) { return afiMlt; } if (mask == rtrBgpParam.mskOlab) { return afiOlab; } if (mask == rtrBgpParam.mskOctp) { return afiOctp; } if (mask == rtrBgpParam.mskOcar) { return afiOcar; } if (mask == rtrBgpParam.mskOuni) { return afiOuni; } if (mask == rtrBgpParam.mskOmlt) { return afiOmlt; } if (mask == rtrBgpParam.mskOflw) { return afiOflw; } if (mask == rtrBgpParam.mskOsrt) { return afiOsrt; } if (mask == rtrBgpParam.mskFlw) { return afiFlw; } if (mask == rtrBgpParam.mskVpnU) { return afiVpnU; } if (mask == rtrBgpParam.mskVpnM) { return afiVpnM; } if (mask == rtrBgpParam.mskVpnF) { return afiVpnF; } if (mask == rtrBgpParam.mskVpoU) { return afiVpoU; } if (mask == rtrBgpParam.mskVpoM) { return afiVpoM; } if (mask == rtrBgpParam.mskVpoF) { return afiVpoF; } if (mask == rtrBgpParam.mskVpls) { return afiVpls; } if (mask == rtrBgpParam.mskMspw) { return afiMspw; } if (mask == rtrBgpParam.mskEvpn) { return afiEvpn; } if (mask == rtrBgpParam.mskMdt) { return afiMdt; } if (mask == rtrBgpParam.mskNsh) { return afiNsh; } if (mask == rtrBgpParam.mskRpd) { return afiRpd; } if (mask == rtrBgpParam.mskSpf) { return afiSpf; } if (mask == rtrBgpParam.mskRtf) { return afiRtf; } if (mask == rtrBgpParam.mskSrte) { return afiSrte; } if (mask == rtrBgpParam.mskLnks) { return afiLnks; } if (mask == rtrBgpParam.mskMvpn) { return afiMvpn; } if (mask == rtrBgpParam.mskMvpo) { return afiMvpo; } if (mask == rtrBgpParam.mskMtre) { return afiMtre; } if (mask == rtrBgpParam.mskMtro) { return afiMtro; } logger.info("unknown safi (" + mask + ") requested"); return -1; } /** * mask to list * * @param mask mask * @return list */ public List mask2list(long mask) { List safis = new ArrayList(); if ((mask & rtrBgpParam.mskUni) != 0) { safis.add(afiUni); } if ((mask & rtrBgpParam.mskLab) != 0) { safis.add(afiLab); } if ((mask & rtrBgpParam.mskCtp) != 0) { safis.add(afiCtp); } if ((mask & rtrBgpParam.mskCar) != 0) { safis.add(afiCar); } if ((mask & rtrBgpParam.mskMlt) != 0) { safis.add(afiMlt); } if ((mask & rtrBgpParam.mskOlab) != 0) { safis.add(afiOlab); } if ((mask & rtrBgpParam.mskOctp) != 0) { safis.add(afiOctp); } if ((mask & rtrBgpParam.mskOcar) != 0) { safis.add(afiOcar); } if ((mask & rtrBgpParam.mskOuni) != 0) { safis.add(afiOuni); } if ((mask & rtrBgpParam.mskOmlt) != 0) { safis.add(afiOmlt); } if ((mask & rtrBgpParam.mskOflw) != 0) { safis.add(afiOflw); } if ((mask & rtrBgpParam.mskOsrt) != 0) { safis.add(afiOsrt); } if ((mask & rtrBgpParam.mskFlw) != 0) { safis.add(afiFlw); } if ((mask & rtrBgpParam.mskVpnU) != 0) { safis.add(afiVpnU); } if ((mask & rtrBgpParam.mskVpnM) != 0) { safis.add(afiVpnM); } if ((mask & rtrBgpParam.mskVpnF) != 0) { safis.add(afiVpnF); } if ((mask & rtrBgpParam.mskVpoU) != 0) { safis.add(afiVpoU); } if ((mask & rtrBgpParam.mskVpoM) != 0) { safis.add(afiVpoM); } if ((mask & rtrBgpParam.mskVpoF) != 0) { safis.add(afiVpoF); } if ((mask & rtrBgpParam.mskVpls) != 0) { safis.add(afiVpls); } if ((mask & rtrBgpParam.mskMspw) != 0) { safis.add(afiMspw); } if ((mask & rtrBgpParam.mskEvpn) != 0) { safis.add(afiEvpn); } if ((mask & rtrBgpParam.mskMdt) != 0) { safis.add(afiMdt); } if ((mask & rtrBgpParam.mskNsh) != 0) { safis.add(afiNsh); } if ((mask & rtrBgpParam.mskRpd) != 0) { safis.add(afiRpd); } if ((mask & rtrBgpParam.mskSpf) != 0) { safis.add(afiSpf); } if ((mask & rtrBgpParam.mskRtf) != 0) { safis.add(afiRtf); } if ((mask & rtrBgpParam.mskSrte) != 0) { safis.add(afiSrte); } if ((mask & rtrBgpParam.mskLnks) != 0) { safis.add(afiLnks); } if ((mask & rtrBgpParam.mskMvpn) != 0) { safis.add(afiMvpn); } if ((mask & rtrBgpParam.mskMvpo) != 0) { safis.add(afiMvpo); } if ((mask & rtrBgpParam.mskMtre) != 0) { safis.add(afiMtre); } if ((mask & rtrBgpParam.mskMtro) != 0) { safis.add(afiMtro); } return safis; } /** * clear flap statistics */ public void doClearFlaps() { if (flaps == null) { return; } flaps.clear(); } /** * clear peak statistics */ public void doClearPeaks() { changedMax = 0; changedPek = 0; } /** * clear tiny counters */ public void doClearTinys() { reachabStat.clear(); unreachStat.clear(); accptStat.clear(); } /** * clear msg statistics */ public void doClearMsgs() { for (int i = 0; i < msgStats.length; i++) { msgStats[i].clear(); } } /** * clear msg statistics */ public void doClearAttrs() { for (int i = 0; i < attrStats.length; i++) { attrStats[i].clear(); } } /** * get database * * @param safi safi to query * @return table */ public tabRoute getDatabase(int safi) { if (safi == afiUni) { return routerComputedU; } if (safi == afiLab) { return routerComputedU; } if (safi == afiCtp) { return routerComputedU; } if (safi == afiCar) { return routerComputedU; } if (safi == afiMlt) { return routerComputedM; } if (safi == afiOlab) { return computedOuni; } if (safi == afiOctp) { return computedOuni; } if (safi == afiOcar) { return computedOuni; } if (safi == afiOuni) { return computedOuni; } if (safi == afiOmlt) { return computedOmlt; } if (safi == afiOflw) { return computedOflw; } if (safi == afiOsrt) { return computedOsrt; } if (safi == afiFlw) { return routerComputedF; } if (safi == afiVpnU) { return computedVpnU; } if (safi == afiVpnM) { return computedVpnM; } if (safi == afiVpnF) { return computedVpnF; } if (safi == afiVpoU) { return computedVpoU; } if (safi == afiVpoM) { return computedVpoM; } if (safi == afiVpoF) { return computedVpoF; } if (safi == afiVpls) { return computedVpls; } if (safi == afiMspw) { return computedMspw; } if (safi == afiEvpn) { return computedEvpn; } if (safi == afiMdt) { return computedMdt; } if (safi == afiNsh) { return computedNsh; } if (safi == afiRpd) { return computedRpd; } if (safi == afiSpf) { return computedSpf; } if (safi == afiRtf) { return computedRtf; } if (safi == afiSrte) { return computedSrte; } if (safi == afiLnks) { return computedLnks; } if (safi == afiMvpn) { return computedMvpn; } if (safi == afiMvpo) { return computedMvpo; } if (safi == afiMtre) { return computedMtre; } if (safi == afiMtro) { return computedMtro; } logger.info("unknown safi (" + safi + ") requested"); return null; } /** * get changed * * @param safi safi to query * @return table */ public tabRoute getChanged(int safi) { if (safi == afiUni) { return changedUni; } if (safi == afiLab) { return changedUni; } if (safi == afiCtp) { return changedUni; } if (safi == afiCar) { return changedUni; } if (safi == afiMlt) { return changedMlt; } if (safi == afiOlab) { return changedOuni; } if (safi == afiOctp) { return changedOuni; } if (safi == afiOcar) { return changedOuni; } if (safi == afiOuni) { return changedOuni; } if (safi == afiOmlt) { return changedOmlt; } if (safi == afiOflw) { return changedOflw; } if (safi == afiOsrt) { return changedOsrt; } if (safi == afiFlw) { return changedFlw; } if (safi == afiVpnU) { return changedVpnU; } if (safi == afiVpnM) { return changedVpnM; } if (safi == afiVpnF) { return changedVpnF; } if (safi == afiVpoU) { return changedVpoU; } if (safi == afiVpoM) { return changedVpoM; } if (safi == afiVpoF) { return changedVpoF; } if (safi == afiVpls) { return changedVpls; } if (safi == afiMspw) { return changedMspw; } if (safi == afiEvpn) { return changedEvpn; } if (safi == afiMdt) { return changedMdt; } if (safi == afiNsh) { return changedNsh; } if (safi == afiRpd) { return changedRpd; } if (safi == afiSpf) { return changedSpf; } if (safi == afiRtf) { return changedRtf; } if (safi == afiSrte) { return changedSrte; } if (safi == afiLnks) { return changedLnks; } if (safi == afiMvpn) { return changedMvpn; } if (safi == afiMvpo) { return changedMvpo; } if (safi == afiMtre) { return changedMtre; } if (safi == afiMtro) { return changedMtro; } logger.info("unknown safi (" + safi + ") requested"); return null; } public void run() { for (;;) { if (!cfgInit.booting) { break; } bits.sleep(1000); } needFull.add(1); routerCreateComputed(); bits.sleep(scanDelay); for (;;) { if (compute.misleep(0) > 0) { bits.sleep(scanTime); } if (!need2run) { break; } try { routerCreateComputed(); } catch (Exception e) { logger.traceback(e); } } } /** * close interface * * @param ifc interface */ public void closedInterface(ipFwdIface ifc) { } /** * start connection * * @param pipe pipeline * @param id connection * @return false if success, true if error */ public boolean streamAccept(pipeSide pipe, prtGenConn id) { packHolder pckCnt = new packHolder(true, true); accptStat.rx(pckCnt); rtrBgpLstn lstn = null; for (int i = 0; i < lstnTmp.size(); i++) { rtrBgpLstn ntry = lstnTmp.get(i); if (!ntry.acl.matches(id)) { continue; } lstn = ntry; break; } if (lstn == null) { accptStat.drop(pckCnt, counter.reasons.notInTab); return true; } if (lstn.temp.maxClones > 0) { int i = countClones(neighs, lstn.temp); i += countClones(lstnNei, lstn.temp); if (i > lstn.temp.maxClones) { accptStat.drop(pckCnt, counter.reasons.noBuffer); return true; } } id.changeSecurity(lstn.temp.keyId, lstn.temp.passwd, lstn.temp.ttlSecurity, lstn.temp.tosValue); rtrBgpNeigh ntry = new rtrBgpNeigh(this, id.peerAddr); ntry.localIfc = id.iface; ntry.localAddr = id.iface.addr.copyBytes(); ntry.updateOddr(); if (neighs.find(ntry) != null) { accptStat.drop(pckCnt, counter.reasons.notUp); return true; } ntry.copyFrom(lstn.temp); ntry.template = lstn.temp; if (ntry.fallOver) { ntry.sendingIfc = ipFwdTab.findSendingIface(fwdCore, ntry.peerAddr); } ntry.updatePeer(); rtrBgpNeigh res = lstnNei.add(ntry); if (res != null) { accptStat.drop(pckCnt, counter.reasons.noBuffer); return true; } logger.info("accepting dynamic " + id.peerAddr + " " + id.portRem + " as " + lstn.temp); ntry.conn = new rtrBgpSpeak(this, ntry, pipe); ntry.socketMode = 4; ntry.startNow(); accptStat.tx(pckCnt); return false; } private final int countClones(tabGen lst, rtrBgpTemp tmp) { int o = 0; for (int i = lst.size() - 1; i >= 0; i--) { rtrBgpNeigh ntry = lst.get(i); if (ntry == null) { continue; } if (ntry.template != tmp) { continue; } o++; } return o; } /** * add listen peer * * @param peer peer address * @param from from address * @param temp template to use * @return neighbor instance */ public rtrBgpNeigh addListenPeer(addrIP peer, addrIP from, rtrBgpTemp temp) { rtrBgpNeigh ntry = new rtrBgpNeigh(this, peer); ntry.localAddr = from.copyBytes(); if (neighs.find(ntry) != null) { return null; } ntry.copyFrom(temp); ntry.template = temp; ntry.updatePeer(); rtrBgpNeigh res = lstnNei.put(ntry); if (res != null) { res.socketMode = 5; res.stopNow(); } ntry.socketMode = 5; return ntry; } /** * get blocking mode * * @return mode */ public boolean streamForceBlock() { return true; } /** * redistribution changed */ public void routerRedistChanged() { if (debugger.rtrBgpFull) { logger.debug("redist changed"); } needFull.add(1); compute.wakeup(); } /** * others changed */ public void routerOthersChanged() { if (otherTrigger) { if (debugger.rtrBgpFull) { logger.debug("others changed"); } needFull.add(1); compute.wakeup(); return; } if ((nhtRoumap != null) || (nhtRouplc != null) || (nhtPfxlst != null)) { compute.wakeup(); return; } } private void computeFull() { long tim = bits.getTime(); if (debugger.rtrBgpIncr) { logger.debug("bestpath for everything"); } tabGen lstn = new tabGen(lstnNei); routerChangedU = null; routerChangedM = null; routerChangedF = null; other.routerChangedU = null; other.routerChangedM = null; other.routerChangedF = null; changedUni.clear(); changedMlt.clear(); changedOuni.clear(); changedOmlt.clear(); changedOflw.clear(); changedOsrt.clear(); changedFlw.clear(); changedVpnU.clear(); changedVpnM.clear(); changedVpnF.clear(); changedVpoU.clear(); changedVpoM.clear(); changedVpoF.clear(); changedVpls.clear(); changedMspw.clear(); changedEvpn.clear(); changedMdt.clear(); changedNsh.clear(); changedRpd.clear(); changedSpf.clear(); changedRtf.clear(); changedSrte.clear(); changedLnks.clear(); changedMvpn.clear(); changedMvpo.clear(); changedMtre.clear(); changedMtro.clear(); newlyUni = new tabRoute("bst"); newlyMlt = new tabRoute("bst"); newlyOuni = new tabRoute("bst"); newlyOmlt = new tabRoute("bst"); newlyOflw = new tabRoute("bst"); newlyOsrt = new tabRoute("bst"); newlyFlw = new tabRoute("bst"); newlyVpnU = new tabRoute("bst"); newlyVpnM = new tabRoute("bst"); newlyVpnF = new tabRoute("bst"); newlyVpoU = new tabRoute("bst"); newlyVpoM = new tabRoute("bst"); newlyVpoF = new tabRoute("bst"); newlyVpls = new tabRoute("bst"); newlyMspw = new tabRoute("bst"); newlyEvpn = new tabRoute("bst"); newlyMdt = new tabRoute("bst"); newlyNsh = new tabRoute("bst"); newlyRpd = new tabRoute("bst"); newlySpf = new tabRoute("bst"); newlyRtf = new tabRoute("bst"); newlySrte = new tabRoute("bst"); newlyLnks = new tabRoute("bst"); newlyMvpn = new tabRoute("bst"); newlyMvpo = new tabRoute("bst"); newlyMtre = new tabRoute("bst"); newlyMtro = new tabRoute("bst"); if (flowSpec != null) { rtrBgpFlow.doAdvertise(newlyFlw, flowSpec, new tabRouteEntry(), afiUni == rtrBgpUtil.safiIp6uni, localAs); } for (int i = 0; i < linkStates.size(); i++) { rtrBgpLnkst ls = linkStates.get(i); ls.rtr.routerLinkStates(newlyLnks, ls.par, localAs, routerID); } for (int i = 0; i < routerRedistedF.size(); i++) { tabRouteEntry ntry = routerRedistedF.get(i); if (ntry == null) { continue; } ntry = ntry.copyBytes(tabRoute.addType.notyet); ntry.best.rouTyp = rouTyp; ntry.best.protoNum = rtrNum; ntry.best.distance = distantLoc; newlyFlw.add(tabRoute.addType.better, ntry, false, false); } other.doAdvertise(); lspf.doAdvertise(); for (int i = 0; i < vrfs.size(); i++) { vrfs.get(i).doer.doAdvertise(newlyVpnU, newlyVpnM, newlyVpnF, newlyMvpn); } for (int i = 0; i < ovrfs.size(); i++) { ovrfs.get(i).doer.doAdvertise(newlyVpoU, newlyVpoM, newlyVpoF, newlyMvpo); } for (int i = 0; i < clrs.size(); i++) { clrs.get(i).doer.doAdvertise(newlyUni, newlyMlt, newlyFlw, newlyMvpn); } for (int i = 0; i < oclrs.size(); i++) { oclrs.get(i).doer.doAdvertise(newlyOuni, newlyOmlt, newlyOflw, newlyMvpo); } for (int i = 0; i < vpls.size(); i++) { vpls.get(i).doAdvertise(); } for (int i = 0; i < evpn.size(); i++) { evpn.get(i).doAdvertise(); } origntedOuni = new tabRoute(newlyOuni); origntedOmlt = new tabRoute(newlyOmlt); origntedOflw = new tabRoute(newlyOflw); origntedOsrt = new tabRoute(newlyOsrt); origntedFlw = new tabRoute(newlyFlw); origntedVpnU = new tabRoute(newlyVpnU); origntedVpnM = new tabRoute(newlyVpnM); origntedVpnF = new tabRoute(newlyVpnF); origntedVpoU = new tabRoute(newlyVpoU); origntedVpoM = new tabRoute(newlyVpoM); origntedVpoF = new tabRoute(newlyVpoF); origntedVpls = new tabRoute(newlyVpls); origntedMspw = new tabRoute(newlyMspw); origntedEvpn = new tabRoute(newlyEvpn); origntedMdt = new tabRoute(newlyMdt); origntedNsh = new tabRoute(newlyNsh); origntedRpd = new tabRoute(newlyRpd); origntedSpf = new tabRoute(newlySpf); origntedRtf = new tabRoute(newlyRtf); origntedSrte = new tabRoute(newlySrte); origntedLnks = new tabRoute(newlyLnks); origntedMvpn = new tabRoute(newlyMvpn); origntedMvpo = new tabRoute(newlyMvpo); origntedMtre = new tabRoute(newlyMtre); origntedMtro = new tabRoute(newlyMtro); if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " rpki"); } rpkiR = null; if (rpkiT != null) { cfgRtr rtrCfg = cfgAll.rtrFind(rpkiT, rpkiN, false); if (rtrCfg != null) { rpkiR = (rtrRpki) rtrCfg.getRouter(); } } if (rpkiR != null) { rpkiA = rpkiR.getFinalTab(fwdCore.ipVersion); rpkiO = rpkiR.getFinalTab(other.fwd.ipVersion); } else { rpkiA = new tabGen(); rpkiO = new tabGen(); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " neighbors"); } groups = new ArrayList(); have2reflect = false; for (int i = 0; i < lstn.size(); i++) { rtrBgpNeigh nei = lstn.get(i); if (nei == null) { continue; } nei.setAccepted(); nei.setGroup(); nei.setMerge(); } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } nei.setAccepted(); nei.setGroup(); nei.setMerge(); } if (have2reflect) { tabRouteEntry ntry = new tabRouteEntry(); ntry.prefix = new addrPrefix(new addrIP(), 0); ntry.best.rouSrc = rtrBgpUtil.peerOriginate; newlyRtf.add(tabRoute.addType.always, ntry, true, true); origntedRtf.add(tabRoute.addType.always, ntry, true, true); } if (conquer) { if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " counquer"); } computeConquerTable(routerComputedU, newlyUni); computeConquerTable(routerComputedM, newlyMlt); computeConquerTable(computedOuni, newlyOuni); computeConquerTable(computedOmlt, newlyOmlt); computeConquerTable(computedOflw, newlyOflw); computeConquerTable(computedOsrt, newlyOsrt); computeConquerTable(routerComputedF, newlyFlw); computeConquerTable(computedVpnU, newlyVpnU); computeConquerTable(computedVpnM, newlyVpnM); computeConquerTable(computedVpnF, newlyVpnF); computeConquerTable(computedVpoU, newlyVpoU); computeConquerTable(computedVpoM, newlyVpoM); computeConquerTable(computedVpoF, newlyVpoF); computeConquerTable(computedVpls, newlyVpls); computeConquerTable(computedMspw, newlyMspw); computeConquerTable(computedEvpn, newlyEvpn); computeConquerTable(computedMdt, newlyMdt); computeConquerTable(computedNsh, newlyNsh); computeConquerTable(computedRpd, newlyRpd); computeConquerTable(computedSpf, newlySpf); computeConquerTable(computedRtf, newlyRtf); computeConquerTable(computedSrte, newlySrte); computeConquerTable(computedLnks, newlyLnks); computeConquerTable(computedMvpn, newlyMvpn); computeConquerTable(computedMvpo, newlyMvpo); computeConquerTable(computedMtre, newlyMtre); computeConquerTable(computedMtro, newlyMtro); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " groups"); } for (int i = 0; i < groups.size(); i++) { groups.get(i).createNeeded(); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " neigroups"); } lspf.doPeersFull(); boolean diffs = newlyUni.differs(tabRoute.addType.alters, routerComputedU) || newlyMlt.differs(tabRoute.addType.alters, routerComputedM) || newlyFlw.differs(tabRoute.addType.alters, routerComputedF); routerComputedU = newlyUni; routerComputedM = newlyMlt; computedOuni = newlyOuni; computedOmlt = newlyOmlt; computedOflw = newlyOflw; computedOsrt = newlyOsrt; routerComputedF = newlyFlw; computedVpnU = newlyVpnU; computedVpnM = newlyVpnM; computedVpnF = newlyVpnF; computedVpoU = newlyVpoU; computedVpoM = newlyVpoM; computedVpoF = newlyVpoF; computedVpls = newlyVpls; computedMspw = newlyMspw; computedEvpn = newlyEvpn; computedMdt = newlyMdt; computedNsh = newlyNsh; computedRpd = newlyRpd; computedSpf = newlySpf; computedRtf = newlyRtf; computedSrte = newlySrte; computedLnks = newlyLnks; computedMvpn = newlyMvpn; computedMvpo = newlyMvpo; computedMtre = newlyMtre; computedMtro = newlyMtro; if (diffs) { fwdCore.routerChg(this, true); } for (int i = 0; i < lstn.size(); i++) { rtrBgpNeigh nei = lstn.get(i); if (nei == null) { continue; } nei.setNeeded(); } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } nei.setNeeded(); } if (!lspf.enabled && (segrouLab != null)) { if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " segrou"); } tabGen> segrouUsd = new tabGen>(); for (int i = 0; i < newlyUni.size(); i++) { tabRouteEntry ntry = newlyUni.get(i); if (ntry == null) { continue; } if (ntry.best.segrouBeg < 1) { continue; } if ((ntry.best.segrouIdx <= 0) || (ntry.best.segrouIdx >= segrouMax)) { continue; } rtrBgpNeigh nei = findPeer(ntry.best.nextHop); if (nei == null) { continue; } List lab = tabLabel.int2labels(ntry.best.segrouBeg + ntry.best.segrouIdx); segrouLab[ntry.best.segrouIdx].setFwdMpls(tabLabelEntry.owner.bgpSrgb, fwdCore, nei.localIfc, nei.peerAddr, lab); tabIndex.add2table(segrouUsd, new tabIndex(ntry.best.segrouIdx, ntry.prefix)); } tabIndex.add2table(segrouUsd, new tabIndex(segrouIdx, new addrPrefix(new addrIP(), 0))); segrouLab[segrouIdx].setFwdCommon(tabLabelEntry.owner.bgpSrgb, fwdCore); for (int i = 0; i < segrouLab.length; i++) { if (segrouUsd.find(new tabIndex(i, null)) != null) { continue; } segrouLab[i].setFwdDrop(tabLabelEntry.owner.bgpSrgb); } routerComputedI = segrouUsd; } if (!lspf.enabled && (bierLab != null)) { if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " bier"); } tabLabelBier res = new tabLabelBier(bierLab[0].label, tabLabelBier.num2bsl(bierLen)); res.idx = bierIdx; for (int i = 0; i < newlyUni.size(); i++) { tabRouteEntry ntry = newlyUni.get(i); if (ntry == null) { continue; } if (ntry.best.bierBeg < 1) { continue; } if ((ntry.best.bierIdx <= 0) || (ntry.best.bierIdx >= bierMax)) { continue; } rtrBgpNeigh nei = findPeer(ntry.best.nextHop); if (nei == null) { continue; } tabLabelBierN per = new tabLabelBierN(fwdCore, nei.localIfc, nei.peerAddr, ntry.best.bierBeg, 0); tabLabelBierN old = res.peers.add(per); if (old != null) { per = old; } per.setBit(ntry.best.bierIdx - 1); } for (int i = 0; i < bierLab.length; i++) { bierLab[i].setBierMpls(tabLabelEntry.owner.bgpBier, fwdCore, res); } } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " export"); } otherTrigger = (addrFams & rtrBgpParam.mskLab) != 0; otherTrigger |= (addrFams & rtrBgpParam.mskCtp) != 0; otherTrigger |= (addrFams & rtrBgpParam.mskCar) != 0; otherTrigger |= linkStates.size() > 0; if (flowInst) { fwdCore.flowspec = tabQos.convertPolicy(rtrBgpFlow.doDecode(routerComputedF, afiUni == rtrBgpUtil.safiIp6uni)); } other.doPeersFull(); for (int i = 0; i < vrfs.size(); i++) { otherTrigger |= vrfs.get(i).doer.doPeersFull(newlyVpnU, newlyVpnM, newlyVpnF); } for (int i = 0; i < ovrfs.size(); i++) { otherTrigger |= ovrfs.get(i).doer.doPeersFull(newlyVpoU, newlyVpoM, newlyVpoF); } for (int i = 0; i < clrs.size(); i++) { otherTrigger |= clrs.get(i).doer.doPeersFull(newlyUni, newlyMlt, newlyFlw); } for (int i = 0; i < oclrs.size(); i++) { otherTrigger |= oclrs.get(i).doer.doPeersFull(newlyOuni, newlyOmlt, newlyOflw); } for (int i = 0; i < vpls.size(); i++) { vpls.get(i).doPeers(); } for (int i = 0; i < evpn.size(); i++) { evpn.get(i).doPeers(); } fullLast = bits.getTime(); fullTime = (int) (fullLast - tim); fullCount++; } private tabRouteEntry computeIncrBest(int afi, rtrBgpNeigh nei, tabRouteEntry best, tabRouteEntry curr) { if (nei == null) { return best; } if (!nei.reachable) { return best; } tabRoute acc = nei.getAccepted(afi); if (acc == null) { if (debugger.rtrBgpFull) { logger.debug("table not found"); } needFull.add(1); return best; } tabRouteEntry ntry = acc.find(curr); if (ntry == null) { return best; } if (best == null) { return ntry.copyBytes(tabRoute.addType.lnkEcmp); } if (best.best.isOtherBetter(ntry.best, false)) { return ntry.copyBytes(tabRoute.addType.lnkEcmp); } if (ntry.best.isOtherBetter(best.best, false)) { return best; } ntry = ntry.copyBytes(tabRoute.addType.lnkEcmp); best.addAlt(ntry.alts); return best; } private void computeIncrVersion(tabRouteEntry curr) { int ver = compRound.get() + 1; for (int i = 0; i < curr.alts.size(); i++) { curr.alts.get(i).version = ver; } } private void computeIncrEntry(int afi, tabRouteEntry curr, tabRoute cmp, tabRoute org) { if (debugger.rtrBgpIncr) { logger.debug("bestpath for " + tabRouteUtil.rd2string(curr.rouDst) + " " + curr.prefix + " in " + rtrBgpUtil.safi2string(afi)); } tabRouteEntry best = org.find(curr); if (best != null) { best = best.copyBytes(tabRoute.addType.altEcmp); best.best.rouSrc = rtrBgpUtil.peerOriginate; } for (int i = 0; i < lstnNei.size(); i++) { best = computeIncrBest(afi, lstnNei.get(i), best, curr); } for (int i = 0; i < neighs.size(); i++) { best = computeIncrBest(afi, neighs.get(i), best, curr); } if (best == null) { cmp.del(curr); computeIncrVersion(curr); for (int i = 0; i < groups.size(); i++) { rtrBgpGroup grp = groups.get(i); tabRoute wil = grp.getWilling(afi); tabRoute chg = grp.getChanged(afi); if ((wil == null) || (chg == null)) { if (debugger.rtrBgpFull) { logger.debug("table not found"); } needFull.add(1); continue; } if (wil.del(curr)) { continue; } chg.add(tabRoute.addType.always, curr, false, false); } return; } if (routerEcmp) { best.hashBest(); } else { best.selectBest(); } computeIncrVersion(best); if (conquer) { tabRouteEntry res = computeConquerEntry(cmp, best); if (res != null) { best = res; } } if ((best.best.rouSrc == rtrBgpUtil.peerOriginate) && ((afi == afiUni) || (afi == afiMlt))) { cmp.del(best); } else { cmp.add(tabRoute.addType.always, best, false, false); } for (int i = 0; i < groups.size(); i++) { rtrBgpGroup grp = groups.get(i); tabRoute wil = grp.getWilling(afi); tabRoute chg = grp.getChanged(afi); if ((wil == null) || (chg == null)) { if (debugger.rtrBgpFull) { logger.debug("table not found"); } needFull.add(1); continue; } tabRouteEntry ntry = null; tabRouteEntry old = wil.find(best); if (best.best.rouSrc == rtrBgpUtil.peerOriginate) { ntry = grp.originatePrefix(afi, best); } else { ntry = grp.readvertPrefix(afi, best); } if ((afi == afiUni) || (afi == afiMlt)) { ntry = tabRoute.doUpdateEntry(afi, grp.remoteAs, ntry, grp.roumapOut, grp.roupolOut, grp.prflstOut); } else if ((afi == afiOuni) || (afi == afiOmlt)) { ntry = tabRoute.doUpdateEntry(afi, grp.remoteAs, ntry, grp.oroumapOut, grp.oroupolOut, grp.oprflstOut); } else if ((afi == afiOflw) || (afi == afiOsrt) || (afi == afiMvpo) || (afi == afiVpoU) || (afi == afiVpoM) || (afi == afiVpoF)) { ntry = tabRoute.doUpdateEntry(afi, grp.remoteAs, ntry, grp.wroumapOut, grp.wroupolOut, null); } else if ((afi == afiEvpn) || (afi == afiVpls)) { ntry = tabRoute.doUpdateEntry(afi, grp.remoteAs, ntry, grp.eroumapOut, grp.eroupolOut, null); } else { ntry = tabRoute.doUpdateEntry(afi, grp.remoteAs, ntry, grp.vroumapOut, grp.vroupolOut, null); } if ((ntry == null) && (old == null)) { continue; } if (ntry == null) { wil.del(best); chg.add(tabRoute.addType.always, best, false, false); continue; } if (ntry.differs(tabRoute.addType.alters, old) == 0) { continue; } wil.add(tabRoute.addType.always, ntry, false, false); chg.add(tabRoute.addType.always, ntry, false, false); } } private int computeIncrUpdate(int afi, tabRoute don, tabRoute chg, tabRoute cmp, tabRoute org) { int res = 0; if (don == null) { don = new tabRoute("chg"); } for (int i = chg.size() - 1; i >= 0; i--) { tabRouteEntry ntry = chg.get(i); chg.del(ntry); don.add(tabRoute.addType.always, ntry, false, false); computeIncrEntry(afi, ntry, cmp, org); res++; } return res; } private void computeIncrPurge(int ver, tabRoute chg) { for (int i = chg.size() - 1; i >= 0; i--) { tabRouteEntry ntry = chg.get(i); if (ntry.best.version >= ver) { continue; } chg.del(ntry); } } private boolean computeIncr() { long tim = bits.getTime(); if (changedCur > incrLimit) { if (debugger.rtrBgpFull) { logger.debug("limit exceeded"); } return true; } if (lspf.enabled && (changedSpf.size() > 0)) { if (debugger.rtrBgpFull) { logger.debug("spf"); } return true; } if (routerAutoSummary || (routerAggregating.size() > 0)) { if (debugger.rtrBgpFull) { logger.debug("aggregation"); } oldAggr = true; return true; } if (oldAggr) { if (debugger.rtrBgpFull) { logger.debug("old aggregation"); } oldAggr = false; return true; } if ((segrouLab != null) || (bierLab != null)) { return true; } for (int i = 0; i < groups.size(); i++) { rtrBgpGroup grp = groups.get(i); if (grp.sendDefRou || grp.sendOtrDefRou) { return true; } } boolean labPer = routerAutoMesh != null; for (int i = 0; i < lstnNei.size(); i++) { rtrBgpNeigh nei = lstnNei.get(i); if (nei == null) { continue; } if (nei.softReconfig) { return true; } nei.setAccepted(); if (nei.reachOld != nei.reachable) { return true; } labPer |= nei.getLabeledPeer(); } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } if (nei.softReconfig) { return true; } nei.setAccepted(); if (nei.reachOld != nei.reachable) { return true; } labPer |= nei.getLabeledPeer(); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " purge"); } for (int i = 0; i < groups.size(); i++) { groups.get(i).minversion = compRound.get(); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpNeigh nei = lstnNei.get(i); if (nei == null) { continue; } nei.setGrpVer(); } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } nei.setGrpVer(); } groupMin = compRound.get(); groupMax = 0; for (int i = 0; i < groups.size(); i++) { rtrBgpGroup grp = groups.get(i); if (grp.minversion < groupMin) { groupMin = grp.minversion; } if (grp.minversion > groupMax) { groupMax = grp.minversion; } computeIncrPurge(grp.minversion, grp.chgUni); computeIncrPurge(grp.minversion, grp.chgMlt); computeIncrPurge(grp.minversion, grp.chgOuni); computeIncrPurge(grp.minversion, grp.chgOmlt); computeIncrPurge(grp.minversion, grp.chgOflw); computeIncrPurge(grp.minversion, grp.chgOsrt); computeIncrPurge(grp.minversion, grp.chgFlw); computeIncrPurge(grp.minversion, grp.chgVpnU); computeIncrPurge(grp.minversion, grp.chgVpnM); computeIncrPurge(grp.minversion, grp.chgVpnF); computeIncrPurge(grp.minversion, grp.chgVpoU); computeIncrPurge(grp.minversion, grp.chgVpoM); computeIncrPurge(grp.minversion, grp.chgVpoF); computeIncrPurge(grp.minversion, grp.chgVpls); computeIncrPurge(grp.minversion, grp.chgMspw); computeIncrPurge(grp.minversion, grp.chgEvpn); computeIncrPurge(grp.minversion, grp.chgMdt); computeIncrPurge(grp.minversion, grp.chgNsh); computeIncrPurge(grp.minversion, grp.chgRpd); computeIncrPurge(grp.minversion, grp.chgSpf); computeIncrPurge(grp.minversion, grp.chgRtf); computeIncrPurge(grp.minversion, grp.chgSrte); computeIncrPurge(grp.minversion, grp.chgLnks); computeIncrPurge(grp.minversion, grp.chgMvpn); computeIncrPurge(grp.minversion, grp.chgMvpo); computeIncrPurge(grp.minversion, grp.chgMtre); computeIncrPurge(grp.minversion, grp.chgMtro); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " changes"); } routerChangedU = new tabRoute("chg"); routerChangedM = new tabRoute("chg"); routerChangedF = new tabRoute("chg"); other.routerChangedU = new tabRoute("chg"); other.routerChangedM = new tabRoute("chg"); other.routerChangedF = new tabRoute("chg"); tabRoute chgVpnU = new tabRoute("chg"); tabRoute chgVpnM = new tabRoute("chg"); tabRoute chgVpnF = new tabRoute("chg"); tabRoute chgVpoU = new tabRoute("chg"); tabRoute chgVpoM = new tabRoute("chg"); tabRoute chgVpoF = new tabRoute("chg"); tabRoute chgEvpn = new tabRoute("chg"); int cntGlb = computeIncrUpdate(afiUni, routerChangedU, changedUni, routerComputedU, routerRedistedU); cntGlb += computeIncrUpdate(afiMlt, routerChangedM, changedMlt, routerComputedM, routerRedistedM); computeIncrUpdate(afiOuni, other.routerChangedU, changedOuni, computedOuni, origntedOuni); computeIncrUpdate(afiOmlt, other.routerChangedM, changedOmlt, computedOmlt, origntedOmlt); computeIncrUpdate(afiOflw, other.routerChangedF, changedOflw, computedOflw, origntedOflw); computeIncrUpdate(afiOsrt, null, changedOsrt, computedOsrt, origntedOsrt); int cntFlw = computeIncrUpdate(afiFlw, routerChangedF, changedFlw, routerComputedF, origntedFlw); computeIncrUpdate(afiVpnU, chgVpnU, changedVpnU, computedVpnU, origntedVpnU); computeIncrUpdate(afiVpnM, chgVpnM, changedVpnM, computedVpnM, origntedVpnM); computeIncrUpdate(afiVpnF, chgVpnF, changedVpnF, computedVpnF, origntedVpnF); computeIncrUpdate(afiVpoU, chgVpoU, changedVpoU, computedVpoU, origntedVpoU); computeIncrUpdate(afiVpoM, chgVpoM, changedVpoM, computedVpoM, origntedVpoM); computeIncrUpdate(afiVpoF, chgVpoF, changedVpoF, computedVpoF, origntedVpoF); int cntVpls = computeIncrUpdate(afiVpls, null, changedVpls, computedVpls, origntedVpls); computeIncrUpdate(afiMspw, null, changedMspw, computedMspw, origntedMspw); int cntEvpn = computeIncrUpdate(afiEvpn, chgEvpn, changedEvpn, computedEvpn, origntedEvpn); computeIncrUpdate(afiMdt, null, changedMdt, computedMdt, origntedMdt); computeIncrUpdate(afiNsh, null, changedNsh, computedNsh, origntedNsh); computeIncrUpdate(afiRpd, null, changedRpd, computedRpd, origntedRpd); computeIncrUpdate(afiSpf, null, changedSpf, computedSpf, origntedSpf); computeIncrUpdate(afiRtf, null, changedRtf, computedRtf, origntedRtf); computeIncrUpdate(afiSrte, null, changedSrte, computedSrte, origntedSrte); computeIncrUpdate(afiLnks, null, changedLnks, computedLnks, origntedLnks); computeIncrUpdate(afiMvpn, null, changedMvpn, computedMvpn, origntedMvpn); computeIncrUpdate(afiMvpo, null, changedMvpo, computedMvpo, origntedMvpo); computeIncrUpdate(afiMtre, null, changedMtre, computedMtre, origntedMtre); computeIncrUpdate(afiMtro, null, changedMtro, computedMtro, origntedMtro); lspf.doPeersIncr(); if (labPer || ((cntGlb + cntFlw) > 0)) { fwdCore.routerChg(this, labPer); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " export"); } if (flowInst && (cntFlw > 0)) { fwdCore.flowspec = tabQos.convertPolicy(rtrBgpFlow.doDecode(routerComputedF, afiUni == rtrBgpUtil.safiIp6uni)); } other.doPeersIncr(); for (int i = 0; i < vrfs.size(); i++) { vrfs.get(i).doer.doPeersIncr(computedVpnU, computedVpnM, computedVpnF, chgVpnU, chgVpnM, chgVpnF, chgEvpn); } for (int i = 0; i < ovrfs.size(); i++) { ovrfs.get(i).doer.doPeersIncr(computedVpoU, computedVpoM, computedVpoF, chgVpoU, chgVpoM, chgVpoF, chgEvpn); } for (int i = 0; i < clrs.size(); i++) { clrs.get(i).doer.doPeersIncr(routerComputedU, routerComputedM, routerComputedF, routerChangedU, routerChangedM, routerChangedF, chgEvpn); } for (int i = 0; i < oclrs.size(); i++) { oclrs.get(i).doer.doPeersIncr(computedOuni, computedOmlt, computedOflw, other.routerChangedU, other.routerChangedM, other.routerChangedF, chgEvpn); } if (cntVpls > 0) { for (int i = 0; i < vpls.size(); i++) { vpls.get(i).doPeers(); } } if (cntEvpn > 0) { for (int i = 0; i < evpn.size(); i++) { evpn.get(i).doPeers(); } } incrLast = bits.getTime(); incrTime = (int) (incrLast - tim); incrCount++; return false; } private tabRouteEntry computeConquerEntry(tabRoute cmp, tabRouteEntry best) { if (best.best.nextHop == null) { return null; } tabRouteEntry old = cmp.find(best); if (old == null) { return null; } if (old.best.nextHop == null) { return null; } best = best.copyBytes(tabRoute.addType.notyet); if (best.best.locPref < old.best.locPref) { best.best.locPref = old.best.locPref; } if (old.best.nextHop.compareTo(best.best.nextHop) != 0) { best.best.locPref++; } return best; } private void computeConquerTable(tabRoute old, tabRoute cmp) { for (int i = 0; i < cmp.size(); i++) { tabRouteEntry ntry = cmp.get(i); ntry = computeConquerEntry(old, ntry); if (ntry == null) { continue; } cmp.add(tabRoute.addType.always, ntry, false, false); } } /** * update flap statistics * * @param afi afi * @param rd rd * @param prf prefix * @param pth path */ protected void prefixFlapped(int afi, long rd, addrPrefix prf, List pth) { if (pth == null) { pth = new ArrayList(); } rtrBgpFlapStat ntry = new rtrBgpFlapStat(afi, rd, prf); rtrBgpFlapStat old = flaps.add(ntry); if (old != null) { ntry = old; } ntry.count++; ntry.last = bits.getTime(); rtrBgpFlapLst pe = new rtrBgpFlapLst(pth); rtrBgpFlapLst op = ntry.paths.add(pe); if (op != null) { pe = op; } pe.count++; pe.last = ntry.last; } /** * create computed table */ public synchronized void routerCreateComputed() { if (debugger.rtrBgpEvnt) { logger.debug("create table"); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " start"); } changedCur = changedUni.size() + changedMlt.size() + changedOuni.size() + changedOmlt.size() + changedOflw.size() + changedOsrt.size() + changedFlw.size() + changedVpnU.size() + changedVpnM.size() + changedVpnF.size() + changedVpoU.size() + changedVpoM.size() + changedVpoF.size() + changedVpls.size() + changedMspw.size() + changedEvpn.size() + changedMdt.size() + changedNsh.size() + changedRpd.size() + changedSpf.size() + changedSrte.size() + changedLnks.size() + changedRtf.size() + changedMvpn.size() + changedMvpo.size() + changedMtre.size() + changedMtro.size(); changedTot += changedCur; if (changedCur > changedMax) { changedMax = changedCur; changedPek = bits.getTime(); } if (needFull.set(0) > 0) { computeFull(); } else if (computeIncr()) { computeFull(); } compRound.add(1); for (int i = 0; i < lstnNei.size(); i++) { rtrBgpNeigh nei = lstnNei.get(i); if (nei == null) { continue; } nei.transmit.wakeup(); } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } nei.transmit.wakeup(); } if (debugger.rtrBgpComp) { logger.debug("round " + compRound + " done"); } } /** * stop work */ public void routerCloseNow() { if (debugger.rtrBgpEvnt) { logger.debug("shutdown"); } need2run = false; compute.wakeup(); for (int i = 0; i < mons.size(); i++) { rtrBgpMon ntry = mons.get(i); ntry.stopNow(); } for (int i = 0; i < dmps.size(); i++) { rtrBgpMrt ntry = dmps.get(i); ntry.fileHandle.close(); } for (int i = 0; i < lstnTmp.size(); i++) { rtrBgpLstn ntry = lstnTmp.get(i); tcpCore.listenStop(ntry.iface, port, null, 0); } for (int i = lstnNei.size() - 1; i >= 0; i--) { rtrBgpNeigh nei = lstnNei.get(i); if (nei == null) { continue; } nei.stopNow(); nei.conn.closeNow(); } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } nei.stopNow(); nei.conn.closeNow(); } other.unregister2ip(); for (int i = 0; i < vrfs.size(); i++) { vrfs.get(i).doer.unregister2ip(); } for (int i = 0; i < ovrfs.size(); i++) { ovrfs.get(i).doer.unregister2ip(); } for (int i = 0; i < clrs.size(); i++) { clrs.get(i).doer.unregister2ip(); } for (int i = 0; i < oclrs.size(); i++) { oclrs.get(i).doer.unregister2ip(); } for (int i = 0; i < vpls.size(); i++) { vpls.get(i).doStop(); } for (int i = 0; i < evpn.size(); i++) { evpn.get(i).doStop(); } tabLabel.release(evpnUni, tabLabelEntry.owner.evpnPbb); tabLabel.release(evpnMul, tabLabelEntry.owner.evpnPbb); tabLabel.release(segrouLab, tabLabelEntry.owner.bgpSrgb); tabLabel.release(bierLab, tabLabelEntry.owner.bgpBier); fwdCore.routerDel(this); } /** * get help * * @param l list */ public void routerGetHelp(userHelping l) { List tmps = new ArrayList(); for (int i = 0; i < temps.size(); i++) { rtrBgpTemp ntry = temps.get(i); tmps.add(ntry.tempName); } List neis = new ArrayList(); for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh ntry = neighs.get(i); neis.add("" + ntry.peerAddr); } l.add(null, "1 2 address-family specify address families"); rtrBgpParam.getAfiList(l, "2 2,.", "to use", true); l.add(null, "1 2 local-as specify local as number"); l.add(null, "2 . autonomous system number"); l.add(null, "1 . default-originate advertise default route"); l.add(null, "1 . conquer conquer bestpath advertisements"); l.add(null, "1 . flapstat count flap statistics"); l.add(null, "1 . safe-ebgp safe ebgp policy"); l.add(null, "1 2 incremental limit on incremental bestpath calculation"); l.add(null, "2 . maximum prefixes"); l.add(null, "1 2 router-id specify router id"); l.add(null, "2 . router id"); l.add(null, "1 2 scantime scan time interval"); l.add(null, "2 . ms between scans"); l.add(null, "1 2 scandelay initial scan time delay"); l.add(null, "2 . ms before scan"); l.add(null, "1 2 graceful-restart graceful restart interval"); l.add(null, "2 . ms to recover"); l.add(null, "1 2 longlived-graceful long lived graceful restart interval"); l.add(null, "2 . ms to recover"); l.add(null, "1 2 template specify template parameters"); l.add(tmps, "2 3 name of template"); rtrBgpParam.getParamHelp(l); l.add(null, "1 2 nexthop specify next hop tracking parameter"); l.add(null, "2 3 recursion specify recursion depth"); l.add(null, "3 . maximum rounds"); l.add(null, "2 3 route-map filter next hops"); l.add(null, "3 . name of route map"); l.add(null, "2 3 route-policy filter next hops"); l.add(null, "3 . name of route policy"); l.add(null, "2 3 prefix-list filter next hops"); l.add(null, "3 . name of prefix list"); l.add(null, "1 2 segrout segment routing parameters"); l.add(null, "2 3 maximum index"); l.add(null, "3 4,. this node index"); l.add(null, "4 5 base specify base"); l.add(null, "5 4,. label base"); l.add(null, "1 2 bier bier parameters"); l.add(null, "2 3 bitstring length"); l.add(null, "3 4 maximum index"); l.add(null, "4 5,. node index"); l.add(null, "5 . subdomain"); l.add(null, "1 2 afi-links specify link state parameter"); cfgRtr.getRouterList(l, 0, " to advertise"); l.add(null, "3 4 process id"); l.add(null, "4 . area/level number"); l.add(null, "1 . flowspec-install specify flowspec installation"); l.add(null, "1 2 flowspec-advert specify flowspec parameter"); l.add(null, "2 . name of policy map"); l.add(null, "1 2 neighbor specify neighbor parameters"); l.add(neis, "2 3 address of peer"); l.add(null, "3 4 template get configuration from template"); l.add(tmps, "4 5,. name of source template"); l.add(null, "5 . shutdown connection disabled for this peer"); rtrBgpParam.getParamHelp(l); l.add(null, "1 2 distance specify default distance"); l.add(null, "2 3 external peer distance"); l.add(null, "3 4 internal peer distance"); l.add(null, "4 . locally generated distance"); l.add(null, "1 2 listen passively listen for clients"); l.add(null, "2 3 access list name"); l.add(tmps, "3 . template name"); l.add(null, "1 2 dump setup bgp dump file"); l.add(null, "2 3 name of mrt"); l.add(null, "3 4,. name of file"); l.add(null, "4 5 ms between backup"); l.add(null, "5 6,. name of backup"); l.add(null, "6 . maximum size of backup"); l.add(null, "1 2 monitor setup bgp monitor protocol server"); l.add(null, "2 3 name of bmp"); l.add(null, "3 4 proxy profile"); l.add(null, "4 5 hostname"); l.add(null, "5 . port number"); l.add(null, "1 2 rpki setup resource public key infrastructure"); cfgRtr.getRouterList(l, 0, ""); l.add(null, "3 . process number"); l.add(null, "1 2 afi-spf select spf to advertise"); l.add(null, "2 . enable enable processing"); l.add(null, "2 . hostname advertise hostname"); l.add(null, "2 . stub stub router"); l.add(null, "2 3 distance set import distance"); l.add(null, "3 . distance"); l.add(null, "2 . default-originate advertise default route"); l.add(null, "2 3 route-map process prefixes"); l.add(null, "3 . name of route map"); l.add(null, "2 3 route-policy process prefixes"); l.add(null, "3 . name of route policy"); l.add(null, "2 3 prefix-list filter prefixes"); l.add(null, "3 . name of prefix list"); l.add(null, "2 . spf-bidir spf bidir check"); l.add(null, "2 3,. spf-topolog spf topology logging"); l.add(null, "3 3,. noappear exclude node (dis)appearance"); l.add(null, "3 3,. noconnect exclude link (dis)connection"); l.add(null, "3 3,. noforward exclude forward (un)willingness"); l.add(null, "3 3,. noreachable exclude node (un)reachable"); l.add(null, "3 3,. nometric exclude link metric change"); l.add(null, "3 3,. noprefix exclude prefix change"); l.add(null, "2 . spf-hops spf hops disallow"); l.add(null, "2 . spf-ecmp spf ecmp allow"); l.add(null, "2 3 spf-log spf log size"); l.add(null, "3 . number of entries"); l.add(null, "1 2 afi-other select other to advertise"); l.add(null, "2 . enable enable processing"); l.add(null, "2 . default-originate generate default route"); l.add(null, "2 . vpn-mode enable vpn mode"); l.add(null, "2 3 srv6 srv6 advertisement"); l.add(null, "3 . select source to advertise"); l.add(null, "2 3 distance set import distance"); l.add(null, "3 . distance"); l.add(null, "2 . flowspec-install specify flowspec installation"); l.add(null, "2 3 flowspec-advert specify flowspec parameter"); l.add(null, "3 . name of policy map"); cfgRtr.getRedistHelp(l, 1); l.add(null, "1 2 afi-vrf select vrf to advertise"); l.add(null, "2 3 name of routing table"); l.add(null, "3 . enable enable processing"); l.add(null, "3 4 mvpn mvpn advertisement"); l.add(null, "4 . select source to advertise"); l.add(null, "3 4 srv6 srv6 advertisement"); l.add(null, "4 . select source to advertise"); l.add(null, "3 4 set-vrf configure forwarder override"); l.add(null, "4 5 select vrf to use"); l.add(null, "5 . ipv4 select ipv4 to use"); l.add(null, "5 . ipv6 select ipv6 to use"); l.add(null, "3 4 distance set import distance"); l.add(null, "4 . distance"); l.add(null, "3 . default-originate generate default route"); l.add(null, "3 4,. import specify import modes"); l.add(null, "4 4,. evpn select evpn"); l.add(null, "4 4,. l3vpn select l3vpn"); l.add(null, "3 4,. export specify export modes"); l.add(null, "4 4,. evpn select evpn"); l.add(null, "4 4,. l3vpn select l3vpn"); l.add(null, "3 4 update-source select source to advertise"); l.add(null, "4 . name of interface"); l.add(null, "3 . flowspec-install specify flowspec installation"); l.add(null, "3 4 flowspec-advert specify flowspec parameter"); l.add(null, "4 . name of policy map"); cfgRtr.getRedistHelp(l, 2); l.add(null, "1 2 afi-ovrf select other vrf to advertise"); l.add(null, "2 3 name of routing table"); l.add(null, "3 . enable enable processing"); l.add(null, "3 4 mvpn mvpn advertisement"); l.add(null, "4 . select source to advertise"); l.add(null, "3 4 srv6 srv6 advertisement"); l.add(null, "4 . select source to advertise"); l.add(null, "3 4 set-vrf configure forwarder override"); l.add(null, "4 5 select vrf to use"); l.add(null, "5 . ipv4 select ipv4 to use"); l.add(null, "5 . ipv6 select ipv6 to use"); l.add(null, "3 4 distance set import distance"); l.add(null, "4 . distance"); l.add(null, "3 . default-originate generate default route"); l.add(null, "3 4,. import specify import modes"); l.add(null, "4 4,. evpn select evpn"); l.add(null, "4 4,. l3vpn select l3vpn"); l.add(null, "3 4,. export specify export modes"); l.add(null, "4 4,. evpn select evpn"); l.add(null, "4 4,. l3vpn select l3vpn"); l.add(null, "3 4 update-source select source to advertise"); l.add(null, "4 . name of interface"); l.add(null, "3 . flowspec-install specify flowspec installation"); l.add(null, "3 4 flowspec-advert specify flowspec parameter"); l.add(null, "4 . name of policy map"); cfgRtr.getRedistHelp(l, 2); l.add(null, "1 2 afi-clr select vrf to advertise"); l.add(null, "2 3 name of routing table"); l.add(null, "3 . enable enable processing"); l.add(null, "3 4 distance set import distance"); l.add(null, "4 . distance"); l.add(null, "3 . default-originate generate default route"); l.add(null, "3 . flowspec-install specify flowspec installation"); l.add(null, "3 4 flowspec-advert specify flowspec parameter"); l.add(null, "4 . name of policy map"); cfgRtr.getRedistHelp(l, 2); l.add(null, "1 2 afi-oclr select other vrf to advertise"); l.add(null, "2 3 name of routing table"); l.add(null, "3 . enable enable processing"); l.add(null, "3 4 distance set import distance"); l.add(null, "4 . distance"); l.add(null, "3 . default-originate generate default route"); l.add(null, "3 . flowspec-install specify flowspec installation"); l.add(null, "3 4 flowspec-advert specify flowspec parameter"); l.add(null, "4 . name of policy map"); cfgRtr.getRedistHelp(l, 2); l.add(null, "1 2 afi-vpls select vpls to advertise"); l.add(null, "2 3 vpls id in ASnum:IDnum format"); l.add(null, "3 4 bridge-group enable processing"); l.add(null, "4 . bridge group number"); l.add(null, "3 4 update-source select source to advertise"); l.add(null, "4 . name of interface"); l.add(null, "3 . control-word specify control word"); l.add(null, "3 4 ve-id specify ve id"); l.add(null, "4 5 ve id number"); l.add(null, "5 . ve maximum number"); l.add(null, "1 2 afi-evpn select evpn to advertise"); l.add(null, "2 3 evpn id"); l.add(null, "3 4 bridge-group enable processing"); l.add(null, "4 . bridge group number"); l.add(null, "3 4 srv6 srv6 advertisement"); l.add(null, "4 . select source to advertise"); l.add(null, "3 4 bmac set backbone mac"); l.add(null, "4 . mac address"); l.add(null, "3 4 update-source select source to advertise"); l.add(null, "4 . name of interface"); l.add(null, "3 4 encapsulation specify encapsulation to use"); l.add(null, "4 . pbb pbb"); l.add(null, "4 . vxlan vxlan"); l.add(null, "4 . vpws vpws"); l.add(null, "4 . cmac cmac"); } /** * get config * * @param l list * @param beg beginning * @param filter filter */ public void routerGetConfig(List l, String beg, int filter) { l.add(beg + "local-as " + bits.num2str(localAs)); l.add(beg + "router-id " + routerID); cmds.cfgLine(l, !safeEbgp, beg, "safe-ebgp", ""); l.add(beg + "address-family" + rtrBgpParam.mask2string(addrFams)); l.add(beg + "distance " + distantExt + " " + distantInt + " " + distantLoc); l.add(beg + "scantime " + scanTime); l.add(beg + "scandelay " + scanDelay); l.add(beg + "incremental " + incrLimit); l.add(beg + "graceful-restart " + restartTime); l.add(beg + "longlived-graceful " + llRestartTime); cmds.cfgLine(l, !defRou, beg, "default-originate", ""); cmds.cfgLine(l, !conquer, beg, "conquer", ""); cmds.cfgLine(l, flaps == null, beg, "flapstat", ""); cmds.cfgLine(l, nhtRoumap == null, beg, "nexthop route-map", "" + nhtRoumap); cmds.cfgLine(l, nhtRouplc == null, beg, "nexthop route-policy", "" + nhtRouplc); cmds.cfgLine(l, nhtPfxlst == null, beg, "nexthop prefix-list", "" + nhtPfxlst); l.add(beg + "nexthop recursion " + recursion); String a = ""; if (segrouBase != 0) { a += " base " + segrouBase; } cmds.cfgLine(l, segrouMax < 1, beg, "segrout", "" + segrouMax + " " + segrouIdx + a); cmds.cfgLine(l, bierMax < 1, beg, "bier", bierLen + " " + bierMax + " " + bierIdx + " " + bierSub); cmds.cfgLine(l, !flowInst, beg, "flowspec-install", ""); cmds.cfgLine(l, flowSpec == null, beg, "flowspec-advert", "" + flowSpec); if (rpkiT == null) { l.add(beg + "no rpki"); } else { l.add(beg + "rpki " + cfgRtr.num2name(rpkiT) + " " + rpkiN); } for (int i = 0; i < mons.size(); i++) { mons.get(i).getConfig(l, beg); } for (int i = 0; i < dmps.size(); i++) { dmps.get(i).getConfig(l, beg); } l.add(beg + cmds.comment); for (int i = 0; i < temps.size(); i++) { temps.get(i).getConfig(l, beg, filter); } for (int i = 0; i < lstnTmp.size(); i++) { lstnTmp.get(i).getConfig(l, beg); } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } nei.getConfig(l, beg, filter); } other.getConfig(l, beg + "afi-other "); lspf.getConfig(l, beg, "afi-spf "); for (int i = 0; i < vrfs.size(); i++) { vrfs.get(i).doer.getConfig(l, beg, "afi-vrf "); } for (int i = 0; i < ovrfs.size(); i++) { ovrfs.get(i).doer.getConfig(l, beg, "afi-ovrf "); } for (int i = 0; i < clrs.size(); i++) { clrs.get(i).doer.getConfig(l, beg, "afi-clr "); } for (int i = 0; i < oclrs.size(); i++) { oclrs.get(i).doer.getConfig(l, beg, "afi-oclr "); } for (int i = 0; i < vpls.size(); i++) { vpls.get(i).getConfig(l, beg); } for (int i = 0; i < evpn.size(); i++) { evpn.get(i).getConfig(l, beg); } for (int i = 0; i < linkStates.size(); i++) { rtrBgpLnkst ls = linkStates.get(i); l.add(beg + "afi-links " + ls.rtr.routerGetName() + " " + ls.par); } l.add(beg + cmds.comment); } /** * configure router * * @param cmd command * @return false if success, true if error */ public boolean routerConfigure(cmds cmd) { String s = cmd.word(); boolean negated = false; if (s.equals(cmds.negated)) { s = cmd.word(); negated = true; } if (s.equals("local-as")) { localAs = bits.str2num(cmd.word()); return false; } if (s.equals("router-id")) { s = cmd.word(); routerID.fromString(s); cfgIfc ifc = cfgAll.ifcFind(s, 0); if (ifc != null) { if (ifc.addr4 != null) { routerID.setAddr(ifc.addr4); } } if (negated) { routerID = new addrIPv4(); } return false; } if (s.equals("safe-ebgp")) { safeEbgp = !negated; return false; } if (s.equals("address-family")) { addrFams = rtrBgpParam.string2mask(cmd); return false; } if (s.equals("distance")) { distantExt = bits.str2num(cmd.word()); distantInt = bits.str2num(cmd.word()); distantLoc = bits.str2num(cmd.word()); return false; } if (s.equals("scantime")) { scanTime = bits.str2num(cmd.word()); return false; } if (s.equals("scandelay")) { scanDelay = bits.str2num(cmd.word()); return false; } if (s.equals("incremental")) { incrLimit = bits.str2num(cmd.word()); needFull.add(1); compute.wakeup(); return false; } if (s.equals("conquer")) { conquer = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("flapstat")) { if (negated) { flaps = null; } else { flaps = new tabGen(); } return false; } if (s.equals("segrout")) { tabLabel.release(segrouLab, tabLabelEntry.owner.bgpSrgb); segrouLab = null; if (negated) { segrouIdx = 0; segrouMax = 0; segrouBase = 0; needFull.add(1); compute.wakeup(); return false; } segrouMax = bits.str2num(cmd.word()); segrouIdx = bits.str2num(cmd.word()); segrouBase = 0; for (;;) { s = cmd.word(); if (s.length() < 1) { break; } if (s.equals("base")) { segrouBase = bits.str2num(cmd.word()); continue; } } segrouLab = tabLabel.allocate(tabLabelEntry.owner.bgpSrgb, segrouBase, segrouMax); needFull.add(1); compute.wakeup(); return false; } if (s.equals("bier")) { tabLabel.release(bierLab, tabLabelEntry.owner.bgpBier); bierLab = null; if (negated) { bierIdx = 0; bierSub = 0; bierMax = 0; bierLen = 0; needFull.add(1); compute.wakeup(); return false; } bierLen = tabLabelBier.normalizeBsl(bits.str2num(cmd.word())); bierMax = bits.str2num(cmd.word()); bierIdx = bits.str2num(cmd.word()); bierSub = bits.str2num(cmd.word()); bierLab = tabLabel.allocate(tabLabelEntry.owner.bgpBier, (bierMax + bierLen - 1) / bierLen); needFull.add(1); compute.wakeup(); return false; } if (s.equals("default-originate")) { defRou = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("graceful-restart")) { restartTime = bits.str2num(cmd.word()); return false; } if (s.equals("longlived-graceful")) { llRestartTime = bits.str2num(cmd.word()); return false; } if (s.equals("nexthop")) { s = cmd.word(); if (s.equals("recursion")) { recursion = bits.str2num(cmd.word()); needFull.add(1); compute.wakeup(); return false; } if (s.equals("route-map")) { if (negated) { nhtRoumap = null; needFull.add(1); compute.wakeup(); return false; } cfgRoump ntry = cfgAll.rtmpFind(cmd.word(), false); if (ntry == null) { cmd.error("no such route map"); return false; } nhtRoumap = ntry.roumap; needFull.add(1); compute.wakeup(); return false; } if (s.equals("route-policy")) { if (negated) { nhtRouplc = null; needFull.add(1); compute.wakeup(); return false; } cfgRouplc ntry = cfgAll.rtplFind(cmd.word(), false); if (ntry == null) { cmd.error("no such route map"); return false; } nhtRouplc = ntry.rouplc; needFull.add(1); compute.wakeup(); return false; } if (s.equals("prefix-list")) { if (negated) { nhtPfxlst = null; needFull.add(1); compute.wakeup(); return false; } cfgPrfxlst ntry = cfgAll.prfxFind(cmd.word(), false); if (ntry == null) { cmd.error("no such prefix list"); return false; } nhtPfxlst = ntry.prflst; needFull.add(1); compute.wakeup(); return false; } return true; } if (s.equals("afi-links")) { rtrBgpLnkst ls = new rtrBgpLnkst(); tabRouteAttr.routeType rt = cfgRtr.name2num(cmd.word()); if (rt == null) { cmd.error("bad protocol"); return false; } cfgRtr rtr = cfgAll.rtrFind(rt, bits.str2num(cmd.word()), false); if (rtr == null) { cmd.error("no such router"); return false; } ls.rtr = rtr.getRouter(); if (ls.rtr == null) { cmd.error("not initialized"); return false; } ls.par = bits.str2num(cmd.word()); if (negated) { linkStates.del(ls); } else { linkStates.put(ls); } needFull.add(1); compute.wakeup(); return false; } if (s.equals("flowspec-install")) { flowInst = !negated; if (negated) { fwdCore.flowspec = null; } needFull.add(1); compute.wakeup(); return false; } if (s.equals("flowspec-advert")) { if (negated) { flowSpec = null; needFull.add(1); compute.wakeup(); return false; } cfgPlymp ntry = cfgAll.plmpFind(cmd.word(), false); if (ntry == null) { cmd.error("no such policy map"); return false; } flowSpec = ntry.plcmap; needFull.add(1); compute.wakeup(); return false; } if (s.equals("afi-spf")) { s = cmd.word(); if (s.equals("enable")) { lspf.enabled = !negated; routerIgp = lspf.enabled; needFull.add(1); compute.wakeup(); return false; } if (s.equals("distance")) { lspf.distance = bits.str2num(cmd.word()); needFull.add(1); compute.wakeup(); return false; } if (s.equals("default-originate")) { lspf.defRou = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("hostname")) { lspf.hostname = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("stub")) { lspf.stub = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("prefix-list")) { if (negated) { lspf.prflstIn = null; needFull.add(1); compute.wakeup(); return false; } cfgPrfxlst ntry = cfgAll.prfxFind(cmd.word(), false); if (ntry == null) { cmd.error("no such prefix list"); return false; } lspf.prflstIn = ntry.prflst; needFull.add(1); compute.wakeup(); return false; } if (s.equals("route-map")) { if (negated) { lspf.roumapIn = null; needFull.add(1); compute.wakeup(); return false; } cfgRoump ntry = cfgAll.rtmpFind(cmd.word(), false); if (ntry == null) { cmd.error("no such route map"); return false; } lspf.roumapIn = ntry.roumap; needFull.add(1); compute.wakeup(); return false; } if (s.equals("route-policy")) { if (negated) { lspf.roupolIn = null; needFull.add(1); compute.wakeup(); return false; } cfgRouplc ntry = cfgAll.rtplFind(cmd.word(), false); if (ntry == null) { cmd.error("no such route policy"); return false; } lspf.roupolIn = ntry.rouplc; needFull.add(1); compute.wakeup(); return false; } if (s.equals("spf-log")) { lspf.lastSpf.logSize.set(bits.str2num(cmd.word())); if (negated) { lspf.lastSpf.logSize.set(0); } return false; } if (s.equals("spf-topolog")) { if (negated) { lspf.lastSpf.topoLog.set(0); return false; } lspf.lastSpf.setTopoLogMode(cmd); return false; } if (s.equals("spf-bidir")) { if (negated) { lspf.lastSpf.bidir.set(0); } else { lspf.lastSpf.bidir.set(1); } needFull.add(1); compute.wakeup(); return false; } if (s.equals("spf-hops")) { if (negated) { lspf.lastSpf.hops.set(0); } else { lspf.lastSpf.hops.set(1); } needFull.add(1); compute.wakeup(); return false; } if (s.equals("spf-ecmp")) { if (negated) { lspf.lastSpf.ecmp.set(0); } else { lspf.lastSpf.ecmp.set(1); } needFull.add(1); compute.wakeup(); return false; } return false; } if (s.equals("afi-other")) { s = cmd.word(); if (s.equals("enable")) { if (negated) { other.unregister2ip(); } else { other.register2ip(); } needFull.add(1); compute.wakeup(); return false; } if (s.equals("vpn-mode")) { other.routerVpn = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("default-originate")) { other.defRou = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("distance")) { other.distance = bits.str2num(cmd.word()); needFull.add(1); compute.wakeup(); return false; } if (s.equals("srv6")) { if (negated) { other.srv6 = null; } else { other.srv6 = cfgAll.ifcFind(cmd.word(), 0); } needFull.add(1); compute.wakeup(); return false; } if (s.equals("flowspec-install")) { other.flowInst = !negated; if (negated) { other.fwd.flowspec = null; } needFull.add(1); compute.wakeup(); return false; } if (s.equals("flowspec-advert")) { if (negated) { other.flowSpec = null; needFull.add(1); compute.wakeup(); return false; } cfgPlymp ntry = cfgAll.plmpFind(cmd.word(), false); if (ntry == null) { cmd.error("no such policy map"); return false; } other.flowSpec = ntry.plcmap; needFull.add(1); compute.wakeup(); return false; } if (cfgRtr.doCfgRedist(other, other.fwd, negated, s, cmd)) { cmd.badCmd(); } needFull.add(1); compute.wakeup(); return false; } if (s.equals("afi-vrf")) { cfgVrf cfv = cfgAll.vrfFind(cmd.word(), false); if (cfv == null) { cmd.error("no such vrf"); return false; } rtrBgpVrf cur = new rtrBgpVrf(this, cfv, false); s = cmd.word(); if (s.equals("enable")) { rtrBgpVrf old = vrfs.find(cur); if (old != null) { if (!negated) { return false; } old.doer.unregister2ip(); vrfs.del(old); needFull.add(1); compute.wakeup(); return false; } if (negated) { return false; } cur.doer.register2ip(); vrfs.put(cur); needFull.add(1); compute.wakeup(); return false; } cur = vrfs.find(cur); if (cur == null) { cmd.error("vrf not enabled"); return false; } cur.doer.doConfig(negated, cmd, s); return false; } if (s.equals("afi-ovrf")) { cfgVrf cfv = cfgAll.vrfFind(cmd.word(), false); if (cfv == null) { cmd.error("no such vrf"); return false; } rtrBgpVrf cur = new rtrBgpVrf(this, cfv, true); s = cmd.word(); if (s.equals("enable")) { rtrBgpVrf old = ovrfs.find(cur); if (old != null) { if (!negated) { return false; } old.doer.unregister2ip(); ovrfs.del(old); needFull.add(1); compute.wakeup(); return false; } if (negated) { return false; } cur.doer.register2ip(); ovrfs.put(cur); needFull.add(1); compute.wakeup(); return false; } cur = ovrfs.find(cur); if (cur == null) { cmd.error("vrf not enabled"); return false; } cur.doer.doConfig(negated, cmd, s); return false; } if (s.equals("afi-clr")) { cfgVrf cfv = cfgAll.vrfFind(cmd.word(), false); if (cfv == null) { cmd.error("no such vrf"); return false; } rtrBgpVrf cur = new rtrBgpVrf(this, cfv, false); s = cmd.word(); if (s.equals("enable")) { rtrBgpVrf old = clrs.find(cur); if (old != null) { if (!negated) { return false; } old.doer.unregister2ip(); clrs.del(old); needFull.add(1); compute.wakeup(); return false; } if (negated) { return false; } cur.doer.register2ip(); clrs.put(cur); needFull.add(1); compute.wakeup(); return false; } cur = clrs.find(cur); if (cur == null) { cmd.error("vrf not enabled"); return false; } cur.doer.doConfig(negated, cmd, s); return false; } if (s.equals("afi-oclr")) { cfgVrf cfv = cfgAll.vrfFind(cmd.word(), false); if (cfv == null) { cmd.error("no such vrf"); return false; } rtrBgpVrf cur = new rtrBgpVrf(this, cfv, true); s = cmd.word(); if (s.equals("enable")) { rtrBgpVrf old = oclrs.find(cur); if (old != null) { if (!negated) { return false; } old.doer.unregister2ip(); oclrs.del(old); needFull.add(1); compute.wakeup(); return false; } if (negated) { return false; } cur.doer.register2ip(); oclrs.put(cur); needFull.add(1); compute.wakeup(); return false; } cur = oclrs.find(cur); if (cur == null) { cmd.error("vrf not enabled"); return false; } cur.doer.doConfig(negated, cmd, s); return false; } if (s.equals("afi-vpls")) { rtrBgpVpls cur = new rtrBgpVpls(this); cur.id = tabRouteUtil.string2rd(cmd.word()); s = cmd.word(); if (s.equals("bridge-group")) { rtrBgpVpls old = vpls.del(cur); if (old != null) { old.doStop(); } if (negated) { needFull.add(1); compute.wakeup(); return false; } cur.bridge = cfgAll.brdgFind(cmd.word(), false); if (cur.bridge == null) { cmd.error("no such bridge"); return false; } vpls.add(cur); return false; } cur = vpls.find(cur); if (cur == null) { cmd.error("vpls not enabled"); return false; } if (s.equals("control-word")) { cur.ctrlWrd = !negated; needFull.add(1); compute.wakeup(); return false; } if (s.equals("ve-id")) { cur.veId = bits.str2num(cmd.word()); cur.veMax = bits.str2num(cmd.word()); if (negated) { cur.veId = 0; cur.veMax = 0; } needFull.add(1); compute.wakeup(); return false; } if (s.equals("update-source")) { if (negated) { cur.iface = null; needFull.add(1); compute.wakeup(); return false; } cfgIfc res = cfgAll.ifcFind(cmd.word(), 0); if (res == null) { cmd.error("no such interface"); return false; } if (res.vrfFor != vrfCore) { cmd.error("in other vrf"); return false; } cur.iface = res; needFull.add(1); compute.wakeup(); return false; } return false; } if (s.equals("afi-evpn")) { rtrBgpEvpn cur = new rtrBgpEvpn(this); cur.id = bits.str2num(cmd.word()); s = cmd.word(); if (s.equals("bridge-group")) { rtrBgpEvpn old = evpn.del(cur); if (old != null) { old.doStop(); } if (negated) { needFull.add(1); compute.wakeup(); return false; } cur.bridge = cfgAll.brdgFind(cmd.word(), false); if (cur.bridge == null) { cmd.error("no such bridge"); return false; } cur.bridge.bridgeHed.macRouter = cur; cur.bbmac = addrMac.getRandom(); cur.bcmac = ifcDot1ah.dstBmac4flood(cur.id); cur.encap = rtrBgpEvpn.encapType.pbb; evpn.add(cur); return false; } cur = evpn.find(cur); if (cur == null) { cmd.error("evpn not enabled"); return false; } if (s.equals("bmac")) { cur.bbmac.fromString(cmd.word()); return false; } if (s.equals("srv6")) { if (negated) { cur.srv6 = null; } else { cur.srv6 = cfgAll.ifcFind(cmd.word(), 0); } needFull.add(1); compute.wakeup(); return false; } if (s.equals("update-source")) { if (negated) { cur.iface = null; needFull.add(1); compute.wakeup(); return false; } cfgIfc res = cfgAll.ifcFind(cmd.word(), 0); if (res == null) { cmd.error("no such interface"); return false; } if (res.vrfFor != vrfCore) { cmd.error("in other vrf"); return false; } cur.iface = res; needFull.add(1); compute.wakeup(); return false; } if (s.equals("encapsulation")) { s = cmd.word(); if (s.equals("pbb")) { cur.encap = rtrBgpEvpn.encapType.pbb; } if (s.equals("vxlan")) { cur.encap = rtrBgpEvpn.encapType.vxlan; } if (s.equals("cmac")) { cur.encap = rtrBgpEvpn.encapType.cmac; } if (s.equals("vpws")) { cur.encap = rtrBgpEvpn.encapType.vpws; } needFull.add(1); compute.wakeup(); return false; } return false; } if (s.equals("dump")) { rtrBgpMrt dmp = new rtrBgpMrt(cmd.word()); if (negated) { dmp = dmps.del(dmp); if (dmp == null) { return false; } dmp.fileHandle.close(); return false; } rtrBgpMrt old = dmps.add(dmp); if (old != null) { old.fileHandle.close(); dmp = old; } dmp.fileHandle = new logFil(cmd.word()); int tim = bits.str2num(cmd.word()); String bck = cmd.word(); int siz = bits.str2num(cmd.word()); dmp.fileHandle.rotate(bck, siz, tim, 0); dmp.fileHandle.open(true); return false; } if (s.equals("monitor")) { rtrBgpMon mon = new rtrBgpMon(this, cmd.word()); if (negated) { mon = mons.del(mon); if (mon == null) { return false; } mon.stopNow(); return false; } cfgProxy prx = cfgAll.proxyFind(cmd.word(), false); if (prx == null) { cmd.error("no such proxy"); return false; } mon.proxy = prx.proxy; mon.server = cmd.word(); mon.port = bits.str2num(cmd.word()); mon.startNow(); mons.add(mon); return false; } if (s.equals("rpki")) { if (negated) { rpkiT = null; rpkiN = 0; needFull.add(1); compute.wakeup(); return false; } rpkiT = cfgRtr.name2num(cmd.word()); rpkiN = bits.str2num(cmd.word()); if (ipRtr.isRPKI(rpkiT) < 0) { cmd.error("not an rpki process"); rpkiT = null; rpkiN = 0; return false; } needFull.add(1); compute.wakeup(); return false; } if (s.equals("listen")) { rtrBgpLstn ntry = new rtrBgpLstn(); cfgAceslst acl = cfgAll.aclsFind(cmd.word(), false); if (acl == null) { cmd.error("no such acl"); return true; } ntry.acl = acl.aceslst; rtrBgpLstn old = lstnTmp.del(ntry); if (old != null) { tcpCore.listenStop(old.iface, port, null, 0); } if (negated) { return false; } ntry.temp = findTemp(cmd.word()); if (ntry.temp == null) { cmd.error("no such template"); return true; } ntry.iface = null; if (ntry.temp.srcIface != null) { if (afiUni == rtrBgpUtil.safiIp4uni) { ntry.iface = ntry.temp.srcIface.fwdIf4; } else { ntry.iface = ntry.temp.srcIface.fwdIf6; } } lstnTmp.put(ntry); tcpCore.streamListen(this, new pipeLine(ntry.temp.bufferSize, false), ntry.iface, port, null, 0, "bgp", ntry.temp.keyId, ntry.temp.passwd, ntry.temp.ttlSecurity, ntry.temp.tosValue); return false; } if (s.equals("template")) { s = cmd.word(); rtrBgpTemp ntry = new rtrBgpTemp(this, s); rtrBgpTemp old = temps.add(ntry); if (old != null) { ntry = old; } negated = ntry.setParamCfg(cmd, negated); needFull.add(1); compute.wakeup(); if (ntry.remoteAs != 0) { return negated; } temps.del(ntry); return negated; } if (!s.equals("neighbor")) { return true; } s = cmd.word().trim(); addrIP adr = cfgRtr.string2addr(rouTyp, s, null); if (adr == null) { cmd.error("bad address"); return false; } rtrBgpNeigh ntry = new rtrBgpNeigh(this, adr); rtrBgpNeigh old = neighs.add(ntry); if (old == null) { if (!s.equals("" + ntry.peerAddr)) { ntry.description = s; } else { ntry.description = cfgRtr.addr2string(rouTyp, ntry.peerAddr, null); } ntry.startNow(); } else { ntry = old; } negated = ntry.setParamCfg(cmd, negated); ntry.updatePeer(); needFull.add(1); compute.wakeup(); if (ntry.remoteAs != 0) { return negated; } ntry.stopNow(); neighs.del(ntry); return negated; } /** * template configuration * * @param temp template interface * @param cmd command to parse * @param negated negated */ public void templateConfig(rtrBgpTemp temp, String cmd, boolean negated) { for (int i = 0; i < neighs.size(); i++) { templateConfig(neighs.get(i), temp, cmd, negated); } for (int i = 0; i < lstnNei.size(); i++) { templateConfig(lstnNei.get(i), temp, cmd, negated); } } private void templateConfig(rtrBgpNeigh nei, rtrBgpTemp temp, String cmd, boolean negated) { if (nei == null) { return; } if (nei.template == null) { return; } if (!temp.tempName.equals(nei.template.tempName)) { return; } nei.setParamCfg(new cmds("template", cmd), negated); nei.updatePeer(); } /** * list neighbor summary * * @param safi safi to query * @return list of neighbors */ public userFormat showNeighs(int safi) { userFormat l = new userFormat("|", "neighbor|as|learn|accept|will|done|uptime"); for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh ntry = neighs.get(i); if (ntry == null) { continue; } l.add(ntry.showNeighs(safi)); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpNeigh ntry = lstnNei.get(i); if (ntry == null) { continue; } l.add(ntry.showNeighs(safi)); } return l; } /** * list neighbor summary * * @param mod mode: 1=afi, 2=groups, 3=nexthops, 4=graceful, 5=addpath, * 6=routerid, 7=buffer, 8=description, 9=hostname, 10=compress, 11=connect, * 12=resolve, 13=summary, 14=multilab, 15=longlived, 16=software, 17=desum * 18=unknowns, 19=asnsum, 20=pfxsummary * @return list of neighbors */ public userFormat showSummary(int mod) { userFormat l = null; switch (mod) { case 1: l = new userFormat("|", "neighbor|as|open|norem|noloc"); break; case 2: l = new userFormat("|", "neighbor|as|group|mode|uptime"); break; case 3: l = new userFormat("|", "neighbor|as|reach|chg|num|sess|uptime"); break; case 4: case 15: l = new userFormat("|", "neighbor|as|rx|tx"); break; case 5: l = new userFormat("|", "neighbor|as|rx|tx|rx|tx|rx|tx", "2|2open|2norem|2noloc"); break; case 6: l = new userFormat("|", "neighbor|as|router|wideas|refresh|dyncap|extop|extup|type|role"); break; case 7: l = new userFormat("|", "neighbor|as|buffer|over|ver|incr|full|need"); break; case 8: l = new userFormat("|", "neighbor|as|description"); break; case 9: l = new userFormat("|", "neighbor|as|hostname|domain"); break; case 10: l = new userFormat("|", "neighbor|as|rx|tx|rx|tx", "2|2operate|2ratio"); break; case 11: l = new userFormat("|", "neighbor|as|rx|tx|rx|tx|rx|tx|rx|tx", "2|2update|2byte|2refresh|2capa"); break; case 12: l = new userFormat("|", "neighbor|as|domain"); break; case 13: l = new userFormat("|", "neighbor|as|ready|learn|sent|uptime"); break; case 14: l = new userFormat("|", "neighbor|as|rx|tx"); break; case 16: l = new userFormat("|", "neighbor|as|software"); break; case 17: l = new userFormat("|", "neighbor|as|ready|learn|sent|uptim|descr"); break; case 18: l = new userFormat("|", "neighbor|as|updates|bytes|ago"); break; case 19: l = new userFormat("|", "neighbor|as|ready|learn|sent|uptim|asname|asinfo"); break; case 20: l = new userFormat("|", "neighbor|as|rx|tx|rx|tx|rx|tx", "2|2reach|2unrea|2ago"); break; default: return null; } for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh ntry = neighs.get(i); if (ntry == null) { continue; } l.add(ntry.showSummary(mod)); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpNeigh ntry = lstnNei.get(i); if (ntry == null) { continue; } l.add(ntry.showSummary(mod)); } return l; } /** * find peer * * @param adr address to find * @return neighbor, null if not found */ public rtrBgpNeigh findPeer(addrIP adr) { rtrBgpNeigh ntry = new rtrBgpNeigh(this, adr); rtrBgpNeigh res = neighs.find(ntry); if (res != null) { return res; } return lstnNei.find(ntry); } private String findPeers(int mod, rtrBgpNeigh ntry) { switch (mod) { case 1: return "" + ntry.remoteAs; case 2: return "" + ntry.peerAddr; case 3: return "" + (ntry.localAs == ntry.remoteAs); default: return ""; } } /** * find peers * * @param mod mode: 1=asn, 2=addr, 3=ibgp * @param reg regexp * @return list of peers */ public List findPeers(int mod, String reg) { List res = new ArrayList(); for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh ntry = neighs.get(i); String a = findPeers(mod, ntry); if (a.matches(reg)) { res.add(ntry); } } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpNeigh ntry = lstnNei.get(i); String a = findPeers(mod, ntry); if (a.matches(reg)) { res.add(ntry); } } return res; } /** * find group * * @param num number of group * @return group, null if not found */ public rtrBgpGroup findGroup(int num) { if (num < 0) { return null; } if (num >= groups.size()) { return null; } return groups.get(num); } /** * find template * * @param nam name to find * @return template, null if not found */ public rtrBgpTemp findTemp(String nam) { rtrBgpTemp ntry = new rtrBgpTemp(this, nam); return temps.find(ntry); } /** * get neighbor count * * @return count */ public int routerNeighCount() { return neighs.size() + lstnNei.size(); } /** * neighbor list * * @param tab list */ public void routerNeighList(tabRoute tab) { for (int i = 0; i < neighs.size(); i++) { rtrBgpNeigh nei = neighs.get(i); if (nei == null) { continue; } tabRouteEntry ntry = new tabRouteEntry(); ntry.prefix = new addrPrefix(nei.peerAddr, addrIP.size * 8); tabRoute.addUpdatedEntry(tabRoute.addType.better, tab, afiUni, 0, ntry, true, null, null, routerAutoMesh); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpNeigh nei = lstnNei.get(i); if (nei == null) { continue; } tabRouteEntry ntry = new tabRouteEntry(); ntry.prefix = new addrPrefix(nei.peerAddr, addrIP.size * 8); tabRoute.addUpdatedEntry(tabRoute.addType.better, tab, afiUni, 0, ntry, true, null, null, routerAutoMesh); } other.getPeerList(tab); for (int i = 0; i < vrfs.size(); i++) { vrfs.get(i).doer.getPeerList(tab); } for (int i = 0; i < ovrfs.size(); i++) { ovrfs.get(i).doer.getPeerList(tab); } for (int i = 0; i < clrs.size(); i++) { clrs.get(i).doer.getPeerList(tab); } for (int i = 0; i < oclrs.size(); i++) { oclrs.get(i).doer.getPeerList(tab); } for (int i = 0; i < vpls.size(); i++) { vpls.get(i).getPeerList(tab); } for (int i = 0; i < evpn.size(); i++) { evpn.get(i).getPeerList(tab); } } /** * get interface count * * @return count */ public int routerIfaceCount() { return 0; } /** * maximum recursion depth * * @return allowed number */ public int routerRecursions() { return recursion; } /** * get list of link states * * @param tab table to update * @param par parameter * @param asn asn * @param adv advertiser */ public void routerLinkStates(tabRoute tab, int par, int asn, addrIPv4 adv) { lspf.lastSpf.listLinkStates(tab, spfLnkst.protoBgp, -1, asn, adv, addrIPv4.size, 4); } /** * get all routes * * @param safi safi to query * @param prf prefix to find * @return list of routes */ public userFormat getAllRoutes(int safi, tabRouteEntry prf) { userFormat lst = new userFormat("|", "id|category|value"); for (int i = 0; i < neighs.size(); i++) { getAllRoutes(lst, neighs.get(i), safi, prf); } for (int i = 0; i < lstnNei.size(); i++) { getAllRoutes(lst, lstnNei.get(i), safi, prf); } return lst; } private void getAllRoutes(userFormat lst, rtrBgpNeigh nei, int safi, tabRouteEntry prf) { if (nei == null) { return; } tabRoute tab = nei.conn.getLearned(safi); if (tab == null) { return; } tabRouteEntry res = tab.find(prf); if (res == null) { return; } lst.add("|peer|" + nei.peerAddr); lst.add(res.fullDump("" + nei.peerAddr, fwdCore)); } /** * get flap stats * * @param afi afi * @param num minimum flap count * @return list of statistics */ public userFormat getFlapstat(int afi, int num) { userFormat l = new userFormat("|", "prefix|count|paths|ago|last"); if (flaps == null) { return l; } for (int i = 0; i < flaps.size(); i++) { rtrBgpFlapStat ntry = flaps.get(i); if (ntry == null) { continue; } if (ntry.afi != afi) { continue; } if (ntry.count < num) { continue; } l.add(ntry.toFlaps()); } return l; } /** * get flap paths * * @param afi afi * @param rd rd * @param prf prefix * @param rev reverse path * @return list of paths */ public userFormat getFlappath(int afi, long rd, addrPrefix prf, boolean rev) { if (flaps == null) { return null; } rtrBgpFlapStat ntry = new rtrBgpFlapStat(afi, rd, prf); ntry = flaps.find(ntry); if (ntry == null) { return null; } userFormat l = new userFormat("|", "count|ago|last|path"); for (int i = 0; i < ntry.paths.size(); i++) { l.add("" + ntry.paths.get(i).dump(rev)); } return l; } /** * originating as * * @param safi safi to query * @return text */ public userFormat getAsOrigin(int safi) { tabGen lst = new tabGen(); tabRoute rou = getDatabase(safi); for (int i = 0; i < rou.size(); i++) { tabRouteEntry ntry = rou.get(i); if (ntry == null) { continue; } int o = ntry.best.asPathEnd(); if (o == -1) { rtrBgpDump.updateAsOrigin(lst, localAs); } else { rtrBgpDump.updateAsOrigin(lst, o); } } userFormat res = new userFormat("|", "asnum|asnam|nets|asinfo"); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapAsn ntry = lst.get(i); res.add("" + ntry); } return res; } /** * transiting as * * @param safi safi to query * @return text */ public userFormat getAsTransit(int safi) { tabGen lst = new tabGen(); tabRoute rou = getDatabase(safi); for (int i = 0; i < rou.size(); i++) { tabRouteEntry ntry = rou.get(i); if (ntry == null) { continue; } if (ntry.best.pathSeq == null) { continue; } List res = ntry.best.asPathInts(localAs); rtrBgpDump.updateAsOrigin(lst, localAs); int p = res.size() - 1; for (int o = 0; o < p; o++) { rtrBgpDump.updateAsOrigin(lst, res.get(o)); } } userFormat res = new userFormat("|", "asnum|asnam|nets|asinfo"); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapAsn ntry = lst.get(i); res.add("" + ntry); } return res; } /** * as path graph * * @param safi safi to query * @return text */ public List getAsGraph(int safi) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateAsGraph(localAs, lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateAsGraph(localAs, lst, lstnNei.get(i), safi); } int o = 0; for (int i = 0; i < lst.size(); i++) { rtrBgpFlapAsn ntry = lst.get(i); if (o < ntry.count) { o = ntry.count; } } o += 2; List res = new ArrayList(); res.add(spfCalc.graphBeg1); res.add(spfCalc.graphBeg2); res.add(spfCalc.graphBeg3); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapAsn ntry = lst.get(i); res.add("\"" + clntWhois.asn2mixed(ntry.prev, true) + "\" -- \"" + clntWhois.asn2mixed(ntry.asn, true) + "\" [weight=" + (o - ntry.count) + "]"); } res.add(spfCalc.graphEnd1); res.add(spfCalc.graphEnd2); return res; } /** * as path tree * * @param safi safi to query * @param asn asn to start from * @return text */ public List getAsTree(int safi, int asn) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateAsGraph(localAs, lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateAsGraph(localAs, lst, lstnNei.get(i), safi); } if (asn == 0) { asn = localAs; } List res = new ArrayList(); rtrBgpDump.drawAsTree(res, lst, asn, ""); return res; } /** * as path statistics * * @param safi safi to query * @return text */ public userFormat getPathStat(int safi) { tabRoute rou = getDatabase(safi); int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; long sum = 0; for (int i = 0; i < rou.size(); i++) { tabRouteEntry ntry = rou.get(i); if (ntry == null) { continue; } int o = ntry.best.asPathLen(); if (o < min) { min = o; } if (o > max) { max = o; } sum += o; } userFormat res = new userFormat("|", "category|value"); res.add("minimum|" + min); res.add("maximum|" + max); res.add("average|" + (float) sum / (rou.size() + 1)); return res; } /** * as connections * * @param safi safi to query * @return text */ public userFormat getAsConns(int safi) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateAsGraph(localAs, lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateAsGraph(localAs, lst, lstnNei.get(i), safi); } userFormat res = new userFormat("|", "asnum|asnam|conn|net|peers"); int conns = -1; int prefs = -1; String peers = ""; int curr = 0; for (int i = 0; i < lst.size(); i++) { rtrBgpFlapAsn ntry = lst.get(i); if (curr == ntry.prev) { peers += " " + clntWhois.asn2mixed(ntry.asn, true); conns++; prefs += ntry.count; continue; } if (conns > 0) { res.add(bits.num2str(curr) + "|" + clntWhois.asn2name(curr, true) + "|" + conns + "|" + prefs + "|" + peers); } curr = ntry.prev; peers = clntWhois.asn2mixed(ntry.asn, true); conns = 1; prefs = ntry.count; } if (conns > 0) { res.add(curr + "|" + clntWhois.asn2name(curr, true) + "|" + conns + "|" + prefs + "|" + peers); } return res; } /** * usage of next hops * * @param safi safi to query * @return text */ public userFormat getNhPrfxes(int safi) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateNhPrfxes(lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateNhPrfxes(lst, lstnNei.get(i), safi); } userFormat res = new userFormat("|", "nexthop|prefixes"); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapStat ntry = lst.get(i); res.add(ntry.toNhPrfxes()); } return res; } /** * usage of next hops * * @param safi safi to query * @return text */ public userFormat getNhTrnsit(int safi) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateNhTrnsit(lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateNhTrnsit(lst, lstnNei.get(i), safi); } userFormat res = new userFormat("|", "nexthop|count|transits"); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapStat ntry = lst.get(i); res.add(ntry.toNhTrnsit()); } return res; } /** * usage of next hops * * @param safi safi to query * @return text */ public userFormat getNhOrigin(int safi) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateNhOrigin(lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateNhOrigin(lst, lstnNei.get(i), safi); } userFormat res = new userFormat("|", "nexthop|count|origins"); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapStat ntry = lst.get(i); res.add(ntry.toNhTrnsit()); } return res; } /** * inconsistent next hops * * @param safi safi to query * @param mtch matcher * @return text */ public userFormat getNhIncons(int safi, tabIntMatcher mtch) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateNhIncons(lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateNhIncons(lst, lstnNei.get(i), safi); } userFormat res = new userFormat("|", "path|nexthops"); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapStat ntry = lst.get(i); if (!mtch.matches(ntry.infos.size())) { continue; } res.add(ntry.toInconsStr()); } return res; } /** * inconsistent as paths * * @param safi safi to query * @param mtch matcher * @return text */ public userFormat getAsIncons(int safi, tabIntMatcher mtch) { tabGen lst = new tabGen(); for (int i = 0; i < neighs.size(); i++) { rtrBgpDump.updateAsIncons(lst, neighs.get(i), safi); } for (int i = 0; i < lstnNei.size(); i++) { rtrBgpDump.updateAsIncons(lst, lstnNei.get(i), safi); } userFormat res = new userFormat("|", "path|ases"); for (int i = 0; i < lst.size(); i++) { rtrBgpFlapStat ntry = lst.get(i); if (!mtch.matches(ntry.paths.size())) { continue; } res.add(ntry.toInconsPth()); } return res; } /** * get message statistics * * @return list of statistics */ public userFormat getMsgStats() { return rtrBgpDump.getMsgStats(msgStats); } /** * get message statistics * * @return list of statistics */ public userFormat getAttrStats() { return rtrBgpDump.getAttrStats(attrStats); } /** * show spf * * @return log of spf */ public userFormat getSpfStat() { return lspf.lastSpf.listStatistics(); } /** * show topology * * @param cmd entry to find * @return log of spf */ public userFormat getSpfTopo(cmds cmd) { if (cmd.size() < 1) { return lspf.lastSpf.listTopology(); } addrIPv4 ned = new addrIPv4(); ned.fromString(cmd.word()); return lspf.lastSpf.listTopology(ned); } /** * show log * * @return log of spf */ public userFormat getSpfLog() { return lspf.lastSpf.listUsages(); } /** * show tree * * @return tree of spf */ public List getSpfTree() { return lspf.lastSpf.listTree(); } /** * show tree * * @param cmd entry to find * @return tree of spf */ public List getSpfOtherTree(cmds cmd) { spfCalc spf = lspf.lastSpf.copyBytes(); addrIPv4 ned = new addrIPv4(); ned.fromString(cmd.word()); spf.doWork(null, ned, null); return spf.listTree(); } /** * show topology * * @param cmd entry to find * @return log of spf */ public userFormat getSpfOtherTopo(cmds cmd) { spfCalc spf = lspf.lastSpf.copyBytes(); addrIPv4 ned = new addrIPv4(); ned.fromString(cmd.word()); spf.doWork(null, ned, null); if (cmd.size() < 1) { return spf.listTopology(); } ned = new addrIPv4(); ned.fromString(cmd.word()); return spf.listTopology(ned); } /** * show graph * * @param msk masks * @return graph of spf */ public List getSpfGraph(int msk) { return lspf.lastSpf.listGraphviz(msk); } /** * show nh inconsistency * * @param mtch matcher * @return inconsistency list */ public userFormat getNhIncons(tabIntMatcher mtch) { return lspf.lastSpf.listNhIncons(mtch); } /** * show met inconsistency * * @param mtch matcher * @return inconsistency list */ public userFormat getMetIncons(tabIntMatcher mtch) { return lspf.lastSpf.listMetIncons(mtch); } /** * show route * * @return routes of spf */ public tabRoute getSpfRoute() { return lspf.routes; } /** * get bestpath stats * * @return list of statistics */ public userFormat getBestpath() { userFormat l = new userFormat("|", "category|value|addition"); l.add("self|" + this); l.add("other|" + other); l.add("asn|" + clntWhois.asn2mixed(localAs, true)); l.add("routerid|" + routerID); l.add("version|" + compRound); l.add("full run|" + fullCount + "|times"); l.add("full last|" + bits.timePast(fullLast) + "|" + bits.time2str(cfgAll.timeZoneName, fullLast + cfgAll.timeServerOffset, 3)); l.add("full time|" + fullTime + "|ms"); l.add("incr run|" + incrCount + "|times"); l.add("incr last|" + bits.timePast(incrLast) + "|" + bits.time2str(cfgAll.timeZoneName, incrLast + cfgAll.timeServerOffset, 3)); l.add("incr time|" + incrTime + "|ms"); rtrBgpDump.getMsgStats(l, rtrBgpUtil.msgOpen, msgStats, "|", "|"); rtrBgpDump.getMsgStats(l, rtrBgpUtil.msgUpdate, msgStats, "|", "|"); rtrBgpDump.getMsgStats(l, rtrBgpUtil.msgNotify, msgStats, "|", "|"); rtrBgpDump.getUnReachStats(l, reachabStat, unreachStat, "|", "|"); rtrBgpDump.getUnknwSum(l, false, msgStats, "|", "|"); rtrBgpDump.getUnknwSum(l, true, attrStats, "|", "|"); l.add("listen accepts|" + accptStat.packTx + "|" + accptStat.packTx + " " + accptStat.packDr); l.add("changes all|" + changedTot); l.add("changes now|" + changedCur); l.add("changes max|" + changedMax); l.add("changes peak|" + bits.timePast(changedPek) + "|" + bits.time2str(cfgAll.timeZoneName, changedPek + cfgAll.timeServerOffset, 3)); l.add("static peers|" + rtrBgpUtil.tabSiz2str(neighs)); l.add("dynamic peers|" + rtrBgpUtil.tabSiz2str(lstnNei)); l.add("dynamic templates|" + rtrBgpUtil.tabSiz2str(lstnTmp)); l.add("templates|" + rtrBgpUtil.tabSiz2str(temps)); l.add("linkstates|" + rtrBgpUtil.tabSiz2str(linkStates)); l.add("flapstats|" + rtrBgpUtil.tabSiz2str(flaps)); l.add("monitors|" + rtrBgpUtil.tabSiz2str(mons)); l.add("dumps|" + rtrBgpUtil.tabSiz2str(dmps)); l.add("vrfs|" + rtrBgpUtil.tabSiz2str(vrfs)); l.add("other vrfs|" + rtrBgpUtil.tabSiz2str(ovrfs)); l.add("colors|" + rtrBgpUtil.tabSiz2str(clrs)); l.add("other colors|" + rtrBgpUtil.tabSiz2str(oclrs)); l.add("vplses|" + rtrBgpUtil.tabSiz2str(vpls)); l.add("evpns|" + rtrBgpUtil.tabSiz2str(evpn)); l.add("groups|" + groups.size() + "|" + groupMin + ".." + groupMax); l.add("rpki table|" + rpkiA.size() + "|" + rpkiO.size()); l.add("unicast table|" + routerComputedU.size() + "|" + changedUni.size()); l.add("multicast table|" + routerComputedM.size() + "|" + changedMlt.size()); l.add("ouni table|" + computedOuni.size() + "|" + changedOuni.size()); l.add("omlt table|" + computedOmlt.size() + "|" + changedOmlt.size()); l.add("oflw table|" + computedOflw.size() + "|" + changedOflw.size()); l.add("osrt table|" + computedOsrt.size() + "|" + changedOsrt.size()); l.add("flowspec table|" + routerComputedF.size() + "|" + changedFlw.size()); l.add("vpnuni table|" + computedVpnU.size() + "|" + changedVpnU.size()); l.add("vpnmlt table|" + computedVpnM.size() + "|" + changedVpnM.size()); l.add("vpnflw table|" + computedVpnF.size() + "|" + changedVpnF.size()); l.add("ovpnuni table|" + computedVpoU.size() + "|" + changedVpoU.size()); l.add("ovpnmlt table|" + computedVpoM.size() + "|" + changedVpoM.size()); l.add("ovpnflw table|" + computedVpoF.size() + "|" + changedVpoF.size()); l.add("vpls table|" + computedVpls.size() + "|" + changedVpls.size()); l.add("mspw table|" + computedMspw.size() + "|" + changedMspw.size()); l.add("evpn table|" + computedEvpn.size() + "|" + changedEvpn.size()); l.add("mdt table|" + computedMdt.size() + "|" + changedMdt.size()); l.add("nsh table|" + computedNsh.size() + "|" + changedNsh.size()); l.add("rpd table|" + computedRpd.size() + "|" + changedRpd.size()); l.add("spf table|" + computedSpf.size() + "|" + changedSpf.size()); l.add("rtfilter table|" + computedRtf.size() + "|" + changedRtf.size()); l.add("srte table|" + computedSrte.size() + "|" + changedSrte.size()); l.add("linkstate table|" + computedLnks.size() + "|" + changedLnks.size()); l.add("mvpn table|" + computedMvpn.size() + "|" + changedMvpn.size()); l.add("omvpn table|" + computedMvpo.size() + "|" + changedMvpo.size()); l.add("mtree table|" + computedMtre.size() + "|" + changedMtre.size()); l.add("omtree table|" + computedMtro.size() + "|" + changedMtro.size()); return l; } }