Wednesday, April 29, 2015

Running MPLS with Open vSwitch on ubuntu 15.04

Building the Test Topology

Software version used

1. Ubuntu 15.04
2. Open vSwitch 2.3.1


We will build our test topology as shown below

H1 (h1-eth0)------(s1-eth0)S1(s1-eth1)--------(s2-eth1)S2(s2-eth0)------(h2-eth0)H2

Step 1:  Let's create switch S1 and S2 along with ip ethernet links that will be connecting the two switches together along with H1 and H2.


root@ubuntu:~# ovs-vsctl add-br s1
root@ubuntu:~# ovs-vsctl add-br s2

root@ubuntu:~# ip link add s1-eth0 type veth peer name h1-eth0
root@ubuntu:~# ip link add s2-eth0 type veth peer name h2-eth0
root@ubuntu:~# ip link add s2-eth1 type veth peer name s1-eth1

Step 2:- Create Host H1 and H2 and assign them their respective interfaces.

root@ubuntu:~# ip netns add h1
root@ubuntu:~# ip netns add h2

root@ubuntu:~# ip link set h1-eth0 netns h1

root@ubuntu:~# ip link set h2-eth0 netns h2

Step3:-Let's assign Ports to switch S1 and S2.

root@ubuntu:~# ovs-vsctl add-port s1 s1-eth0
root@ubuntu:~# ovs-vsctl add-port s1 s1-eth1
root@ubuntu:~# ovs-vsctl add-port s2 s2-eth0
root@ubuntu:~# ovs-vsctl add-port s2 s2-eth1

Step4:- Let's bring all the Interfaces up

root@ubuntu:~# ip netns exec h1 bash
root@ubuntu:~# ifconfig h1-eth0 up
root@ubuntu:~# ifconfig lo up

root@ubuntu:~# ip netns exec h2 bash
root@ubuntu:~# ifconfig lo up
root@ubuntu:~# ifconfig h2-eth0 up

root@ubuntu:~# ip link set s1-eth0 up
root@ubuntu:~# ip link set s2-eth0 up
root@ubuntu:~# ip link set s2-eth1 up
root@ubuntu:~# ip link set s1-eth1 up

Step 5:- Assign Ip address 192.168.10.1/24 to host H1 and 192.168.10.2/24 to host H2 as shown below


root@ubuntu:~# ip netns exec h1 bash
root@ubuntu:~# ifconfig h1-eth0 192.168.10.1/24
root@ubuntu:~# exit

root@ubuntu:~# ip netns exec h2 bash
root@ubuntu:~# ifconfig h2-eth0 192.168.10.2/24
root@ubuntu:~# exit

Step 6:- Run ping from host H1 to H2 to verify the connection

root@ubuntu:~# ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.334 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.061 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=0.071 ms
64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=0.078 ms

Step 7:- Check the rules in both switches to see what is allowing the ping to pass through.

root@ubuntu:~# ovs-ofctl -O OpenFlow13 dump-flows s1
OFPST_FLOW reply (OF1.3) (xid=0x2):
 cookie=0x0, duration=990.380s, table=0, n_packets=30, n_bytes=2388, priority=0 actions=NORMAL
root@ubuntu:~# 
root@ubuntu:~# 
root@ubuntu:~# ovs-ofctl -O OpenFlow13 dump-flows s2
OFPST_FLOW reply (OF1.3) (xid=0x2):
 cookie=0x0, duration=990.540s, table=0, n_packets=29, n_bytes=2318, priority=0 actions=NORMAL
root@ubuntu:~# 

Hosts are able to ping each other because of the default rule with NORMAL action.

Step 8:- Let's delete the default rule and try ping again


root@ubuntu:~# ovs-ofctl -O OpenFlow13 del-flows s2
root@ubuntu:~# ovs-ofctl -O OpenFlow13 del-flows s1

Verify the deletion of rules 

root@ubuntu:~# ovs-ofctl -O OpenFlow13 dump-flows s1
OFPST_FLOW reply (OF1.3) (xid=0x2):
root@ubuntu:~# 
root@ubuntu:~# ovs-ofctl -O OpenFlow13 dump-flows s2
OFPST_FLOW reply (OF1.3) (xid=0x2):

Check the Ping from Host H1 to H2.. to see if its working


root@ubuntu:~# ip netns exec h1 bash

root@ubuntu:~# ping 192.168.10.2
PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.
^C
--- 192.168.10.2 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 4033ms

root@ubuntu:~# ping 192.168.10.2
PING 192.168.10.2 (192.168.10.2) 56(84) bytes of data.
From 192.168.10.1 icmp_seq=1 Destination Host Unreachable
From 192.168.10.1 icmp_seq=2 Destination Host Unreachable

Ping failed ... because there are no rules to forward the traffic.

Step 9:- Add MPLS rules for ARP and IP in switch S1. Use MPLS label value of 40 for ARP and MPLS label value of 30 for IP traffic

