Creating a Cisco switch using IOUl2 loaded on Linux Core Qemu Image

Introduction

It has always been a dream of Cisco guys to run Cisco IOS on a computer instead of real Cisco hardware. Unfortunately, it is almost impossible to emulate  Cisco devices using  ASICs due to lack of their public specifications. It had changed when Cisco IOS images known as IOU leaked from Cisco. They are basically IOS images compiled either for x86 Linux or Sparc Unix platform. Uncontrollably shared over the Internet, they are widely used in many home labs by Cisco students.

For those individuals not familiar with IOU, the IOU FAQ is available hereTo connect IOU to the real network  a perl script -  iou2net.pl was written by "einval" and can be found here.

The goal of this tutorial is to build Cisco like switch based on IOU that can be used in GNS3 lab. The switch is built on Linux Core that is installed on Qemu virtual machine. Linux Core is occupied with Cisco IOU image and with the script iou2net.pl that connects IOU to other GNS3 devices. In general, the script bridges Core Linux interfaces with Cisco IOU interfaces. Therefore it creates connection between IOU interfaces bridged to particular Core interfaces and between network devices connected to Core Linux interfaces.

They are also my own two scripts loaded in Linux Core. They help to create NETMAP file and to start IOU after boot of Core.

Note I decided to use Linux Core because it is incredibly small size and with minimal hardware requirements.  Linux Core installation on Qemu virtual machine  is not  shown in the tutorial but you can find it here.

For those of you not willing to build  Linux Core from scratch, here is my Core Qemu image.

1. Start Core Qemu image

/usr/local/bin/qemu-system-i386 -m 512 ./linux-microcore-4.0.2-ioul2.img -serial telnet:0.0.0.0:3000,server,nowait --enable-kvm

Telnet to Core.

telnet localhost 3000

2. Install necessary extensions

tce-load -w -i libpcap libpcap-dev perl5 tunctl perl_Net_Pcap ipv6-3.0.3-tinycore.tcz openssh.tcz bridge-utils

3. Load ipv6, 8021q module and make additional Core configuration

echo "modprobe ipv6" >> /opt/bootlocal.sh
echo "modprobe 8021q" >> /opt/bootlocal.sh
sudo modprobe 8021q
sudo modprobe ipv6

Forwarding between interfaces is disabled by default, so we are going to change it.

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
exit
echo "/etc/sysctl.conf" >> /opt/.filetool.lst
echo "sysctl -p /etc/sysctl.conf" >> /opt/bootlocal.sh

Pair hostname with IP address of loopback interface.

sudo su

echo "127.0.0.1 box" >> /etc/hosts
echo "/etc/hosts" >> /opt/.filetool.lst

Save files in listed in /opt/.filetool.lst

/usr/bin/filetool.sh -b
exit

4. Load IOUl2, iou2net.pl, wrapper and iourc to Core Linux

Default hostname for Core is box. The license file - iourc should be configured for that hostname and must contain a valid license key obtained from Cisco.

Create /mnt/sda1/IOU/ directory. This directory will remain IOU image and configuration files untouched after restart.

sudo mkdir /mnt/sda1/IOU/

Copy following files to Core.

sudo du

scp -rv brezular@10.0.2.2:/home/brezular/i86bi_linuxl2* /mnt/sda1/IOU/
scp -rv brezular@10.0.2.2:/home/brezular/wrapper /mnt/sda1/IOU/
scp -rv brezular@10.0.2.2:/home/brezular/iourc /mnt/sda1/IOU/
scp -rv brezular@10.0.2.2:/home/brezular/iou2net.pl /mnt/sda1/IOU/
exit

Assign privilegies to iou2net.pl.

sudo chmod +x /mnt/sda1/IOU/iou2net.pl

5. Create a symbolic link and NETMAP file

To run IOU  it needs library libcrypto.so.4. For this purpose, pointing libcrypto.so.4 to libcrypto.so.0.9.8 is necessary.

sudo ln -s /usr/local/lib/libcrypto.so.0.9.8 /usr/lib/libcrypto.so.4
echo "/usr/lib/libcrypto.so.4" >> /opt/.filetool.lst
/usr/bin/filetool.sh -b

6. Create a perl script netmap.pl that creates IOU topology file - NETMAP file

A script "netmap.pl" creates a new NETMAP file every time the script is started. If the NETMAP file exists, unique local ID for IOU instance is read from original NETMAP.  If the NETMAP file does not exists local ID is generated. An unique pseudo ID is always generated for each instance of iou2net.pl. A number of running iou2net.pl instances matches a number of Linux Core Ethernet interfaces.

