package es.tid.topologyModuleBase.plugins.updaters; import java.net.Inet4Address; import java.net.UnknownHostException; import java.util.LinkedList; import java.util.concurrent.LinkedBlockingQueue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import es.tid.ospf.ospfv2.OSPFv2LinkStateUpdatePacket; import es.tid.ospf.ospfv2.lsa.LSA; import es.tid.ospf.ospfv2.lsa.LSATypes; import es.tid.ospf.ospfv2.lsa.OSPFTEv2LSA; import es.tid.ospf.ospfv2.lsa.tlv.LinkTLV; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.AvailableLabels; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.MaximumBandwidth; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.MaximumReservableBandwidth; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.UnreservedBandwidth; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.complexFields.BitmapLabelSet; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.complexFields.LabelSetField; import es.tid.ospf.ospfv2.lsa.tlv.subtlv.complexFields.LabelSetParameters; import es.tid.tedb.DomainTEDB; import es.tid.tedb.IntraDomainEdge; import es.tid.tedb.MultiLayerTEDB; import es.tid.tedb.SimpleTEDB; import es.tid.tedb.TE_Information; public class TopologyUpdaterThread extends Thread{ private LinkedBlockingQueue<OSPFv2LinkStateUpdatePacket> ospfv2PacketQueue; private Logger log; private DomainTEDB TEDB; /** * Variables used to specify the range of lambdas the PCE is using * Variables para especificar el rango de lambdas que el PCE esta usando, es decir, * el rango de lambdas en el que puede calcular caminos */ private int lambdaIni=0; private int lambdaEnd=Integer.MAX_VALUE; private boolean isCompletedAuxGraph=false; private boolean multilayer=false; private int layer=LayerTypes.SIMPLE_NETWORK; public TopologyUpdaterThread(LinkedBlockingQueue<OSPFv2LinkStateUpdatePacket> ospfv2PacketQueue, DomainTEDB TEDB, int lambdaIni, int lambdaEnd) { log=LoggerFactory.getLogger("PCEServer"); this.ospfv2PacketQueue=ospfv2PacketQueue; this.TEDB=TEDB; this.lambdaIni=lambdaIni; this.lambdaEnd=lambdaEnd; } public TopologyUpdaterThread(LinkedBlockingQueue<OSPFv2LinkStateUpdatePacket> ospfv2PacketQueue,DomainTEDB TEDB, int lambdaIni, int lambdaEnd, boolean isCompletedAuxGraph, boolean multilayer) { log=LoggerFactory.getLogger("PCEServer"); this.ospfv2PacketQueue=ospfv2PacketQueue; this.TEDB=TEDB; this.lambdaIni=lambdaIni; this.lambdaEnd=lambdaEnd; this.isCompletedAuxGraph=isCompletedAuxGraph; this.multilayer=multilayer; } @Override public void run() { log.info("Starting Topology Upadater Thread"); LinkedList<LSA> lsaList; OSPFTEv2LSA lsa; OSPFv2LinkStateUpdatePacket ospfv2Packet; while(true){ try { ospfv2Packet = ospfv2PacketQueue.take(); //log.info("OSPF PACKET READ"); //System.out.println("OSPF AREA: "+ospfv2Packet.getAreaID().toString()); Inet4Address domainId = (Inet4Address) Inet4Address.getByName("0.0.0.1"); TEDB.getReachabilityEntry().setDomainId(domainId); //System.out.println("MY AREA: "+TEDB.getReachabilityEntry().getDomainId()); // Filtered by domain ID if ((TEDB.getReachabilityEntry().getDomainId())!=null){ if(ospfv2Packet.getAreaID().toString().equalsIgnoreCase(this.TEDB.getReachabilityEntry().getDomainId().toString())){ //System.out.println("Adding OSPF Message"); // If ospf packet is from my domain Inet4Address localInterfaceIPAddress = ospfv2Packet.getRouterID(); lsaList = (ospfv2Packet).getLSAlist(); for (int i =0;i< lsaList.size();i++){ if (lsaList.get(i).getLStype() == LSATypes.TYPE_10_OPAQUE_LSA){ lsa=(OSPFTEv2LSA)lsaList.get(i); //log.info("Starting to process LSA"); LinkTLV linkTLV = lsa.getLinkTLV(); if (linkTLV!=null){ //log.info("Link TLV ha llegado "+lsa.toString()); //System.out.println(linkTLV.toString()); if (localInterfaceIPAddress == null){ localInterfaceIPAddress = linkTLV.getLocalInterfaceIPAddress().getLocalInterfaceIPAddress(0); } log.debug("Local InterfaceIPAddress: "+localInterfaceIPAddress); Inet4Address remoteInterfaceIPAddress = linkTLV.getLinkID().getLinkID(); //Inet4Address remoteInterfaceIPAddress =linkTLV.getRemoteInterfaceIPAddress().getRemoteInterfaceIPAddress(0); log.debug("Remote InterfaceIPAddress: "+remoteInterfaceIPAddress); AvailableLabels newAvailableLabels = linkTLV.getAvailableLabels(); IntraDomainEdge edge = null; if (multilayer){ if (isCompletedAuxGraph){ //tenemos que realizar la conversión a nodos y links del grafo auxiliar if (newAvailableLabels!=null){ //System.out.println("MODIFICACIÓN GRAFO PARA ÓPTICA"); //Es de las capas 1-Numlabels //Modificación en parte óptica int lambda = 0; lambda = ((BitmapLabelSet)linkTLV.getAvailableLabels().getLabelSet()).getDwdmWavelengthLabel().getN(); //System.out.println("Modificamos Grafo para la lambda :"+lambda); ((MultiLayerTEDB)TEDB).notificationEdgeOPTICAL_AuxGraph(localInterfaceIPAddress, remoteInterfaceIPAddress, lambda); } else{ //System.out.println("MODIFICACIÓN GRAFO PARA IP"); TE_Information informationTEDB = new TE_Information(); MaximumBandwidth maximumBandwidth = linkTLV.getMaximumBandwidth(); if (maximumBandwidth!= null){ informationTEDB.setMaximumBandwidth(maximumBandwidth); //System.out.println("Meto el maximumBandwidth :"+maximumBandwidth.getMaximumBandwidth()); } UnreservedBandwidth unreservedBandwidth = linkTLV.getUnreservedBandwidth(); if (unreservedBandwidth!=null){ informationTEDB.setUnreservedBandwidth(unreservedBandwidth); //System.out.println("Meto el unreservedBandwidth :"+unreservedBandwidth.getUnreservedBandwidth()[0]); } MaximumReservableBandwidth maximumReservableBandwidth = new MaximumReservableBandwidth(); maximumReservableBandwidth.setMaximumReservableBandwidth(unreservedBandwidth.getUnreservedBandwidth()[0]); if (maximumReservableBandwidth!= null){ informationTEDB.setMaximumReservableBandwidth(maximumReservableBandwidth); //System.out.println("Meto el MaximumReservableBandwidth :"+maximumReservableBandwidth.maximumReservableBandwidth); } //Es de las capas "NumLabels + 1" o "NumLabels + 2" ((MultiLayerTEDB)TEDB).notificationEdgeIP_AuxGraph(localInterfaceIPAddress, remoteInterfaceIPAddress, informationTEDB); } } else { if (newAvailableLabels== null){ // caso Multilayer CAPA MPLS //System.out.println("Link de "+localInterfaceIPAddress+" al dest "+remoteInterfaceIPAddress); edge=((MultiLayerTEDB)TEDB).getUpperLayerGraph().getEdge(localInterfaceIPAddress, remoteInterfaceIPAddress); layer = LayerTypes.UPPER_LAYER; //System.out.println("Actualización grafo IP --> CAPA SUPERIOR"); } else{ // caso MULTILAYER capa OPTICA edge=((MultiLayerTEDB)TEDB).getLowerLayerGraph().getEdge(localInterfaceIPAddress, remoteInterfaceIPAddress); layer = LayerTypes.LOWER_LAYER; //System.out.println("Actualización grafo ÓPTICO --> CAPA INFERIOR"); } } } else{ edge=((SimpleTEDB)TEDB).getNetworkGraph().getEdge(localInterfaceIPAddress, remoteInterfaceIPAddress); layer = LayerTypes.SIMPLE_NETWORK; } boolean newEdge=false; boolean newVertex =false; boolean newEdge_virtual=false; boolean changeWavelength = false; boolean lighpath_flag = false; BitmapLabelSet previousBitmapLabelSet=null; BitmapLabelSet newBitmapLabelSet=null; if (edge!=null){ //System.out.println("ACTUALIZACIÓN ÓPTICA O IP/MPLS SIN AÑADIR NUEVO LIGTH PATH"); } if ((edge == null) && !(isCompletedAuxGraph)){ log.info("ADDING EDGE"); edge= new IntraDomainEdge(); if (layer == LayerTypes.SIMPLE_NETWORK){ ((SimpleTEDB)TEDB).getNetworkGraph().addVertex(localInterfaceIPAddress); ((SimpleTEDB)TEDB).getNetworkGraph().addVertex(remoteInterfaceIPAddress); if(linkTLV.getLinkLocalRemoteIdentifiers()!=null){ long src_if_Id = linkTLV.getLinkLocalRemoteIdentifiers().getLinkLocalIdentifier(); long dst_if_Id = linkTLV.getLinkLocalRemoteIdentifiers().getLinkRemoteIdentifier(); edge.setSrc_if_id(src_if_Id); edge.setDst_if_id(dst_if_Id); } ((SimpleTEDB)TEDB).getNetworkGraph().addEdge(localInterfaceIPAddress, remoteInterfaceIPAddress, edge); } else if (layer == LayerTypes.LOWER_LAYER){ ((MultiLayerTEDB)TEDB).getLowerLayerGraph().addVertex(localInterfaceIPAddress); ((MultiLayerTEDB)TEDB).getLowerLayerGraph().addVertex(remoteInterfaceIPAddress); ((MultiLayerTEDB)TEDB).getLowerLayerGraph().addEdge(localInterfaceIPAddress, remoteInterfaceIPAddress, edge); } else { //((MultiLayerTEDB)TEDB).getUpperLayerGraph().addEdge(localInterfaceIPAddress, remoteInterfaceIPAddress, edge); newEdge_virtual = true; if (newEdge_virtual){ TE_Information informationTEDB = new TE_Information(); MaximumBandwidth maximumBandwidth = linkTLV.getMaximumBandwidth(); if (maximumBandwidth!= null){ informationTEDB.setMaximumBandwidth(maximumBandwidth); // System.out.println("Meto el maximumBandwidth"); } UnreservedBandwidth unreservedBandwidth = linkTLV.getUnreservedBandwidth(); if (unreservedBandwidth!=null){ informationTEDB.setUnreservedBandwidth(unreservedBandwidth); //System.out.println("Meto el unreservedBandwidth"); } MaximumReservableBandwidth maximumReservableBandwidth = new MaximumReservableBandwidth(); maximumReservableBandwidth.setMaximumReservableBandwidth(unreservedBandwidth.getUnreservedBandwidth()[0]); if (maximumReservableBandwidth!= null){ informationTEDB.setMaximumReservableBandwidth(maximumReservableBandwidth); //System.out.println("Meto el MaximumReservableBandwidth"); } ((MultiLayerTEDB)TEDB).notifyNewEdgeIP(localInterfaceIPAddress, remoteInterfaceIPAddress, informationTEDB); lighpath_flag = true; } } if (layer == LayerTypes.LOWER_LAYER || layer == LayerTypes.SIMPLE_NETWORK){ newVertex=true; newEdge=true; } } if (lighpath_flag == false && !(isCompletedAuxGraph)){ TE_Information informationTEDB=edge.getTE_info(); if (informationTEDB == null){ informationTEDB = new TE_Information(); } if (layer == LayerTypes.UPPER_LAYER){ if (newAvailableLabels == null){ MaximumBandwidth maximumBandwidth = linkTLV.getMaximumBandwidth(); if (maximumBandwidth!= null) informationTEDB.setMaximumBandwidth(maximumBandwidth); UnreservedBandwidth unreservedBandwidth = linkTLV.getUnreservedBandwidth(); if (unreservedBandwidth!=null) informationTEDB.setUnreservedBandwidth(unreservedBandwidth); //AvailableLabels MaximumReservableBandwidth maximumReservableBandwidth = new MaximumReservableBandwidth(); maximumReservableBandwidth.setMaximumReservableBandwidth(unreservedBandwidth.getUnreservedBandwidth()[0]); if (maximumReservableBandwidth!= null) informationTEDB.setMaximumReservableBandwidth(maximumReservableBandwidth); } edge.setTE_info(informationTEDB); } else if (newAvailableLabels!= null){ if (newAvailableLabels.getLabelSet()!=null){ if (newAvailableLabels.getLabelSet().getAction()==LabelSetParameters.BitmapLabelSet){ //We store here the previous BitmapLabelSet, to know the differences //log.info("TEMA BITMAP LABEL"); if (informationTEDB.getAvailableLabels() == null){ informationTEDB.setAvailableLabels(new AvailableLabels()); } //Primera vez que llega la topologia. Creamos el LABELSET if (informationTEDB.getAvailableLabels().getLabelSet() == null){ //log.info("TEMA BITMAP LABEL POR PRIMERA VEZ"); newBitmapLabelSet = new BitmapLabelSet(); previousBitmapLabelSet=newBitmapLabelSet; newBitmapLabelSet.createBytesBitMap(((BitmapLabelSet)newAvailableLabels.getLabelSet()).getBytesBitMap()); int numLabels = linkTLV.getAvailableLabels().getLabelSet().getNumLabels(); int numberBytes = getNumberBytes(numLabels); log.info("NUM LABELS: "+numLabels+" NUMBER BYTES: "+numberBytes); byte[] bytesBitMapReserved = new byte[numberBytes]; for (int j=0;j<numberBytes;j++) bytesBitMapReserved[j]=0x00; newBitmapLabelSet.setBytesBitmap(bytesBitMapReserved); newBitmapLabelSet.setBytesBitmapReserved(bytesBitMapReserved); log.info("antes"); log.info("NUM LABELS: "+newBitmapLabelSet.getBytesBitMap().length); newBitmapLabelSet.setNumLabels(numLabels); informationTEDB.getAvailableLabels().setLabelSet(newBitmapLabelSet); newBitmapLabelSet.setDwdmWavelengthLabel(((BitmapLabelSet)linkTLV.getAvailableLabels().getLabelSet()).getDwdmWavelengthLabel()); changeWavelength = true; edge.setTE_info(informationTEDB); }else{//La topologia ya esta creada previousBitmapLabelSet = new BitmapLabelSet(); previousBitmapLabelSet.createBytesBitMap(((BitmapLabelSet)informationTEDB.getAvailableLabels().getLabelSet()).getBytesBitMap()); } if (!newEdge){ if (hasChanged(previousBitmapLabelSet,newAvailableLabels.getLabelSet())){ if (lambdaEnd!=Integer.MAX_VALUE){ ((BitmapLabelSet)informationTEDB.getAvailableLabels().getLabelSet()).arraycopyBytesBitMap(((BitmapLabelSet)newAvailableLabels.getLabelSet()).getBytesBitMap(),getNumberBytes(lambdaIni),getNumberBytes(lambdaEnd)); } else{ System.out.println("Actualizamos el nuevo bit map label set en la TEDB"); ((BitmapLabelSet)informationTEDB.getAvailableLabels().getLabelSet()).arraycopyBytesBitMap(((BitmapLabelSet)newAvailableLabels.getLabelSet()).getBytesBitMap()); } changeWavelength = true; } } } }else { log.info("TopologyUpdaterThread: El label set es null."); } } if (newVertex){ if (multilayer){ ((MultiLayerTEDB)TEDB).notifyNewVertex(localInterfaceIPAddress); ((MultiLayerTEDB)TEDB).notifyNewVertex(remoteInterfaceIPAddress); } else{ TEDB.notifyNewVertex(localInterfaceIPAddress); TEDB.notifyNewVertex(remoteInterfaceIPAddress); } } if (newEdge){ if (multilayer) ((MultiLayerTEDB)TEDB).notifyNewEdge(localInterfaceIPAddress,remoteInterfaceIPAddress); else TEDB.notifyNewEdge(localInterfaceIPAddress,remoteInterfaceIPAddress); } if (changeWavelength){ if (multilayer) ((MultiLayerTEDB)TEDB).notifyWavelengthChange(localInterfaceIPAddress, remoteInterfaceIPAddress, previousBitmapLabelSet,(BitmapLabelSet)informationTEDB.getAvailableLabels().getLabelSet()); else{ System.out.println("Entramos en el notifyWavelengthChange"); TEDB.notifyWavelengthChange(localInterfaceIPAddress, remoteInterfaceIPAddress, previousBitmapLabelSet,(BitmapLabelSet)informationTEDB.getAvailableLabels().getLabelSet()); } } } } else { log.debug("Link TLV de OSPFTEv2LSA esta a null"); } log.debug("Processing LSA to update topology"); } } } // END area ID comparation } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void LSASDifferences(OSPFTEv2LSA lsaOriginal, OSPFTEv2LSA lsaReceived){ //RouterAddressTLV //LinkTLV: // //LinkType ; // // LinkID ; // // LocalInterfaceIPAddress ; // // RemoteInterfaceIPAddress ; // // TrafficEngineeringMetric ; // // MaximumBandwidth ; // // MaximumReservableBandwidth ; // // UnreservedBandwidth ; // // AdministrativeGroup ; // // LinkLocalRemoteIdentifiers ; // // - LinkProtectionType ; // // - InterfaceSwitchingCapabilityDescriptor ; // // - SharedRiskLinkGroup ; // // - RemoteASNumber ; // // - IPv4RemoteASBRID ; // // - AvailableLabels: // // if ((lsaOriginal.getLinkTLV().getLinkLocalRemoteIdentifiers() != null )&&(lsaReceived.getLinkTLV().getLinkLocalRemoteIdentifiers() != null)) if (!(lsaOriginal.getLinkTLV().getLinkLocalRemoteIdentifiers().equals(lsaReceived.getLinkTLV().getLinkLocalRemoteIdentifiers()))) //No son iguales log.info("Distinto el LinkLocalRemoteIdentifiers"); if ((lsaOriginal.getLinkTLV().getLinkProtectionType() != null )&&(lsaReceived.getLinkTLV().getLinkProtectionType() != null)) if (!(lsaOriginal.getLinkTLV().getLinkProtectionType().equals(lsaReceived.getLinkTLV().getLinkProtectionType()))) //No son iguales log.info("Distinto el LinkProtectionType"); if ((lsaOriginal.getLinkTLV().getInterfaceSwitchingCapabilityDescriptor() != null )&&(lsaReceived.getLinkTLV().getInterfaceSwitchingCapabilityDescriptor() != null)) if (!(lsaOriginal.getLinkTLV().getInterfaceSwitchingCapabilityDescriptor().equals(lsaReceived.getLinkTLV().getInterfaceSwitchingCapabilityDescriptor()))) //No son iguales log.info("Distinto el InterfaceSwitchingCapabilityDescriptor"); if ((lsaOriginal.getLinkTLV().getSharedRiskLinkGroup() != null )&&(lsaReceived.getLinkTLV().getSharedRiskLinkGroup() != null)) if (!(lsaOriginal.getLinkTLV().getSharedRiskLinkGroup().equals(lsaReceived.getLinkTLV().getSharedRiskLinkGroup()))) //No son iguales log.info("Distinto el getSharedRiskLinkGroup"); if ((lsaOriginal.getLinkTLV().getRemoteASNumber() != null )&&(lsaReceived.getLinkTLV().getRemoteASNumber() != null)) if (!(lsaOriginal.getLinkTLV().getRemoteASNumber().equals(lsaReceived.getLinkTLV().getRemoteASNumber()))) //No son iguales log.info("Distinto el getRemoteASNumber"); if ((lsaOriginal.getLinkTLV().getiPv4RemoteASBRID()!= null )&&(lsaReceived.getLinkTLV().getiPv4RemoteASBRID() !=null)) if (!(lsaOriginal.getLinkTLV().getiPv4RemoteASBRID().equals(lsaReceived.getLinkTLV().getiPv4RemoteASBRID()))) log.info("Distinto el getiPv4RemoteASBRID");//No son iguales if ((lsaOriginal.getLinkTLV().getAvailableLabels() != null )&&(lsaReceived.getLinkTLV().getAvailableLabels() != null)) if (!(lsaOriginal.getLinkTLV().getAvailableLabels().equals(lsaReceived.getLinkTLV().getAvailableLabels()))) //No son iguales log.info("Distinto el LinkProtectionType"); } public int getNumberBytes(int lambda){ int numberBytes = lambda/8; if ((numberBytes*8)<lambda){ numberBytes++; } return numberBytes; } // public boolean changeBytesBitMap(LabelSetField LabelTEinfo ,LabelSetField LabelTElink){ // byte[] bytesBitMapTEinfo = (((BitmapLabelSet)LabelTEinfo).getBytesBitMap()); // //byte[] bytesBitMapTElink = ((BitmapLabelSet)LabelTElink).getBytesBitMap(); // //printByte(bytesBitMapTEinfo,"bytesBitMapTEinfo"); // //printByte(bytesBitMapTElink,"bytesBitMapTElink"); // if (bytesBitMapTEinfo.length != ((BitmapLabelSet)LabelTElink).getBytesBitMap().length){ // return false; // } // byte[] bytesToChange = new byte[bytesBitMapTEinfo.length]; // // for (int i =0; i<bytesBitMapTEinfo.length;i++){ // bytesBitMapTEinfo[i]=(byte) ( (bytesBitMapTEinfo[i]) | (((BitmapLabelSet)LabelTElink).getBytesBitMap()[i])); // } // ((BitmapLabelSet)LabelTEinfo).changeBytesBitMap(bytesToChange); // //printByte(bytesToChange,"bytesToChange"); // return true; // } public boolean hasChanged(LabelSetField LabelTEinfo ,LabelSetField LabelTElink){ byte[] bytesBitMapTEinfo = (((BitmapLabelSet)LabelTEinfo).getBytesBitMap()); byte[] bytesBitMapTElink = ((BitmapLabelSet)LabelTElink).getBytesBitMap(); //FIXME: mirar que pasa si la lonmgitud no es la misma //Si la longitud no es la misma, significa que hay balanceo de carga //Entonces tengo que coger los bytes de LabelTElink que quiero, para ello necesito la 'n' //del base label de la topologia del PCE if (bytesBitMapTEinfo.length != bytesBitMapTElink.length){ int nMin=((SimpleTEDB)TEDB).getWSONinfo().getnMin(); int numLambdas=((SimpleTEDB)TEDB).getWSONinfo().getNumLambdas(); int numberBytes = getNumberBytes(numLambdas); byte[] newBytes = new byte[bytesBitMapTElink.length]; System.arraycopy(bytesBitMapTElink, nMin, newBytes, 0,numberBytes); for (int i =0; i<bytesBitMapTEinfo.length;i++){ if (bytesBitMapTEinfo[i] != newBytes[i]) return true; } } else if (lambdaEnd!=Integer.MAX_VALUE){ /*El PCE esta actuando sobre un rango de lambdas determinado*/ for (int i =getNumberBytes(lambdaIni); i<getNumberBytes(lambdaEnd);i++){ if (bytesBitMapTEinfo[i] != bytesBitMapTElink[i]) return true; } } else{ for (int i =0; i<bytesBitMapTEinfo.length;i++){ if (bytesBitMapTEinfo[i] != bytesBitMapTElink[i]) return true; } } return false; } /* private void printByte(byte[] bytes,String name){ if (bytes ==null){ System.out.println(name + " = null"); } else { System.out.print(name +": "); for (int i =0;i<bytes.length;i++){ if((bytes[i]&0xFF)<=0x0F){ System.out.print("0"+Integer.toHexString(bytes[i]&0xFF)); }else{ System.out.print(Integer.toHexString(bytes[i]&0xFF)); } } System.out.println(); } } */ }