/** The number of bytes sent since the last_update time. */
uint32_t bytes_since;
+ /* Statistics below. */
+
+ /** The current number of flows. */
+ uint32_t num_flows;
+
+ /** The number of flows sending above 5KB/s. */
+ uint32_t num_flows_5k;
+
+ /** The number of flows sending above 10KB/s. */
+ uint32_t num_flows_10k;
+
+ /** The number of flows sending above 20KB/s. */
+ uint32_t num_flows_20k;
+
+ /** The number of flows sending above 50KB/s. */
+ uint32_t num_flows_50k;
+
+ /** The average flow rate. */
+ uint32_t avg_rate;
+
} common_accounting_t;
/** Determines the difference between two timeval structs (in seconds, with
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGHUP);
+ sigaddset(&signal_mask, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
#include "ratetypes.h" /* needs util and pthread.h */
#include "logging.h"
+#define PRINT_COUNTER_RESET (7)
+
extern uint8_t system_loglevel;
-static int printcounter = 8;
+static int printcounter = PRINT_COUNTER_RESET - 1;
+
+uint8_t do_enforcement = 0;
/**
* Called for each identity each estimate interval. Uses flow table information
}
if (printcounter <= 0) {
- printlog(LOG_WARN, "%d %.1f %.1f %.1f\n", local_rate, idealweight, ident->localweight, total_weight);
- printcounter = 8;
+ printlog(LOG_WARN, "%d %.1f %.1f %.1f %d %d %d %d %d %d ", local_rate, idealweight,
+ ident->localweight, total_weight, ftable->num_flows, ftable->num_flows_5k, ftable->num_flows_10k,
+ ftable->num_flows_20k, ftable->num_flows_50k, ftable->avg_rate);
+ printcounter = PRINT_COUNTER_RESET;
} else {
printcounter -= 1;
}
printf("FPS: Setting local limit to %d\n", ident->locallimit);
}
printlog(LOG_DEBUG, "%d Limit ID:%d\n", ident->locallimit, ident->id);
- printlog(LOG_WARN, "%d\n", ident->locallimit);
+
+ if (printcounter == PRINT_COUNTER_RESET) {
+ printlog(LOG_WARN, "%d\n", ident->locallimit);
+ }
snprintf(cmd, CMD_BUFFER_SIZE,
"/sbin/tc class change dev eth0 parent 1:%x classid 1:%x htb rate 8bit ceil %dbps quantum 1600",
ident->htb_parent, ident->htb_node, ident->locallimit);
- ret = system(cmd);
+ if (do_enforcement) {
+ ret = system(cmd);
- if (ret) {
- /* FIXME: call failed. What to do? */
+ if (ret) {
+ /* FIXME: call failed. What to do? */
+ printlog(LOG_CRITICAL, "***TC call failed?***\n");
+ }
}
break;
ident->leaves[i]->xid, ident->leaves[i]->xid,
(100 * ident->leaves[i]->drop_prob));
#endif
- ret = system(cmd);
+ if (do_enforcement) {
+ ret = system(cmd);
- if (ret) {
- /* FIXME: call failed. What to do? */
+ if (ret) {
+ /* FIXME: call failed. What to do? */
+ printlog(LOG_CRITICAL, "***TC call failed?***\n");
+ }
}
}
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGHUP);
+ sigaddset(&signal_mask, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
/* Determine the number of intervals we should wait before hitting the
struct in_addr src, dst;
char sip[22], dip[22];
+ /* Reset statistics. */
+ table->common->num_flows = 0;
+ table->common->num_flows_5k = 0;
+ table->common->num_flows_10k = 0;
+ table->common->num_flows_20k = 0;
+ table->common->num_flows_50k = 0;
+ table->common->avg_rate = 0;
+ /* End statistics. */
+
time_delta = timeval_subtract(now, table->common->last_update);
if (time_delta <= 0) {
maxflowrate = current->rate;
}
+ if (current->rate > 51200) {
+ table->common->num_flows_50k += 1;
+ table->common->num_flows_20k += 1;
+ table->common->num_flows_10k += 1;
+ table->common->num_flows_5k += 1;
+ table->common->num_flows += 1;
+ } else if (current->rate > 20480) {
+ table->common->num_flows_20k += 1;
+ table->common->num_flows_10k += 1;
+ table->common->num_flows_5k += 1;
+ table->common->num_flows += 1;
+ } else if (current->rate > 10240) {
+ table->common->num_flows_10k += 1;
+ table->common->num_flows_5k += 1;
+ table->common->num_flows += 1;
+ } else if (current->rate > 5120) {
+ table->common->num_flows_5k += 1;
+ table->common->num_flows += 1;
+ } else {
+ table->common->num_flows += 1;
+ }
+
src.s_addr = ntohl(current->source_ip);
dst.s_addr = ntohl(current->dest_ip);
strcpy(sip, inet_ntoa(src));
current->rate);
}
+ if (table->common->num_flows > 0) {
+ table->common->avg_rate = table->common->rate / table->common->num_flows;
+ }
+
printlog(LOG_DEBUG, "FLOW:--\n--\n");
table->common->max_flow_rate = maxflowrate;
limiter_t limiter;
extern FILE *logfile;
extern uint8_t system_loglevel;
+extern uint8_t do_enforcement;
/* functions */
// Seems to take about 85ms / iteration
}
+static int stop_enforcement(drl_instance_t *instance) {
+ char cmd[300];
+ int i;
+
+ for (i = 0; i < instance->machine_count; ++i) {
+ sprintf(cmd, "/sbin/tc class change dev eth0 parent 1:%x classid 1:%x htb rate 8bit ceil 100mbit",
+ instance->machines[i]->htb_parent,
+ instance->machines[i]->htb_node);
+
+ if (execute_cmd(cmd)) {
+ return 1;
+ }
+ }
+
+ for (i = 0; i < instance->set_count; ++i) {
+ sprintf(cmd, "/sbin/tc class change dev eth0 parent 1:%x classid 1:%x htb rate 8bit ceil 100mbit",
+ instance->sets[i]->htb_parent,
+ instance->sets[i]->htb_node);
+
+ if (execute_cmd(cmd)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static void *signal_thread_func(void *args) {
int sig;
int err;
sigemptyset(&sigs);
sigaddset(&sigs, SIGHUP);
+ sigaddset(&sigs, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &sigs, NULL);
while (1) {
sigemptyset(&sigs);
sigaddset(&sigs, SIGHUP);
+ sigaddset(&sigs, SIGUSR1);
err = sigwait(&sigs, &sig);
case SIGHUP:
printlog(LOG_WARN, "Caught SIGHUP - re-reading XML file.\n");
reconfig();
- //time_reconfig(1000); //instrumentation
+ //time_reconfig(1000); /* instrumentation */
flushlog();
break;
+ case SIGUSR1:
+ pthread_rwlock_wrlock(&limiter.limiter_lock);
+ if (do_enforcement) {
+ do_enforcement = 0;
+ stop_enforcement(&limiter.stable_instance);
+ printlog(LOG_CRITICAL, "--Switching enforcement off.--\n");
+ } else {
+ do_enforcement = 1;
+ printlog(LOG_CRITICAL, "--Switching enforcement on.--\n");
+ }
+ pthread_rwlock_unlock(&limiter.limiter_lock);
+ break;
default:
- /* Should be impossible... */
+ /* Intentionally blank. */
break;
}
}
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGHUP);
+ sigaddset(&signal_mask, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
if (pthread_create(&signal_thread, NULL, &signal_thread_func, NULL) != 0) {