{"id":240,"date":"2017-02-05T09:30:26","date_gmt":"2017-02-05T08:30:26","guid":{"rendered":"http:\/\/www.opencloudblog.com\/?p=240"},"modified":"2021-01-17T12:02:13","modified_gmt":"2021-01-17T11:02:13","slug":"boot-integration-of-the-openvswitch-in-ubuntu","status":"publish","type":"post","link":"https:\/\/www.opencloudblog.com\/?p=240","title":{"rendered":"Boot integration of the Openvswitch in Ubuntu"},"content":{"rendered":"\n<p>The installation of the Openvswitch on Ubuntu brings an automatic integration into the boot sequence. When Ubuntu is booted, the Openvswitch is also started. Any bridge or port, which has been defined in previous sessions, is restored.<br><strong>BUT:<\/strong> No L3 interfaces are set up, junk interfaces, which have been defined in previous sessions, are restored.<\/p>\n\n\n\n<p>The ideal start sequence of the Openvswitch delivers:<\/p>\n\n\n\n<ul><li>an empty Openvswitch database during the startup of Ubuntu &#8211;&gt; clean the Openvswitch database (patch necessary)<\/li><li>define all bridges, interfaces, port,&#8230; using \/etc\/network\/interfaces &#8211;&gt; this is supported<\/li><li>brings also up all defined L3 interfaces on Openvswitch internal interfaces &#8211;&gt; patch necessary<\/li><\/ul>\n\n\n\n<p>With <strong>Ubuntu 16.04<\/strong> systemd is used to start the system. Older systems using upstart have now a fixed upstart script (see below) &#8211; but the systemd scripts do not allow out of the box an automatic setup of OVS interfaces. How to fix it? See below&#8230; \ud83d\ude42 Lets hope, that Canonical provides a patch for 16.04 before 18.04 shows up&#8230;<\/p>\n\n\n\n<p>With <strong>Ubuntu 16.10<\/strong> boot integration works out of the box.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Define bridges, ports, interfaces using \/etc\/network\/interfaces<\/h1>\n\n\n\n<p>All configurations items, which are necessary to set up the Openvswitch, can be defined in \/etc\/network\/interfaces .<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Define a bridge<\/h2>\n\n\n\n<p>All ports and interfaces on the Openvswitch must be attached to a bridge. Defining a bridge (which is a virtual switch) requires the following configuration items:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# create an Openvswitch bridge\n# on the commandline: ovs-vsctl add-br vmbr-int\n#\nauto vmbr-int\nallow-ovs vmbr-int\niface vmbr-int inet manual\n  ovs_type OVSBridge<\/pre>\n\n\n\n<p>The configurations lines are<\/p>\n\n\n\n<ul><li><strong>auto<\/strong> is necessary to allow an automatic start (Ubuntu 16.04 using systemd)<\/li><li><strong>allow-ovs<\/strong> is the marker for an Openvswitch bridge. The bridge name follows, here <em>vmbr-int<\/em><\/li><li><strong>iface<\/strong> is the well known \/etc\/network\/interfaces identifier to start an interface configuration<\/li><li><strong>ovs_type<\/strong> defines the interface type for ovs. <strong>OVSBridge<\/strong> identifies an Openvswitch bridge<\/li><\/ul>\n\n\n\n<p>The lines above are an equivalent of the command <strong>ovs-vsctl add-br vmbr-int<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Define a L2 port (untagged)<\/h2>\n\n\n\n<p>The next step is to attach a port (not seen by Linux) to the bridge above.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# create an untagged ovs port in vlan 444\n# (config not yet complete)\n#\nallow-vmbr-int l2port\niface l2port inet manual\n  ovs_bridge vmbr-int\n  ovs_type OVSPort\n  ovs_options tag=444<\/pre>\n\n\n\n<p>The configuration lines are<\/p>\n\n\n\n<ul><li><strong>allow-[name of the bridge to attach the port]<\/strong> defines the name of the bridge, to which the port should be attached to. In our example this is <em>vmbr-int<\/em>. The name of the port follows (here <em>l2port)<\/em><\/li><li>i<strong>face<\/strong>&nbsp;is the well known \/etc\/network\/interfaces identifier to start an interface configuration &#8212; set the config to manual<\/li><li><strong>ovs-bridge<\/strong>&nbsp;holds the name of the bridge&nbsp;to which the port should be attached to. In our example this is&nbsp;<em>vmbr-int<\/em>.<\/li><li><strong>ovs_type<\/strong>&nbsp;defines the interface type for ovs.&nbsp;<strong>OVSPort<\/strong>&nbsp;identifies an Openvswitch port not seen by the Linux Operating system<\/li><li><strong>ovs_options<\/strong> defines additional options for the port &#8211; here define an untagged port, which is member of Vlan 444. If this option is not set, a port may use all vlan tags on the interfaces, because all ports transport vlan tags by default.<\/li><\/ul>\n\n\n\n<p>The bad thing is, that the bridge (vmbr-int) must be defined twice. But this is not the whole truth. This definition is required a third time. The complete definition for the bridge and port is now:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# create an Openvswitch bridge\n#\nauto vmbr-int\nallow-ovs vmbr-int\niface vmbr-int inet manual\n  ovs_type OVSBridge\n  ovs_ports l2port\n#\n# create an untagged ovs port in vlan 444\n#\nallow-vmbr-int l2port\niface l2port inet manual\n  ovs_bridge vmbr-int\n  ovs_type OVSPort\n  ovs_options tag=444<\/pre>\n\n\n\n<p>This is the summary definition. It contains one <strong>additional<\/strong> line in the bridge definition iface<\/p>\n\n\n\n<ul><li><strong>ovs_ports<\/strong> holds the list of all ports which should be attached to the bridge<\/li><\/ul>\n\n\n\n<p>The port which is added to the bridge in the example above can also be an existing physical nic. The example below shows the config to add a physical interface to a bridge:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">auto br-phys\nallow-ovs br-phys\niface br-phys inet manual\n  ovs_type OVSBridge\n  ovs_ports eno1\n\nallow-br-phys eno1\niface eno1 inet manual\n  ovs_bridge br-phys\n  ovs_type OVSPort\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Define a L3 interface<\/h2>\n\n\n\n<p>The definition of a L3 interface requires the following configuration lines<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# create an untagged ovs port in vlan 444\n#\nallow-vmbr-int l3port\niface l3port inet static\n  ovs_bridge vmbr-int\n  ovs_type OVSIntPort\n  ovs_options tag=444\n  address 192.168.1.254\n  netmask 255.255.255.0<\/pre>\n\n\n\n<p>The differences compared to the L2 port are<\/p>\n\n\n\n<ul><li><strong>iface<\/strong> &#8212; set the mode to <strong>static<\/strong> &#8212; because an IP address is configured on this interface<\/li><li><strong>ovs_type<\/strong> &#8212; an L3 port must be defined as an <strong>internal port<\/strong> &#8212; must be set to <strong>OVSIntPort<\/strong><\/li><li><strong>address<\/strong> and <strong>netmask<\/strong> are the well known parameters for IPV4 an address\/netmask combination<\/li><\/ul>\n\n\n\n<p>Do not forget to add the port to the bridge definition of vmbr-int.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Define a L2 port (tagged\/trunking)<\/h2>\n\n\n\n<p>The definition of a L2 port, which is tagged looks like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# create an tagged ovs port\n#\nallow-vmbr-int l2taggedport\niface l2taggedport inet manual\n  ovs_bridge vmbr-int\n  ovs_type OVSPort\n  ovs_options trunks=2101,2102,2110,2120,2999,3000<\/pre>\n\n\n\n<p>A trunking port does not require an additional definition. In the example above, we want to limit the vlans on the port. This requires a trunk definition using the <strong>ovs_options<\/strong> line.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Define a fake bridge<\/h2>\n\n\n\n<p>It is also possible to add the definition of an ovs fake bridge<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# a fake bridge without an ip address\n# ovs-vsctl add-br fakebr vmbr-int 2102\n#\nallow-vmbr-int fakebr\niface fakebr inet manual\n  ovs_bridge vmbr-int\n  ovs_type OVSBridge\n  ovs_options vmbr-int 2102<\/pre>\n\n\n\n<p>A fake bridge definition requires a special option<\/p>\n\n\n\n<ul><li><strong>ovs_options<\/strong> must be set to vmbr-int 2102<\/li><\/ul>\n\n\n\n<p>On the commandline the command would be: <em>ovs-vsctl add-br fakebr vmbr-int 2102<\/em> . The ovs_options are the two last options being necessary on the commandline.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Define a tagged LACP bond port<\/h2>\n\n\n\n<p>It is also possible to define a tagged bond port using LACP as the bonding protocol<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# add a tagged bond port using LACP\n#\nallow-vmbr-int bondpub\niface bondpub inet manual\n  ovs_bridge vmbr-int \n  ovs_type OVSBond\n  ovs_bonds eth4 eth5\n  ovs_options other_config:lacp-port-id=103 bond_fake_iface=true bond_mode=balance-slb lacp=active other_config:lacp-time=fast bond_updelay=2000 bond_downdelay=400 trunks=2101,2102,2110,2120,2999,3000<\/pre>\n\n\n\n<p>The options are<\/p>\n\n\n\n<ul><li><strong>ovs_type<\/strong> must be set to <strong>OVSBond<\/strong><\/li><li><strong>ovs_bonds<\/strong> has the list of the interfaces to be added to the bond &#8212; here eth4 and eth5<\/li><li><strong>ovs_options<\/strong> holds all the extra options for the bond and the trunk. These are the same options, which have to be used on the command line<\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Interface helper script<\/h1>\n\n\n\n<p>ifup and ifdown are using a helper script, which is part of the openvswitch-switch package. This script <em>openvswitch<\/em> is located in <em>\/etc\/network\/if-pre-up.d\/<\/em> . This script executes all commands.<\/p>\n\n\n\n<p>This script is missing only the support to change the mtu of Openvswitch bridges, ports and interfaces.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Boot support (Ubuntu 20.04)<\/h1>\n\n\n\n<p>Boot support in Ubuntu 20.04 should work out of the box &#8211; should. But in Ubuntu 20.04 and some version before, there is a race condition which makes the ovs interface setup not predictable.<\/p>\n\n\n\n<p>A small change helps here.<\/p>\n\n\n\n<p>The systemd file for the ovsdb server in \/lib\/systemd\/system\/ovsdb-server.service should be changed.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true crayon-selected\">[Unit]\nDescription=Open vSwitch Database Unit\nAfter=syslog.target network-pre.target dpdk.service local-fs.target\nBefore=network.target networking.service\nPartOf=openvswitch-switch.service\nDefaultDependencies=no\n\n&lt; more data below&gt;\n<\/pre>\n\n\n\n<p>The dependencies must be adjusted in order to avoid ovs components start before the local file systems are mounted.<br>Add &#8222;<span style=\"color: #ff0000;\"><strong>local-fs.target<\/strong><\/span>&#8220; to the &#8222;After&#8220; list.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Boot support (Ubuntu 16.04 &#8211; when using systemd)<\/h1>\n\n\n\n<p>Canonical did it again &#8211; deliver an OS which does not support the autostart of OVS interfaces.. The upstart scripts have been fixed to allow the autostart of OVS interfaces, but now systemd is used &#8211; and the automatic start of OVS interfaces is broken again.<\/p>\n\n\n\n<p>A fix is available, see <a href=\"https:\/\/bugs.launchpad.net\/ubuntu\/+source\/openvswitch\/+bug\/1448254\" target=\"_blank\" rel=\"noopener noreferrer\">Launchpad Bug<\/a>. The systemd start file for OVS needs to be changed to add dependencies. OVS must be started before setting up the network interfaces.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">[Unit]\nDescription=Open vSwitch Internal Unit\nPartOf=openvswitch-switch.service\n\n#https:\/\/bugs.launchpad.net\/ubuntu\/+source\/openvswitch\/+bug\/1448254\n\n# Without this all sorts of looping dependencies occur doh!\nDefaultDependencies=no\n\n#precedants pulled from isup@ service requirements\nAfter=apparmor.service local-fs.target systemd-tmpfiles-setup.service\n\n#subsequent to this service we need the network to start\nWants=network-pre.target openvswitch-switch.service\nBefore=network-pre.target openvswitch-switch.service\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nEnvironmentFile=-\/etc\/default\/openvswitch-switch\nExecStart=\/usr\/share\/openvswitch\/scripts\/ovs-ctl start \\\n          --system-id=random $OVS_CTL_OPTS\nExecStop=\/usr\/share\/openvswitch\/scripts\/ovs-ctl stop\n<\/pre>\n\n\n\n<p>Replace \/lib\/systemd\/system\/openvswitch-nonetwork.service with the file content above, and you&#8217;re done.<\/p>\n\n\n\n<p>One option to delete all existing bridges should be set in the config file \/etc\/default\/openvswitch-switch to start with an empty openvswitch config.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">OVS_CTL_OPTS='--delete-bridges'\n<\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Boot support (Ubuntu 14.04 and later &#8211; when using upstart)<\/h1>\n\n\n\n<p>Ubuntu 14.04 has a better boot support for the openvswitch, but it is still not perfect. The interface up\/down stuff is still missing.<\/p>\n\n\n\n<p>One option to delete all existing bridges should be set in the config file \/etc\/defaults\/openvswitch-switch<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">OVS_CTL_OPTS='--delete-bridges'\n<\/pre>\n\n\n\n<p>The upstart script must be patched twice to start and stop ovs components and the associated interfaces.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">  \"$@\" || exit $?\n  ########## PATCH START ##############\n  # start the bridges\n  bridges=`ifquery --allow ovs -l` \n  [ -n \"${bridges}\" ] &amp;&amp; ifup --allow=ovs ${bridges}\n  logger -t ovs-start pre-start end\n  ########## PATCH END ################\nend script<\/pre>\n\n\n\n<p>You must insert all lines between &#8222;exit $?&#8220; and &#8222;end script&#8220; to bring up the Openvswitch interfaces.<\/p>\n\n\n\n<p>The shutdown sequence requires the following patch:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">post-stop script\n  ########### PATCH START ################\n  logger -t ovs-stop post-stop\n  bridges=`ifquery --allow ovs -l` \n  [ -n \"${bridges}\" ] &amp;&amp; ifdown --allow=ovs ${bridges}\n  ######### PATCH END ##############\n  . \/usr\/share\/openvswitch\/scripts\/ovs-lib\n  test -e \/etc\/default\/openvswitch-switch &amp;&amp; . \/etc\/default\/openvswitch-switch\n<\/pre>\n\n\n\n<p>There is still a dependency. The openvswitch start script assumes, that the loopback interface is brought up as the last interface.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Boot support (pre Ubuntu 14.04)<\/h1>\n\n\n\n<p>The boot support for the Openvswitch is implemented very different. It depends on the Openvswitch version, the Ubuntu version and the package repository. Up to now there is <strong>NO<\/strong> support to bring up the interfaces automatically. In any case, a patch is required.<\/p>\n\n\n\n<p>All Ubuntu distributions are using Openvswitch packages(by November 2013), which do not have an openvswitch upstart script. One way to bring up interfaces here is using a few lines in \/etc\/rc.local or patching \/etc\/init.d\/openvswitch-switch .<\/p>\n\n\n\n<p>The necessary lines for \/etc\/rc.local would be:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">#\n# list the bridges\n#\nbridges=`awk '{ if ($1 == \"allow-ovs\") { print $2; } }' \"${INTERFACES}\"`\n#\n# and bring them up\n#\n[ -n \"${bridges}\" ] &amp;&amp; ifup --allow=ovs ${bridges}<\/pre>\n\n\n\n<p>You may add the necessary lines to \/etc\/init.d\/openvswitch-switch , but the interfaces may come up too late, because the non upstart script starts too late.<\/p>\n\n\n\n<p>If you are using the openvswitch package from the Havana Ubuntu Cloud Archive [deb http:\/\/ubuntu-cloud.archive.canonical.com\/ubuntu precise-updates\/havana main] you have an openvswitch-switch upstart script. This must be patched to bring up all ovs network components.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">  \"$@\" || exit $?\n  ########## PATCH START ##############\n  # get the bridges defined \n  INTERFACES=\"\/etc\/network\/interfaces\"\n  [ -e \"${INTERFACES}\" ] || return\n  bridges=$(ovs-vsctl list-br)\n  # delete the bridges defined in interfaces which survived a crash or reboot\n  if [ -n \"${bridges}\" ]\n  then\n    for b in ${bridges}\n    do\n      ovs-vsctl --timeout=2 -- --if-exists del-br $b\n    done\n  fi\n  # and start the bridges\n  bridges=`awk '{ if ($1 == \"allow-ovs\") { print $2; } }' \"${INTERFACES}\"`\n  [ -n \"${bridges}\" ] &amp;&amp; ifup --allow=ovs ${bridges}\n  logger -t ovs-start pre-start end\n  ########## PATCH END ################\nend script<\/pre>\n\n\n\n<p>You must insert all lines between &#8222;exit $?&#8220; and &#8222;end script&#8220; to bring up the Openvswitch interface.<\/p>\n\n\n\n<p>The shutdown sequence requires the following patch:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted lang:sh decode:true\">post-stop script\n  ########### PATCH START ################\n  logger -t ovs-stop post-stop\n  INTERFACES=\"\/etc\/network\/interfaces\"\n  [ -e \"${INTERFACES}\" ] || return\n  bridges=`awk '{ if ($1 == \"allow-ovs\") { print $2; } }' \"${INTERFACES}\"`\n  [ -n \"${bridges}\" ] &amp;&amp; ifdown --allow=ovs ${bridges}\n  ######### PATCH END ##############\n  . \/usr\/share\/openvswitch\/scripts\/ovs-lib\n  test -e \/etc\/default\/openvswitch-switch &amp;&amp; . \/etc\/default\/openvswitch-switch<\/pre>\n\n\n\n<p>There is still a dependency. &#8222;ifup -a&#8220; in networking.conf brings up the loopback interface as the last interface. This is the trigger to emit the event &#8222;loopback interface is up&#8220; which triggers then openvswitch-switch upstart script. This might be too late. Hopefully there will be a fully integrated solution for Ubuntu in future release (after 13.10)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The installation of the Openvswitch on Ubuntu brings an automatic integration into the boot sequence. When Ubuntu is booted, the Openvswitch is also started. Any bridge or port, which has been defined in previous sessions, is restored.BUT: No L3 interfaces are set up, junk interfaces, which have been defined in previous sessions, are restored. The [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,4,6],"tags":[],"_links":{"self":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts\/240"}],"collection":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=240"}],"version-history":[{"count":22,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts\/240\/revisions"}],"predecessor-version":[{"id":920,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=\/wp\/v2\/posts\/240\/revisions\/920"}],"wp:attachment":[{"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.opencloudblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}