Using Linux GRE tunnels to connect two Mininet networks

I’ve had a few posts about how to use Open vSwitch’s built in GRE tunnel support to connect two Mininet networks. As many that have tried to use my scripts, I’ve also found it a pain to get going. Sometimes it works, sometimes it doesn’t. Then I saw a post in the Mininet mailing list from Felix Wallaschek about how he uses Linux GRE tunnels to connect separate Mininet networks in a program he setup called Maxinet. I decided to take a look at how his application did it and try using that same method.

Below is an example of the commands to run on one of the systems running Mininet. You would need to setup this tunnel before you can bind it into your switch in Mininet using the Intf(name, node) method like the example in mininet/examples/hwintf.py.

sudo ip link add s1-gre1 type gretap remote 192.168.56.103 local 192.168.56.102 ttl 64
sudo ip link set dev s1-gre1 up

A few notes. I am using Ubuntu 12.04. The version of Open vSwitch that comes with this version of Ubuntu does not play nicely with the Linux GRE tunnels. But when I upgraded to Open vSwitch 2.0, everything worked much better. So below are the scripts that I had in my previous post, but changed to setup and use Linux GRE tunnels.

Script for VM1(192.168.56.102):

#!/usr/bin/python

from mininet.net import Mininet
from mininet.node import Controller, RemoteController, Node
from mininet.cli import CLI
from mininet.log import setLogLevel, info
from mininet.link import Link, Intf

def emptyNet():

    NODE1_IP='192.168.56.102'
    NODE2_IP='192.168.56.103'
    CONTROLLER_IP='192.168.56.103'

    net = Mininet( topo=None,
                   build=False)

    net.addController( 'c0',
                      controller=RemoteController,
                      ip=CONTROLLER_IP,
                      port=6633)

    h1 = net.addHost( 'h1', ip='10.0.0.1' )
    h2 = net.addHost( 'h2', ip='10.0.0.2' )
    s1 = net.addSwitch( 's1' )
    net.addLink( h1, s1 )
    net.addLink( h2, s1 )

    # Delete old tunnel if still exists
    s1.cmd('ip tun del s1-gre1')
    # Create GRE tunnel
    s1.cmd('ip li ad s1-gre1 type gretap local '+NODE1_IP+' remote '+NODE2_IP+' ttl 64')
    s1.cmd('ip li se dev s1-gre1 up')
    Intf( 's1-gre1', node=s1 )

    net.start()
    CLI( net )
    net.stop()

if __name__ == '__main__':
    setLogLevel( 'info' )
    emptyNet()

Script for VM2(192.168.56.103):

#!/usr/bin/python

from mininet.net import Mininet
from mininet.node import Controller, RemoteController
from mininet.cli import CLI
from mininet.log import setLogLevel, info
from mininet.link import Link, Intf

def emptyNet():

    NODE1_IP='192.168.56.102'
    NODE2_IP='192.168.56.103'
    CONTROLLER_IP='192.168.56.103'

    net = Mininet( topo=None,
                   build=False)

    net.addController( 'c0',
                      controller=RemoteController,
                      ip=CONTROLLER_IP,
                      port=6633)

    h3 = net.addHost( 'h3', ip='10.0.0.3' )
    h4 = net.addHost( 'h4', ip='10.0.0.4' )
    s2 = net.addSwitch( 's2' )
    net.addLink( h3, s2 )
    net.addLink( h4, s2 )

    # Delete old tunnel if still exists
    s2.cmd('ip tun del s2-gre1')
    # Create GRE tunnel
    s2.cmd('ip li ad s2-gre1 type gretap local '+NODE2_IP+' remote '+NODE1_IP+' ttl 64')
    s2.cmd('ip li se dev s2-gre1 up')
    Intf( 's2-gre1', node=s2 )

    net.start()
    CLI( net )
    net.stop()

if __name__ == '__main__':
    setLogLevel( 'info' )
    emptyNet()

I just run the above script on the appropriate VM and then test it. Below shows me having h1 on the VM1 Mininet ping h3 on the VM2 Mininet.

