Commit a9cd0174 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Support for using the delay agent with linkdelays (which means running

on end nodes). Add support for lans (only duplex links were really
supported). Finish up simplex vs duplex stuff wrt the delay_mapping
file. Some cleanup, but this program needs a total rewrite and I was
not in the mood.
parent 65b17f18
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2002 University of Utah and the Flux Group.
* All rights reserved.
*/
/*
* agent-callback-dummy.c --
*
* Delay node agent callback handling.
*/
/******************************* INCLUDES **************************/
#include "main-d.h"
/******************************* INCLUDES **************************/
/******************************* EXTERNS **************************/
extern structlink_map link_map[MAX_LINKS];
extern int link_index;
extern int s_dummy;
/******************************* EXTERNS **************************/
/********************************FUNCTION DEFS *******************/
/*************************** agent_callback **********************
This function is called from the event system when an event
notification is recd. from the server. It checks whether the
notification is valid (sanity check). If not print a warning,else
call handle_pipes which does the rest of thejob
*************************** agent_callback **********************/
void agent_callback(event_handle_t handle,
event_notification_t notification, void *data)
{
#define MAX_LEN 50
char objname[MAX_LEN];
char eventtype[MAX_LEN];
int l_index = -1;
#ifdef DEBUG
info ("entering callback \n");
#endif
/* get the name of the object, eg. link0 or link1*/
if(event_notification_get_string(handle,
notification,
"OBJNAME", objname, MAX_LEN) == 0){
error("could not get the objname \n");
return;
}
/* check we are handling the objectname for which we have recd an event */
if ((l_index = check_object(objname)) == -1){
error("not handling events for this object\n");
return;
}
/* get the eventtype, eg up/down/modify*/
if(event_notification_get_string(handle,
notification,
"EVENTTYPE", eventtype, MAX_LEN) == 0){
error("could not get the eventtype \n");
return;
}
/* call function to handle this event for this object */
handle_event(objname, eventtype, notification,handle);
#ifdef DEBUG
info ("exiting callback \n");
#endif
return;
}
/******************** handle_pipes ***************************************
******************** handle_pipes ***************************************/
void handle_event (char *objname, char *eventtype,
event_notification_t notification, event_handle_t handle)
{
#ifdef DEBUG
info ("entering handle_event \n");
#endif
if(strcmp(eventtype, TBDB_EVENTTYPE_UP) == 0){
handle_link_up(objname);
}
else if(strcmp(eventtype, TBDB_EVENTTYPE_DOWN) == 0){
handle_link_down(objname);
}
else if(strcmp(eventtype, TBDB_EVENTTYPE_MODIFY) == 0){
handle_link_modify(objname, handle, notification);
}
else error("unknown link event type\n");
#ifdef DEBUG
info ("exiting handle_event \n");
#endif
}
void handle_link_up(char * linkname){
#ifdef DEBUG
info ("entering handle_link_up \n");
#endif
info("recd. UP event for link = %s\n", linkname);
#ifdef DEBUG
info ("exiting handle_link_up \n");
#endif
}
void handle_link_down(char * linkname)
{
#ifdef DEBUG
info ("entering handle_link_down \n");
#endif
info("recd. DOWN event for link = %s\n", linkname);
#ifdef DEBUG
info ("exiting handle_link_down \n");
#endif
}
void handle_link_modify(char *linkname, event_handle_t handle,
event_notification_t notification)
{
char argvalue[50];
char * argtype;
int bw = 0, delay = 0;
#ifdef DEBUG
info ("entering handle_link_modify \n");
#endif
info("recd. MODIFY event for link = %s\n", linkname);
if(event_notification_get_string(handle,
notification,
"ARGS", argvalue, 50) != 0){
argtype = strtok(argvalue,"=");
if(strcmp(argtype,"BANDWIDTH")== 0){
bw = atoi(strtok(NULL," "));
info("Bandwidth = %d \n", bw);
}else if (strcmp(argtype,"DELAY")== 0){
delay = atoi(strtok(NULL," "));
info("Delay = %d \n", delay);
}else error("unrecognized argument\n");
}
#ifdef DEBUG
info ("exiting handle_link_modify \n");
#endif
}
int check_object (char *objname)
{
return search(objname);
}
/*********************** search ********************************
This function does a linear search on the link_map and returns
the index of the link_map entry which matches with the objectname
from the event notification
There will hardly be a few entries in this table, so we dont need
anything fancier than a linear search.
*********************** search ********************************/
int search(char* objname){
/* for now we do a linear search, maybe bin search later*/
int i;
for(i = 0; i < link_index; i++){
if(strcmp(link_map[i].linkname, objname) == 0)
return i;
}
return -1;
}
This diff is collapsed.
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2002 University of Utah and the Flux Group.
* All rights reserved.
*/
/* AGENT-MAIN-DUMMY.H*/
#ifndef _AGENT_MAIN_DUMMY_H_
#define _AGENT_MAIN_DUMMY_H_
#if 0
#include <ctype.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include "event.h"
#include <stdio.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "event.h"
#include "tbdefs.h"
#include "log.h"
#if 0
#include "tbdb.h"
#endif
#if 0
/* these are defined in testbed/lib/libtb/tbdb.h, will include
that directory later and then throw out these defines
*/
#define TBDB_OBJECTTYPE_LINK "LINK"
#define TBDB_EVENTTYPE_UP "UP"
#define TBDB_EVENTTYPE_DOWN "DOWN"
#define TBDB_EVENTTYPE_MODIFY "MODIFY"
#endif
/*************************INCLUDES******************************************/
/**************************DEFINES******************************************/
#define MAX_LINE_LENGTH 256
#define MAX_LINKS 4 /* 4 simplex or 2 duplex, since we have 4 interfaces
on delay nodes*/
/**************************DEFINES******************************************/
/*************************USER DEFINED TYPES********************************/
#define PIPE_QSIZE_IN_BYTES 0x0001
#define PIPE_Q_IS_RED 0x0002
#define PIPE_Q_IS_GRED 0x0004
#define PIPE_HAS_FLOW_MASK 0x0008
/* Parameters for RED and gentle RED*/
typedef struct {
/* from ip_dummynet.h*/
int w_q ; /* queue weight (scaled) */
int max_th ; /* maximum threshold for queue (scaled) */
int min_th ; /* minimum threshold for queue (scaled) */
int max_p ; /* maximum value for p_b (scaled) */
} structRed_params;
/* Pipe parameter structures*/
typedef struct {
int delay; /* pipe delay*/
int bw; /* pipe bw*/
int plr; /* queue loss rate*/
int q_size; /* queuq size in slots/bytes*/
structRed_params red_gred_params; /* red/gred params*/
#if REAL_WORLD
struct ipfw_flow_id id ; /* flow mask of the pipe*/
#endif
int buckets; /* number of buckets*/
int n_qs; /* number of dynamic queues */
u_short flags_p;
}structpipe_params, *structpipe_params_t;
/* This structure maps the linkname (eg. link0 ) to the physical
interfaces(eg. fxp0) and to the pipe numbers created at the start of
the experiment.
Later as events are recd. this table tells which pipe configuration should
be modified
*/
typedef struct {
char *linkname; /*link0, link1 etc*/
char *interfaces[2];/* fxp0, fxp1 etc*/
char *linktype; /*simplex, duplex */
int pipes[2]; /* array of pipe numbers*/
structpipe_params params[2]; /* params for the two pipes*/
}structlink_map, * structlink_map_t;
/*************************USER DEFINED TYPES********************************/
/******************************Function prototypes******************************/
void usage(char *);
void fill_tuple(address_tuple_t);
void agent_callback(event_handle_t handle,
event_notification_t notification, void *data);
void handle_event(char* , char* , event_notification_t ,event_handle_t);
void handle_link_modify(char *objname, event_handle_t handle,
event_notification_t notification);
void handle_link_up (char* linkname);
void handle_link_down (char* linkname);
int check_object(char* objname);
int search(char * objname);
void dump_link_map();
/******************************Function prototypes******************************/
#endif /*__AGENT_MAIN_DUMMY_H*/
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2002 University of Utah and the Flux Group.
* Copyright (c) 2000-2003 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -48,6 +48,12 @@ int s_dummy;
/* agent IP address */
char *ipaddr = NULL;
/* my pid/eid for event subscription */
char *myexp = NULL;
/* The list of linknames in tuple format, for the event subscription */
char myobjects[1024];
int debug = 0;
char buf_link [MAX_LINKS][MAX_LINE_LENGTH];
......@@ -78,7 +84,7 @@ int main(int argc, char **argv)
opterr = 0;
/* get params from the optstring */
while ((c = getopt(argc, argv, "s:p:f:d")) != -1) {
while ((c = getopt(argc, argv, "s:p:f:dE:")) != -1) {
switch (c) {
case 'd':
debug++;
......@@ -92,6 +98,9 @@ int main(int argc, char **argv)
case 'f':
map_file = optarg;
break;
case 'E':
myexp = optarg;
break;
case '?':
default:
usage(argv[0]);
......@@ -120,21 +129,60 @@ int main(int argc, char **argv)
char * temp = NULL;
char *sep = " \n";
while(fgets(buf_link[link_index], 256, mp)){
while(fgets(buf_link[link_index], MAX_LINE_LENGTH, mp)){
temp = buf_link[link_index];
link_map[link_index].linkname = strsep(&temp, sep);
link_map[link_index].linktype = strsep(&temp, sep);
link_map[link_index].interfaces[0] = strsep(&temp, sep);
if(!strcmp(link_map[link_index].linktype,"duplex"))
{
link_map[link_index].interfaces[1] = strsep(&temp,sep);
link_map[link_index].pipes[0] = atoi(strsep(&temp,sep));
link_map[link_index].pipes[1] = atoi(strsep(&temp,sep));
}
else{
link_map[link_index].pipes[0] = atoi(strsep(&temp,sep));
if(!strcmp(link_map[link_index].linktype,"duplex")){
/*
* By convention, the first pipe is towards the switch if its
* a lan node delay. This is important cause of queue params,
* which we do not want to set on the pipe coming from the switch.
*/
link_map[link_index].vnodes[0] = strsep(&temp, sep);
link_map[link_index].vnodes[1] = strsep(&temp,sep);
link_map[link_index].interfaces[0] = strsep(&temp, sep);
link_map[link_index].interfaces[1] = strsep(&temp,sep);
link_map[link_index].pipes[0] = atoi(strsep(&temp,sep));
link_map[link_index].pipes[1] = atoi(strsep(&temp,sep));
sprintf(link_map[link_index].linkvnodes[0], "%s-%s",
link_map[link_index].linkname, link_map[link_index].vnodes[0]);
sprintf(link_map[link_index].linkvnodes[1], "%s-%s",
link_map[link_index].linkname, link_map[link_index].vnodes[1]);
if (!strcmp(link_map[link_index].vnodes[0],
link_map[link_index].vnodes[1])) {
link_map[link_index].islan = 1;
}
link_map[link_index].numpipes = 2;
}
else{
link_map[link_index].vnodes[0] = strsep(&temp, sep);
link_map[link_index].interfaces[0] = strsep(&temp, sep);
link_map[link_index].pipes[0] = atoi(strsep(&temp,sep));
sprintf(link_map[link_index].linkvnodes[0], "%s-%s",
link_map[link_index].linkname, link_map[link_index].vnodes[0]);
link_map[link_index].numpipes = 1;
}
/*
* Form the comma separated list of linkname for the subscription
* There are two objects, one for the lan, and one for lan-vnode.
*/
/* Do not have name yet, so add it to the string */
if (strlen(myobjects)) {
strcat(myobjects, ",");
}
sprintf(&myobjects[strlen(myobjects)], "%s,%s",
link_map[link_index].linkname,
link_map[link_index].linkvnodes[0]);
if(!strcmp(link_map[link_index].linktype,"duplex") &&
!link_map[link_index].islan) {
sprintf(&myobjects[strlen(myobjects)], ",%s",
link_map[link_index].linkvnodes[1]);
}
link_index++;
}
}
......@@ -258,19 +306,20 @@ void usage(char *progname)
void fill_tuple(address_tuple_t at)
{
#ifdef DEBUG
info("entering function fill_tuple\n");
#endif
/* fill the objectname, objecttype and the eventtype from the file*/
at->objname = ADDRESSTUPLE_ANY;
at->objname = myobjects;
at->objtype = TBDB_OBJECTTYPE_LINK;
at->eventtype = ADDRESSTUPLE_ANY;
at->host = ipaddr;
at->expt = myexp;
at->host = ADDRESSTUPLE_ANY;
info("tuple: %s -- %s\n", myobjects, myexp);
/*fill in other values, dont know what to fill in yet*/
at->site = ADDRESSTUPLE_ANY;
at->expt = ADDRESSTUPLE_ANY;
at->group= ADDRESSTUPLE_ANY;
at->scheduler = 0;
#ifdef DEBUG
......@@ -283,61 +332,44 @@ void fill_tuple(address_tuple_t at)
A debugging aid.*/
/***************************dump_link_map******************************/
void dump_link_map(){
int i;
int i,j;
for (i = 0; i < link_index; i++){
info ("================================================================\n");
info ("===============================================================\n");
info("linkname = %s\n", link_map[i].linkname);
info("interface[0] = %s \t interface[1] = %s\n", link_map[i].interfaces[0], link_map[i].interfaces[1]);
info("linktype = %s\n", link_map[i].linktype);
info("linkstatus = %d \n", link_map[i].stat);
info("pipes[0] = %d \t pipes[1] = %d \n", link_map[i].pipes[0], link_map[i].pipes[1]);
info ("--------------------------------------------------\n");
info("Pipe params.....\n");
info("Pipe 0 .....\n");
info("delay = %d, bw = %d plr = %f q_size = %d buckets = %d n_qs = %d flags_p = %d \n", link_map[i].params[0].delay, link_map[i].params[0].bw, link_map[i].params[0].plr, link_map[i].params[0].q_size, link_map[i].params[0].buckets, link_map[i].params[0].n_qs, link_map[i].params[0].flags_p);
if(link_map[i].params[0].flags_p & PIPE_Q_IS_RED){
info(" queue is RED min_th = %d max_th = %d w_q = %f max_p = %f\n",
link_map[i].params[0].red_gred_params.min_th,
link_map[i].params[0].red_gred_params.max_th,
link_map[i].params[0].red_gred_params.w_q,
link_map[i].params[0].red_gred_params.max_p);
}
else if(link_map[i].params[0].flags_p & PIPE_Q_IS_GRED){
info(" queue is GRED min_th = %d max_th = %d w_q = %f max_p = %f\n",
link_map[i].params[0].red_gred_params.min_th,
link_map[i].params[0].red_gred_params.max_th,
link_map[i].params[0].red_gred_params.w_q,
link_map[i].params[0].red_gred_params.max_p);
}else info(" queue is droptail\n");
info ("--------------------------------------------------\n");
info("Pipe 1 .....\n");
info("delay = %d, bw = %d plr = %f q_size = %d buckets = %d n_qs = %d flags_p = %d \n", link_map[i].params[1].delay, link_map[i].params[1].bw, link_map[i].params[1].plr, link_map[i].params[1].q_size, link_map[i].params[1].buckets, link_map[i].params[1].n_qs, link_map[i].params[1].flags_p);
if(link_map[i].params[1].flags_p & PIPE_Q_IS_RED){
info(" queue is RED min_th = %d max_th = %d w_q = %f max_p = %f\n",
link_map[i].params[1].red_gred_params.min_th,
link_map[i].params[1].red_gred_params.max_th,
link_map[i].params[1].red_gred_params.w_q,
link_map[i].params[1].red_gred_params.max_p);
info("numpipes = %d \n", link_map[i].numpipes);
info("islan = %d \n", link_map[i].islan);
for (j = 0; j < link_map[i].numpipes; j++) {
info("Pipe params:\n");
info("interface = %s\n", link_map[i].interfaces[j]);
info("pipe num = %d\n", link_map[i].pipes[j]);
info("vnode = %s\n", link_map[i].vnodes[j]);
info("delay = %d, bw = %d plr = %f\n", link_map[i].params[j].delay,
link_map[i].params[j].bw, link_map[i].params[j].plr);
info("q_size = %d buckets = %d n_qs = %d flags_p = %d\n",
link_map[i].params[j].q_size, link_map[i].params[j].buckets,
link_map[i].params[j].n_qs, link_map[i].params[j].flags_p);
if(link_map[i].params[j].flags_p & PIPE_Q_IS_RED){
info(" queue is RED min_th = %d max_th = %d w_q = %f max_p = %f\n",
link_map[i].params[j].red_gred_params.min_th,
link_map[i].params[j].red_gred_params.max_th,
link_map[i].params[j].red_gred_params.w_q,
link_map[i].params[j].red_gred_params.max_p);
}
else if(link_map[i].params[j].flags_p & PIPE_Q_IS_GRED){
info(" queue is GRED min_th = %d max_th = %d w_q = %f max_p = %f\n",
link_map[i].params[j].red_gred_params.min_th,
link_map[i].params[j].red_gred_params.max_th,
link_map[i].params[j].red_gred_params.w_q,
link_map[i].params[j].red_gred_params.max_p);
}
else info("queue is droptail\n");
info ("-----------------------------------------------------------\n");
}
else if(link_map[i].params[1].flags_p & PIPE_Q_IS_GRED){
info(" queue is GRED min_th = %d max_th = %d w_q = %f max_p = %f\n",
link_map[i].params[1].red_gred_params.min_th,
link_map[i].params[1].red_gred_params.max_th,
link_map[i].params[1].red_gred_params.w_q,
link_map[i].params[1].red_gred_params.max_p);
}else info(" queue is droptail\n");
info ("--------------------------------------------------\n");
}
}
/************************** FUNCTION DEFS *******************************/
/*
* EMULAB-COPYRIGHT
* Copyright (c) 2000-2002 University of Utah and the Flux Group.
* Copyright (c) 2000-2003 University of Utah and the Flux Group.
* All rights reserved.
*/
......@@ -79,7 +79,7 @@
/**************************DEFINES******************************************/
#define MAX_LINE_LENGTH 256
#define MAX_LINE_LENGTH 512
#define MAX_LINKS 4 /* 4 simplex or 2 duplex, since we have 4 interfaces
on delay nodes*/
/**************************DEFINES******************************************/
......@@ -130,7 +130,11 @@ typedef struct {
typedef struct {
char *linkname; /*link0, link1 etc*/
int islan; /* 1 if a lan, 0 if a duplex link */
int numpipes; /* 1 if a simplex pipe, 2 if a duplex pipe */
char *interfaces[2];/* fxp0, fxp1 etc*/
char *vnodes[2]; /* nodeA, nodeB*/
char linkvnodes[2][256]; /* link0-nodeA, link0-nodeB*/
char *linktype; /*simplex, duplex */
int pipes[2]; /* array of pipe numbers*/
structpipe_params params[2]; /* params for the two pipes*/
......@@ -150,8 +154,6 @@ void agent_callback(event_handle_t handle,
void handle_pipes (char *objname, char *eventtype, event_notification_t
,event_handle_t, int);
int checkevent (char *);
int search(char* objname);
int check_object(char* objname);
void handle_link_up(char * linkname, int l_index);
void handle_link_down(char * linkname, int l_index);
void handle_link_modify(char * linkname, int l_index,
......@@ -160,10 +162,10 @@ void handle_link_modify(char * linkname, int l_index,
int get_link_params(int l_index);
void get_flowset_params(struct dn_flow_set*, int, int);
void get_queue_params(struct dn_flow_set*,int, int);
void set_link_params(int l_index, int blackhole, int,int);
void set_link_params(int l_index, int blackhole, int);
int get_new_link_params(int l_index, event_handle_t handle,
event_notification_t notification,
int *, int*);
int *);
void dump_link_map();
int get_link_info();
/******************************Function prototypes******************************/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment