OVS Switch-As-A-Service Oracle Linux 7 UEK4

Summary

Below is switch "sw1' status showing how it is setup as a service. This post here was my starting point in RHEL 7 (RedHat 7) and similar distros such as Oracle Linux 7 or CentOS 7 etc. I did this work on Oracle Linux 7 UEK4 but this should (but has not been tested) for other RHEL-type Linux 7 distro. It has only been tested and works on Oracle Linux 7 UEK4.

Another note is that I didn't like having my "service sw1 status" returning some failed service info, so then I discovered setting a service as "oneshot" at this reference at DigitalOcean which reference by the way is a great source where I got the better understanding of how to set this up successfully. Some details of the fairly easy setup are shown below. This is a way to have your OpenvSwitch switch startup on boot after the network interfaces are up, but also with a bunch of scripted options applied to it (such as iptables rules) etc. using a custom script (in this example the script is crt_ovs_sw1.sh). It may not be the best way to do such things but it will get the openvswitch up and configured onboot in a supported way.

This was useful for me when working with OpenvSwitch switches in [ Oracle Linux 7 / RedHat 7 / CentOS 7 ] where strategies that worked for this on Ubuntu Linux do not work well or do not work at all. Therefore, new approach was needed and this was found and works to get the openvswitch up and configured onboot.

Example OpenvSwitch Switch-As-A-Service

[root@ol72 openvswitch]# service sw1 status

Redirecting to /bin/systemctl status sw1.service

● sw1.service - sw1 Service

Loaded: loaded (/etc/systemd/system/sw1.service; enabled; vendor preset: disabled)

Active: active (exited) since Thu 2016-10-13 11:30:32 CDT; 3min 25s ago

Process: 2127 ExecStart=/etc/network/openvswitch/crt_ovs_sw1.sh (code=exited, status=0/SUCCESS)

Main PID: 2127 (code=exited, status=0/SUCCESS)

CGroup: /system.slice/sw1.service

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2313]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s1 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2322]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s2 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2332]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s3 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2343]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s4 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2357]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s5 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: IP: 192.168.1.23

Oct 13 11:30:31 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: Interface: wlp4s0

Oct 13 11:30:31 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: Redirecting to /bin/systemctl start dhcpd.service

Oct 13 11:30:32 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: Redirecting to /bin/systemctl restart named.service

Oct 13 11:30:32 ol72.orabuntu-lxc.com systemd[1]: Started sw1 Service.

[root@ol72 openvswitch]#

The configuration file for this service is shown below. The sw1 service is what's called a "oneshot" service which means among other things that it remains in an active status even though it is not a resident process and is just a one-time script that is run to setup switch sw1.

Creating the OpenvSwitch Service

[root@stlns01 ~]# cat /etc/systemd/system/sw1.service

[Unit]

Description=sw1 Service

After=network.target

[Service]

Type=oneshot

User=root

RemainAfterExit=yes

ExecStart=/usr/bin/crt_ovs_sw1.sh

[Install]

WantedBy=multi-user.target

[root@stlns01 ~]#

Here's some more details on this (I had to do this this morning so I captured some more detail about it as shown below). Create the sw1.service file as shown below and finish the other steps and reboot. The fully-configured OpenvSwitch will start up on boot and run as a service.

[root@ol72 openvswitch]# vi /etc/systemd/system/sw1.service

[root@ol72 openvswitch]# systemctl enable sw1

Created symlink from /etc/systemd/system/multi-user.target.wants/sw1.service to /etc/systemd/system/sw1.service.

[root@ol72 openvswitch]# ls -l /etc/systemd/system/sw1.service

-rw-r--r--. 1 root root 179 Oct 12 12:29 /etc/systemd/system/sw1.service

[root@ol72 openvswitch]# cat /etc/systemd/system/sw1.service

[Unit]

Description=sw1 Service

After=network.target

[Service]

Type=oneshot

User=root

RemainAfterExit=yes

ExecStart=/etc/network/openvswitch/crt_ovs_sw1.sh

[Install]

WantedBy=multi-user.target

[root@ol72 openvswitch]#

And here is how it looks after reboot. Up and running and as-a-service as shown below.

[root@ol72 openvswitch]# ifconfig sw1

sw1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

inet 10.207.39.1 netmask 255.255.255.0 broadcast 0.0.0.0

inet6 fe80::d0b1:a8ff:fe22:1f4b prefixlen 64 scopeid 0x20<link>

ether d2:b1:a8:22:1f:4b txqueuelen 0 (Ethernet)

RX packets 0 bytes 0 (0.0 B)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 28 bytes 3996 (3.9 KiB)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

[root@ol72 openvswitch]# service sw1 status

Redirecting to /bin/systemctl status sw1.service

● sw1.service - sw1 Service

Loaded: loaded (/etc/systemd/system/sw1.service; enabled; vendor preset: disabled)

Active: active (exited) since Thu 2016-10-13 11:30:32 CDT; 3min 25s ago

Process: 2127 ExecStart=/etc/network/openvswitch/crt_ovs_sw1.sh (code=exited, status=0/SUCCESS)