mininet> h1 ping -c 1 10.0.0.3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_req=1 ttl=64 time=7.97 ms

--- 10.0.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 7.972/7.972/7.972/0.000 ms

One other thing to note, the above is a point to point network. If you are going to have more than two Mininet networks, you will also need to add the ‘key’ parameter to tunnel creation command.

Thanks again Felix for showing us how to use Linux GRE tunnels with Mininet.

This post ‘Using Linux GRE tunnels to connect two Mininet networks’ first appeared on https://gregorygee.wordpress.com/.

Connecting two Mininet networks with GRE tunnel – Part 2

Update: Find another post about how I used Linux GRE tunnels to do the same.

—-

This is a followup to an older post about connecting two MiniNet sessions with a GRE tunnel. I’ve made up some new scripts to help test the functionality plus I’ll provide a little more information on checking if the GRE tunnel is actually registered. The one problem I have run into a few times using Open vSwitch was trying to get the GRE tunnel interface on each switch to register with the controller. If it doesn’t register, then you aren’t going to see any traffic flow across. For this example, both MiniNet sessions will connect to a remote controller. This will also help show if the GRE registered.

The following in the MiniNet python script that you will run on the your first VM.

#!/usr/bin/python

from mininet.net import Mininet
from mininet.node import Controller, RemoteController
from mininet.cli import CLI
from mininet.log import setLogLevel, info

def emptyNet():

    NODE2_IP='192.168.56.103'
    CONTROLLER_IP='192.168.56.103'

    net = Mininet( topo=None,
                   build=False)

    net.addController( 'c0',
                      controller=RemoteController,
                      ip=CONTROLLER_IP,
                      port=6633)

    h1 = net.addHost( 'h1', ip='10.0.0.1' )
    h2 = net.addHost( 'h2', ip='10.0.0.2' )
    s1 = net.addSwitch( 's1' )
    net.addLink( h1, s1 )
    net.addLink( h2, s1 )
    net.start()

    # Configure the GRE tunnel
    s1.cmd('ovs-vsctl add-port s1 s1-gre1 -- set interface s1-gre1 type=gre options:remote_ip='+NODE2_IP)
    s1.cmdPrint('ovs-vsctl show')

    CLI( net )
    net.stop()

if __name__ == '__main__':
    setLogLevel( 'info' )
    emptyNet()

This next MiniNet python script will be run on another VM.

#!/usr/bin/python

from mininet.net import Mininet
from mininet.node import Controller, RemoteController
from mininet.cli import CLI
from mininet.log import setLogLevel, info

def emptyNet():

    NODE1_IP='192.168.56.102'
    CONTROLLER_IP='192.168.56.103'

    net = Mininet( topo=None,
                   build=False)

    net.addController( 'c0',
                      controller=RemoteController,
                      ip=CONTROLLER_IP,
                      port=6633)

    h3 = net.addHost( 'h3', ip='10.0.0.3' )
    h4 = net.addHost( 'h4', ip='10.0.0.4' )
    s2 = net.addSwitch( 's2' )
    net.addLink( h3, s2 )
    net.addLink( h4, s2 )
    net.start()

    # Configure the GRE tunnel
    s2.cmd('ovs-vsctl add-port s2 s2-gre1 -- set interface s2-gre1 type=gre options:remote_ip='+NODE1_IP)
    s2.cmdPrint('ovs-vsctl show')

    CLI( net )
    net.stop()

if __name__ == '__main__':
    setLogLevel( 'info' )
    emptyNet()

You will need to modify the scripts to set the IP addresses at the top to the appropriate values for your environment. Once the scripts are ready, we’ll start them up. Don’t worry about the message about not being able to contact the controller. We’ll start it up after. Also, I’ve configured the scripts to automatically create the GRE tunnel to the other MiniNets.

On VM1.

