Tag Archives: Linux

Using bird to pull global BGP route counts

For an electronics project I’m working on I wanted a way to check the current global routing table every five minutes for both IPv4 and IPv6. I did not want to log into anyone else’s router or looking glass as checking every 5 minutes may be considered abuse.

So I thought to spin up a bird routing instance. I just wanted to receive the routes, not actually install them into the kernel on my linux box. From there I’d be able to check the table size sent over.

Nat Morris helped me out by sending a full tables over a multihop BGP session.

Installing bird is trivial. In order to ensure I’m only running BGP and not installing into the kernel, my configuration looks pretty simple.

/etc/bird.conf:

log syslog all;

router id x.x.x.x;

protocol device { }

protocol bgp {
        local as xxxxx;
        neighbor x.x.x.x as xxxxx;
        multihop;
        password "xxxxx";
}

/etc/bird6.conf:

log syslog all;

router id x.x.x.x;

protocol device { }

protocol bgp {
        local as xxxxx;
        neighbor x:x:x:x:x::x as xxxxx;
        source address x:x:x:x:x:x::x;
        multihop;
        password "xxxxx";
}

In order to get the figures I need, I’d usually have to log into the console of the daemon like so:

$ birdc
BIRD 1.3.7 ready.
bird> show protocols all bgp1
name     proto    table    state  since       info
bgp1     BGP      master   up     19:06       Established
  Preference:     100
  Input filter:   ACCEPT
  Output filter:  REJECT
  Routes:         511014 imported, 0 exported, 511014 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:         523721          0          0        826     522895
    Import withdraws:         1313          0        ---          0       1313
    Export updates:         522895     522895          0        ---          0
    Export withdraws:         1313        ---        ---        ---          0
  BGP state:          Established
    Neighbor address: x.x.x.x
    Neighbor AS:      xxxxx
    Neighbor ID:      x.x.x.x
    Neighbor caps:    refresh AS4
    Session:          external multihop AS4
    Source address:   x.x.x.x
    Hold timer:       142/180
    Keepalive timer:  33/60

I could get a script to log in and get the required information via regular expressions, but there has to be an easier way. Turns out you can push a command directly to bird without logging into it first:

$birdc 'show protocols all bgp1'
BIRD 1.3.7 ready.
name     proto    table    state  since       info
bgp1     BGP      master   up     19:06       Established
  Preference:     100
  Input filter:   ACCEPT
  Output filter:  REJECT
  Routes:         511025 imported, 0 exported, 511025 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:         523924          0          0        839     523085
    Import withdraws:         1329          0        ---          0       1329
    Export updates:         523085     523085          0        ---          0
    Export withdraws:         1329        ---        ---        ---          0
  BGP state:          Established
    Neighbor address: x.x.x.x
    Neighbor AS:      xxxxx
    Neighbor ID:      x.x.x.x.x
    Neighbor caps:    refresh AS4
    Session:          external multihop AS4
    Source address:   x.x.x.x
    Hold timer:       161/180
    Keepalive timer:  24/60

Still too much information, but we can use grep!

$birdc 'show protocols all bgp1' | grep 'Routes'
  Routes:         510977 imported, 0 exported, 510977 preferred

Better, but those fields are nicely tabbed so awk to the rescue! I’d like to get that route count. Easily done.

$birdc 'show protocols all bgp1' | grep 'Routes' | awk {'print $2'}
510976

I can now cron a script that will pull those values once every 5 minutes and generate an XML file which you can see right here.

Feel free to query that page and use it for your own projects. Just be aware there is NO SLA on it :)

Quick and dirty way to create a bunch of loopbacks with IP addresses

This can be handy when doing some sort of BGP lab. There are ways to pull various source data with real prefixes into BGP, but sometimes you just want to create a bunch of local addresses.

Daniel helped me out with this initially and I’ve simple added a couple of things.

This is the script on my linux box:

#!/usr/bin/perl
for ($ip=1; $ip<256; $ip++)
{
print "interface loopback$ip\n";
print "ip address 1.2.3.$ip 255.255.255.255\n";
print "ip address 2.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 3.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 4.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 5.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 6.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 7.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 8.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 9.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 10.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 11.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 12.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 13.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 14.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 15.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 16.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 17.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 18.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 19.2.3.$ip 255.255.255.255 secondary\n";
print "ip address 20.2.3.$ip 255.255.255.255 secondary\n";
}