Main PID: 2127 (code=exited, status=0/SUCCESS)

CGroup: /system.slice/sw1.service

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2313]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s1 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2322]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s2 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2332]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s3 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2343]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s4 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com ovs-vsctl[2357]: ovs|00001|vsctl|INFO|Called as ovs-vsctl set port s5 tag=10

Oct 13 11:30:31 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: IP: 192.168.1.23

Oct 13 11:30:31 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: Interface: wlp4s0

Oct 13 11:30:31 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: Redirecting to /bin/systemctl start dhcpd.service

Oct 13 11:30:32 ol72.orabuntu-lxc.com crt_ovs_sw1.sh[2127]: Redirecting to /bin/systemctl restart named.service

Oct 13 11:30:32 ol72.orabuntu-lxc.com systemd[1]: Started sw1 Service.

[root@ol72 openvswitch]#

The crt_ovs_sw1.sh Script

This is the script that runs when the service is created at boot. This script sets up connectivity to the WAN for the OpenvSwitch using iptables rules instead of direct attachment to a physical inteface. Note that in [ Oracle Linux 7 / Redhat 7 / CentOS 7 ] etc. we can't use "tunctl" anymore; it has been replaced by the "ip tuntap add ... mode tap" syntax as highlighted below. The "tunctl" command works on Ubuntu 16 but not on these RedHat flavors.

Also note that the piped expressions that evaluate to "Interface" and "IP" are revised from the equivalents for Ubuntu Linux and that the commands to start dhcpd and named are of course revised from their Ubuntu equivalents (isc-dhcp-server and bind9, respectively) highlighted in bold.

The "tag=10" on the ports is of course VLAN'g and indicates "VLAN=10".

All the other code in crt_ovs_sw1.sh is fully portable for both RedHat and Ubuntu (well actually, to be correct, Debian) distros (but I haven't tested on Debian ever so I'm saying "Ubuntu" even though to be correct one would say "RedHat and Debian" since these are the base OS distros from which CentOS etc. and Ubuntu etc. were forked.

[root@ol72 openvswitch]# cat crt_ovs_sw1.sh

#!/bin/bash

ip tuntap add s1 mode tap

ip tuntap add s2 mode tap

ip tuntap add s3 mode tap

ip tuntap add s4 mode tap

ip tuntap add s5 mode tap

ip link set s1 up

ip link set s2 up

ip link set s3 up

ip link set s4 up

ip link set s5 up

ovs-vsctl add-br sw1

ovs-vsctl add-port sw1 s1

ovs-vsctl add-port sw1 s2

ovs-vsctl add-port sw1 s3

ovs-vsctl add-port sw1 s4

ovs-vsctl add-port sw1 s5

ip link set up dev sw1

ip addr add 10.207.39.1/24 dev sw1

ip route replace 10.207.39.0/24 dev sw1

ovs-vsctl set port sw1 trunks=10

ovs-vsctl set port sw1 tag=10

ovs-vsctl set port s1 tag=10

ovs-vsctl set port s2 tag=10

ovs-vsctl set port s3 tag=10

ovs-vsctl set port s4 tag=10

ovs-vsctl set port s5 tag=10

# GLS 20160813 Get active external interface dynamically at boot. Tested & works with Oracle Linux 7 UEK4 Desktop x86_64.

### BEGIN Get Active EXTIF Dynamcially. ###

function GetInterface

{

ifconfig | egrep -B1 'inet' | egrep -A1 'enp|wlp|wlan|eth|bnep' | sed '$!N;s/\n/ /' | sed 's/ */ /g' | cut -f1,7 -d' ' | sed 's/ addr//' | head -1 | cut -f1 -d':'

}

Interface=$(GetInterface)

function GetIP

{

ifconfig | grep -A1 $Interface | grep inet | sed '$!N;s/\n/ /' | sed 's/ */ /g' | cut -f3 -d' '

}

### END Get Active EXTIF Dynamically. ###

echo ' IP: '$(GetIP)

echo 'Interface: '$(GetInterface)

INTIF="sw1"

EXTIF=$(GetInterface)

echo 1 > /proc/sys/net/ipv4/ip_forward

# clear existing iptable rules, set a default policy

iptables -P INPUT ACCEPT

iptables -F INPUT

iptables -P OUTPUT ACCEPT

iptables -F OUTPUT

iptables -P FORWARD DROP

iptables -F FORWARD

iptables -t nat -F

function CheckIptablesRulesCount {

iptables -S | grep FORWARD | grep sw1 | wc -l

}

IptablesRulesCount=$(CheckIptablesRulesCount)

while [ $IptablesRulesCount -ne 0 ]

do

iptables -D FORWARD -i $EXTIF -o $INTIF -j ACCEPT > /dev/null 2>&1

iptables -D FORWARD -i $INTIF -o $EXTIF -j ACCEPT > /dev/null 2>&1

IptablesRulesCount=$(CheckIptablesRulesCount)

done

# set forwarding and nat rules

iptables -A FORWARD -i $EXTIF -o $INTIF -j ACCEPT

iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

service dhcpd start

service named restart

[root@ol72 openvswitch]#

Thanks, enjoy.