Commit 1529f157 authored by Leigh B Stoller's avatar Leigh B Stoller

Brutalize to use ipfw command line interface when > FreeBSD 8.

The socket interface changed and rather rewrite this client or try to
figure out how to finish the "new" client, I whacked the crap out of
this to use ipfw. This is of course more fragile since it depends on
the input language of ipfw, and the especially the output from ipfw to
determine the current settings. When upgrading, we must be sure to
test this.
parent 7c6a2dd3
/*
* Copyright (c) 2000-2008 University of Utah and the Flux Group.
* Copyright (c) 2000-2012 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -114,8 +114,7 @@ void handle_pipes (char *objname, char *eventtype,
else error("unknown link event type\n");
if(debug){
system ("echo ======================================== >> /tmp/ipfw.log");
system("(date;echo PARAMS ; ipfw pipe show all) >> /tmp/ipfw.log");
system("ipfw pipe show");
}
}
......@@ -137,7 +136,7 @@ void handle_link_up(char * linkname, int l_index)
/* no need to do anything if link is already up*/
if(link_map[l_index].stat == LINK_UP)
return;
link_map[l_index].stat = LINK_UP;
set_link_params(l_index, 0, -1);
}
......@@ -222,6 +221,7 @@ void handle_link_modify(char * linkname, int l_index,
get_new_link_params(l_index, handle, notification, &p_which);
}
#ifdef USESOCKET
/* link field changed in 6.1 */
#if __FreeBSD_version >= 601000
#define DN_PIPE_NEXT(p) ((p)->next.sle_next)
......@@ -581,6 +581,188 @@ void set_link_params(int l_index, int blackhole, int p_which)
}
}
}
#else
int get_link_params(int l_index)
{
int p_index = 0;
int pipeno;
char _buf[BUFSIZ], *cp;
FILE *cfd;
for (p_index = 0; p_index < link_map[l_index].numpipes; p_index++) {
pipeno = link_map[l_index].pipes[p_index];
structpipe_params *p_params =
&(link_map[l_index].params[p_index]);
sprintf(_buf, "%s pipe %d show", IPFW, pipeno);
if ((cfd = popen(_buf, "r")) == NULL) {
error("Could not start ipfw for pipe %d\n", pipeno);
return -1;
}
/*
* The first line is bw/delay. It looks like:
* 60120: 100.000 bit/s 0 ms burst 0
* or
* 60120: unlimited 0 ms burst 0
*/
if (fgets(_buf, sizeof _buf, cfd) == NULL) {
error("No first line from ipfw for pipe %d\n", pipeno);
return -1;
}
int tpipeno, delay;
float bw = 0.0;
char bwspec[16], delayunits[10];
bzero(bwspec, sizeof(bwspec));
if (sscanf(_buf, "%d: unlimited %d %10s",
&tpipeno, &delay, delayunits) != 3 &&
sscanf(_buf, "%d: %f %16s %d %10s",
&tpipeno, &bw, bwspec, &delay, delayunits) != 5) {
error("Could not parse '%s'\n", _buf);
return -1;
}
if (tpipeno != pipeno) {
error("Bad pipeno: %d!=%d\n", pipeno, tpipeno);
}
/*
* The second line has slot/plr info
*/
if (fgets(_buf, sizeof _buf, cfd) == NULL) {
error("No second line from ipfw for pipe %d\n", pipeno);
return -1;
}
int qsize;
float plr;
char qspec[16];
if (sscanf(_buf, "q%d %d %16s %f",
&tpipeno, &qsize, qspec, &plr) != 4) {
error("Could not parse '%s'\n", _buf);
return -1;
}
if (strncmp(qspec, "KB", 2) && strncmp(qspec, "sl", 2)) {
error("Could not parse slot type '%s'\n", qspec);
return -1;
}
/* plr is optional, and there are no spaces after Q spec. */
if (strstr(qspec, "plr") == NULL) {
plr = 0.0;
}
/*
* Next line might be optional RED/GRED stuff.
*/
if (fgets(_buf, sizeof _buf, cfd) == NULL) {
error("No third line from ipfw for pipe %d\n", pipeno);
return -1;
}
if ((cp = strstr(_buf, "RED"))) {
double w_q;
int max_th;
int min_th;
double max_p;
char *ccp = strchr(cp, ' ');
*ccp = '\0';
ccp++;
if (sscanf(ccp, "w_q %lf min_th %d max_th %d max_p %lf",
&w_q, &min_th, &max_th, &max_p) != 4) {
error("Could not parse RED '%s'\n", ccp);
return -1;
}
if (strstr(_buf, "GRED")) {
p_params->flags_p |= PIPE_Q_IS_GRED;
}
else {
p_params->flags_p |= PIPE_Q_IS_RED;
}
p_params->red_gred_params.w_q = w_q;
p_params->red_gred_params.max_p = max_p;
p_params->red_gred_params.min_th = min_th;
p_params->red_gred_params.max_th = max_th;
}
else {
p_params->flags_p &= ~(PIPE_Q_IS_RED|PIPE_Q_IS_GRED);
}
pclose(cfd);
p_params->delay = delay;
#if !defined(USESOCKET) && (__FreeBSD_version >= 800000 && __FreeBSD_version < 803000)
/*
* Whacky hack for a bug in ipfw that results in the
* delay not being converted back into milliseconds.
*/
if (delay) {
p_params->delay = p_params->delay * 1000 / kern_hz;
}
#endif
p_params->bw = bw;
strcpy(p_params->bwspec, bwspec);
p_params->plr = plr;
p_params->q_size = qsize;
if (strncmp(qspec, "KB", 2) == 0) {
p_params->flags_p |= PIPE_QSIZE_IN_BYTES;
}
else {
p_params->flags_p &= ~PIPE_QSIZE_IN_BYTES;
}
}
return 1;
}
void set_link_params(int l_index, int blackhole, int p_which)
{
int p_index;
for (p_index = 0; p_index < link_map[l_index].numpipes; p_index++) {
structpipe_params *p_params;
int pipeno;
char cmd[BUFSIZ];
/*
* Want to do all the pipes, or just the one pipe that was
* specified.
*/
if (! (p_which == -1 || p_which == p_index))
continue;
/* get the params stored in the link table*/
p_params = &(link_map[l_index].params[p_index]);
pipeno = link_map[l_index].pipes[p_index];
if (debug)
info("entered the loop, pindex=%d, pipe=%d\n",
p_index, pipeno);
sprintf(cmd, "%s pipe %d config delay %dms bw %f%s plr %lf "
"queue %d%s ",
IPFW, pipeno, p_params->delay,
p_params->bw, p_params->bwspec,
(blackhole ? 1.0 : p_params->plr),
(p_params->flags_p &
PIPE_QSIZE_IN_BYTES ?
p_params->q_size / 1000 : p_params->q_size),
(p_params->flags_p &
PIPE_QSIZE_IN_BYTES ? "KBytes" : ""));
if (p_params->flags_p & (PIPE_Q_IS_GRED|PIPE_Q_IS_RED)) {
/* set GRED params */
sprintf(cmd + strlen(cmd), " %s %lf/%d/%d/%lf ",
(p_params->flags_p & PIPE_Q_IS_GRED ?
"gred" : "red"),
p_params->red_gred_params.w_q,
p_params->red_gred_params.min_th,
p_params->red_gred_params.max_th,
p_params->red_gred_params.max_p);
}
if (debug)
info("%s\n", cmd);
if (system(cmd)) {
error("ipfw failed: '%s'\n", cmd);
}
}
}
#endif
/********* get_new_link_params ***************************
For a modify event, this function gets the parameters
......@@ -634,8 +816,13 @@ int get_new_link_params(int l_index, event_handle_t handle,
if (! gotpipe) {
link_map[l_index].params[1].bw = link_map[l_index].params[0].bw;
}
#ifndef USESOCKET
strcpy(link_map[l_index].params[p_num].bwspec, "Kbits/s");
if (! gotpipe) {
strcpy(link_map[l_index].params[1].bwspec, "Kbits/s");
}
#endif
}
else if (strcmp(argtype,"DELAY")== 0){
info("Delay = %d\n", atoi(argvalue));
link_map[l_index].params[p_num].delay = atoi(argvalue);
......
/*
* Copyright (c) 2000-2011 University of Utah and the Flux Group.
* Copyright (c) 2000-2012 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -29,13 +29,7 @@
*/
/*********************************INCLUDES********************************/
#define REAL_WORLD 1
#if REAL_WORLD
#include "main.h"
#else
#include "main-d.h"
#endif
#include "main.h"
/*********************************INCLUDES********************************/
/************************GLOBALS*****************************************/
......@@ -80,6 +74,11 @@ void reset_callback(event_handle_t handle,
event_notification_t notification, void *data);
char *myvnode;
/* Whacky ipfw bug work around */
#ifndef USESOCKET
int kern_hz;
#endif
int main(int argc, char **argv)
{
char c;
......@@ -92,10 +91,7 @@ int main(int argc, char **argv)
FILE *mp = NULL;
//char *log = NULL;
char buf[BUFSIZ];
#if REAL_WORLD
char ipbuf[BUFSIZ];
#endif
opterr = 0;
......@@ -233,13 +229,32 @@ int main(int argc, char **argv)
/* create a raw socket to configure Dummynet through setsockopt*/
#if REAL_WORLD
#ifdef USESOCKET
s_dummy = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
if ( s_dummy < 0 ){
error("cant create raw socket\n");
return 1;
}
#endif
#if !defined(USESOCKET) && (__FreeBSD_version >= 800000 && __FreeBSD_version < 803000)
/*
* Whacky hack for a bug in ipfw that results in the delay not being
* converted back into milliseconds.
*/
{
size_t len = sizeof(int);
if (sysctlbyname("kern.hz", &kern_hz, &len, NULL, 0) == -1) {
error("cannot get kern.hz from kernel");
return 1;
}
if (kern_hz == 0) {
error("kern.hz must greater than zero");
return 1;
}
info("kern.hz is %d\n", kern_hz);
}
#endif
/* this gets the current pipe params from dummynet and populates
the link map table
*/
......@@ -251,7 +266,6 @@ int main(int argc, char **argv)
/* dump the link_map to log*/
dump_link_map();
/*
* Get our IP address. Thats how we name ourselves to the
* Testbed Event System.
......@@ -273,7 +287,7 @@ int main(int argc, char **argv)
strcpy(ipbuf, inet_ntoa(myip));
ipaddr = ipbuf;
}
#endif
/*
* Write out a pidfile.
*/
......@@ -413,7 +427,7 @@ void dump_link_map(){
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);
(int)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);
......
/*
* Copyright (c) 2000-2003 University of Utah and the Flux Group.
* Copyright (c) 2000-2012 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -76,6 +76,15 @@
#include "tbdefs.h"
#include "log.h"
/*
* After 8.0, everything changed!
*/
#if __FreeBSD_version < 800000
#define USESOCKET 1
#else
#define IPFW "ipfw"
extern int kern_hz;
#endif
#if 0
#include "tbdb.h"
......@@ -127,7 +136,12 @@ typedef enum {
/* Pipe parameter structures*/
typedef struct {
int delay; /* pipe delay*/
#ifdef USESOCKET
int bw; /* pipe bw*/
#else
float bw;
char bwspec[16];
#endif
int backfill; /*pramod-CHANGES, -add backfill to the pipe*/
double plr; /* queue loss rate*/
int q_size; /* queuq size in slots/bytes*/
......@@ -135,7 +149,7 @@ typedef struct {
struct ipfw_flow_id id ; /* flow mask of the pipe*/
int buckets; /* number of buckets*/
int n_qs; /* number of dynamic queues */
u_short flags_p;
u_short flags_p;
}structpipe_params, *structpipe_params_t;
/* This structure maps the linkname (eg. link0 ) to the physical
......@@ -158,7 +172,6 @@ structpipe_params params[2]; /* params for the two pipes*/
enumlinkstat stat; /* link status : UP/DOWN*/
}structlink_map, * structlink_map_t;
/*************************USER DEFINED TYPES********************************/
......@@ -177,8 +190,10 @@ void handle_link_modify(char * linkname, int l_index,
event_handle_t handle,
event_notification_t notification);
int get_link_params(int l_index);
#ifdef USESOCKET
void get_flowset_params(struct dn_flow_set*, int, int);
void get_queue_params(struct dn_flow_set*,int, int);
#endif
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,
......
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