Skip to content

Commit

Permalink
Merge HIRT code
Browse files Browse the repository at this point in the history
Changes improving IPv6 and adding SRv6 encap/decap and some processing capabilities to showcase the HIRT paper to be presented at ICNP'24
  • Loading branch information
tbarbette committed Sep 17, 2024
2 parents 9f0af7e + 5ec7bad commit 18d3a55
Show file tree
Hide file tree
Showing 38 changed files with 4,001 additions and 602 deletions.
8 changes: 7 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ variables:
NETMAP_VERSION: "11.1"
CONFIG: "--enable-all-elements --disable-verbose-batch --enable-simtime"

default:
tags:
- sudo
- docker
image: ubuntu:20.04

batch:
script:
- ./configure CXXFLAGS="-std=gnu++11" --enable-batch $CONFIG --disable-verbose-batch && make && make check
Expand Down Expand Up @@ -83,5 +89,5 @@ before_script:
- gcc -v
- if [ ! -e "netmap-$NETMAP_VERSION/sys/net/netmap.h" ] ; then wget https://github.com/luigirizzo/netmap/archive/v$NETMAP_VERSION.tar.gz && tar -xvf v$NETMAP_VERSION.tar.gz && ( cd netmap-$NETMAP_VERSION && cd LINUX && ./configure --no-drivers ; cd .. && cd .. ) ; fi
- ls -al
- if [ `sudo -n whoami` = "root" ] ; then sudo insmod netmap-$NETMAP_VERSION/LINUX/netmap.ko && sudo chmod 666 /dev/netmap ; fi
- if [ `sudo -n whoami` = "root" ] && command -v insmod ; then sudo insmod netmap-$NETMAP_VERSION/LINUX/netmap.ko && sudo chmod 666 /dev/netmap ; fi
- export CONFIG_NETMAP="--with-netmap=`pwd`/netmap-$NETMAP_VERSION/sys/"
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Quick start (using DPDK for I/O)
* Build FastClick, with support for DPDK using the following command:

```
./configure --enable-dpdk --enable-intel-cpu --verbose --enable-select=poll CFLAGS="-O3" CXXFLAGS="-std=c++11 -O3" --disable-dynamic-linking --enable-poll --enable-bound-port-transfer --enable-local --enable-flow --disable-task-stats --disable-cpu-load
./configure CFLAGS="-O3" CXXFLAGS="-std=c++11 -O3" --enable-dpdk --enable-intel-cpu --disable-dynamic-linking --enable-bound-port-transfer --enable-flow --disable-task-stats --disable-cpu-load
make
```