IP flow rules

ovs-ofctl -O OpenFlow13 add-flow s1 "table=0,in_port=1,ip,action=push_mpls:0x8847,set_mpls_label:30,output:2"

ovs-ofctl -O OpenFlow13 add-flow s1 "table=0,in_port=2,mpls,mpls_label=30,action=pop_mpls:0x0800,output:1"

ARP Flow  rules

ovs-ofctl -O OpenFlow13 add-flow s1 "table=0,in_port=1,arp,action=push_mpls:0x8847,set_mpls_label:40,output:2"

ovs-ofctl -O OpenFlow13 add-flow s1 "table=0,in_port=2,mpls,mpls_label=40,action=pop_mpls:0x0806,output:1"

Step 10:- Add MPLS rules on switch S2 using the same label value as Switch S1

IP flow rules

ovs-ofctl -O OpenFlow13 add-flow s2 "table=0,in_port=1,ip,action=push_mpls:0x8847,set_mpls_label:30,output:2"

ovs-ofctl -O OpenFlow13 add-flow s2 "table=0,in_port=2,mpls,mpls_label=30,action=pop_mpls:0x0800,output:1"

ARP flow rules

ovs-ofctl -O OpenFlow13 add-flow s2 "table=0,in_port=1,arp,action=push_mpls:0x8847,set_mpls_label:40,output:2"

ovs-ofctl -O OpenFlow13 add-flow s2 "table=0,in_port=2,mpls,mpls_label=40,action=pop_mpls:0x0806,output:1"

Step 11:- Try ping from host H1 to see if it can ping Host H2


root@ubuntu:~# ip netns exec h2 bash
root@ubuntu:~# ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=0.420 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=0.346 ms
^C

Ping works ...!!!!





Installing Quagga on Ubuntu 15.04

Installing Quagga on Ubuntu 15.04

Step 1:- Ubuntu 15.04 comes with quagga 0.99.23.1 release package. To install the software - 


root@R2:~# sudo apt-get install quagga

Step 2:- Create the following files in the etc/quagga folder using touch command as shown below 


root@R2:~# cd /etc/quagga/
root@R2:/etc/quagga# touch ospfd.conf
root@R2:/etc/quagga# touch zebra.conf
root@R2:/etc/quagga# touch ospf6d.conf
root@R2:/etc/quagga# touch ripd.conf
root@R2:/etc/quagga# touch ripngd.conf
root@R2:/etc/quagga# touch isisd.conf
root@R2:/etc/quagga# touch bgpd.conf
root@R2:/etc/quagga# touch vtysh.conf

Step 3:- Enable all the protocols by editing  "daemons" file located in /etc/quagga directory


root@R2:/etc/quagga# vi daemons

Change following lines to YES except babled - because we don't need it for our test

zebra=yes
bgpd=yes
ospfd=yes
ospf6d=yes
ripd=yes
ripngd=yes
isisd=yes
babeld=no


Step 4:- Change the permission for quagga directory as follows


root@R2:/etc/quagga# chown quagga.quaggavty /etc/quagga/*.conf
root@R2:/etc/quagga# chmod 640 /etc/quagga/*.conf

Step 5: Edit the file to add  “export VTYSH_PAGER=more” in the /etc/bash.bashrc file

root@R2:/etc/quagga# vi /etc/bash.bashrc

Add the following line at the end of the file

export VTYSH_PAGER=more

Step 6:- Edit the file /etc/environment to add "VTYSH_PAGER=more"

root@R2:/etc/quagga# vi /etc/environment

Add the following line at the bottom of the file

VTYSH_PAGER=more

Step 7:- Restart the QUAGGA DAEMON  as shown below


root@R2:/etc/quagga# /etc/init.d/quagga restart
Restarting quagga (via systemctl): quagga.service.
root@R2:/etc/quagga# 


Step 8:- Verify to make sure that all the daemons are up and running


root@R2:/etc/quagga# ps -ef | grep qua
quagga    2589     1  0 15:42 ?        00:00:00 /usr/lib/quagga/zebra --daemon -A 127.0.0.1
quagga    2593     1  0 15:42 ?        00:00:00 /usr/lib/quagga/bgpd --daemon -A 127.0.0.1
quagga    2597     1  0 15:42 ?        00:00:00 /usr/lib/quagga/ripd --daemon -A 127.0.0.1
quagga    2601     1  0 15:42 ?        00:00:00 /usr/lib/quagga/ripngd --daemon -A ::1
quagga    2605     1  0 15:42 ?        00:00:00 /usr/lib/quagga/ospfd --daemon -A 127.0.0.1
quagga    2609     1  0 15:42 ?        00:00:00 /usr/lib/quagga/ospf6d --daemon -A ::1
quagga    2613     1  0 15:42 ?        00:00:00 /usr/lib/quagga/isisd --daemon -A 127.0.0.1
root      2618     1  0 15:42 ?        00:00:00 /usr/lib/quagga/watchquagga --daemon zebra bgpd ripd ripngd ospfd ospf6d isisd
root      2628  1001  0 15:43 pts/0    00:00:00 grep --color=auto qua
root@R2:/etc/quagga# 

