Ejemplos de Modelos en Matlab y NS-2 Jhon Jairo Padilla Aguilar, PhD. Ejemplo: Simulación de tráfico de paquetes hacia un Router en Matlab Objetivo del experimento • Analizar los retardos de los paquetes al pasar por routers con dos tipos de algoritmos de procesamiento de los datos. • La diferencia se identificó que iba en el módulo de clasificación de paquetes. • Se modeló el algoritmo de clasificación de paquetes en sus dos versiones (original y modificada) Estrategia Arquitectura Interna del Router Contar el número de operaciones de lectura de memoria que se realizan en cada módulo al pasar el paquete. El retardo se obtiene multiplicando el número de operaciones por los tiempos respectivos de cada tipo de operación IXP 1200 Parámetros del Procesador de Red Parámetro Valor Lsdram (tiempo de lectura sdram) 160 ns Lsram (tiempo de lectura sram) 80 ns Tamaño de palabra del procesador 32 bits Tiempos de Procesamiento ti =1Lsram ; (tiempo de verificación de la tabla 80ns hash - IntServ, IntServ6) te =2Lsram+ 32Lsdram ;(tiempo de enrutamiento de 5280ns paquete,es el mismo para IntServ e IntServ6) tcomp =10*Lsram (tiempo de comparación de la 800ns quíntupla para el proceso de resolución de colisiones) tq =10*Lsram (tiempo de lectura de la quíntupla 800ns para búsqueda de la tabla hash DFD del Proceso clasificación de paquetes en un Router DTE del proceso de clasificación de paquetes en un Router Llegada del paquete Sólo existe en los routers IntServ estándar. Para los routers IntServ6, estos pasos no existen 1. Lectura de la quíntupla (tq) 2. Cálculo del número hash (th) No existe la etiqueta 3. Búsqueda en tabla hash y verificación de colisión (tb para IntServ, ti para IntServ6) 6. Enrutamiento normal Beteffort Se encuentra etiqueta y no hay colisión 5. Enrutamiento del paquete (tc para ambas tecnologías) Se encuentra la etiqueta y hay colisión 4. Búsqueda en tabla de resolución de colisiones (tx’ para IPv4, tx para IPv6) Se resolvió la colisión Condiciones del experimento • Para este ejemplo se supone que hay un número de comunicaciones simultáneas (reserv) • Cada comunicación genera paquetes de una longitud fija que puede ser programada (longpaqu) • Los módulos reciben una traza en forma de matriz con los instantes de llegada de los paquetes Simulación de tráfico de paquetes hacia un Router • Se calcula el tiempo medio entre llegadas de paquetes (la5): lambda1=(64*1024)/(longpaqu); % % % lambda_i=lambda1*reserv; % % % la5=1/lambda_i; % % Xcin1=la5*1000; % % Donde lambda1 es la tasa media de llegadas de paquetes y longpaqu es la longitud del paquete. lambda_i es la tasa media de llegada de paquetes que dependerá del la cantidad de flujos ‘reserv’. la5 es el tiempo medio entre-llegada de paquetes dado en segundos. Escala de 1000 para obtener valores manejables. Generación de tiempos exponenciales • Una vez creado el tiempo medio entre-llegadas de paquetes Xcin1, se procede a generar los paquetes, como se muestra en el siguiente código: Pin=0; % Inicialización while Pin<paqord(1,1) % % Pin=Pin+1; % tone(Pin,1)=exprnd(Xcin1); % % % % end ttwo=cumsum(tone); % % % % % del contador. Realiza el conteo de uno en uno hasta el número máx. de paquetes 'paqord' Conteo de posición del vector La función R = EXPRND (MU) genera exponencialmente tiempos aleatorios con tiempo medio 'Xcin1' y son guardados en 'tone' La función CUMSUM(X) toma la matriz 'tone' sumando la fila siguiente con la anterior para obtener los tiempos de llegada de cada paquete y son guardados en la nueva matriz 'ttwo'. Generación del tráfico de entrada tthre=round(ttwo*scal); % Con la funcion ROUND(X) redondea al % entero más cercano y lo multiplica % por una escala de 1000 con el fin de % utilizar tiempos más manejables. ttotal=tthre(length(tthre));% Obtenemos el ultimo numero o ultimo % tiempo generado exponencialmente, % escalado y redondeado, determinando % el tiempo máximo en el que se genero % el último paquete. Corrección tiempos de llegadas % % % % % % % % % % % % % % % tone 0.020677 0.016708 0.011388 0.0011644 0.00032835 0.01677 0.001279 0.0026112 0.0047002 0.00064122 0.030458 0.0069445 . . ttwo tthre 0.020677 21 0.037385 37 0.048773 49 0.049938 50 * 0.050266 50 * 0.067036 67 0.068315 68 0.070926 71 0.075627 76 ** 0.076268 76 ** 0.10673 107 0.11367 114 % Observamos para este ejemplo que algunos tiempos se repiten en la columna 'three', 50 y el 76, esto se debe a que se escala y redondea los valores de la columna 'ttwo' al entero más cercano. Corrección tiempos de llegadas • El siguiente algoritmo corrige el anterior problema, Incrementa en uno los tiempos de llegada de paquetes que se repiten con el fin de que existan todos los paquetes solicitados por el usuario o predeterminado por el simulador. if tthre(1,1)==0 % si el el primer tiempo de llegada de % paquetes es cero, se coloca un uno con % fin de que exista el paquete % incrementa a uno y asi exista el paquete num3(1,1)=1; else Corrección tiempo de llegadas num3=tthre(1,1); end k=0; while k<=paqu-2 k=k+1; var=num3(k,1); % Inicializacion de conteo % del vector. de la posicion % % Se guardas en la variable 'var' el % primer tiempo a compara. var2=tthre(k+1,1); % Se guarda el siguiente tiempo de la % columna 'tthree' del valor a comparar if var2<=var % Si el primer tiempo 'var' es mayor e % igual que el siquiente tiempo de la % primera columna del vector 'tthre' y que % es guardado en 'var2' se incrementa en inc=var2+1; % uno 'inc= var2+1' y luego se crea una num3(k+1,1)=inc;% nuevo vector llamado 'num' y asi guardar % los tiempos actualizados. else % ahora si no se cumple la condicion num3(k+1,1)=... % 'if var2<=var' se guardara en el vector tthre(k+1,1);%directamente sin aumentar en uno ya que % quiere decir que no se repite estos % tiempos de llegada de paquetes. end end intime(:,1)=num3; intime(:,2)=longpaqu; % 'num3' es donde guarda la nueva matriz con lo tiempos de los paketes existentes, para esta linea se inicializa la matriz num3 con el primer tiempo de a matriz 'tthre'. Este while finaliza cuando se analizan todos los tiempos del vector 'tthre', se decrementa el total de paquetes en dos debido a que el programa analiza los tiempos de dos en dos. Por tanto se debe decrementar 'paqu' para no exceda las dimensiones de la matriz la matriz. Algoritmo de clasificación VARIABLES DE ENTRADA: -La variable simple paqord, que es el número de paquetes a simular. -Otra variable es la hashtab que es una matriz de reservas depurada, es decir, sin colisiones. Esta consta de dos columnas, en las cuales se encuentra almacenada la identificación de flujo correspondiente a cada reserva, además de una bandera que identifica la presencia o ausencia de colisiones respectivamente. -Y finalmente, una última variable de entrada es coltab que es la matriz de resolución de colisiones, la cual consta de dos columnas, en las cuales se encuentra almacenada la identificación de flujo correspondiente a cada reserva, así como la quíntupla que identifica a la misma respectivamente. VARIABLE DE SALIDA: La variable datatab es la matriz de datos obtenida de este subprograma, la cual consta de cuatro columnas que contienen datos de identificación de flujo, número de instrucciones de lectura en tabla Hash, número de instrucciones de lectura en la tabla de resolución de colisiones, e instrucciones de lectura de quíntupla. Esta última columna se refiere a cuantos flowid iguales tuvo que leer en la tabla de resolución de colisiones, antes de encontrar el indicado, organizados respectivamente para cada paquete procesado. hashn abs(1* (10000 1).* rand(1,1)) Algunos resultados obtenidos Simulador NS-2 • Es gratuito • Funciona sobre Linux • Es ampliamente utilizado • Permite simulaciones de redes compuestas de diferentes protocolos y dispositivos • Simula redes fijas e inalámbricas Componentes generales de una simulación en NS-2 • El programa simulador NS-2 • Características de la simulación (dadas en el archivo en TCL): • Topología de la red • Dispositivos que la componen • Protocolos usados en los dispositivos • Aplicaciones utilizadas • Graficadores de resultados • Planificación en el tiempo Archivo TCL (Características de la simulación) Simulador NS-2 • Resultados de la simulación: • Se almacenan en un archivo de texto plano • Los resultados pueden ser graficados por algún programa como Xgraph, NAM Resultados de la simulación (Tablas y/o gráficos) Cómo se especifican las características de la simulación? • Se describen en un archivo de texto plano con extensión “.tcl” • Se utiliza un lenguaje llamado TCL simple.tcl set $ns $ns $ns ns [new Simulator] at 1 “puts \“Hello World!\”” at 1.5 “exit” run swallow 74% ns simple.tcl Hello World! swallow 75% Los dispositivos • Se crean los dispositivos uno a uno #Creación de Nodos en Tcl: set n0 [$ns node] set n1 [$ns node] Topología de la red • Se describe la forma en que se interconectan los dispositivos mediante los enlaces #Creación de enlaces en Tcl: $ns duplex-link $n0 $n1 <bandwidth> <delay> <queue_type> <queue_type>: DropTail, RED, CBQ, FQ, SFQ, DRR Protocolos Utilizados • Para cada dispositivo se definen: • La capa de acceso (MAC): Ethernet, Token Ring, Wi-Fi, WiMAX, Zig-Bee, etc. • La capa de red se asume IP • La capa de transporte puede ser: TCP, UDP • La capa de Aplicación: • Generador de paquetes (algún comportamiento estadístico particular) • Sumidero de paquetes Aplicación Transporte Red Acceso Física #Creación de protocolos de la capa de transporte con Tcl: set udp [new Agent/UDP] $ns attach-agent $n0 $udp set tcp [new Agent/TCP] $ns attach-agent $n1 $tcp Definición de la capa MAC Aplicaciones utilizadas • Son las encargadas de generar los paquetes y recibirlos • Pueden tener diferentes comportamientos estadísticos: • • • • CBR: Tasa de bits constante Exponencial Poisson etc • Los receptores o sumideros permiten llevar estadísticas de los parámetros de interés. • Las estadísticas pueden ser graficadas posteriormente. #Creación de una aplicación CBR: set src [new Application/Traffic/CBR] #Creación de una aplicación Exponencial y otra Pareto on-off: set src [new Application/Traffic/Exponential] set src [new Application/Traffic/Pareto] Graficadores • Pueden ser de dos tipos: • Gráficas en dos dimensiones (Funciones) (Ej: XGRAPH) • Animaciones del envío de paquetes por la red (Ej: NAM) # Encabezado al final de la simulación $ns at 2.0 "finish" proc finish {} { global ns fd close $fd $ns flush-trace puts "running nam..." exec nam out.nam & exit 0 } $ns run Planificación en el tiempo • Se refiere a el orden en que suceden las cosas: • • • • • Inicio/Finalización de generación de paquetes de una aplicación Instante de inicio/final del movimiento de nodos (redes móviles) Trayectoria de los nodos Velocidad de los nodos Cálculo de parámetros de salida #Crear planificador de eventos: set ns [new Simulator] # Planificar eventos: $ns at <time> <event> <event>: any legitimate ns/tcl commands #Iniciar el planificador: $ns run Cómo extender NS-2 Metodología para crear nuevos protocolos y agentes Jhon Jairo Padilla Aguilar Recomendaciones Generales • Identifique qué es lo que quiere construir • Identifique los objetos de NS-2 que ya existen y que se modificarán para crear nuevos objetos. Esto debe hacerse analizando las clases existentes en NS-2. • Crear nuevos objetos que heredan las características de los objetos existentes de NS-2 y que son útiles para sus propósitos. Caminos para extender NS-2 • Hay dos formas de hacer los cambios a NS-2: • Cambiar en Otcl • Cambiar en C++ Cuál camino escoger? Escalabilidad vs Flexibilidad • Es tentador escribir toda la simulación en OTcl: • Beneficio: prototipado rápido • Costo: memoria + tiempo de ejecución • Solución • Controlar la granularidad de su objeto migrando métodos desde OTcl a C++ El Mérito de OTcl high Program size, complexity low OTcl C/C++ split objects • Ajusta suavemente la granularidad de los programas para un balance entre extensibilidad y desempeño • Tiene completa compatibilidad con los scripts de simulación existentes Tips de Granularidad de los objetos • Funcionalidad • Procesamiento por paquetes C++ • Código que cambia frecuentemente OTcl • Manejo de Datos • Estructuras de datos complejas C++ • Variables de configuración simples OTcl 1. Extender NS-2 con OTcl • Si usted no quiere compilar: • Coloque sus cambios en los archivos de simulación (.tcl) • Si quiere compilar: • Modifique el código • Para agregar nuevos archivos en la compilación: • Cambie el archivo Makefile (NS_TCL_LIB), tcl/lib/ns-lib.tcl • Re-compile Cómo agregar los nuevos archivos a NS-2: Crear nueva carpeta con los fuentes en OTcl ns-allinone Tcl8.3 TK8.3 OTcl tclcl ... tcl ex examples test validation tests mysrc msg.tcl ns-2 lib nam-1 C++ code mcast OTcl code ... Modificar archivos claves para compilación: • tcl/lib/ns-lib.tcl Class Simulator … source ../mysrc/msg.tcl • Makefile NS_TCL_LIB = \ tcl/mysrc/msg.tcl \ … • O también: cambiar Makefile.in, make distclean, entonces hacer ./configure --enable-debug , make depend and make 2. Extender NS-2 en C++ • Si sólo va a modificar código sin crear nuevos archivos de componentes: • Haga “make depend” • Re-compile • Si va a crear nuevos componentes: • Cambie el archivo “makefile” • Haga “make depend” • Re-compile Pasos • Decida la posición en la jerarquía de clases (de qué clase se derivará el nuevo componente?) • Cree la nueva cabecera de paquete (si es necesario) • Cree la clase en C++ (archivo.h) • Cree los métodos de la nueva clase (archivo.cc) • Defina las correspondencias con Otcl (si hay alguna) • Escriba el código Otcl (si hay alguno) • Construya (Build) y depure (debug) Ejemplo: Nuevo Agente, cabecera de paquete no cambia • Algoritmo Jump-Start de TCP: • Ventana de transmisión que cambia su ancho desde un valor mínimo al iniciar hasta un límite máximo si no hay pérdidas de paquetes Paso 1: Ubicar en la jerarquía de clases de NS-2 TclObject Handler NsObject Connector Queue Delay Agent DropTail RED TCP Reno SACK Classifier Trace AddrClassifier McastClasifier Enq Deq JS Drop Paso 2: Crear la nueva clase • New file: tcp-js.h class JSTCPAgent : public TcpAgent { public: virtual void set_initial_window() { cwnd_ = MAXWIN_; } private: int MAXWIN_; }; Paso 3: Crear los métodos de la nueva clase • New file: tcp-js.cc static JSTcpClass : public TclClass { public: JSTcpClass() : TclClass("Agent/TCP/JS") {} TclObject* create(int, const char*const*) { return (new JSTcpAgent()); } }; JSTcpAgent::JSTcpAgent() { bind(“MAXWIN_”, MAXWIN_); } Paso 4: Crear simulación en el script Tcl • Crear una instancia de jump-start TCP en su script tcl “tcp-js.tcl” • Fijar el valor de MAXWIN_ en el script tcl • Agregar “tcp-js.o” (el archivo objeto o compilado) en el archivo Makefile.in • Re-configurar, hacer “make depend” y recompilar • Ejecutar su script tcl “tcp-js.tcl” Creación de una Nueva cabecera de paquete Formato del paquete cmn header header data ip header tcp header rtp header trace header ... ts_ ptype_ uid_ size_ iface_ Pasos para la creación de la nueva cabecera de paquete • Crear una nueva estructura de cabecera • Habilitar el soporte de trazas de la nueva cabecera • Crear la clase estática para la correspondencia con OTcl (en el archivo packet.h) • Habilitar la nueva cabecera en OTcl (en el archivo tcl/lib/ns-packet.tcl) • Esto no aplica cuando usted agrega un nuevo campo en una cabecera existente! Ejemplo: Creación de un paquete Message y un Agente que lo procesa • Creación de una nueva cabecera de paquete para un mensaje de 64 bytes • Creación de un nuevo agente de transporte para procesar esta nueva cabecera Nueva cabecera de Paquete – Paso 1 • Crear la estructura de la cabecera struct hdr_msg { char msg_[64]; static int offset_; inline static int& offset() { return offset_; } inline static hdr_msg* access(Packet* p) { return (hdr_msg*) p->access(offset_); } /* per-field member functions */ char* msg() { return (msg_); } int maxmsg() { return (sizeof(msg_)); } }; Nueva cabecera de Paquete – Paso 2 • Crear la clase Cabecera del mensaje static class MessageHeaderClass : public PacketHeaderClass { public: MessageHeaderClass() : PacketHeaderClass("PacketHeader/Message", sizeof(hdr_msg)) { bind_offset(&hdr_msg::offset_); } } class_msghdr; Nueva cabecera de Paquete – Paso 3 • Habilitar las trazas (packet.h): enum packet_t { PT_TCP, …, PT_MESSAGE, PT_NTYPE // This MUST be the LAST one }; class p_info { …… name_[PT_MESSAGE] = “message”; name_[PT_NTYPE]= "undefined"; …… }; Nueva cabecera de Paquete – Paso 4 • Registrar la nueva cabecera (tcl/lib/ns-packet.tcl) foreach prot { { Common off_cmn_ } … { Message off_msg_ } } add-packet-header $prot Nueva cabecera de Paquete: Precaución • Algún código antiguo, e.g.: RtpAgent::RtpAgent() { …… bind(“off_rtp_”, &off_rtp); } …… hdr_rtp* rh = (hdr_rtp*)p->access(off_rtp_); • No siga este ejemplo! Creación del Agente: Message – Paso 1 TclObject NsObject Connector Queue Delay Agent DropTail RED TCP Reno Classifier Trace AddrClassifier McastClasifier Message Enq Deq SACK Drop Creación del Agente: Message – Paso 2 • Definición de la clase en C++ // Standard split object declaration static … class MessageAgent : public Agent { public: MessageAgent() : Agent(PT_MESSAGE) {} virtual int command(int argc, const char*const* argv); virtual void recv(Packet*, Handler*); }; Creación del Agente: Message – Paso 3 • Procesamiento del paquete: send int MessageAgent::command(int, const char*const* argv) { Tcl& tcl = Tcl::instance(); if (strcmp(argv[1], "send") == 0) { Packet* pkt = allocpkt(); hdr_msg* mh = hdr_msg::access(pkt); // We ignore message size check... strcpy(mh->msg(), argv[2]); send(pkt, 0); return (TCL_OK); } return (Agent::command(argc, argv)); } Creación del Agente: Message – Paso 4 • Procesamiento del paquete: receive void MessageAgent::recv(Packet* pkt, Handler*) { hdr_msg* mh = hdr_msg::access(pkt); // OTcl callback char wrk[128]; sprintf(wrk, "%s recv {%s}", name(), mh->msg()); Tcl& tcl = Tcl::instance(); tcl.eval(wrk); Packet::free(pkt); }