Running the script spits out a ton of IPs:

./IP_Generate.pl
interface loopback1
ip address 1.2.3.1 255.255.255.255
ip address 2.2.3.1 255.255.255.255 secondary
ip address 3.2.3.1 255.255.255.255 secondary
ip address 4.2.3.1 255.255.255.255 secondary
ip address 5.2.3.1 255.255.255.255 secondary
ip address 6.2.3.1 255.255.255.255 secondary
ip address 7.2.3.1 255.255.255.255 secondary
ip address 8.2.3.1 255.255.255.255 secondary
ip address 9.2.3.1 255.255.255.255 secondary
ip address 10.2.3.1 255.255.255.255 secondary
ip address 11.2.3.1 255.255.255.255 secondary
ip address 12.2.3.1 255.255.255.255 secondary
ip address 13.2.3.1 255.255.255.255 secondary
ip address 14.2.3.1 255.255.255.255 secondary
ip address 15.2.3.1 255.255.255.255 secondary
ip address 16.2.3.1 255.255.255.255 secondary
ip address 17.2.3.1 255.255.255.255 secondary
ip address 18.2.3.1 255.255.255.255 secondary
ip address 19.2.3.1 255.255.255.255 secondary
ip address 20.2.3.1 255.255.255.255 secondary
interface loopback2
ip address 1.2.3.2 255.255.255.255
ip address 2.2.3.2 255.255.255.255 secondary
ip address 3.2.3.2 255.255.255.255 secondary
ip address 4.2.3.2 255.255.255.255 secondary
ip address 5.2.3.2 255.255.255.255 secondary
ip address 6.2.3.2 255.255.255.255 secondary
ip address 7.2.3.2 255.255.255.255 secondary
ip address 8.2.3.2 255.255.255.255 secondary
ip address 9.2.3.2 255.255.255.255 secondary
ip address 10.2.3.2 255.255.255.255 secondary
ip address 11.2.3.2 255.255.255.255 secondary
ip address 12.2.3.2 255.255.255.255 secondary
ip address 13.2.3.2 255.255.255.255 secondary
ip address 14.2.3.2 255.255.255.255 secondary
ip address 15.2.3.2 255.255.255.255 secondary
ip address 16.2.3.2 255.255.255.255 secondary
ip address 17.2.3.2 255.255.255.255 secondary
ip address 18.2.3.2 255.255.255.255 secondary
ip address 19.2.3.2 255.255.255.255 secondary
ip address 20.2.3.2 255.255.255.255 secondary
interface loopback3
ip address 1.2.3.3 255.255.255.255
ip address 2.2.3.3 255.255.255.255 secondary
ip address 3.2.3.3 255.255.255.255 secondary
ip address 4.2.3.3 255.255.255.255 secondary
ip address 5.2.3.3 255.255.255.255 secondary
ip address 6.2.3.3 255.255.255.255 secondary
ip address 7.2.3.3 255.255.255.255 secondary
ip address 8.2.3.3 255.255.255.255 secondary
ip address 9.2.3.3 255.255.255.255 secondary
ip address 10.2.3.3 255.255.255.255 secondary
ip address 11.2.3.3 255.255.255.255 secondary
ip address 12.2.3.3 255.255.255.255 secondary
ip address 13.2.3.3 255.255.255.255 secondary
ip address 14.2.3.3 255.255.255.255 secondary
ip address 15.2.3.3 255.255.255.255 secondary
ip address 16.2.3.3 255.255.255.255 secondary
ip address 17.2.3.3 255.255.255.255 secondary
ip address 18.2.3.3 255.255.255.255 secondary
ip address 19.2.3.3 255.255.255.255 secondary
ip address 20.2.3.3 255.255.255.255 secondary
etc
etc
etc
...

You can redirect that to a text file to import or whatever. Adjust as needed

Why buy a terminal server when an old PC will do

My lab will require me to console into 4 switches. I don’t want to buy another router to be my terminal server, and I also don’t want to have to swap out console cables every 2 minutes.

Thankfully I don’t have to. Linux has a handy tool to turn a regular PC with a bunch of USB serial ports into a terminal server.

All you need is a bunch of USB ports (a USB hub will do), some rollover cables and a bunch of these which I found on ebay:

I bought 3 of the above, as the PC itself already has 1 serial port.

