Temporarily Changing the Default Gateway to a Virtual Station

When testing a virtual station and you need to verify with a browser that you can reach a captive portal page, or browse the Internet–you want to change the default gateway of the system to the gateway that the virtual station was assigned. This is a manual change, because when the virtual station associates, the default route of the system doesn’t change. If it did, you’d probably lose connection between the LANforge resource and your management station would probably be lost.

After checking your associated station, you can write a script to help set the new default gateway. Here’s an example with some fixed values:

#!/bin/bash
echo "Please do this command in screen"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Use this script to modify your routes to allow a station      #
# to become the default route. Should maintain route for your   #
# existing connection to management laptop through eth0.        #
# This script is an example to be modified.                     #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
set -x
ip a show eth0
ip a show sta100
ip route show

# this adds address to station, referred to below
# ip a add 10.45.1.23/24 dev sta100

# make static route to old gateway
ip route add 192.168.45.1 dev eth0

# make static route to mgt laptop
ip route add 192.168.45.2 dev eth0

# now update default route to go out sta100
ip route change default via 10.45.1.23 dev sta100

sleep 1s
ping -nc2 192.168.45.1
ping -nc2 192.168.45.2

# adjust this to your work time window
read -t $((2 * 60)) -p "Press Enter to end and reset"

# and set the route back
ip route change default via 192.168.45.1 dev eth0
ip route show
ping -nc2 192.168.45.1
ping -nc2 192.168.45.2

Notice that the script suggests using screen.  Why use screen? Because if your terminal session disconnects, the script will continue and reset the previous default gateway. If the script is interrupted (by session disconnection or control-c) your default route will remain running across your AP. (We add default link-local routes to our laptop to help mitigate this.)
There is a default .screenrc file in /home/lanforge. You want to run the script as root. This will work: sudo ./change_gw.sh

This is an example script with some logic to help detect the default gateway, your ssh connection, and you tell it what station to use:

#!/bin/bash
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#  Use this script to modify your routes to allow a station     #
#  to become the default route. Should maintain route for your  #
#  existing connection to management laptop through eth0.       #
#  This script is an example to be modified.                    #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

if [ -z "$3" ]; then
   echo "Use this script to assign a station on this system to be the new default gateway."
   echo "Usage: $0   "
   echo ""
   echo "Your manager-ip is the LANforge resource in mode 'manager' or 'both' and might"
   echo "not be the machine hosting the virtual station."
   echo "Example, sta3000 on resource 3, manager is 192.168.1.101:"
   echo ""
   echo "./$0 192.168.1.101 3 sta3000"
   echo ""
   echo "Please do this command in screen"
   exit 1
fi