mininet@mininet21:~$ sudo ./greTest-1.py
Unable to contact the remote controller at 192.168.56.103:6633
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 1 switches
s1
*** s1 : ('ovs-vsctl show',)
007a537b-9138-4ee9-b0dd-77182c3b4cea
    Bridge "s1"
        Controller "tcp:192.168.56.103:6633"
        fail_mode: secure
        Port "s1-eth1"
            Interface "s1-eth1"
        Port "s1-eth2"
            Interface "s1-eth2"
        Port "s1-gre1"
            Interface "s1-gre1"
                type: gre
                options: {remote_ip="192.168.56.103"}
        Port "s1"
            Interface "s1"
                type: internal
    ovs_version: "1.4.0+build0"
*** Starting CLI:
mininet>

On VM2:

mininet@mininet21:~$ sudo ./greTest-2.py
*** Configuring hosts
h3 h4
*** Starting controller
*** Starting 1 switches
s2
*** s2 : ('ovs-vsctl show',)
ef39063c-46be-44e3-b89c-faaf7ffcf351
    Bridge "s2"
        Controller "tcp:192.168.56.103:6633"
        fail_mode: secure
        Port "s2-gre1"
            Interface "s2-gre1"
                type: gre
                options: {remote_ip="192.168.56.102"}
        Port "s2-eth1"
            Interface "s2-eth1"
        Port "s2-eth2"
            Interface "s2-eth2"
        Port "s2"
            Interface "s2"
                type: internal
    ovs_version: "1.4.0+build0"
*** Starting CLI:
mininet>

Now start the controller. For this test, I’m just going to use the OpenFlow reference controller.

mininet@mininet21:~$ controller -v ptcp:6633

The above will start printing a lot of messages as soon at the switches start connecting to the controller. But here is where you want to watch closely as the switches register. You want to look for the following message.

Jan 20 21:24:10|00009|vconn|DBG|tcp:192.168.56.102:41173: received: features_reply (xid=0x9ba82531): ver:0x1, dpid:1
n_tables:255, n_buffers:256
features: capabilities:0xc7, actions:0xfff
 1(s1-eth1): addr:ca:06:71:62:79:85, config: 0, state:0
     current:    10GB-FD COPPER
 2(s1-eth2): addr:72:89:9d:be:6f:1f, config: 0, state:0
     current:    10GB-FD COPPER
 3(s1-gre1): addr:fe:d4:30:b3:b9:e0, config: 0, state:0
 LOCAL(s1): addr:9a:a3:5c:e3:01:40, config: 0x1, state:0x1

Jan 20 21:24:11|00017|vconn|DBG|tcp:192.168.56.103:36309: received: features_reply (xid=0x9a4c5b0d): ver:0x1, dpid:2
n_tables:255, n_buffers:256
features: capabilities:0xc7, actions:0xfff
 1(s2-eth1): addr:72:52:76:ea:d6:90, config: 0, state:0
     current:    10GB-FD COPPER
 2(s2-eth2): addr:d2:80:1b:4b:89:43, config: 0, state:0
     current:    10GB-FD COPPER
 3(s2-gre1): addr:6e:ad:4b:5c:e6:be, config: 0, state:0
 LOCAL(s2): addr:ae:49:99:96:c7:4e, config: 0x1, state:0x1

The above two messages that got printed out are what is important. Make sure you see your GRE interface listed for each switch. If it isn’t there, then something is wrong with your configuration or with the Open vSwitch that you have installed. If all looks good, then the last step is to verify with some traffic.

In MiniNet on VM1:

mininet> h1 ping -c 1 10.0.0.3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_req=1 ttl=64 time=0.613 ms

--- 10.0.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.613/0.613/0.613/0.000 ms

There you go. I sent a ping from h1 on VM1 to h3 on VM2 over the GRE tunnel. In the above example I use the reference controller. You can use whatever controller you wish and it might give you more details on the interfaces and connection. Just update the CONTROLLER_IP with the IP address where your controller is running.

Hope these new scripts and extra info help you in your journey.

This post ‘Connecting two Mininet networks with GRE tunnel – Part 2’ first appeared on https://gregorygee.wordpress.com/.

Installing Cisco CSR 1000V in VirtualBox