The app I’m going to use is called ser2net. Let’s install it

darreno@CCIE:~$ sudo apt-get install ser2net

Now let’s see if Ubuntu 10.10 has reconised my USB serial cables:

darreno@CCIE:~$ dmesg | grep tty
[    0.000000] console [tty0] enabled
[    0.932016] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    0.932314] 00:05: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    6.625434] usb 6-1: ch341-uart converter now attached to ttyUSB0
[    6.649441] usb 6-3: ch341-uart converter now attached to ttyUSB1
[    6.672443] usb 3-2: ch341-uart converter now attached to ttyUSB2

Looks good so far. ttyS0 is my physical serial port and the ttyUSBx ports are the 3 USB-Serial cables. I’ll now configure ser2net to map TCP ports to my onboard port and my 3 USB ports.

darreno@CCIE:~$ sudo vi /etc/ser2net.conf

At the bottom of that file you’ll see this:

2000:telnet:600:/dev/ttyS0:9600 8DATABITS NONE 1STOPBIT banner
2001:telnet:600:/dev/ttyS1:9600 8DATABITS NONE 1STOPBIT banner
3000:telnet:600:/dev/ttyS0:19200 8DATABITS NONE 1STOPBIT banner
3001:telnet:600:/dev/ttyS1:19200 8DATABITS NONE 1STOPBIT banner

Let’s change it to this:

2000:telnet:600:/dev/ttyS0:9600 8DATABITS NONE 1STOPBIT banner
2001:telnet:600:/dev/ttyUSB0:9600 8DATABITS NONE 1STOPBIT banner
2002:telnet:600:/dev/ttyUSB1:9600 8DATABITS NONE 1STOPBIT banner
2003:telnet:600:/dev/ttyUSB2:9600 8DATABITS NONE 1STOPBIT banner

save and quit, then restart ser2net:

darreno@CCIE:~$ sudo /etc/init.d/ser2net restart
 * Restarting Serial port to network proxy ser2net                                                          [ OK ]

Now to test!

My dynamips box has an IP of 10.20.30.11. If I want to get to the physical serial port from my laptop, I only need to do this:

C:\Users\Darren>telnet 10.20.30.11 2000
ser2net port 2000 device /dev/ttyS0 [9600 N81] (Debian GNU/Linux)

C3560#
C3560#

What about a USB cable?

C:\Users\Darren>telnet 10.20.30.11 2003
ser2net port 2003 device /dev/ttyUSB2 [9600 N81] (Debian GNU/Linux)

C3550#
C3550#

I use a tabbed telnet/SSH app called ZOC. From there I can specify the telnet ports and which switch they map to. I can now console into all of them without the need of a terminal server. The actual USB-Serial cables only cost me £2 each, and you can have loads of them.

(2011/02/19) EDIT: Dariush below mentioned that you can get multiple serial adaptors through a single USB port. This is an example: http://www.amazon.co.uk/NEWLink-Serial-Quad-Cable-Adaptor/dp/B003DA5TG4

If you don’t want to go the USB hub root, this could certainly work. Serial cables aren’t exactly high bandwidth. I’ve even found an 8 port model here, but no price: http://www.delock.com/produkte/gruppen/USB+Adapter/Delock_Adapter_USB_8x_Serial_61519.html

New consumer router – Asus RT-N16

At home I’ve been using a Linksys WRT54GL loaded with DD-WRT for quite some time. I think it’s time has come and gone though. 100Mb LAN speed and no ‘N’ wireless speed.

I’ve decided upon the Asus RT-N16 and I’m going to load Tomato USB on it. This thing supports Wireless ‘N’, has gigabit lan, a faster CPU and hopefully better performance.

I wanted to do a baseline performance comparison of my current set up first. I have an Acer Revo 3610 in my lounge hard wired to my router. The 3610 has a gig onboard NIC. My PC has a gig NIC and is also hardwired. I have a Synology ds210j NAS that has a gig NIC onboard and is hardwired. I also have a Acer Revo 3600 in my bedroom which currently uses it’s onboard Wireless ‘G’ NIC, which xbmc doesn’t seem to like playing media through: http://mellowd.co.uk/ccie/?p=1081 – I also have various other wireless devices.

I have iperf installed on all my main devices, so let’s see what kind of results I get with the Linksys WRT54GL

NAS <==> 100Mb Hard Wired 3610