Note: Local ID and pseudo IDs are generated in the range of 1 to 1023. All these IDs for GNS3 topology must be unique numbers otherwise a problem with duplicate MAC could occurs. The number of available Ethernet interfaces of Core image can be changed with parameter Edit-> Preferences-> Qemu-> Qemu Host, in GNS3 settings.

Note: Maximum number of allowed interfaces depends on particular Qemu version.

/mnt/sda1/IOU/netmap.pl

Assign privilegies to netmap.pl.

sudo chmod +x /mnt/sda1/IOU/netmap.pl

Put a script to /opt/bootlocal.sh and save it.

echo "/mnt/sda1/IOU/netmap.pl" >> /opt/bootlocal.sh
/usr/bin/filetool.sh -b

Explanation

If Core is started with one Ethernet interfaces, the NETMAP might be generated as following.

10:0/0@box 20:0/0@box

The local IOU instance with ID 10 is running on Core with hostname box. This instance is connected with its interface Ethernet0/0 to pseudo IOU instance with ID 20 and pseudo interface 0/0. Pseudo IOU instance is handled by the script iou2net.pl running on the same Core with hostname box.

The number of lines in NETMAP file matches the number of Ethernet interfaces found in /sys/class/net/ directory. For example, if there were eight ethernet interfaces presented in Core the NETMAP file would have eight lines.

The summary table shows matching IOU interfaces with corresponding Core interfaces. In this case, Core is occupied with twelve Ethernet interfaces.

IOU - Linux Core

Eth 0/0 - eth0
Eth 0/1 - eth1
Eth 0/2 - eth2
Eth 0/3 - eth3
Eth 1/0 - eth4
Eth 1/1 - eth5
Eth 1/2 - eth6
Eth 1/3 - eth7
Eth 2/0 - eth8
Eth 2/1 - eth9
Eth 2/2 - eth10
Eth 2/3 - eth11

7. IOU startup script

The script /mnt/sda1/IOU/iou_start.sh is responsible for these jobs:

  • starts the script netmap.pl
  • starts single IOU instance with 16 Ethernet interfaces and local IOU ID read from NETMAP file, on port 6000
  • brings up all the Ethernet interfaces presented in Core Linux
  • creates appropriate number of tap interfaces and bridges br corresponding to number of Ethernet interfaces
  • assigns a particular ethernet interface e.g eth0 and tap interface e.g tap0 to the particular bridge e.g br0
  • starts iou2net.pl script for particular tap interface with unique pseudo ID

Assign privilegies to iou_start.sh.

sudo chmod +x /mnt/sda1/IOU/iou_start.sh

Put a script to /opt/bootlocal.sh and save it.

echo "/mnt/sda1/IOU/iou_start.sh" >> /opt/bootlocal.sh
/usr/bin/filetool.sh -b

8. After install steps - fixing root's UID for iou2net.pl and cleaning Core Linux

Iou2net.pl must be started with root's privilegies otherwise an error message "pcap: can't open device" appears. Line 202 of io2net.pl says that an enviroment variable SUDO_UID is assigned to variable $uid. As SUDO_UID always has value 1001 (that is UID of user tc) io2net.pl is never started with root's privilegies. In this case an error message "Can't connect to IOU socket" appears and the script is halted.

To fix it, edit io2net.pl and change line 202 starting with $uid = $ENV{SUDO_UID}; to $uid = 0;

Cleaning Core

a) Remove .ssh/known_hosts

rm /root/.ssh/known_hosts
rm /home/tc/.ssh/known_hosts

b) Delete commands' history

rm /root/.ash_history
rm /home/tc/.ash_history
/usr/bin/filetool.sh -b

9. Login to IOU instance

telnet localhost 6000

10. Known issues:

a) Undesired random matching Local ID by pseudo ID

Local ID is generated in range of 1 - 1023. Pseudo IDs are generated in range of 1 - 999. Possibly a problem with mismatched IDs could occur if pseudo ID matches Local ID. In this case, restarts Qemu image as the Pseudo IDs are newly generated after restart of Core Linux.

c) Show command displays only first 24 lines of configuration file when IOU is used with wrapper

This issue is only when certain terminal emulator is used (e.g. kde konsole). Putty is known to work. Workaround is command "terminal lenghth 0" which displays configuration at once. This is valid for a current terminal session only. If you wish to keep setting permanent, configure command length 0 under line-console and line-vty in global configuration mode.

