Commit f472879e authored by Leigh Stoller's avatar Leigh Stoller

Implement dynamic delay for linux using the same strategy as freebsd;

call tc qdisc/class command lines. Had to implement a perl script to get
the current delay parameters cause parsing all that stuff in C is too
much of a pain, sorry Mike. Reshuffle a few things around since we are
now going to install delay-agent and rc.delayagent on linux.
parent dc852a4b
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -31,7 +31,7 @@ include $(OBJDIR)/Makeconf
SUBDIRS = program-agent link-agent tevc proxy bs-agent linktest
ifeq ($(SYSTEM),Linux)
SUBDIRS += disk-agent
SUBDIRS += disk-agent delay-agent
endif
ifneq ($(SYSTEM),CYGWIN_NT-5.1)
ifneq ($(ARCH),aarch64)
......
#
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -36,6 +36,7 @@ CFLAGS += -O -g -Wall
CFLAGS += -I. -I$(TESTBED_LIBSRCDIR)/libtb
CFLAGS += -I$(TESTBED_LIBSRCDIR)/event
CFLAGS += -I/usr/local/include
CFLAGS += -DCLIENT_BINDIR='"$(CLIENT_BINDIR)"'
LDFLAGS += $(LDSTATIC)
LDFLAGS += -L${TESTBED_LIBOBJDIR}/libtb -L${TESTBED_LIBOBJDIR}/event
......
/*
* Copyright (c) 2000-2012 University of Utah and the Flux Group.
* Copyright (c) 2000-2016 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -114,7 +114,10 @@ void handle_pipes (char *objname, char *eventtype,
else error("unknown link event type\n");
if(debug){
#ifdef linux
#else
system("ipfw pipe show");
#endif
}
}
......@@ -582,6 +585,165 @@ void set_link_params(int l_index, int blackhole, int p_which)
}
}
#else
#if defined(linux)
int get_link_params(int l_index)
{
char _buf[BUFSIZ], bwspec[16];
char *linkname = link_map[l_index].linkname;
FILE *cfd;
int delay, qlen, bw;
float plr;
bzero(bwspec, sizeof(bwspec));
/*
* Call out to perl script to get the actual params.
*/
sprintf(_buf, "%s/%s %s", CLIENT_BINDIR, "getdelayinfo", linkname);
if ((cfd = popen(_buf, "r")) == NULL) {
error("Could not start getdelayinfo for link %s\n", linkname);
return -1;
}
/*
* First line:
*
* bw:1500000 kbit delay:10000 plr:0.0 qlen:50
*/
if (fgets(_buf, sizeof _buf, cfd) == NULL) {
error("No first line from getdelayinfo for link %s\n",
linkname);
return -1;
}
if (sscanf(_buf, "bw:%d %s delay:%d plr:%f qlen:%d",
&bw, bwspec, &delay, &plr, &qlen) != 5) {
error("Could not parse '%s'\n", _buf);
return -1;
}
/*
* Well this is funny; it will display "bit" but not accept "bit".
* But that is default, so just clear it.
*/
if (strcmp(bwspec, "bit") == 0) {
strcpy(bwspec, "");
}
structpipe_params *p_params = &(link_map[l_index].params[0]);
p_params->delay = delay;
p_params->bw = bw;
strcpy(p_params->bwspec, bwspec);
p_params->plr = (double) plr;
p_params->q_size = qlen;
/*
* Second line will be the reverse params, if duplex.
*/
if (link_map[l_index].numpipes == 2) {
structpipe_params *p_params = &(link_map[l_index].params[1]);
bzero(bwspec, sizeof(bwspec));
/*
* Second line:
*
* rbw:1500000 kbit rdelay:10000 rplr:0.0
*/
if (fgets(_buf, sizeof _buf, cfd) == NULL) {
error("No second line from getdelayinfo for link %s\n",
linkname);
return -1;
}
if (sscanf(_buf, "rbw:%d %s rdelay:%d rplr:%f",
&bw, bwspec, &delay, &plr) != 4) {
error("Could not parse '%s'\n", _buf);
return -1;
}
/*
* Well this is funny; it will display "bit" but not
* accept "bit". But that is default, so just clear
* it.
*/
if (strcmp(bwspec, "bit") == 0) {
strcpy(bwspec, "");
}
p_params->delay = delay;
p_params->bw = bw;
strcpy(p_params->bwspec, bwspec);
p_params->plr = (double) plr;
}
pclose(cfd);
return 1;
}
void set_link_params(int l_index, int blackhole, int p_which)
{
structpipe_params *p_params = &(link_map[l_index].params[0]);
int pipeno = link_map[l_index].pipes[0];
char *iface = link_map[l_index].interfaces[0];
char cmd[BUFSIZ];
// Qsize only on pipe1 (outgoing) side and only for slots.
if (p_params->flags_p & PIPE_QSIZE_IN_BYTES) {
error("Refusing to set qsize, since its in bytes not slots\n");
}
else {
sprintf(cmd, "ifconfig %s txqueuelen %d",
iface, p_params->q_size);
if (debug)
info("%s\n", cmd);
if (system(cmd)) {
error("tc failed: '%s'\n", cmd);
}
}
// Bandwidth by itself.
sprintf(cmd, "tc class change dev %s classid %d:1 htb "
"rate %d %s ceil %d %s",
iface, pipeno, (int) p_params->bw, p_params->bwspec,
(int) p_params->bw, p_params->bwspec);
if (debug)
info("%s\n", cmd);
if (system(cmd)) {
error("tc failed: '%s'\n", cmd);
}
// Now loss and delay. loss is in percent.
sprintf(cmd, "tc qdisc change "
"dev %s handle %d netem drop %.2f delay %dms",
iface, pipeno + 10,
p_params->plr * 100, p_params->delay);
if (debug)
info("%s\n", cmd);
if (system(cmd)) {
error("tc failed: '%s'\n", cmd);
}
// And the reverse pipe in duplex mode.
if (link_map[l_index].numpipes == 2) {
p_params = &(link_map[l_index].params[1]);
pipeno = link_map[l_index].pipes[1];
iface = link_map[l_index].interfaces[1];
// Bandwidth by itself.
sprintf(cmd, "tc class change dev %s classid 2:1 htb "
"rate %d %s ceil %d %s",
iface, (int) p_params->bw, p_params->bwspec,
(int) p_params->bw, p_params->bwspec);
if (debug)
info("%s\n", cmd);
if (system(cmd)) {
error("tc failed: '%s'\n", cmd);
}
// Now loss and delay. loss is in percent.
sprintf(cmd, "tc qdisc change "
"dev %s handle 3 netem drop %.2f delay %dms",
iface, p_params->plr * 100, p_params->delay);
if (debug)
info("%s\n", cmd);
if (system(cmd)) {
error("tc failed: '%s'\n", cmd);
}
}
}
#else
int get_link_params(int l_index)
{
int p_index = 0;
......@@ -763,6 +925,7 @@ void set_link_params(int l_index, int blackhole, int p_which)
}
}
#endif
#endif
/********* get_new_link_params ***************************
For a modify event, this function gets the parameters
......@@ -812,19 +975,28 @@ int get_new_link_params(int l_index, event_handle_t handle,
#endif
if(strcmp(argtype,"BANDWIDTH")== 0){
int newbw = atoi(argvalue);
char *rate = "Kbits/s";
#ifdef USESOCKET
/* Convert to bits/s */
newbw = newbw * 1000;
#endif
info("Bandwidth = %d\n", newbw);
#ifdef linux
/*
* The BW is a pain cause tc uses Kbit to mean 1024 while
* we take it to mean 1000. So convert to bits. Overflow?
*/
rate = "";
newbw = newbw * 1000;
#endif
link_map[l_index].params[p_num].bw = newbw;
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");
strcpy(link_map[l_index].params[p_num].bwspec, rate);
if (! gotpipe) {
strcpy(link_map[l_index].params[1].bwspec, "Kbits/s");
strcpy(link_map[l_index].params[1].bwspec, rate);
}
#endif
}
......@@ -872,7 +1044,11 @@ int get_new_link_params(int l_index, event_handle_t handle,
link_map[l_index].params[p_num].flags_p &= ~PIPE_QSIZE_IN_BYTES;
}
else {
#ifdef linux
error("QSize in bytes is not supported on linux!\n");
#else
info("QSize in bytes\n");
#endif
link_map[l_index].params[p_num].flags_p |= PIPE_QSIZE_IN_BYTES;
}
gotqib = 1;
......
/*
* Copyright (c) 2000-2015 University of Utah and the Flux Group.
* Copyright (c) 2000-2016 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -140,8 +140,10 @@ int main(int argc, char **argv)
loginit(0, log_file);
else {
/* Become a daemon */
daemon(0, 0);
if (daemon(0, 0)) {
fprintf(stderr, "failed to daemonize\n");
exit(-1);
}
if (log_file)
loginit(0, log_file);
else
......@@ -433,7 +435,7 @@ void dump_link_map(){
info("bw = %.3f %s, ", link_map[i].params[j].bw,
link_map[i].params[j].bwspec);
#endif
info("plr = %d\n", link_map[i].params[j].plr);
info("plr = %f\n", 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-2012 University of Utah and the Flux Group.
* Copyright (c) 2000-2016 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -35,12 +35,14 @@
/*************************INCLUDES******************************************/
/* for setsockopt and stuff */
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/wait.h>
#ifndef linux
#include <sys/mbuf.h>
#include <sys/sockio.h>
#endif
#include <paths.h>
#include <ctype.h>
......@@ -63,9 +65,11 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#ifndef linux
#include <netinet/ip_fw.h>
#include <net/route.h> /* def. of struct route */
#include <netinet/ip_dummynet.h>
#endif
#include <netinet/tcp.h>
#include <arpa/inet.h>
/* for setsockopt and stuff */
......@@ -79,12 +83,14 @@
/*
* After 8.0, everything changed!
*/
#ifndef linux
#if __FreeBSD_version < 800000
#define USESOCKET 1
#else
#define IPFW "ipfw"
extern int kern_hz;
#endif
#endif
#if 0
#include "tbdb.h"
......@@ -146,7 +152,9 @@ typedef struct {
double plr; /* queue loss rate*/
int q_size; /* queuq size in slots/bytes*/
structRed_params red_gred_params; /* red/gred params*/
#ifdef USESOCKET
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;
......
#
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -154,6 +154,7 @@ local-script-install: common-script-install nodecheck-install
$(INSTALL) -m 755 $(SRCDIR)/rc.slothd $(RCDIR)/rc.slothd
$(INSTALL) -m 755 $(SRCDIR)/rc.canaryd $(RCDIR)/rc.canaryd
$(INSTALL) -m 755 $(SRCDIR)/rc.linktest $(RCDIR)/rc.linktest
$(INSTALL) -m 755 $(SRCDIR)/rc.delayagent $(RCDIR)/rc.delayagent
$(INSTALL) -m 755 $(SRCDIR)/rc.inelab $(RCDIR)/rc.inelab
$(INSTALL) -m 755 $(SRCDIR)/rc.pgeni $(RCDIR)/rc.pgeni
# Symlink this cause we invoke it from boss, and its too much
......
......@@ -154,12 +154,6 @@ my $TBDIR = "/usr/testbed";
#
my $WINSUPPORT = 1;
#
# Whether installation of all collab tools should be disabled.
# XXX here for compat; replaced by emulabconfig option.
#
my $NOCOLLAB = 1;
#
# Enable elvin compatibility.
# XXX here for compat; replaced by emulabconfig option.
......@@ -222,13 +216,6 @@ my %emulabconfig = (
# CONFIG_SINGLECNET use the real cnet as the inner cnet.
# CONFIG_ELVIN support Elvin compatibility
# CONFIG_WINDOWS support Windows OS on nodes
# CONFIG_COLLAB install/configure for collaboration tools support.
# CONFIG_ARCHIVE support integrated archival via svn (part of COLLAB)
# CONFIG_BUGSDB support integrated bug database (part of COLLAB)
# CONFIG_CVS support integrated CVS SCM (part of COLLAB)
# CONFIG_MAILMAN support integrated mailman lists (part of COLLAB)
# CONFIG_USERDB support integrated MySQL DB (part of COLLAB)
# CONFIG_WIKI support integrated wiki (part of COLLAB)
# CONFIG_SHAREDFS support shared filesystem
# CONFIG_QUERIER configure mfrisbeed to act as IGMP querier
#
......@@ -237,13 +224,6 @@ my %emulabconfig = (
"CONFIG_SINGLECNET" => $SINGLE_CONTROLNET,
"CONFIG_ELVIN" => $ELVIN_COMPAT,
"CONFIG_WINDOWS" => $WINSUPPORT,
"CONFIG_COLLAB" => !$NOCOLLAB,
"CONFIG_ARCHIVE" => !$NOCOLLAB,
"CONFIG_BUGSDB" => !$NOCOLLAB,
"CONFIG_CVS" => !$NOCOLLAB,
"CONFIG_MAILMAN" => !$NOCOLLAB,
"CONFIG_USERDB" => !$NOCOLLAB,
"CONFIG_WIKI" => !$NOCOLLAB,
"CONFIG_SHAREDFS" => $SHAREDFS,
"CONFIG_NFSRACY" => $NFSRACY,
"CONFIG_QUERIER" => $NEEDQUERIER,
......@@ -463,19 +443,6 @@ sub doboot()
}
$emulabconfig{$key} = $val;
#
# Handle ordered setting/clearing of aggregate options.
# These may be later overridden by individual options.
#
if ($key eq "CONFIG_COLLAB") {
$emulabconfig{"CONFIG_ARCHIVE"} = $val;
$emulabconfig{"CONFIG_BUGSDB"} = $val;
$emulabconfig{"CONFIG_CVS"} = $val;
$emulabconfig{"CONFIG_MAILMAN"} = $val;
$emulabconfig{"CONFIG_USERDB"} = $val;
$emulabconfig{"CONFIG_WIKI"} = $val;
}
}
}
......@@ -1716,9 +1683,6 @@ sub SetupOpsNode($)
print RC "inetd_enable=\"YES\"\n";
print RC "sendmail_enable=\"YES\"\n";
if ($emulabconfig{"CONFIG_MAILMAN"}) {
print RC "mailman_enable=\"YES\"\n";
}
print RC "sshd_enable=\"YES\"\n";
print RC "ntpdate_enable=\"YES\"\n";
......@@ -3077,9 +3041,6 @@ sub SetupOpsJail()
SetupFatal("Could not open /etc/rc.conf for writing: $!");
print RC "sendmail_enable=\"YES\"\n";
if ($emulabconfig{"CONFIG_MAILMAN"}) {
print RC "mailman_enable=\"YES\"\n";
}
print RC "linux_enable=\"YES\"\n";
print RC "accounting_enable=\"YES\"\n";
print RC "nfs_client_enable=\"YES\"\n";
......@@ -3400,60 +3361,6 @@ sub CreateDefsFile($)
#
# Configurable options
#
/^MAILMANSUPPORT$/ && do {
if ($emulabconfig{"CONFIG_MAILMAN"} && $FBSD_VERSION >= 6) {
print OUTDEFS "MAILMANSUPPORT=1\n";
}
else {
print OUTDEFS "MAILMANSUPPORT=0\n";
}
last SWITCH;
};
/^CVSSUPPORT$/ && do {
if ($emulabconfig{"CONFIG_CVS"} && $FBSD_VERSION >= 6) {
print OUTDEFS "CVSSUPPORT=1\n";
}
else {
print OUTDEFS "CVSSUPPORT=0\n";
}
last SWITCH;
};
/^BUGDBSUPPORT$/ && do {
if ($emulabconfig{"CONFIG_BUGSDB"} && $FBSD_VERSION >= 6) {
print OUTDEFS "BUGDBSUPPORT=1\n";
}
else {
print OUTDEFS "BUGDBSUPPORT=0\n";
}
last SWITCH;
};
/^OPSDBSUPPORT$/ && do {
if ($emulabconfig{"CONFIG_USERDB"} && $FBSD_VERSION >= 6) {
print OUTDEFS "OPSDBSUPPORT=1\n";
}
else {
print OUTDEFS "OPSDBSUPPORT=0\n";
}
last SWITCH;
};
/^WIKISUPPORT$/ && do {
if ($emulabconfig{"CONFIG_WIKI"} && $FBSD_VERSION >= 6) {
print OUTDEFS "WIKISUPPORT=1\n";
}
else {
print OUTDEFS "WIKISUPPORT=0\n";
}
last SWITCH;
};
/^ARCHIVESUPPORT$/ && do {
if ($emulabconfig{"CONFIG_ARCHIVE"} && $FBSD_VERSION >= 6.1) {
print OUTDEFS "ARCHIVESUPPORT=1\n";
}
else {
print OUTDEFS "ARCHIVESUPPORT=0\n";
}
last SWITCH;
};
/^FSDIR_SCRATCH$/ && do {
if ($emulabconfig{"CONFIG_SCRATCHFS"}) {
print OUTDEFS "FSDIR_SCRATCH=$FSMOUNTDIR/scratch\n";
......
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -266,7 +266,6 @@ script-install: dir-install $(SCRIPTS)
$(INSTALL) -m 755 $(SRCDIR)/liblocsetup.pm $(BINDIR)/liblocsetup.pm
$(INSTALL) -m 755 $(SRCDIR)/liblocstorage.pm $(BINDIR)/liblocstorage.pm
$(INSTALL) -m 755 $(SRCDIR)/libvnode.pm $(BINDIR)/libvnode.pm
$(INSTALL) -m 755 $(SRCDIR)/rc.delayagent $(BINDIR)/rc/rc.delayagent
$(INSTALL) -m 755 $(SRCDIR)/rc.healthd $(BINDIR)/rc/rc.healthd
$(INSTALL) -m 755 $(SRCDIR)/healthd.conf $(BINDIR)/healthd.conf
$(INSTALL) -m 755 $(SRCDIR)/rc.ipod $(BINDIR)/rc/rc.ipod
......
#!/usr/bin/perl -w
#
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
use English;
use Getopt::Std;
sub usage()
{
print "Usage: rc.delayagent [-j <vnodeid>] start | stop\n";
exit(1);
}
my $optlist = "j:";
my $vnodeid;
my $action = "start";
# Turn off line buffering on output
$| = 1;
# Drag in path stuff so we can find emulab stuff.
BEGIN { require "/etc/emulab/paths.pm"; import emulabpaths; }
#
# Load the OS independent support library. It will load the OS dependent
# library and initialize itself.
#
use libsetup;
use libtmcc;
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
%options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"j"})) {
$vnodeid = $options{"j"};
libsetup_setvnodeid($vnodeid);
}
if (@ARGV) {
$action = $ARGV[0];
usage()
if ($action ne "start" and $action ne "stop");
}
# Must do this *after* setting vnode id.
my $MAPFILE = TMDELMAP();
my $KEYFILE = TMEVENTKEY();
my $logfile;
my $pidfile;
my $vnodearg = "";
if (defined($vnodeid)) {
$logfile = CONFDIR() . "/delayagent.debug";
$pidfile = CONFDIR() . "/delayagent.pid";
$vnodearg = "-j $vnodeid";
}
else {
$logfile = "$LOGDIR/delayagent.debug";
$pidfile = "/var/run/delayagent.pid";
}
# Stop.
if ($action eq "stop") {
if (-e $pidfile) {
my $pidno = `cat $pidfile`;
chomp($pidno);
print "$pidno\n";
# The delay agent will not die properly for some reason.
system("kill -9 $pidno");
unlink($pidfile);
}
exit(0);
}
# Start.
if (! -s $MAPFILE) {
exit(0);
}
print "Starting Delay Agent ...\n";
#
# Need the pid/eid.
#
my ($pid, $eid, $vname) = check_nickname();
#
# The agent always talks to the local elvind, which talks to boss.
#
my $elvind = getlocalevserver();
system("delay-agent -s $elvind -E $pid/$eid $vnodearg ".
"-f $MAPFILE -l $logfile -i $pidfile -k $KEYFILE &");
exit($? >> 0);
......@@ -305,6 +305,7 @@ script-install: dir-install $(SCRIPTS)
$(INSTALL) -m 755 $(SRCDIR)/get_edd_map $(BINDIR)
$(INSTALL) -m 755 $(SRCDIR)/rc.linux $(BINDIR)/rc
$(INSTALL) -m 755 $(SRCDIR)/fixup-fstab-swaps $(BINDIR)
$(INSTALL) -m 755 $(SRCDIR)/getdelayinfo $(BINDIR)
sfs-install:
$(INSTALL) -m 755 -o root -g $(DIRGROUP) -d $(DESTDIR)/etc/sfs
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
# Copyright (c) 2000-2013, 2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -230,11 +230,14 @@ sub LinkDelaySetup()
# print DEL "ipfw -f flush\n";
if ($useifb) {
print DEL "modprobe ifb numifbs=10\n";
print DEL "modprobe ifb numifbs=20\n";
}
else {
print DEL "modprobe imq numdevs=10\n";
print DEL "modprobe imq numdevs=20\n";
}
# We have to dole out the ifb/imqs
my $nextifbimq = 0;
print DEL "sysctl -w net.core.rmem_max=8388608\n";
print DEL "sysctl -w net.core.wmem_max=8388608\n";
print DEL "sysctl -w net.core.netdev_max_backlog=2048\n";
......@@ -382,18 +385,18 @@ sub LinkDelaySetup()
# shaping should be performed).
#
if ($bandw != 0) {
print DEL "$TC qdisc add dev $iface handle ". ($pipeno+20) .
print DEL "$TC qdisc add dev $iface handle ". $pipeno .
" root htb default 1\n";
print DEL "$TC class add dev $iface classid ".
($pipeno+20) .":1 parent " . ($pipeno+20) .
$pipeno .":1 parent " . $pipeno .
" htb rate ${bandw} ceil ${bandw}\n";
print DEL "$TC qdisc add dev $iface handle ".
($pipeno+10) . " parent " . ($pipeno+20) . ":1 " .
($pipeno+10) . " parent " . $pipeno . ":1 " .
"netem drop $plr delay ${delay}us\n";
}
else {
print DEL "$TC qdisc add dev $iface handle ".
($pipeno+10) . " root " .
$pipeno . " root " .
"netem drop $plr delay ${delay}us\n";
}
}
......@@ -414,10 +417,10 @@ sub LinkDelaySetup()
print DEL "ceil ${bandw}\n";
}
}
$iface =~ /\D+(\d+)/;
my $inum = $1;
my $idev = ($useifb ? "ifb" : "imq") . "$inum";
if ($type eq "duplex") {
my $inum = $nextifbimq++;
my $idev = ($useifb ? "ifb" : "imq") . $inum;
if ($usenetem) {
# packet loss in netem is percent
$rplr *= 100;
......
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