Simba> iperf -s -p 555  -i 10
------------------------------------------------------------
Server listening on TCP port 555
TCP window size: 85.3 KByte (default)
------------------------------------------------------------


mellowd@XBMCLive:~$ iperf -c 10.20.30.4 -p 555  -i 10 -t 90
------------------------------------------------------------
Client connecting to 10.20.30.4, TCP port 555
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 10.20.30.140 port 50237 connected with 10.20.30.4 port 555
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec    112 MBytes  94.3 Mbits/sec
[  3] 10.0-20.0 sec    112 MBytes  94.1 Mbits/sec
[  3] 20.0-30.0 sec    112 MBytes  94.0 Mbits/sec
[  3] 30.0-40.0 sec    112 MBytes  94.1 Mbits/sec
[  3] 40.0-50.0 sec    112 MBytes  94.1 Mbits/sec
[  3] 50.0-60.0 sec    112 MBytes  94.1 Mbits/sec
[  3] 60.0-70.0 sec    112 MBytes  94.1 Mbits/sec
[  3] 70.0-80.0 sec    112 MBytes  94.1 Mbits/sec
[  3] 80.0-90.0 sec    112 MBytes  94.0 Mbits/sec
[  3]  0.0-90.0 sec  1010 MBytes  94.1 Mbits/sec
mellowd@XBMCLive:~$ sudo iperf -s -p 555  -i 10
------------------------------------------------------------
Server listening on TCP port 555
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

Simba> iperf -c 10.20.30.140 -p 555  -i 10 -t 90
------------------------------------------------------------
Client connecting to 10.20.30.140, TCP port 555
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 10.20.30.4 port 51931 connected with 10.20.30.140 port 555
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec    112 MBytes  94.1 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 10.0-20.0 sec    112 MBytes  94.1 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 20.0-30.0 sec    112 MBytes  94.2 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 30.0-40.0 sec    101 MBytes  84.5 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 40.0-50.0 sec  54.5 MBytes  45.7 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 50.0-60.0 sec  54.6 MBytes  45.8 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 60.0-70.0 sec  54.5 MBytes  45.8 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 70.0-80.0 sec  54.5 MBytes  45.7 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3] 80.0-90.0 sec  54.6 MBytes  45.8 Mbits/sec
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-90.0 sec    710 MBytes  66.2 Mbits/sec

I had already tested the wireless Revo 3600, but here were it’s results:
NAS <==> Wireless Revo

Simba> iperf -s -p 555  -i 10
------------------------------------------------------------
Server listening on TCP port 555
TCP window size: 85.3 KByte (default)
------------------------------------------------------------


mellowd@XBMCLive:~$ iperf -c 10.20.30.4 -p 555  -i 10 -t 600
------------------------------------------------------------
Client connecting to 10.20.30.4, TCP port 555
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 10.20.30.110 port 45553 connected with 10.20.30.4 port 555
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  19.2 MBytes  16.1 Mbits/sec
[  3] 10.0-20.0 sec  19.4 MBytes  16.3 Mbits/sec
[  3] 20.0-30.0 sec  18.6 MBytes  15.6 Mbits/sec
[  3] 30.0-40.0 sec  18.4 MBytes  15.4 Mbits/sec
[  3] 40.0-50.0 sec  18.5 MBytes  15.5 Mbits/sec
[  3] 50.0-60.0 sec  18.4 MBytes  15.4 Mbits/sec
[  3] 60.0-70.0 sec  15.7 MBytes  13.1 Mbits/sec
[  3] 70.0-80.0 sec  16.9 MBytes  14.2 Mbits/sec
.
.
.
.
.
.
[  3] 270.0-280.0 sec  18.7 MBytes  15.7 Mbits/sec
^C[  3]  0.0-285.7 sec    503 MBytes  14.8 Mbits/sec

Basically an avergage of between 66-94Mb on the wire and 14.8Mb on the wireless. How does the Asus hold up?

NAS <==> 1Gb Hard Wired 3610

Simba> iperf -s -p 555  -i 10
------------------------------------------------------------
Server listening on TCP port 555
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