End.

31 thoughts on “Creating a Cisco switch using IOUl2 loaded on Linux Core Qemu Image

  1. Hi Brezular,

    Great write-up, with one minor correction. The author of iou2net.pl is "einval". I made an "enhancement" or two to the script and intended to send him my changes, but he incorporated the changes himself before I got around to sending the code.

    I'm about to move it from the inetpro.org wiki to Github, but he is the author of the code.

    Thanks,
    -Jeremy

      1. Heh, I didn't really do anything besides write up the FAQ and make information available. einval reverse engineered ioulive and made it available. Cisco did the original, hard work. =)

        Regardless, I'm glad it's been helpful to you; that was the whole point!

  2. Hi Brezular, great write-up.

    However at step 6 I am confused. After "Put a script to /opt/bootlocal.sh and save it."

    Should I execute:
    echo "/mnt/sda1/IOU/netmap.pl" >> /opt/bootlocal.sh
    /usr/bin/filetool.sh -b

  3. Ok Thanks. i have another question though.
    Where do I get the wrapper for Microcore you mention? I can't find it with Google.
    Thanx

    1. This is impossible .Please how does it work .Can I run a 3560 catalyst ios on the switch.I was almost getting set to purchase a 3550 for cost .

      1. wait, we're talking about IOU /IOS on Unix/ not IOS. Cisco developed IOU in order to run IOS on Linux without need of physical hardware. Even IOU offers many features you may find in IOS, they are features such as QoS, voice you can't do with IOU. For example, you can't configure interfaces as full-duplex and it brings other possible problems. Also a version of IOU available on the Internet may be bugged.

        Another option is using GNS3 and 3725 router loaded with NM-16SW. It should be enough for testing STP.

        To sum up, IOU L2 brings certain benefits and can simulate switches - but be aware that it is not real IOS running on physical switch. On the other hand, Cisco uses IOU even for CCIE candidate testing so it really can't be trash.

    2. Hi Brezular,

      One question regarding the screenhost you have posted above. I saw that each L2IOU image has different MAC addresses. How did you do that ?
      I have made copies of the qemu image and each instance of L2IOU has same MAC and this cause each instance of L2IOU to think that he is the root and all ports on both sides are on FWD mode.
      The only solution I have found is to manually lower the priority on one of the switches for STP to work properly.

      Thanks,

      1. MAC address for IOU Ethernet interfaces are derived from local IOU instance ID. That is why local ID must be unique across your topology for every IOU device. If you used my netmap.pl script it should be OK as the script generate IOU IDs in range of 1 to 1023. It is not very likely that IOU Ids match but it could happen.
        Just to be sure, check every generated NETMAP file for IOU ID. If IDs match, delete NETMAP file and run netmap.pl again.

  4. Hi.

    First of all great work man, I`ve been reading your blog for some while now - great work!!!

    regarding this manual, I am trying to understand your working enviromnet to do the same.

    on which distro are you working? and which qemu are you using cause on ubuntu i`m getting erros wih regular one.

    also can the procedure be done on windows?

    1. Hi,
      Thanks. I use Fedora 15 and patched Qemu 0.14.1 for UDP tunnels and multicast. Patch for both Qemu 0.11.0 and 0.13.0 is available for download on GNS3 site. When you use Linux you have to patch Qemu sources by yourself.

      Patch for Qemu 0.11.0, 0.13.0.
      http://www.gns3.net/download/

      Patch for Qemu 0.14.1
      http://forum.gns3.net/topic3224-20.html?sid=0ccfc59bbffb4a16816b5b80db26c9a8

      If you use Windows you don't have to patch Qemu sources as patched Qemu is packaged in GNS3 all-in-one package.

      The same installing procedure can be done on Windows. As ssh server doesn't normally run on Windows you must run FTP server on Windows and download IOU files with ftp client from Microcore.

  5. Hi there,
    Is there any way to autologin to IOU instance once the qemu image has started successfully ?
    I have placed this command telnet localhost 6000 in the /opt/bootlocal.sh file then ran /usr/bin/filetool.sh -b and rebooted the image but it did not have any effect.

    Thanks for you great work.

    1. Hi,
      to be honest I couldn't get it working on Microcore. If you do that, please tell me ;-)
      It works as a charm on CentOS when script is placed in to /etc/rc.local. Really funny to see booting CentOS and finally Cisco CLI prompt.

  6. I have problem when running qemu images on gns:
    syntax error at /mnt/sda1/IOU/netmap.pl line 14, near "if"
    syntax error at /mnt/sda1/IOU/netmap.pl line 22, near "}"
    Execution of /mnt/sda1/IOU/netmap.pl aborted due to compilation errors.
    /mnt/sda1/IOU/iou_start.sh: line 6: syntax error: unexpected "|"
    /mnt/sda1/IOU/iou_start.sh: line 6: syntax error: unexpected "|"
    Can you help me?

    1. I've just pasted&copied netmap.pl and it's working. Start Qemu as following, telnet to localhost 3000 and do the same. You must have missed something.

      qemu ./your_image.img -serial telnet:0.0.0.0:3000,server,nowait

  7. Hello Brezular,
    please define how do you installed GNS3 on fedora. I am following your labs as it is. Because the directories are confusing me(eg GNS3-files ... )

  8. Could you please upload your QEMU image (off course without IOU files) as I'm trying to follow the example but have failed 2 times already. My environment is Windows as I don't have Linux dedicated PC. and my CPU is too old for nested virtualization :( . Please, as this driving me crazy

  9. Guys, I've tried everything! i receive:
    /opt/bootlocal.sh: line 8: /mnt/sda1/IOU/netmap.pl: Permission denied
    /mnt/sda1/IOU/iou_start.sh: line 5: /mnt/sda1/IOU/netmap.pl: Permission denied
    tc@box:~$ Waiting on port 6000 ...
    Process Id for child is 1581, parent is 1576
    /mnt/sda1/IOU/i86bi_linuxl2-upk9-ms.M: line 1: syntax error: unexpected "("
    IOU 1581 exit
    Set 'tap0' persistent and owned by uid 0
    expr: syntax error
    Set 'tap1' persistent and owned by uid 0
    expr: syntax error
    Set 'tap2' persistent and owned by uid 0
    expr: syntax error
    Set 'tap3' persistent and owned by uid 0
    expr: syntax error
    Set 'tap4' persistent and owned by uid 0
    expr: syntax error
    Set 'tap5' persistent and owned by uid 0
    expr: syntax error
    Set 'tap6' persistent and owned by uid 0
    expr: syntax error
    Set 'tap7' persistent and owned by uid 0
    expr: syntax error
    Option p requires an argument
    iou2net.pl, Version v0.5, 20-Sep-2011.

    Please provide -i, -t or -u, and -p!

  10. Dear Brezular can you please share the Video tutorial for this ,I am not a qemu or linux guy so having problem in understanding , maybe video help me to understand .thanks

    Hope you or someone the web share the video for this.

  11. Hi Brezular,

    Followed your great procedure and everything works fine when IOUl2 is connected to a GNS3 router.

    CDP and spanning tree is also fine between two IOUl2 but we were never able to have L3 communication between two IOUl2 via remote VLAN1 interface.

    Do you know if there is any existing issue with L3 communication between two IOUl2.

    Thanks
    Mononcle63

    1. Hi,
      If I remember correctly, I only noticed issue with 802.1q tagged traffic. Non tagged traffic vlan1 traffic was transferred correctly between two nodes.

      1. Hi Brezular

        I have found the same thing on my side, 802.1q traffic does not seems to work using Qemu and GNS3. Are you aware of any fix or do you know if 802.1q is functional when we run IOUl2 over Centos using GNS3

        You are truly doing a terrific job

        Thanks
        Mononcle63

        1. Hi Mononcle63,
          if I remember correctly the problem with non passing 802.1q traffic is also presented in CentOS.
          Try to connect my IOU-Microcore switch to e.g 3725 emulated by Dynamips via trunk. Issue ping from Microcore to 3725 and start wireshark on the 3725 end. Do you receive tagged traffic on 3725? If not, tag is stripped by Microcore before the frame is send to the "wire".

          Also try to connect IOU instance (without GNS3) to the real Cisco gear and check if trunking is working. Ping from IOU to Cisco with enabled particular debug of ip packets on a real Cisco gear(or enable any debug that inspects L2 frames).

          Another possibility is to try another NIC type that is offered by GNS3. I made some NIC tests to check if trunking is working, hope it helps:
          https://brezular.com/category/lisa/

          And the last solution (and probably the best one) is to send email to einval and explain the problem.

  12. Hi Brezular,

    TInyCore hex editor: You can find a hex editor (xxd) in vim-7.2-bin.tcz
    Load file into vim then -
    :%!xxd - to switch to hex mode
    :%!xxd -r - to return to text mode.

    HTH,
    Nick.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.