Example experiments¶
Basic testbed¶
In this simple experiment, we run the eCLAT script called basic_example.eclat. This script executes a HIKe program that can extract some information from the packet and display it in a log. For example, it can display transport ports for UDP or TCP packets.
The source code of the eCLAT script is reported below.
To execute the experiment, run the following command in the HIKe / eCLAT container:
cd /opt/eclat-daemon && testbed/basic_testbed.sh
A tmux session will start. It deploys the topology depicted below, with the following three namespaces:
SUT (System Under Test)
TG (Traffic Generator)
COLLECTOR
The SUT is the namespace in which we run the eCLAT daemon and the HIKe VM is attached to the XDP hook on the incoming interface enp6s0f0. The TG is the namespace in which we generate traffic to be processed by our HIKe / eCLAT framework. The COLLECTOR namespace can be used in some examples in which we redirect some incoming packets from the SUT to the COLLECTOR, but it is not used in this basic example.
+------------------+ +------------------+
| TG | | SUT |
| | | |
| enp6s0f0 +------+ enp6s0f0 <--- HIKe VM XDP loader
| | | |
| | | |
| enp6s0f1 +------+ enp6s0f1 |
| | | + cl0 <-|- towards the collector
+------------------+ +---------|--------+
|
+---------|------+
| + veth0|
| |
| COLLECTOR |
+----------------+
Commands to control the tmux session¶
To exit from the tmux session type
Ctrl-bd.To resume the session
cd /opt/eclat-daemon && scripts/resume-tmux.sh.To kill the tmux session
cd /opt/eclat-daemon && scripts/kill-tmux.sh(note that the previous session is automatically killed if the experiment is executed again).
Windows in the tmux session¶
There are 9 windows in the TMUX, click with the mouse on the window name in the status bar to activate them.
In the TG1 and TG2 windows you can type and run the commands to generate traffic from the TG namespace:
* Command prepared in TG1: tcpreplay -i enp6s0f0 hike_v3/testbed/pkts/pkt_ipv6_udp.pcap
* Command prepared in TG2: ping -i 5 fc01::3
The MAIN, MAPS and DEBUG windows are in the default namespace of the container. In the MAPS window you can see the content of the eBPF maps. In the DEBUG window you can see the low-level debug printout of the HIKe programs.
The SUT, SUT2 and SUTDA windows are in the SUT namespace. The eCLAT daemon is executed in the SUTDA windows.
You can execute the tcpreply command from TG1 to send an udp packet and read the UDP source and destination ports written by the show_pkt_info HIKe/eBPF program in the log (shown in the DEBUG window).
You can execute the ping command from TG2 and it will send an ICMP packet every 5 seconds. In this case, the transport protocol 58 will be displayed in the log.
Now you can try to modify the eCLAT script basic_example.eclat: cd /opt/eclat-daemon && nano test/eclat_scripts/basic_example.eclat.
For example, change line 20 from show_pkt_info(TRANSP_LAYER, myvar) to show_pkt_info(NET_LAYER | TRANSP_LAYER, 2000).
Now both Network Layer and Transport Layer information are displayed in the log, and the displayed “User info” passed as parameter to the show_pkt_info HIKe/eBPF program is changed from 1000 to 2000.
eCLAT script basic_example.eclat¶
# basic example
#
# (basic_example.eclat)
#
#from programs.mynet import hike_drop, hike_pass, monitor, show_pkt_info
from programs.hike_default import hike_drop, hike_pass, monitor
from programs.info import show_pkt_info
from loaders.hike_default import ip6_simple_classifier
# send all IPv6 packets to our chain
ip6_simple_classifier[ipv6_simple_classifier_map] = { (0): (basic_example) }
ip6_simple_classifier.attach('DEVNAME', 'xdp')
def basic_example():
LAYER_2=1; NET_LAYER=2; TRANSP_LAYER=4
u64 : myvar = 1000
show_pkt_info(TRANSP_LAYER, myvar)
hike_pass()
return 0
DDoS mitigation experiment¶
In this experiment, we combine 7 HIKe programs inside an eCLAT script to implement a DDOS mitigation scenario.
In particular, we first use a token bucket meter to measure the packet rate per each IPv6 destination and detect “out of profile” flows. If the aggregate rate for a given IPv6 destination is “out of profile”, we activate (only for the “out of profile” packet) another token bucket meter operating per (source, destination) couple. If the packet rate for a (source, destination) couple is “out of profile”, we “blacklist” all packet with the specific (source, destination) for a time interval T=10 s. During the interval in which a flow is blacklisted, we sample one packet every 500 and redirect it over a layer 2 interface, on which we can capture and store or analyze the packets.
The source code of the eCLAT script is reported below.
To execute the experiment, run the following command in the HIKe / eCLAT container:
cd /opt/eclat-daemon && testbed/ddos_double_token_bucket_with_sampler.sh
A tmux session will start, implementing the topology depicted in the basic example above, with the three namespaces:
SUT (System Under Test)
TG (Traffic Generator)
COLLECTOR
Refer to that example above for the instructions on how to manage the tmux session.
The SUT is the namespace in which we run the eCLAT daemon and the HIKe VM is attached to the XDP hook on the incoming interface enp6s0f0. The TG is the namespace in which we generate traffic to be processed by our HIKe / eCLAT framework. The COLLECTOR namespace is used in this examples in which we redirect some incoming packets to the outgoing interface cl0 of the SUT.
There are 9 windows in the TMUX, click with the mouse on the window name in the status bar to activate them.
In the TG1 and TG2 windows you can run the ping commands to generate traffic from the TG namespace.
On TG1 the command ping -i 0.01 fc01::2 which sends 100 p/s is displayed and ready to be executed.
On TG2 the command ping -i 0.5 fc01::3 which sends 2 p/s is displayed and ready to be executed.
The MAIN, MAPS and DEBUG windows are in the default namespace of the container. In the MAPS window you can see the content of the eBPF maps. In the DEBUG window you can see the low-level debug printout of the HIKe programs.
The SUT, SUT2 and SUTDA windows are in the SUT namespace. The eCLAT daemon is executed in the SUTDA windows.
The CLT windows runs in the COLLECTOR namespace. In the CLT window we have run the tcpdump -i veth0 command to display the packets that are redirected to the collector.
To perform an experirent first run the 2 p/s ping ping -i 0.5 fc01::3 on TG2. Go in the MAPS window and can see that the flow with destination fc01::3 is monitored in the per destination token bucket and it remains IN_PROFILE. The packet monitor (map map_pcpu_mon) counts the transmitted packets (code 0).
Then add the 100 p/s ping ping -i 0.01 fc01::2 on TG1. You will notice that after few seconds the ping are not replied, because the (src, dst) flow has been blacklisted (for 10 seconds). After 10 seconds the flow is removed from the blacklist and some ping replies are again received. Looking in the MAPS windows, you can see that token bucket per (src, dst) has been activated and that the packet monitor (map map_pcpu_mon) shows many dropped packets (code 1). One packet every 500 packets is shown as redirected (code 2). You can check on the CLT window that the redirected packet has been captured by tcpdump.
eCLAT script for ddos mitigation¶
# ddos_tb_2_levels with packet samples redirected to collector
#
# (ddos_tb_2_levels_sample_constants.eclat)
#
# first token bucket monitor per ip6 dst
# the out-profile packets are processed by a second token bucket per src,dst
# the out-profile (src,dst) are blacklisted
# for a time interval (e.g. 10 s) which is defined in ip6_hset.h: HIKE_IPV6_HSET_EXP_TIMEOUT_NS
# token bucket parameters (rate, bucket) are defined in tb_defs.h
# a packet every 500 blacklisted packets is redirected to an interface
# the script is also counting the accepted, dropped and redirected packets
#from programs.mynet import hike_pass, ip6_hset_srcdst, ip6_sd_tbmon, monitor, ip6_dst_tbmon, l2_redirect, ip6_sd_dec2zero
from programs.hike_default import hike_drop, hike_pass, ip6_hset_srcdst, monitor, l2_redirect
from programs.meter import ip6_sd_tbmon, ip6_dst_tbmon
from programs.sampler import ip6_sd_dec2zero
from loaders.hike_default import ip6_simple_classifier
# send all IPv6 packets to our chain
ip6_simple_classifier[ipv6_simple_classifier_map] = { (0): (ddos_tb_2_lev) }
ip6_simple_classifier.attach('DEVNAME', 'xdp')
def ddos_tb_2_lev():
PASS=0; DROP=1; REDIRECT=2
ADD=1; LOOKUP=2
BLACKLISTED = 0
REDIRECT_IF_INDEX = 6
IN_PROFILE = 0
# (src,dest) in blacklist ?
u64 : res = ip6_hset_srcdst(LOOKUP)
if res == BLACKLISTED:
# redirect one packet out of 500
res = ip6_sd_dec2zero(500)
if res == 0:
monitor(REDIRECT)
l2_redirect(REDIRECT_IF_INDEX)
return 0
monitor(DROP)
hike_drop()
return 0
# check the rate per (dst)
res = ip6_dst_tbmon()
if res != IN_PROFILE:
# check the rate per (src,dst)
res = ip6_sd_tbmon()
if res != IN_PROFILE:
# add (src,dest) to blacklist
ip6_hset_srcdst(ADD)
monitor(DROP)
hike_drop()
return 0
monitor(PASS)
hike_pass()
return 0
Experiment on EIP (Extensible In-band Processing)¶
+------------------+ +------------------+ +------------------+ +------------------+
| r1 | | r2 | | r3 | | r4 |
| | | | | | | |
| i12 +------+ i21 i23 +------+ i32 i34 +------+ i43 |
| | | | | | | |
| | | | | | | |
+------------------+ +------------------+ +------------------+ +------------------+
In this experiment, we set up a testbed with four routers (running in separated network namespaces) connected as shown in the figure above. The testbed will create a tmux session with multiple windows. In particular, we have one window for each router, plus 1 more window for routers r2 and r3 where the eCLAT daemon will be running. Lastly, a MAIN window, a MAPS window and a DEBUG window.
You can kill the entire session by running: cd /opt/eclat-daemon && scripts/kill-tmux.sh. But you don’t need to manually kill the session before starting a new one, as this operation will be performed automatically.
On this topology we can run experiments to test a few EIP Information Elements (IEs). A packet containing EIP data is sent from r1 to r4. The data is processed by nodes r2 and r3 before reaching the destination.
The eBPF code can be found at https://github.com/netgroup/hikepkg-eip
Beforehand, you have to download the EIP package following these instructions:
cd /opt/eclat-daemon && testbed/development_only_daemon.sh
In the TMUX CLIENT1 window, run:
python eclat.py fetch_pkg eip
Exit from the tmux session with Ctrl-b d, now you can proceed with the examples below.
Path Tracing example¶
You can run the testbed with the command:
cd /opt/eclat-daemon && components/eip/testbed/pt_eip_testbed.sh
This will deploy the eCLAT script for Path Tracing on routers r2 and r3.
You can re-attach to the tmux by running the script: cd /opt/eclat-daemon && scripts/resume-tmux.sh.
You can now send a packet from r1 using tcpreplay, the command will be ready at the R1 window. On the R4 window you can start tcpdump to analyze the received packet. Also in this case the command will be ready to be executed on the R4 window. Use the DEBUG window to see the logs printed by both r2 and r3. It’s likely that you’ll see twice the same logs if the packet is forwarded correctly, because logs from both routers will be shown.
eCLAT script for Path Tracing eip_pt.eclat¶
# eip_pt
#
# (eip_pt.eclat)
#
from programs.hike_default import hike_pass
from programs.eip import mcd, hello
from loaders.hike_default import ip6_simple_classifier
# send all IPv6 packets to our chain
ip6_simple_classifier[ipv6_simple_classifier_map] = { (0): (eip_pt) }
ip6_simple_classifier.attach('DEVNAME', 'xdp')
def eip_pt():
u64 : res = mcd()
if res == 0:
hello()
hike_pass()
return 0
Experiment on STAMP (Simple Two-way Active Measurement Protocol)¶
In this experiment we use the basic testbed. An HIKe chain will be deployed on the SUT node. It implements a STAMP Reflector.
Once the testbed is launched, from the tmux window of the TG, a command is ready to send a STAMP packet to the SUT. The packet will be processed and returned to the TG.
It is possible to check a few logs in the DEBUG tmux window. In another TG window, one can also capture the returned packet using tcpdump to inspect it more deeply.
eCLAT script for STAMP stamp.eclat¶
# stamp
#
# (stamp.eclat)
#
from programs.stamp import stamp_mono
from loaders.hike_default import ip6_simple_classifier
# send all IPv6 packets to our chain
ip6_simple_classifier[ipv6_simple_classifier_map] = { (0): (stamp) }
ip6_simple_classifier.attach('DEVNAME', 'xdp')
def stamp():
stamp_mono()
return 0
The eBPF code can be found at https://github.com/netgroup/hikepkg-stamp.