mellowd@XBMCLive:~$ iperf -c 10.20.30.4 -p 555  -i 10 -t 90
------------------------------------------------------------
Client connecting to 10.20.30.4, TCP port 555
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  3] local 10.20.30.6 port 44203 connected with 10.20.30.4 port 555
[ ID] Interval         Transfer       Bandwidth
[  3]  0.0-10.0 sec    752 MBytes    631 Mbits/sec
[  3] 10.0-20.0 sec    753 MBytes    632 Mbits/sec
[  3] 20.0-30.0 sec    742 MBytes    622 Mbits/sec
[  3] 30.0-40.0 sec    751 MBytes    630 Mbits/sec
[  3] 40.0-50.0 sec    747 MBytes    627 Mbits/sec
[  3] 50.0-60.0 sec    743 MBytes    623 Mbits/sec
[  3] 60.0-70.0 sec    750 MBytes    629 Mbits/sec
[  3] 70.0-80.0 sec    748 MBytes    627 Mbits/sec
[  3] 80.0-90.0 sec    746 MBytes    626 Mbits/sec
[  3]  0.0-90.0 sec  6.57 GBytes    627 Mbits/sec

NAS <==> Wireless 3610

mellowd@XBMCLive:~$ iperf -c 10.20.30.4 -p 777  -i 10 -t 60
------------------------------------------------------------ 
Client connecting to 10.20.30.4, TCP port 777 
TCP window size: 16.00 KByte (default) 
------------------------------------------------------------ 
[196] local 10.20.30.14 port 55378 connected with 10.20.30.4 port 777 
[ ID] Interval       Transfer         Bandwidth 
[196] 0.0-10.0 sec   38.9 MBytes      32.6 Mbits/sec 
[196] 10.0-20.0 sec  37.6 MBytes      31.5 Mbits/sec 
[196] 20.0-30.0 sec  38.8 MBytes      32.5 Mbits/sec 
[196] 30.0-40.0 sec  39.3 MBytes      33.0 Mbits/sec 
[196] 40.0-50.0 sec  36.1 MBytes      30.3 Mbits/sec 
[196] 50.0-60.0 sec  40.0 MBytes      33.6 Mbits/sec 
[196] 0.0-60.0 sec   231 MBytes       32.2 Mbits/sec

Basically, the wired LAN has improved loads, but not exactly running at 1Gbps. Also the wireless speed has doubled, but nothing to write home about. It’s great for surfing, but forget about streaming HD video

Protocol fundamentals – Traceroute differences between Windows and Linux

My last post about Traceroute over here: http://mellowd.co.uk/ccie/?p=609 – got some interesting conversation going on in the comments.

Basically there is quite a big difference in the way in which Windows and Linux handle traceroute. I tested on both Windows 7 and Ubuntu 10.04, but my guess is that all Windows follow the same format as do all *nix’s (please let me know if otherwise though!)

I would recommend reading the above post again quickly to get all the basics out the way before we delve into the differences.

Step-wise, this is what happens on Windows:

  1. The OS send a DNS PTR request to 1.2.2.4.in-addr.arpa to get the hostname for 4.2.2.1
  2. I get a DNS PTR response giving me a hostname
  3. The OS send an ICMP ECHO request with a TTL of 1
  4. I get an ICMP TTL Exceeded packet back from my local router
  5. 3 & 4 above happens twice more
  6. The OS send a DNS PTR request to my local router
  7. My local router responds with it’s hostname
  8. The cycle above (3-7) is then repeated with a TTL of 2, then 3 and so on
  9. We finally get to 4.2.2.1 – which sends back an ICMP ECHO reply – Once I get 3 the job is complete.

Ubuntu does this completely differently though. Step-wise this is what’s going on:

  1. The OS immidiately sent 3 UDP packets with a high port number straight to 4.2.2.1 with a TTL of 1
  2. The local router responded with 3X ICMP TTL Exceeded message
  3. The above (1 & 2) is then repeated until we get to 4.2.2.1
  4. 4.2.2.1 does not generate a ICMP ECHO reply as an ECHO request was not sent. Rather we get 3 ICMP Code 3 (Port unreachable) replies
  5. The OS now throws out 7 DNS PTR request specifically to each IP it determined in the path from above (Including 4.2.2.1 iself!)
  6. As soon as all the replies come, the job is complete.

The main differences are that Windows will send a DNS PTR request from the start, then send ICMP ECHO requests. At each hop it’ll send a DNS PTR request and then move onto the next hop.
Linux starts with sending UDP packets to a high port number straight away. When it finally gets to the last hop it’ll then send out a mass DNS PTR request to every hop in the path that it has determined.