====== Aggregating multiple ISP links with ML PPP ======
This lab shows an example of aggregating multiple independent ISP links with [[http://mpd.sourceforge.net/ | MPD5]].
===== Network diagram ====
Here is the concept:
{{:documentation:examples:bsdrp.lab.aggregate.isp.links.concept.png|}}
And here is this lab detailed diagram:
{{:documentation:examples:bsdrp.lab.aggregate.isp.links.detail.png|}}
===== Virtual Lab =====
This chapter will describe how to start each routers and configuring the 3 central routers.
More information on these BSDRP lab scripts available on [[documentation:examples:How to build a BSDRP router lab]].
Start the Virtual lab (example using bhyve):
# ./tools/BSDRP-lab-bhyve.sh -n 6
Setting-up a virtual lab with 6 VM(s):
- Working directory: /tmp/BSDRP
- Each VM has 1 core(s) and 512M RAM
- Emulated NIC: virtio-net
- Switch mode: bridge + tap
- 0 LAN(s) between all VM
- Full mesh Ethernet links between each VM
VM 1 has the following NIC:
- vtnet0 connected to VM 2
- vtnet1 connected to VM 3
- vtnet2 connected to VM 4
- vtnet3 connected to VM 5
- vtnet4 connected to VM 6
VM 2 has the following NIC:
- vtnet0 connected to VM 1
- vtnet1 connected to VM 3
- vtnet2 connected to VM 4
- vtnet3 connected to VM 5
- vtnet4 connected to VM 6
VM 3 has the following NIC:
- vtnet0 connected to VM 1
- vtnet1 connected to VM 2
- vtnet2 connected to VM 4
- vtnet3 connected to VM 5
- vtnet4 connected to VM 6
VM 4 has the following NIC:
- vtnet0 connected to VM 1
- vtnet1 connected to VM 2
- vtnet2 connected to VM 3
- vtnet3 connected to VM 5
- vtnet4 connected to VM 6
VM 5 has the following NIC:
- vtnet0 connected to VM 1
- vtnet1 connected to VM 2
- vtnet2 connected to VM 3
- vtnet3 connected to VM 4
- vtnet4 connected to VM 6
VM 6 has the following NIC:
- vtnet0 connected to VM 1
- vtnet1 connected to VM 2
- vtnet2 connected to VM 3
- vtnet3 connected to VM 4
- vtnet4 connected to VM 5
For connecting to VM'serial console, you can use:
- VM 1 : cu -l /dev/nmdm1B
- VM 2 : cu -l /dev/nmdm2B
- VM 4 : cu -l /dev/nmdm4B
- VM 3 : cu -l /dev/nmdm3B
- VM 5 : cu -l /dev/nmdm5B
- VM 6 : cu -l /dev/nmdm6B
==== Backbone routers configuration ====
=== Router 2 ===
Router 2 is configured for rate-limiting traffic at 1 Mb/s on interface to/from R1.
sysrc hostname=R2
sysrc ifconfig_vtnet0="inet 10.0.12.2/24"
sysrc ifconfig_vtnet3="inet 10.0.25.2/24"
sysrc defaultrouter="10.0.25.5"
sysrc firewall_enable=YES
sysrc firewall_script="/etc/ipfw.rules"
cat > /etc/ipfw.rules <
=== Router 3 ===
Router 3 is configured for rate-limiting traffic at 20 Mb/s on interface to/from R1.
sysrc hostname=R3
sysrc ifconfig_vtnet0="inet 10.0.13.3/24"
sysrc ifconfig_vtnet3="inet 10.0.35.3/24"
sysrc defaultrouter="10.0.35.5"
sysrc firewall_enable=YES
sysrc firewall_script="/etc/ipfw.rules"
cat > /etc/ipfw.rules <
=== Router 4 ===
Router 4 is configured for rate-limiting traffic at 3 Mb/s on interface to/from R1.
sysrc hostname=R4
sysrc ifconfig_vtnet0="inet 10.0.14.4/24"
sysrc ifconfig_vtnet3="inet 10.0.45.4/24"
sysrc defaultrouter="10.0.45.5"
sysrc firewall_enable=YES
sysrc firewall_script="/etc/ipfw.rules"
cat > /etc/ipfw.rules <
=== Router 5 ===
Router 5 is the MLPPP server default gateway.
sysrc hostname=R5
sysrc ifconfig_vtnet1="inet 10.0.25.5/24"
sysrc ifconfig_vtnet2="inet 10.0.35.5/24"
sysrc ifconfig_vtnet3="inet 10.0.45.5/24"
sysrc ifconfig_vtnet4="inet 10.0.56.5/24"
sysrc static_routes="ISP1 ISP2 ISP3"
sysrc route_ISP1="-host 10.0.12.1 10.0.25.2"
sysrc route_ISP2="-host 10.0.13.1 10.0.35.3"
sysrc route_ISP3="-host 10.0.14.1 10.0.45.4"
service netif restart
service routing restart
hostname R5
config save
==== Router 6 : L2TP MLPPP server ====
Router 6 is configured as a L2TP server.
sysrc hostname=R6
sysrc cloned_interfaces="lo1"
sysrc ifconfig_lo1="inet 10.6.6.6/32"
sysrc ifconfig_vtnet4="inet 10.0.56.62/24"
sysrc ifconfig_vtnet4_alias1="inet 10.0.56.63/32"
sysrc ifconfig_vtnet4_alias2="inet 10.0.56.64/32"
sysrc defaultrouter="10.0.56.5"
sysrc mpd_enable=YES
sysrc mpd_flags="-b -s ppp"
cat > /usr/local/etc/mpd5/mpd.conf <
==== Router 1 : L2TP MLPPP client ====
Router 1 is configured as a simple L2TP MLPPP client router connected to 3 Internet link.
sysrc hostname=R1
sysrc ifconfig_vtnet0="inet 10.0.12.1/24"
sysrc ifconfig_vtnet1="inet 10.0.13.1/24"
sysrc ifconfig_vtnet2="inet 10.0.14.1/24"
sysrc static_routes="ISP1 ISP2 ISP3"
sysrc route_ISP1="-host 10.0.56.62 10.0.12.2"
sysrc route_ISP2="-host 10.0.56.63 10.0.13.3"
sysrc route_ISP3="-host 10.0.56.64 10.0.14.4"
sysrc mpd_enable=YES
sysrc mpd_flags="-b -s ppp"
cat > /usr/local/etc/mpd5/mpd.conf <
===== Final testing =====
==== Each ISP link bandwidth ====
Start iperf in server mode on R6:
[root@R6]~# iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Now check the correct limited bandwitdh for each different links:
* Link to R6 across R2: 1Mb/s
* Link to R6 across R3: 2Mb/s
* Link to R6 across R4: 3Mb/s
[root@R1]~# iperf3 -i 0 -c 10.0.56.62
Connecting to host 10.0.56.62, port 5201
[ 5] local 10.0.12.1 port 30648 connected to 10.0.56.62 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-10.00 sec 1.21 MBytes 1.02 Mbits/sec 0 65.1 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 1.21 MBytes 1.02 Mbits/sec 0 sender
[ 5] 0.00-10.51 sec 1.19 MBytes 953 Kbits/sec receiver
iperf Done.
[root@R1]~# iperf3 -i 0 -c 10.0.56.63
Connecting to host 10.0.56.63, port 5201
[ 5] local 10.0.13.1 port 13090 connected to 10.0.56.63 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-10.00 sec 2.35 MBytes 1.97 Mbits/sec 0 65.1 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 2.35 MBytes 1.97 Mbits/sec 0 sender
[ 5] 0.00-10.26 sec 2.33 MBytes 1.91 Mbits/sec receiver
iperf Done.
[root@R1]~# iperf3 -i 0 -c 10.0.56.64
Connecting to host 10.0.56.64, port 5201
[ 5] local 10.0.14.1 port 57319 connected to 10.0.56.64 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-10.00 sec 3.48 MBytes 2.92 Mbits/sec 0 65.1 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 3.48 MBytes 2.92 Mbits/sec 0 sender
[ 5] 0.00-10.16 sec 3.46 MBytes 2.86 Mbits/sec receiver
iperf Done.
==== Aggregated ISP link bandwidth ====
The aggregated link bandwidth should be negotiated to 6Mb/s (1+2+3):
[root@R1]~# grep Bundle /var/log/ppp.log
Nov 12 06:04:54 router ppp[87823]: [B-1] Bundle: Interface ng0 created
Nov 12 06:04:54 router ppp[87823]: [B-1] Bundle: Status update: up 1 link, total bandwidth 2000000 bps
Nov 12 06:04:54 router ppp[87823]: [B-1] Bundle: Status update: up 2 links, total bandwidth 3000000 bps
Nov 12 06:04:54 router ppp[87823]: [B-1] Bundle: Status update: up 3 links, total bandwidth 6000000 bps
and iperf measurement close to 6Mb/s:
[root@R1]~# iperf3 -i 0 -c 10.6.6.6
Connecting to host 10.6.6.6, port 5201
[ 5] local 10.0.16.10 port 51350 connected to 10.6.6.6 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-10.00 sec 6.42 MBytes 5.38 Mbits/sec 0 65.1 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 6.42 MBytes 5.38 Mbits/sec 0 sender
[ 5] 0.00-10.09 sec 6.40 MBytes 5.32 Mbits/sec receiver
iperf Done.
In the same time, if you start a "netstat -ihw 1" on R2, R3 and R4, you should see distributed traffic between them.
===== Performance lab =====
This lab will test mpd5 performance by aggregating 2 gigabit links.
Here is the concept:
{{:documentation:examples:bsdrp.lab.mpd5.performance.png|}}
This lab use 3 [[IBM System x3550 M3]] with **quad** cores (Intel Xeon L5630 2.13GHz, hyper-threading disabled), quad NIC 82580 connected to the PCI-Express Bus and dual port Intel 10-Gigabit X540-AT2 connected to the PCI-Express Bus.
==== Router 1 ====
Router 1 is configured a a simple end-point.
Set the base parameters:
sysrc hostname=R1
sysrc ifconfig_ix0="1.1.1.1/24"
sysrc ifconfig_ix0_ipv6="inet6 2001:db8:1::1/64"
sysrc defaultrouter="1.1.1.2"
sysrc ipv6_defaultrouter="2001:db8:1::2"
service netif restart
service routing restart
config save
==== Router 2 ====
Router 2 is configured as a L2TP MLPPP client router.
Configure global parameters:
sysrc hostname=R2
sysrc ifconfig_ix0="1.1.1.2/24"
sysrc ifconfig_ix0_ipv6="inet6 2001:db8:1::2/64"
sysrc ifconfig_igb2="10.0.23.2/24"
sysrc ifconfig_igb3="10.1.23.2/24"
sysrc mpd_enable=YES
sysrc mpd_flags="-b -s ppp"
Configure mpd:
cat > /usr/local/etc/mpd5/mpd.conf <<'EOF'
default:
load l2tp_client
l2tp_client:
# Create the bundle
create bundle template B
# Enable IPv6
set bundle enable ipv6cp
# Disable compression (for iperf test)
#set bundle enable compression
#set ccp yes deflate
# Enable TCP MSS fix
set iface enable tcpmssfix
# Use this interface as default route
set iface route default
# Disable IPCP configuration for the iperf test
#set ipcp yes vjcomp
# Create clonable template link
create link template L l2tp
set link action bundle B
set link enable multilink
set link keep-alive 10 30
set link mtu 1460
set l2tp secret blah
set link max-redial 0
# LINK1
create link static link1 L
set l2tp peer 10.0.23.3
open link
# LINK2
create link static link2 L
set l2tp peer 10.1.23.3
open link
'EOF'
And apply your changes:
service netif restart
service routing restart
service mpd5 start
config save
==== Router 3 ====
Router 3 is configured as a (L2TP server).
Set the global parameters:
sysrc hostname=R3
sysrc cloned_interfaces="lo1"
sysrc ifconfig_lo1="inet 3.3.3.3/32"
sysrc ifconfig_lo1_ipv6="inet6 2001:db8:3::3/64"
sysrc ifconfig_igb2="10.0.23.3/24"
sysrc ifconfig_igb3="10.1.23.3/24"
sysrc mpd_enable=YES
sysrc mpd_flags="-b -s ppp"
Configure mpd5:
cat > /usr/local/etc/mpd5/mpd.conf <<'EOF'
default:
load l2tp_server
l2tp_server:
# IP Pool
set ippool add pool1 10.3.23.10 10.3.23.100
# Create bundle template named B
create bundle template B
# Enable compression (disabled on the client)
set bundle enable compression
set ccp yes deflate
# Enable IPv6
set bundle enable ipv6cp
# Configure interface
set iface enable tcpmssfix
# Handle IPCP configuration
set ipcp yes vjcomp
# Handle the IPCP configuration
set ipcp ranges 10.3.23.1/24 ippool pool1
# Create clonable link template
create link template L l2tp
set link action bundle B
set link enable multilink
set link keep-alive 10 30
set link mtu 1460
set l2tp secret blah
# LINK1
create link static link1 L
set l2tp self 10.0.23.3
set link enable incoming
# LINK2
create link static link2 L
set l2tp self 10.1.23.3
set link enable incoming
'EOF'
if-up script (for installing routes to R1 subnet):
cat > /usr/local/etc/mpd5/if-up.sh <<'EOF'
#!/bin/sh
#mpd5 call script with options:
#interface proto local-ip remote-ip authname [ dns1 server-ip ] [ dns2 server-ip ] peer-address
#Examples
#command "/usr/local/etc/mpd5/if-up.sh ng0 inet 10.3.23.1/32 10.3.23.10 '-' '' '' '10.1.23.2'"
#command "/usr/local/etc/mpd5/if-up.sh ng0 inet6 fe80::5ef3:fcff:fee5:a4c0%ng0 fe80::5ef3:fcff:fee5:7338%ng0 '-' '10.1.23.2'"
#mpd5 wait for 0 as successful
set -e
logger "$0 called with parameters: $@"
remote_inet="1.1.1.0/24"
remote_inet6="2001:db8:1:: -prefixlen 64"
eval "
if route get -net -\$2 \${remote_$2}; then
logger \"route \${remote_$2} already present\"
return 0
else
cmd=\"route add -\$2 \${remote_$2} \$4\"
fi
"
if $cmd; then
logger "$0: $cmd successfull"
return 0
else
logger "$0: $cmd failed"
return 1
fi
'EOF'
chmod +x /usr/local/etc/mpd5/if-up.sh
Then the if-down script:
cat > /usr/local/etc/mpd5/if-down.sh <<'EOF'
#!/bin/sh
#mpd5 call script with options:
#interface proto local-ip remote-ip authname peer-address
#example:
#command "/urs/local/etc/mpd5/if-down.sh ng0 inet 10.3.23.1/32 10.3.23.10 '-' '10.0.23.2'"
logger "$0 called with parameters: $@"
remote_inet="1.1.1.0/24"
remote_net6="2001:db8:1::1 -prefixlen 64"
eval "
if ! route get -net -\$2 ${remote_$2}; then
logger "Route ${remote_inet} not in table"
return 0
else
cmd=\"route del \${remote_$2} \$4\"
fi
"
if $cmd; then
logger "if-down: ${cmd} succesfull"
return 0
else
logger "if-down: ${cmd} failed"
return 1
fi
'EOF'
chmod +x /usr/local/etc/mpd5/if-down.sh
And apply your changes:
service netif restart
service routing restart
service mpd5 start
config save
==== Performance tests ====
=== Checking perf tool ===
== Direct tests between R1 and R2 ===
[root@bsdrp1]~# iperf -c 1.1.1.2 -t 60
------------------------------------------------------------
Client connecting to 1.1.1.2, TCP port 5001
TCP window size: 32.5 KByte (default)
------------------------------------------------------------
[ 3] local 1.1.1.1 port 57149 connected with 1.1.1.2 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-60.0 sec 24.5 GBytes 3.50 Gbits/sec
==== Direct tests between R2 and R3 ====
We start by testing each Gigabit links between R2 and R3 for measuring iperf value on standard gigabit link:
[root@R2]~# iperf -c 10.0.23.3 -t 60
------------------------------------------------------------
Client connecting to 10.0.23.3, TCP port 5001
TCP window size: 32.5 KByte (default)
------------------------------------------------------------
[ 3] local 10.0.23.2 port 21046 connected with 10.0.23.3 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-60.0 sec 6.54 GBytes 936 Mbits/sec
[root@R2]~# iperf -c 10.1.23.3 -t 60
------------------------------------------------------------
Client connecting to 10.1.23.3, TCP port 5001
TCP window size: 32.5 KByte (default)
------------------------------------------------------------
[ 3] local 10.1.23.2 port 50717 connected with 10.1.23.3 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-60.0 sec 6.55 GBytes 937 Mbits/sec
==== mpd5 perfs ===
=== between R2 and R3 ==
Iperf will use the MPPP tunnel extremity:
[root@R2]~# set DEST=`ifconfig ng0 | grep 'inet ' | cut -d ' ' -f 4`
[root@R2]~# iperf -c $DEST -t 60
------------------------------------------------------------
Client connecting to 10.3.23.1, TCP port 5001
TCP window size: 32.5 KByte (default)
------------------------------------------------------------
[ 3] local 10.3.23.10 port 19383 connected with 10.3.23.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-60.1 sec 6.14 GBytes 878 Mbits/sec
The value is almost the same than without MLPPP aggregated link, but correctly load-balanced across each link.
iR2 stats during this test:
/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10
Load Average ||||
Interface Traffic Peak Total
ng0 in 17.271 Mb/s 18.694 Mb/s 3.743 GB
out 974.656 Mb/s 1055.503 Mb/s 7.324 GB
igb3 in 11.405 Mb/s 12.261 Mb/s 3.456 GB
out 507.970 Mb/s 550.255 Mb/s 27.449 GB
igb2 in 11.389 Mb/s 12.274 Mb/s 3.422 GB
out 508.061 Mb/s 550.328 Mb/s 18.673 GB
And the load show:
[root@R2]~# top -nCHSIzs1
last pid: 14152; load averages: 0.94, 0.48, 0.21 up 0+23:54:56 12:40:23
155 processes: 5 running, 99 sleeping, 51 waiting
Mem: 3564K Active, 26M Inact, 384M Wired, 256K Cache, 17M Buf, 15G Free
Swap:
PID USERNAME PRI NICE SIZE RES STATE C TIME CPU COMMAND
8524 root -16 - 0K 64K sleep 0 2:04 25.68% ng_queue{ng_queue2}
8524 root -16 - 0K 64K sleep 1 1:47 25.49% ng_queue{ng_queue1}
8524 root -16 - 0K 64K sleep 3 2:03 22.36% ng_queue{ng_queue0}
14149 root 36 0 32136K 3092K sbwait 1 0:06 21.88% iperf{iperf}
8524 root -16 - 0K 64K sleep 2 1:56 20.26% ng_queue{ng_queue3}
11 root -92 - 0K 816K WAIT 3 0:20 7.57% intr{irq286: igb3:que}
11 root -92 - 0K 816K WAIT 1 0:17 5.96% intr{irq279: igb2:que}
11 root -92 - 0K 816K WAIT 3 0:09 0.78% intr{irq281: igb2:que}
11 root -92 - 0K 816K WAIT 2 0:05 0.59% intr{irq280: igb2:que}
11 root -92 - 0K 816K WAIT 0 0:06 0.39% intr{irq278: igb2:que}
0 root -92 0 0K 560K - 1 0:00 0.10% kernel{igb3 que}
For information, using netblast (UDP packet generator) disturb the links:
netblast $DEST 9090 1470 30 `sysctl -n hw.ncpu`
and measure the bandwidth received on R3:
0 pps 0.000 Mbps - 0 pkts in 0.522753682 ns
2149 pps 25.277 Mbps - 1079 pkts in 0.501997052 ns
0 pps 0.000 Mbps - 0 pkts in 0.501999569 ns
45 pps 0.539 Mbps - 23 pkts in 0.502000238 ns
0 pps 0.000 Mbps - 0 pkts in 0.502000362 ns
713 pps 8.387 Mbps - 358 pkts in 0.501999604 ns
2107 pps 24.786 Mbps - 1077 pkts in 0.511002670 ns
0 pps 0.000 Mbps - 0 pkts in 0.501998712 ns
0 pps 0.000 Mbps - 0 pkts in 0.501998967 ns
21 pps 0.255 Mbps - 11 pkts in 0.508000385 ns
0 pps 0.000 Mbps - 0 pkts in 0.501998785 ns
The packet generator prevent to manage keepalive:
Jan 27 10:50:38 R2 ppp: [link1] LCP: no reply to 1 echo request(s)
Jan 27 10:50:38 R2 ppp: [link2] LCP: no reply to 1 echo request(s)
Jan 27 10:50:48 R2 ppp: [link2] LCP: no reply to 2 echo request(s)
Jan 27 10:50:48 R2 ppp: [link2] LCP: peer not responding to echo requests
Jan 27 10:50:48 R2 ppp: [link2] LCP: state change Opened --> Stopping
Jan 27 10:50:48 R2 ppp: [link2] Link: Leave bundle "B-1"