def_gw_dev=`route -n | awk '/^0.0.0.0 / {print \$NF}'`
def_gw_ip=`ip a show $def_gw_dev | awk '/inet /{print \$2}'`
def_gw_ip=${def_gw_ip%/*}
echo "default gw device: $def_gw_dev $def_gw_ip "
sleep 3
manager_ip=`who | perl -ne '/\(([0-9.]+)\)$/ && print "$1\n";'`
#ip a show $def_gw_dev
echo "This is the station you requested:"
ip a show $3
sleep 3

#  make static route to old gateway
echo "ip route add $def_gw_ip dev $def_gw_dev"
ip route add $def_gw_ip dev $def_gw_dev

#  make static route to mgt laptop
echo "ip route add $manager_ip dev $def_gw_dev"
ip route add $manager_ip dev $def_gw_dev
sleep 3

# now update default route to go out sta100
cd /home/lanforge/scripts
sta_gw=`./lf_portmod.pl --manager $1 --card $2 --port_name $3 \
  --show_port --quiet yes \
  | awk '/ IP:/{print \$6}'`

echo "* Changing default gateway in 3 seconds *"
sleep 3s
echo "ip route change default via $sta_gw dev $3"
sleep 1s
ip route change default via $sta_gw dev $3
sleep 1s
ping -nc2 $def_gw_ip
ping -nc2 $manager_ip

# adjust this to your work time window (in seconds)
#  $(( 2 * 60)) == 120, 2 minutes
read -t $((2 * 60)) -p "Press Enter to end and reset"

# and set the route back
echo "changing route back to previous default gw..."
ip route change default via $def_gw_ip dev $def_gw_dev
ping -nc2 $def_gw_ip
ping -nc2 $manager_ip
echo "...done."
#

To use the script, you would say:

sudo ./change_gw.sh 192.168.100.41 3 sta3000

You are probably going to need to alter the script. If you hit Ctlc in the script you will need to reset the routes by hand.

For actually using Firefox, you need to operate this from the desktop of LANforge resource hosting the virtual station. So if, in this example, sta3000 is on resource 3, you need to get on the virtual desktop of resource 3. Open a terminal from the virtual desktop or ssh to resource 3 and start screen as user LANforge.

Advertisements

Modifying the Port Bringup Report

The LANforge Port Bringup plugin produces a highly detailed and verbose report including all the wifi events from the stations involved. This plugin can be used to record performance of station association and captive portal logins. When you save the Graphical Report screen, it saves an HTML document with pictures to a directory on your machine.

pbu-01

pbu-02

pbu-03

We see the report files created by saving the report below:

pbu-04

This report can be reformatted, and the log messages at the bottom of the output are a useful resource to recreate graphs of interest. With some accessory JavaScript, we can create a completely different report. I start off by writing a shell script that backs up the original index.html file of the report and concatenates it to the end of a new title block.

Example shell script below:
(please excuse my lazy [] brackets, because  &-lt; &-gt; takes longer to type)

#!/bin/bash
if [ ! -f orig.html ]; then
   mv -v index.html orig.html
   dos2unix orig.html
fi
cp -v "~/report-1s.js"      report.js
cp -v "~/chartist.min.css"  .
cp -v "~/chartist.min.js"   .
cp -v "~/moment.js"         .
cp -v "~/images/header.png" .
# now create a new header
cat ▶ 00-report.html ◀◀ EOF
[html]
   [head]
     [title]Customized Report[/title]
     [link rel='stylesheet' type='text/css' href='chartist.min.css']
     [script src='moment.js'][/script]
     [script src='chartist.min.js'][/script]
     [script src='report.js'][/script]
   [/head]
   [body]
     [h1]Station Latency Report[/h1]
     [img src='header.png' /]
     [div id="new_chart"][/div]
     [h2]Station event latency[/h2]
     [div class="ct-chart lf_chart" id="link_1"][/div]
     [pre id='log_messages' style='display:none;']
EOF
# and append old report like so:
cat orig.html ▶▶ 00-report.html
echo "please edit 00-report.html"

I have example update_report.sh and report.js examples posted for you to download and use.

The basis of the reformatting is to move the contents at the top of orig.html into the new report header. Delete content that you don’t want, but leave the Log Messages section, because it will be parsed by the javascript. The style tag keeps it from showing on the page. The first column of the messages is in Unix epoch seconds and milliseconds.

[pre id='log_messages' style='display:none;']
1499751346.692  Starting loop number: 1
1499751346.697  #[1] Bringing all selected ports down.
1499751346.841  #[1] Bringing up selected ports in batches of 100
1499751346.845  set_port 1 1 7 NA NA NA NA 0 NA NA NA NA 8388610
1499751346.854  set_port 1 1 8 NA NA NA NA 0 NA NA NA NA 8388610
1499751346.854  set_port 1 1 9 NA NA NA NA 0 NA NA NA NA 8388610

Data is collected in the report.js javascript by parsing each line for important events, using regular expressions:

matches = line.match(/^(\d+\.\d+) EVENT: .*? eventType:Link-Up details:Port (sta\d+) is Link UP.$/) || [];

Bar charts are created with the create_bar() function.

Line and point charts are created with the Chartist javascript library. Point charts are line charts with lines turned off. The moment.js library allows the Chartist library to process domain data on a time axis.

Below is an example of what a resulting report looks like:pbu-05

Controlling ARP Solicitations

When your network endpoints are not changing during testing scenario, transmitting ARP packets at the default rate is arguably wasted bandwidth. You can tune the Linux networking stack to extend the time between ARP broadcasts.

These tunables are in /proc/sys/net/ipv4/neigh and are divided by default and per-device settings. The knobs I find that are useful are:

  • base_reachable_time: a guideline on how often to broadcast for ARP updates
  • gc_stale_time: threshold in seconds on when to consider evicting an arp entry
  • locktime: minimum time to keep an ARP entry

You can set twist these knobs for two ports in a shell script like so:

for f in /proc/sys/net/ipv4/{enp2,enp3}/{base_reachable_time,gc_stale_time,locktime} ; do
    echo 300 > $f
done

This changes the values to 5 minutes.

Turning off IPMI DHCP

Many SuperMicro motherboards have IPMI features that have a dual-port feature. The first two Ethernet ports on the motherboard are capable of serving the IPMI function.

IPMI served by these ports
IPMI served by these ports

If the dedicated IPMI port is not cabled, IPMI will be served off the LAN1 port (which is predictably the MGT port on LANforge machines).

Turning off IPMI is often not possible, but turning off the IPMI port DHCP is possible. There are two ways of doing this, and you might not even need to reboot your server if your IPMI driver is included in the Linux distribution you are using.

Using the Linux IPMI tools

You might have either the ipmiutils or the ipmitool package available, maybe both. Both are probably going to rely on the same drivers, however.

ipmiutil

# install
 $ sudo yum install ipmiutil
# show configuration
 $ sudo ipmiutil lan -c
# disable the LAN feature (if desired)
 $ sudo ipmiutil lan -d
# or set a fixed IP:
 $ ipmiutil lan -e -I 0.0.0.0

Setting the address of 0.0.0.0 sometimes is a shortcut for disabling the IPMI LAN features. Or you can set a normal non-routable address like 192.168.0.251. (Refer to this post.)

ipmitool

Similar commands are listed for IPMITool on this post. The “lan set 1” phrase refers to “IPMI Device 1.”

 $ sudo ipmitool lan set 1 ipsrc static
 $ sudo ipmitool lan set 1 ipaddr 192.168.0.251
 $ sudo ipmitool lan set 1 netmask 255.255.255.0
 $ sudo ipmitool lan set 1 defgw ipaddr 192.168.0.1

Configuring the BIOS

We might have a motherboard that isn’t in the driver set for these tools. This is how you’d know:
ipmi-100

In this scenario, we need to reboot and press DEL to get into the BIOS. You will likely never see two motherboards with exactly the same BIOS screen layout…but just look for IPMI and you’ll likely get to screens that look like this:

Advanced screen bios-100

Advanced – IPMI Configuration

bios-101

IPMI LAN Configuration

bios-102We can verify that this is the MAC address we’re seeing traffic from using tcpdump. Let’s also gather the MAC addresses because we’ll want those as a reference when looking at our tcpdump data.

bios-ip-103

Now we can craft a tcpdump that will show useful things:

tcpdump -eni eth1 \
    ether host 00:25:90:01:66:0a \
 or ether host 00:25:90:01:66:0b \
 or ether host 00:25:90:01:8a:ef

And we’ll see results like this:

17:35:07.814819 00:25:90:01:8a:ef > Broadcast, ethertype IPv4 (0x0800), length 590: 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:25:90:01:8a:ef, length 548
17:35:10.874561 00:25:90:01:8a:ef > Broadcast, ethertype IPv4 (0x0800), length 590: 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:25:90:01:8a:ef, length 548
17:35:13.945135 00:25:90:01:8a:ef > Broadcast, ethertype IPv4 (0x0800), length 590: 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:25:90:01:8a:ef, length 548

Clearly, we’re getting getting DHCP broadcasts from that port. After setting the IPMI IP in the BIOS to 0.0.0.0, those broadcasts stop.