Virtual networking is becoming more and more popular.  Just a little while back, Cisco released a virtual router called CSR 1000V that can run in a VM.  CSR is for Cloud Services Router.  But Cisco had limited its use to VMWare based technology like ESX and VMWare Player/Workstation.  Well, when Cisco released version 3.10, is supported more virtual machines and it looked like it had the possibility to run in Virtual Box.  I was quite happy to try as I use Virtual Box a lot.  So after lots of tweaks and tries, I got it to work the way I wanted.

For this example, I am going to create a router called csr1000v-2.  A few notes:

  • Needs to run on a PC that is a Core i5 or better.
  • CSR 1000V is free (if you already have a support contract) but extremely low throughput of 2.5Mbps.  A paid license is required for higher throughput. But this is good enough to learning purposes.

To install, you will need the following:

  • Download and install VirtualBox.
  • Download the ‘Cisco CSR 1000V Series ADVANCED ENTERPRISE SERVICES – ISO’ file from Cisco.  I am currently using 3.10.0S, which is IOS 15.3(3)S as it is the first release to support(unofficially).  There are newer versions available, this just happens to be the one I first grabbed when it came out.

First to explain why using Named Pipe.  When you first start the installer, it will ask you if you want to use the VM console as the routers ‘console’ port or if you want to use the VMs serial port as the ‘console’ port.  Since I will need to copy and paste commands, I decided to use the serial port option as it allowed me to connect to the serial port using Putty.  The Named Pipe utility creates a TCP port proxy.  So you can open a connection to a specific TCP port and the utility will redirect it to the serial Pipe.

So after you download the Named Pipe utility, just

  • Start the program “piped.exe”
  • Create our first pipe with the following settings.
    •  Pipe-Name “\\.\pipe\csr1000v-2”
    • Port 1999.
  • I put the router name in the Pipe-Name so I know which pipe is for which router.  You will need to create a new entry for each CSR you install on your PC.  Choose a different port for each too.

Now that this is setup, if you telnet to localhost port 1999 on you PC, you will be attached to the serial port.

Next we are going to create the VM.  Create a new VM in VirtualBox with the following settings.

  • General:
    • Type: Linux
    • Version: RedHat (64bit)
  • Memory: 4GB
  • Network: (You can choose if you want each interface to be NAT, BIND, LocalHost, etc.)
    • Enable all 4 adapters and set the 'Adapter Type' to 'Paravirtualized Network (virt-io net)'
  • Audio:
    • Off
  • Serial Ports:
    • Enable Serial Port 1
    • Port Number: COM1
    • Port Mode: Host Pipe
    • Create Pipe checked
    • Port/File Path: \\.\pipe\csr1000v-2

Before we start the VM, make sure you have started the Named Pipe Proxy TCP Proxy.

  • Open telnet connection to proxy port (eg, localhost port 1999)
    • If using Putty, change setting in Putty session under    Connection->Telnet
      • Turn off ‘Return key sends Telnet New Line instead of ^M’.

Now start the VM.

  • In GRUB menu, choose ‘Serial Console’.
  • First boot takes a long while.  It will reboot once automatically.  There is nothing else you need to do.

There you go.  Wasn’t that easy?  It’s all automatic.  So, connect to router to see what IP address the GigabitEthernet0 was given.

Router>enable
Router#sh dhcp lease
Temp IP addr: 192.168.56.102  for peer on Interface: GigabitEthernet0

Now it’s up to you to configure the remainder.  Below is some extra initial config to just get you going.

Give the router an initial enable and telnet password and hostname.  An example is as follows.

Router>en
Router#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#enable secret cisco
Router(config)#line vty 0 4
Router(config-line)#password cisco
Router(config-line)#exit
Router(config)#hostname csr1000v-2
csr1000v-2(config)#^Z
csr1000v-2#wr
Building configuration...
[OK]

Now a few closing comments. You may have noticed that it takes a lot of RAM.  I haven’t tried reducing it to see how low I could get it, but I did try 1GB memory for the VM and it didn’t successfully boot.

Also, now that it is in a VirtualBox VM, you GNS3 people can add a CSR 1000V into your topologies.

Enjoy everyone.

This post ‘Installing Cisco CSR 1000V in VirtualBox’ first appeared on https://gregorygee.wordpress.com/.