MODELOS DE PROCESO PADRE E HIJOS

Anuncio
IMPLEMENTACIÓN ALGORITMO RED
El objetivo del presente documento es el estudio de la implementación del algoritmo RED en
OPNET Modeler. De esta forma, se explicarán las distintas funciones y modelos de proceso para
llevar a cabo el algoritmo.
INTRODUCCIÓN
Antes de analizar el código de la implementación del algoritmo RED en OPNET vamos a tratar
dos aspectos muy importantes de los modelos de procesos.
MODELOS DE PROCESO PADRE E HIJOS
Todo modelo de proceso puede tener procesos hijos. Para poder acceder a ellos en OPNET ir al
editor de procesos y a continuación File → Open Child Open Process Model .
En este documento se trata el proceso de modelo “ip_dispatch” y su proceso hijo “ip_output_iface”.
Por lo tanto, para acceder al proceso ip_output_iface lo haremos de la forma anteriormente
explicada.
FICHEROS EXTERNOS
OPNET dispone de una serie de ficheros externos. Los modelos de proceso pueden llamar en su
código a funciones definidas e implementadas en estos ficheros externos. Para ver que ficheros
emplea el modelo de proceso ir a File → Declare External File.
OBJETO QoS ATTRIBUTE CONFIG
El objeto QoS Attribute Config permite definir perfiles de cola para cualquier disciplina QoS
( FIFO, WFQ, priority queuing , custom queuing) usada por los nodos IP en OPNET . La ventaja de
encontrar estos perfiles definidos en un objeto global es que simplemente tienes que hacer
referencia a él en cada uno de los objetos IP individuales.
Basandonos en FIFO Profile como ejemplo, podemos observar como dicho atributo posee una serie
de subatributos como son el “Profile Name” y “Details”. Desplegando “Details” se muestran
“Maximum Queue Size” y “RED Parameters”.
Estos dos últimos subatributos serán de gran interés para el análisis de la implementación del
algoritmo RED en OPNET Modeler. Si desplegamos “RED Parameters” podemos observar la
posibilidad de elegir entre RED, WRED, RED con ECN y WRED con ECN, también
implementados en OPNET.
Una vez visto donde podemos establecer el tamaño máximo de cola y los parametros RED vamos a
analizar más a fondo el objeto IP QoS pasando a su modelo de procesos
“qos_attribute_definer”.Una vez dentro haz clic sobre el botón Function Block.
Encontramos implementadas las siguientes funciones, para cada disciplina de cola:
static void attr_def_fifo_profiles_info_parse (void)
static void attr_def_wfq_profiles_info_parse (void)
static void attr_def_mwrr_profiles_info_parse (void)
static void attr_def_priority_queuing_profiles_info_parse (void)
static void attr_def_custom_queuing_profiles_info_parse (void)
Estas funciones sirven para parsear la información definida en los atributos compuestos tales como
“FIFO Profiles” o “Priority Queuing Profiles”. También crea instancias de una estructura de datos
denominada “QM Information”, reserva memoria para estas instancias y guarda la información
parseada en ellas. La estructura “QM Information” contiene para cada interfaz información general
acerca de sus colas.
Continuando
como
ejemplo
con “FIFO Profiles” , nos centraremos en static void
attr_def_fifo_profiles_info_parse(void) . Dentro de este código destacamos tres funciones a tener en
cuenta:
1. op_ima_obj_attr_get: sirve para poder leer los valores de los atributos establecidos en
el modelo de red.
2. attr_def_red_parameters_get: esta función esta definida en el propio FB que estamos
analizando. Sirve para obtener los Parametros RED y almacenarlos en la estructura “QM
Information”.
3. oms_data_def_entry_insert: se utiliza para almacenar toda la información en la
estructura “QM Information” denominada qm_attr_ptr.
oms_data_def_entry_insert ("FIFO Profiles", prof_name, qm_attr_ptr );
La estructura qm_attr_ptr de tipo OmsT_Qm_Attributes contiene los siguientes campos:
1.
2.
3.
4.
Número de colas en la interfaz: int no_queues
Cola por defecto para encolar los paquetes: int default_queue
Máximo numero de paquetes: int max_total_no_buf_pkts
Puntero a la estructura que almacena los criterios de clasificación: List
classification_list
5. Estructura que guarda los parametros de configuración de las colas: void
**queue_configuration
6. Nombre del perfil de cola de la interfaz : String name.
CONFIGURACIÓN DE LOS OBJETOS IP
Situate sobre el router ethernet4_slip8_gtwy y haz clic sobre el botón derecho del ratón. Ir al
atributo IP → IP QoS Parameters → Interface Information. Como podemos observar en QoS
Scheme tenemos el FIFO Profile. Recordamos que para obtener estos valores debemos realizar los
pasos siguientes: Selecciona el link entre los dos routers y haz clic en Protocols → IP → QoS →
Configure QoS del menú y elige como planificador la disciplina FIFO.
MODELO DE PROCESO IP_DISPACH
Una vez vistos los parámetros de configuración del router, nos centraremos a continuación en el
modelo de proceso “ip_dispach”. Para acceder a él solo tenemos que ir al modelo de nodos del
router , doble clic sobre nodo ip.
Haz doble clic sobre el botón Function Block
y vete a
la función static void
ip_rte_qos_information_process (void) donde se crea el proceso hijo “ip_output_iface”.
Los procesos padres e hijos disponen de memoria compartida entre ellos, por ello, en este método lo
primero que hace es almacenar en esta memoria (module_data), información sobre cada interfaz, los
paquetes enviados y descartados a los que luego ip_output_iface accederá cuando lo necesite.
A continuación obtiene una lista de QoS y de esta lista coge elemento a elemento,obteniendo de
cada elemento información de la estructura qm_attr_ptr (QM Information).
Otra de las operaciones realizadas en este método es la obtención del número de interfaces, creando
una tabla donde almacena el id de cada interfaz. Para cada interfaz inicializa QoS Parameters tales
como profile name, buffer_size, reserved_bandwitch (en intf_qos_info), Queuing Schemes (en
iface_info_ptr → queuing_scheme) , CAR y RED/WRED.
Solo nos queda lo más importante, la creación e invocación del modelo de proceso ip_output_iface,
que como vemos se creará y se invocará para cada interfaz.
iface_info_ptr-->output_iface_prohandle =op_pro_create("ip_output_iface",&module_data.shared_mem);
op_pro_invoke (iface_info_ptr->output_iface_prohandle, intf_qos_info);
MODELO DE PROCESO IP_OUTPUT_IFACE
Los pasos para acceder a este modelo de procesos son los que explicamos en la parte de
Introducción.
Analizemos las funciones definidas en este modelo de proceso como do_init(), allocate_buffers(),
o enqueue_packet( ).
Las dos primeras sirven para inicializar variables y estructuras. En do_init() obtiene
queuing_processing_scheme de tipo OmsT_Qm_Queuing_Scheme. Esta estructura, junto con
intf_qos_info_ptr, será usada en la función allocate_buffers() para crear la estructura qm_info la
cual es configurada para cada interfaz.
La estructura qm_info contendrá información general como el máximo número de paquetes en las
colas, número de colas en la interfaz etc.
Pero sobre todo hay que destacar la función enqueue_packet(void) donde nos encontramos el
siguiente código, usado para procesar el paquete que ha llegado a la interfaz:
Oms_Qm_Packet_Process(pkptr, qm_info, classify_func_ptr, &q_pool_ptr, &queue_id);
Esta función se encuentra en los ficheros externos de OPNET dentro del paquete oms_qm. Este
paquete soportará cada uno de los algoritmos variantes de RED.
El siguiente paso consiste en localizar oms_qm_packet_process en el fichero oms_qm.exe.c. El
código que nos guiará en la búsqueda de la implementación del algoritmo RED se muestra a
continuación:
OMSC_EXPORT void
Oms_Qm_Packet_Process (Packet *pkptr, OmsT_Qm_Info* qm_info,
OmsT_Qm_Classifier_Func_Ptr classify_func_ptr,
OmsT_Qm_Queue_Pool** sel_pool_pptr, int *enqueue_id_ptr)
{
OmsT_Qm_Queue_Pool*
qpool_ptr = OPC_NIL;
OmsT_Qm_Pkt_Info
pkt_info;
int
enq_id = OMSC_UNASSIGNED;
/** This functions determines classifier function and dispatches the packer to respective
enqueue procedures
**/
FIN (Oms_Qm_Packet_Process (<args>));
switch (qm_info- >queu e_pro c e s s i n g _ s c h e m e )
{
ca s e
ca s e
ca s e
ca s e
ca s e
ca s e
ca s e
ca s e
Om s C_Q m_ FI F O_Q u e uin g :
Om s C_Q m_ Priority_Qu e uin g :
Om s C_Q m_ C u s t o m _ Q u e u in g :
Om s C_Q m_W F Q_Q u e uin g :
Om s C_Q m_W R R_Qu e uin g :
Om s C_Q m_R R_Qu e uin g :
Om s C_Q m_DWRR_Qu e uin g :
Om s C_Q m_MDRR_Qu e uin g :
c a s e Om s C_Q m_MWR R_Qu e uin g :
{
qpool_ptr = qm_info->child_queue_pool_ptr;
/* Find the queue/pool to which this packet belongs */
pkt_info = classify_func_ptr (pkptr, &qpool_ptr, &enq_id);
*enqueue_id_ptr = enq_id;
if (enq_id == OMSC_UNASSIGNED)
{
/* Do not perform any further action if a queue was not selected.*/
qm_info->signal = OmsC_Qm_Dropped_Packet;
break;
}
/* Based on processor status, enqueue or send the packet */
/* Use the queue pool obtained from classifier results.
*/
Om s_Q m_In c o m i n g_ P a c k e t _H a n d l er (pkptr, qm_info, qpool_ptr,
enq_id, pkt_info);
/*Update
queuing
scheme
specific
variables
on
enqueue*/
if (OMS_QSCHEME_VARS_UPDATE_ENQ_FUNC (qm_info->queue_processing_scheme) !
=OPC_NIL)
(OMS_QSCHEME_VARS_UPDATE_ENQ_FUNC (qm_info->
queue_processing_scheme))(pkptr, qm_info, qpool_ptr, enq_id);
break;
}
caseOmsC_Qm_No_Queuing:
{
qm_info->signal=OmsC_Qm_Send_Packet;
break;
}
default:break;
}
*(sel_pool_pptr)=qpool_ptr;
FOUT;
}
Para todas las disciplinas se ejecutará el código implementado bajo el case
OmsC_Qm_MWRR_Queuing. Dentro de este código se llama a la función
Om s_Q m_In c o m i n g_ P a c k e t _H a n d l er (pkptr, qm_info, qpool_ptr, enq_id, pkt_info); implementada
en el mismo fichero oms_qm.exe.c. Dentro de esta función vemos el proceso para enconlar el
paquete en el buffer de la forma:
insert_ok= Oms_Qm_Packet_Enqueue(pkptr, qm_info, q_info_ptr, pkt_info, current_time,
enqueue_q_id);
La función Oms_Qm_Packet_Enqueu también se encuentra definida en el fichero oms_qm.exe.c
cuyo código se muestra a continuación:
OMSC_EXPORT Boolean Oms_Qm_Packet_Enqueue (Packet* pkptr, OmsT_Qm_Info*
qm_info, OmsT_Qm_Queue_Info* q_info_ptr, OmsT_Qm_Pkt_Info pkt_info, double insert_time,
int PRG_ARG_UNUSED (enqueue_q_id))
{
/** Enqueues packets in the correct subqueue according to the **/
/** criterion described by the passed in function. It also
**/
/** checks if it is a state of congestion. In this case the
**/
/** queuing policy to restrain the size of queue is enforced.
**/
/** It returns a TRUE if the insertion succeeds, FALSE
**/
/** otherwise.
**/
FIN (Oms_Qm_Packet_Enqueue (pkptr, qm_info, function_ptr, warning_message,
queue_id));
if ((OMS_E N Q_T E S T _ F U N C (qm_info- >arch_typ e)) (qm_info,
q_info_ptr, pkptr,
pkt_info)==Om s C _ B u ff e r_In s e r t_Aft er )
{
if (oms_buffer_enqueue (q_info_ptr->buffer_handle, pkptr,
OPC_NIL,insert_time)!=OmsC_Buffer_Enqueue_Success)
{
FRET(OPC_FALSE);
}
}
else {
FRET(OPC_FALSE);
}
FRET(OPC_TRUE);
}
El código destacado en negrita nos lleva a una macro definida en la librería oms_qm.h :
#define OMS_ENQ_TEST_FUNC(arch_type)((OmsT_Qm_Enqueue_Test_Func)\
OmsI_Arch_Specific_Func_Table [arch_type] [OmsC_Qm_Enqueue_Test_Func])
A
continuación
abre
el
fichero
ip_qos_support.exe.c.
En
la
función
ip_qos_sup_functions_register(void) se lleva a cabo el registro de funciones. En la tabla
OmsI_Arch_Specific_Func_Table
cuyos
indices
son
OmsC_Qm_IP
y
OmsT_Qm_Enqueue_Test_Func la función es ip_qos_packet_enqueue_test.
OmsI_Arch_Specific_Func_Table [OmsC_Qm_IP][OmsC_Qm_Enqueue_Test_Func]=
(OmsT_Qm_Arch_Void_Func ) ip_qos_packet_enqueue_test;
Por eso nuestro siguiente paso es buscar la función ip_qos_packet_enqueue_test definida e
implementada en el fichero ip_qos_support.exe.c
En ip_qos_packet_enqueue_test se llama a las dos funciones que desarrollan el algoritmo RED en
los dos siguientes pasos:
1. Calcula el tamaño medio de cola.
Oms_Qm_Average_Queue_Size_Update
2. Establece si RED necesita descartar el paquete.
red_drop_status=oms_qm_red_packet_drop
if (red_drop_status==OPC_TRUE) {
pkt_drop=OPC_TRUE
}
Las dos funciones nombradas anteriormente que implementan el algoritmo RED se encuentran en el
fichero oms_qm.exe.c
Descargar