Step 9: Connect with the Quagga Router using vtysh as shown below and save the config

root@R2:~# vtysh

Hello, this is Quagga (version 0.99.23.1).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

R2# wri
Building Configuration...
Configuration saved to /etc/quagga/zebra.conf
Configuration saved to /etc/quagga/ripd.conf
Configuration saved to /etc/quagga/ripngd.conf
Configuration saved to /etc/quagga/ospfd.conf
Configuration saved to /etc/quagga/ospf6d.conf
Configuration saved to /etc/quagga/bgpd.conf
Configuration saved to /etc/quagga/isisd.conf
[OK]
R2# 

This completes the configuration of Quagga router on ubuntu 15.04...

Note :- if you still see the END message-- restart your VM/computer..

Tuesday, April 14, 2015

VLAN translation using Open-Vswitch

VLAN Translation using Open-vSwitch

Deploying OpenvSwitch as a traditional access switch

In this post - I am going to explore the application of Open vSwitch as traditional switch that can be used in the LAN closets during migration to SDN using either Openflow or some other SDN overlay technology. OVS initially started as a soft switch  and was seen as an alternative to linux bridge. But today it has become de-facto SDN switch supporting Openflow 1.3+ including some 1.5 features as well.  Due to its popularity - many switch vendors have started to ship hardware switches integrated with OVS. It is still available as a freely downloadable switch from the openvswitch.org's web site.

Let's look at some of the most commonly used traditional layer 2 access technology that OVS needs to support for it to become a viable alternative to regular expensive vendor switches.

1. It must support VLANs.
2. Trunk Interfaces
3. VLAN tagging (Q-in-Q, EVC etc)
4. Spanning tree (RSTP, MSTP etc)
5. Access-list - packet filtering
6.  QOS for VoIP/Data traffic
7. Policing

OVS supports some of these functions exactly like regular access switches. In fact - I found configuring OVS using ovs-vsctl  lot more simpler than the the traditional switches. We will go over the configuration of some of these functions using Linux name Space and Open vSwitch.

OVS offers two most important commands to configure the switch 1) using "ovs-vsctl" command  and 2) using "ovs-ofctl" command. However, these two commands operate differently. Of these two , "ovs-vsctl" modifies the ovsdb database which stores the switch level configuration. All the changes made using ovs-vsctl are permanent.
Contrary to this, "ovs-ofctl" modifies the forwading table of the switch and has the ability to modify most ( I mean all in case of ethernet)  of the header fields in a packet.

VLAN /Trunk Interface Configuration using "ovs-vsctl" command

Using the topology shown below we will configure VLAN switching on OpenvSwitch S1 and S2. I used Linux Name Space to build the topology. However, using Linux name space and installation of OVS switch are outside the scope of this post. You can refer to my most on Linux tools for virtual networking if you need more information on building virtual topology in a Linux environment..




Let's put host H1 and H3 in VLAN 10.

Configure port s1-eth1 with tag=10 as shown below. It will automatically add ths port to VLAN = 10

#ovs-vsctl set port s1-eth1 tag=10 
#ovs-vsctl set port s1-trunk vlan_mode=access

Configure the trunk link between S1 and S2 to be trunk and assign it the VLAN tag of 10.

On switch S1
#ovs-vsctl set port s1-trunk trunk=10

on Switch S2
#ovs-vsctl set port s2-trunk trunk=10

Finally, Configure port s2-eth1 to be access port with VLAN tag 10.
#ovs-vsctl set port s2-eth1 tag=10 
#ovs-vsctl set port s1-trunk vlan_mode=access

The above configuration will put H1 and H3 in VLAN 10. Let's expand our configuration by adding host H2 and H4 to VLAN 20.

on Switch S1
#ovs-vsctl set port s1-eth2 tag=20 
#ovs-vsctl set port s1-trunk trunk=10,20

on Switch S2
#ovs-vsctl set port s2-eth2 tag=20 
#ovs-vsctl set port s2-trunk trunk=10,20

This completes our simple VLAN configuration. However, if were to support trunk ports with native VLAN its configuration would be as shown below. ( Assuming VLAN 10 to be the native VLAN.)

On Switch1
# ovs-vsctl set port s1-trunk vlan_mode=native-untagged
# ovs-vsctl set port s1-trunk tag=10
# ovs-vsctl set port s1-trunk=20,30

On Switch S2
# ovs-vsctl set port s2-trunk vlan_mode=native-untagged
# ovs-vsctl set port s2-trunk tag=10
# ovs-vsctl set port s2-trunk=20,30


 I just included VLAN 30 to make the configuration complete and show you that except native  VLAN , all other VLANs will need to go there. 

Please check my other posts for more Layer 2 examples using OVS.