Expand All @@ -32,7 +32,7 @@ FastClick "Light"
-----------------
FastClick, like Click comes with a lot of features that you may not use. The following options will improve performance further :
```
./configure --enable-dpdk --enable-intel-cpu --verbose --enable-select=poll CFLAGS="-O3" CXXFLAGS="-std=c++11 -O3" --disable-dynamic-linking --enable-poll --enable-bound-port-transfer --enable-local --enable-flow --disable-task-stats --disable-cpu-load --enable-dpdk-packet --disable-clone --disable-dpdk-softqueue
./configure CFLAGS="-O3" CXXFLAGS="-std=c++11 -O3" --enable-dpdk --enable-intel-cpu --disable-dynamic-linking --enable-bound-port-transfer --enable-flow --disable-task-stats --disable-cpu-load --enable-dpdk-packet --disable-clone --disable-dpdk-softqueue
make
```
* Disable task stats suppress statistics tracking for advanced task scheduling with e.g. BalancedThreadSched. With DPDK, it's polling anyway... And as far as scheduling is concerned, [RSS++](#rss) has a better solution.
Expand Down
2 changes: 1 addition & 1 deletion doc/click-elem2man
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ my(@section_headers) =
'nat' => 'Network Address Translation',
'tcp' => 'TCP',
'udp' => 'UDP',
'gtp' => 'GTP',
'tunnel' => 'Tunnel (GRE, ...)',
'app' => 'Applications',
'traces' => 'Trace Manipulation',
'ipmeasure' => 'TCP/IP Measurement',
Expand Down
50 changes: 33 additions & 17 deletions doc/clicktest.1
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
Expand Down Expand Up @@ -219,7 +219,8 @@ ClickTest test files consist of several sections, each introduced by a line
starting with \fB%\fR. There must be, at least, a \fB\f(CB%script\fB\fR section.
The \fB\f(CB%file\fB\fR and \fB\f(CB%expect\fB\fR sections define input and output files by
name.
.IP "\fB\f(CB%script\fB\fR" 8
.ie n .IP "\fB\fB%script\fB\fR" 8
.el .IP "\fB\f(CB%script\fB\fR" 8
.IX Item "%script"
The \fBsh\fR shell script that controls the test. ClickTest will run each
command in sequence. Every command in the script must succeed, with
Expand All @@ -236,7 +237,8 @@ The script's environment is populated with any \fI\s-1VARIABLE\s0\fRs set on the
clicktest command line with \fB\f(BI\s-1VARIABLE\s0\fB=\f(BI\s-1VALUE\s0\fB\fR syntax. Also, the
\&\fB\f(CB$rundir\fB\fR environment variable is set to the directory in which
clicktest was originally run.
.IP "\fB\f(CB%require\fB [\-q]\fR" 8
.ie n .IP "\fB\fB%require\fB [\-q]\fR" 8
.el .IP "\fB\f(CB%require\fB [\-q]\fR" 8
.IX Item "%require [-q]"
An \fBsh\fR shell script defining prerequisites that must be satisfied
before the test can run. Every command in the script must succeed, with
Expand All @@ -246,15 +248,18 @@ if a requirement fails.
.Sp
ClickTest runs the requirement script before creating any other test files.
For example, contents of \fB\f(CB%file\fB\fR sections are not available.
.IP "\fB\f(CB%info\fB\fR" 8
.ie n .IP "\fB\fB%info\fB\fR" 8
.el .IP "\fB\f(CB%info\fB\fR" 8
.IX Item "%info"
A short description of the test. In \fB\-\-superverbose\fR mode, the first
paragraph of its contents is printed before the test results.
.IP "\fB\f(CB%cut\fB\fR" 8
.ie n .IP "\fB\fB%cut\fB\fR" 8
.el .IP "\fB\f(CB%cut\fB\fR" 8
.IX Item "%cut"
This section is ignored. It is intended to comment out obsolete parts of
the test.
.IP "\fB\f(CB%file\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.ie n .IP "\fB\fB%file\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.el .IP "\fB\f(CB%file\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.IX Item "%file [-de] [+LENGTH] FILENAME..."
Create an input file for the script. \fI\s-1FILENAME\s0\fR can be \fBstdin\fR,
which sets the script's standard input. If \fB+\fR\fI\s-1LENGTH\s0\fR is provided,
Expand All @@ -266,7 +271,8 @@ Base64\-encoded (see \fBbase64\fR\|(1)); it is decoded before use. To
include a file with lines that start with \fB%\fR (which would normally
start a new section), use \fB\-d\fR and preface each line of the file with
a space, or use \fB\-e\fR.
.IP "\fB\f(CB%expect\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.ie n .IP "\fB\fB%expect\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.el .IP "\fB\f(CB%expect\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.IX Item "%expect [-adeiw] [+LENGTH] FILENAME..."
Define an expected output file. Differences between the script's
output \fI\s-1FILENAME\s0\fR and the contents of the \fB\f(CB%expect\fB\fR section will
Expand Down Expand Up @@ -308,48 +314,58 @@ The \fB\-a\fR flag marks this expected output as an alternate. ClickTest will
compare the script's output file with each provided alternate; the
test succeeds if any of the alternates match. The \fB\-d\fR flag behaves
as in \fB\f(CB%file\fB\fR.
.IP "\fB\f(CB%expectv\fB [\-ade] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.ie n .IP "\fB\fB%expectv\fB [\-ade] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.el .IP "\fB\f(CB%expectv\fB [\-ade] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.IX Item "%expectv [-ade] [+LENGTH] FILENAME..."
Define a literal expected output file. This behaves like \fB\f(CB%expect\fB\fR,
except that the script's output file must match the provided data
\&\fIexactly\fR: \fB\f(CB%expectv\fB\fR never ignores whitespace differences, does not
treat \f(CW\*(C`{{}}\*(C'\fR blocks as regular expressions, and does not parse
\&\fB\f(CB%ignore\fB\fR patterns.
.IP "\fB\f(CB%expectx\fB [\-adiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.ie n .IP "\fB\fB%expectx\fB [\-adiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.el .IP "\fB\f(CB%expectx\fB [\-adiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8
.IX Item "%expectx [-adiw] [+LENGTH] FILENAME..."
Define a regular-expression expected output file. This behaves like
\&\fB\f(CB%expect\fB\fR, except that every line is treated as a regular expression.
\&\f(CW\*(C`{{?comment}}\*(C'\fR blocks are ignored, but other brace pairs are treated
according to the normal regular expression rules.
.IP "\fB\f(CB%stdin\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.ie n .IP "\fB\fB%stdin\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.el .IP "\fB\f(CB%stdin\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.IX Item "%stdin [-de] [+LENGTH]"
Same as \fB\f(CB%file\fB stdin\fR.
.IP "\fB\f(CB%stdout\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.ie n .IP "\fB\fB%stdout\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.el .IP "\fB\f(CB%stdout\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.IX Item "%stdout [-adeiw] [+LENGTH]"
Same as \fB\f(CB%expect\fB stdout\fR.
.IP "\fB\f(CB%stderr\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.ie n .IP "\fB\fB%stderr\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.el .IP "\fB\f(CB%stderr\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8
.IX Item "%stderr [-adeiw] [+LENGTH]"
Same as \fB\f(CB%expect\fB stderr\fR.
.IP "\fB\f(CB%ignorex\fB [\-di] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8
.ie n .IP "\fB\fB%ignorex\fB [\-di] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8
.el .IP "\fB\f(CB%ignorex\fB [\-di] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8
.IX Item "%ignorex [-di] [+LENGTH] [FILENAME]"
Each line in the \fB\f(CB%ignorex\fB\fR section is a Perl regular expression. Lines in
the supplied \fI\s-1FILENAME\s0\fR that match any of those regular expressions will not
be considered when comparing files with \fB\f(CB%expect\fB\fR data. The regular
expression must match the whole line. \fI\s-1FILENAME\s0\fR may be \fBall\fR, in which case
the regular expressions will apply to all \fB\f(CB%expect\fB\fR files. \f(CW\*(C`{{?comment}}\*(C'\fR
blocks are ignored.
.IP "\fB\f(CB%ignore\fB\fR, \fB\f(CB%ignorev\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8
.ie n .IP "\fB\fB%ignore\fB\fR, \fB\fB%ignorev\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8
.el .IP "\fB\f(CB%ignore\fB\fR, \fB\f(CB%ignorev\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8
.IX Item "%ignore, %ignorev [-adeiw] [+LENGTH] [FILENAME]"
Like \fB\f(CB%ignorex\fB\fR, but \fB\f(CB%ignore\fB\fR parses regular expressions only inside
double braces (\f(CW\*(C`{{ }}\*(C'\fR), and \fB\f(CB%ignorev\fB\fR lines must match exactly.
.IP "\fB\f(CB%include\fB \f(BI\s-1FILENAME\s0\fB\fR" 8
.ie n .IP "\fB\fB%include\fB \f(BI\s-1FILENAME\s0\fB\fR" 8
.el .IP "\fB\f(CB%include\fB \f(BI\s-1FILENAME\s0\fB\fR" 8
.IX Item "%include FILENAME"
Interpolate the contents of another clicktest file.
.IP "\fB\f(CB%eot\fB\fR" 8
.ie n .IP "\fB\fB%eot\fB\fR" 8
.el .IP "\fB\f(CB%eot\fB\fR" 8
.IX Item "%eot"
Marks the end of the current test. The rest of the file will be parsed for
additional tests.
.IP "\fB\f(CB%eof\fB\fR" 8
.ie n .IP "\fB\fB%eof\fB\fR" 8
.el .IP "\fB\f(CB%eof\fB\fR" 8
.IX Item "%eof"
The rest of the file is ignored.
.SH "EXAMPLE"
Expand Down
2 changes: 1 addition & 1 deletion elements/ip/checkipheader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ CheckIPHeader::configure(Vector<String> &conf, ErrorHandler *errh)

if (Args(conf, this, errh)
.read("BADSRC", OldBadSrcArg(), _bad_src)
.read("OFFSET", _offset)
.read_or_set("OFFSET", _offset, 0)
.complete() < 0)
return -1;

Expand Down
2 changes: 1 addition & 1 deletion elements/ip6/checkip6header.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ CheckIP6Header::read_handler(Element *e, void *thunk)
switch (reinterpret_cast<uintptr_t>(thunk)) {
case h_count: {
PER_THREAD_SUM(uint64_t, count, c->_count);
return String(count);
return String(count);
}
case h_drops: {
return String(c->_drops);
Expand Down
173 changes: 173 additions & 0 deletions elements/ip6/ip6drop.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
* ip6drop.{cc,hh} -- element drops packets following a Gilbert Eliott model
* Louis Navarre
*
* Copyright (c) 2024 UCLouvain
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, subject to the conditions
* listed in the Click LICENSE file. These conditions include: you must
* preserve this copyright notice, and you cannot mention the copyright
* holders in advertising related to the Software without their permission.
* The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
* notice is a summary of the Click LICENSE file; the license in that file is
* legally binding.
*/

#include <click/config.h>
#include "ip6drop.hh"
#include <click/nameinfo.hh>
#include <click/confparse.hh>
#include <click/error.hh>
#include <click/glue.hh>

CLICK_DECLS

IP6Drop::IP6Drop()
{
_use_dst_anno = false;
}

IP6Drop::~IP6Drop()
{
}

int
IP6Drop::configure(Vector<String> &conf, ErrorHandler *errh)
{
if (Args(conf, this, errh)
.read_all("ADDR", addrs)
.read_or_set("P", p, 0)
.read_or_set("R", r, 0)
.read_or_set("H", h, 0)
.read_or_set("K", k, 1)
.read_or_set("SEED", seed, 51)
.complete() < 0)
return -1;

total_seen = 0;
srand(seed);
state = good;

return 0;
}

void
IP6Drop::push(int input, Packet *p_in)
{
drop_model(p_in, [this](Packet*p){output(0).push(p);});
}

#if HAVE_BATCH
void
IP6Drop::push_batch(int input, PacketBatch *batch) {
EXECUTE_FOR_EACH_PACKET_DROPPABLE(drop_model, batch, [](Packet *){});
if (batch) {
output_push_batch(0, batch);
}
}
#endif

#if HAVE_BATCH
Packet *
#else
void
#endif
IP6Drop::drop_model(Packet *p_in)
{
return drop_model(p_in, [this](Packet*p){output(0).push(p);});
}

#if HAVE_BATCH
Packet *
#else
void
#endif
IP6Drop::drop_model(Packet *p_in, std::function<void(Packet*)>push)
{
const click_ip6 *ip6 = reinterpret_cast<const click_ip6 *>(p_in->data());
uint32_t *dst_32 = (uint32_t *)&ip6->ip6_dst;
bool found = false;
for (int i = 0; i < addrs.size(); ++i) {
IP6Address addr = addrs.at(i);
uint32_t *addr_32 = (uint32_t *)addr.data32();
if (addr_eq(addr_32, dst_32)) {
found = true;
break;
}
}
if (!found) {
#if HAVE_BATCH
return p_in;
#else
push(p_in);
#endif
}

total_seen++;
// Do not drop the first packets to ensure a connection between the client and the broker
if (total_seen < 20) {
return p_in;
}

if (!gemodel()) {
click_chatter("Drop packet #%u", total_seen);
#if HAVE_BATCH
return 0;
}
return p_in;
#else
}
push(p_in);
#endif
}

bool
IP6Drop::gemodel()
{
bool keep_packet = true;
bool change_state = false;
// click_chatter("State is %u", state);
if (state == good) {
double rand_val1 = rand() / (RAND_MAX + 1.);
// click_chatter("Generated value: %f", rand_val1);
keep_packet = rand_val1 < k;
rand_val1 = rand() / (RAND_MAX + 1.);
change_state = rand_val1 < p;
// click_chatter("K and keep packet: %f, %u change state=%u (p=%u)", k * 100, keep_packet, change_state, p * 100);
if (change_state) {
state = bad;
}
} else {
double rand_val1 = rand() / (RAND_MAX + 1.);
keep_packet = rand_val1 < h;
rand_val1 = rand() / (RAND_MAX + 1.);
change_state = rand_val1 < r;
if (change_state) {
state = good;
}
}
return keep_packet;
}

bool
IP6Drop::addr_eq(uint32_t *a1, uint32_t *a2)
{
return (a1[0] == a2[0] && a1[1] == a2[1] && a1[2] == a2[2] && a1[3] == a2[3]);
}

String
IP6Drop::read_handler(Element *e, void *thunk)
{
return "<error>";
}

void
IP6Drop::add_handlers()
{
}

CLICK_ENDDECLS
EXPORT_ELEMENT(IP6Drop)
ELEMENT_MT_SAFE(IP6Drop)
Loading

0 comments on commit 18d3a55

Please sign in to comment.