On Tue, Oct 23, 2012 at 11:04 AM, Gurucharan Shetty <span dir="ltr">&lt;<a href="mailto:gshetty@nicira.com" target="_blank">gshetty@nicira.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">Add a new command - &quot;restart&quot; to ovs-ctl. Calling this command<br>
will save and restore the Openflow flows on each bridge while<br>
stopping and starting the userspace daemons respectively.<br>
<br>
Also, during a force-reload-kmod, save the flows and kernel datapath<br>
configuration. Use the saved datapath configuration while readding<br>
the kernel module and the flows while starting the userspace daemons.<br>
<br>
Feature #13555.<br>
Signed-off-by: Gurucharan Shetty &lt;<a href="mailto:gshetty@nicira.com">gshetty@nicira.com</a>&gt;<br>
</div>---<br>
 utilities/ovs-ctl.8  |   29 +++--<br>
 utilities/<a href="http://ovs-ctl.in" target="_blank">ovs-ctl.in</a> |  102 +++++++++++++--<br>
 utilities/ovs-save   |  336 ++++++++++++++++++++++++++++++++++----------------<br>
 3 files changed, 339 insertions(+), 128 deletions(-)<br>
<div><div class="h5"><br>
diff --git a/utilities/ovs-ctl.8 b/utilities/ovs-ctl.8<br>
index 8cbd3cf..3092d46 100644<br>
--- a/utilities/ovs-ctl.8<br>
+++ b/utilities/ovs-ctl.8<br>
@@ -250,6 +250,14 @@ modules.<br>
 This command does nothing and finishes successfully if the OVS daemons<br>
 aren&#39;t running.<br>
 .<br>
+.SH &quot;The ``restart&#39;&#39; command&quot;<br>
+.<br>
+.PP<br>
+The \fBrestart\fR command performs a \fBstop\fR followed by a \fBstart\fR<br>
+command.  The command can take the same options as that of the \fBstart\fR<br>
+command. In addition, it saves and restores Openflow flows for each<br>
+individual bridge.<br>
+.<br>
 .SH &quot;The ``status&#39;&#39; command&quot;<br>
 .<br>
 .PP<br>
@@ -279,27 +287,32 @@ implemented by Open vSwitch.  The most common examples of these are<br>
 bridge ``local ports&#39;&#39;.<br>
 .<br>
 .IP 2.<br>
+Saves the Openflow flows of each bridge and the kernel datapath<br>
+configuration for each of the kernel datapaths.<br>
+.<br>
+.IP 3.<br>
 Stops the Open vSwitch daemons, as if by a call to \fBovs\-ctl<br>
 stop\fR.<br>
 .<br>
-.IP 3.<br>
+.IP 4.<br>
 Saves the kernel configuration state of the OVS internal interfaces<br>
 listed in step 1, including IP and IPv6 addresses and routing table<br>
 entries.<br>
 .<br>
-.IP 4.<br>
+.IP 5.<br>
 Unloads the Open vSwitch kernel module (including the bridge<br>
 compatibility module if it is loaded).<br>
 .<br>
-.IP 5.<br>
-Starts OVS back up, as if by a call to \fBovs\-ctl start\fR.  This<br>
-reloads the kernel module and restarts the OVS daemons (including<br>
-\fBovs\-brcompatd\fR, if \fB\-\-brcompat\fR is specified).<br>
-.<br>
 .IP 6.<br>
-Restores the kernel configuration state that was saved in step 3.<br>
+Starts OVS back up, as if by a call to \fBovs\-ctl start\fR.  This<br>
+reloads the kernel module, restores the saved kernel datapath configuration,<br>
+restarts the OVS daemons (including \fBovs\-brcompatd\fR, if \fB\-\-brcompat\fR<br>
+is specified) and finally restores the saved Openflow flows.<br>
 .<br>
 .IP 7.<br>
+Restores the kernel configuration state that was saved in step 4.<br>
+.<br>
+.IP 8.<br>
 Checks for daemons that may need to be restarted because they have<br>
 packet sockets that are listening on old instances of Open vSwitch<br>
 kernel interfaces and, if it finds any, prints a warning on stdout.<br>
diff --git a/utilities/<a href="http://ovs-ctl.in" target="_blank">ovs-ctl.in</a> b/utilities/<a href="http://ovs-ctl.in" target="_blank">ovs-ctl.in</a><br>
</div></div>index 2ead004..4b63f62 100755<br>
--- a/utilities/<a href="http://ovs-ctl.in" target="_blank">ovs-ctl.in</a><br>
+++ b/utilities/<a href="http://ovs-ctl.in" target="_blank">ovs-ctl.in</a><br>
@@ -30,13 +30,21 @@ done<br>
<div class="im"> ## start ##<br>
 ## ----- ##<br>
<br>
</div>+restore_datapaths () {<br>
<div class="im">+    [ -n &quot;${script_datapaths}&quot; ] &amp;&amp; \<br>
+        action &quot;Restoring datapath configuration&quot; &quot;${script_datapaths}&quot;<br>
</div><div class="im">+}<br>
+<br>
 insert_openvswitch_mod_if_required () {<br>
     # If openvswitch is already loaded then we&#39;re done.<br>
     test -e /sys/module/openvswitch -o -e /sys/module/openvswitch_mod &amp;&amp; \<br>
</div><div class="im">      return 0<br>
<br>
     # Load openvswitch.  If that&#39;s successful then we&#39;re done.<br>
-    action &quot;Inserting openvswitch module&quot; modprobe openvswitch &amp;&amp; return 0<br>
+    if action &quot;Inserting openvswitch module&quot; modprobe openvswitch; then<br>
</div>+        restore_datapaths<br>
<div class="im">+        return 0<br>
+    fi<br>
<br>
     # If the bridge module is loaded, then that might be blocking<br>
     # openvswitch.  Try to unload it, if there are no bridges.<br>
</div>@@ -50,6 +58,7 @@ insert_openvswitch_mod_if_required () {<br>
<div class="im"><br>
     # Try loading openvswitch again.<br>
     action &quot;Inserting openvswitch module&quot; modprobe openvswitch<br>
</div>+    restore_datapaths<br>
 }<br>
<br>
 insert_brcompat_mod_if_required () {<br>
@@ -293,14 +302,46 @@ internal_interfaces () {<br>
     done<br>
 }<br>
<br>
+save_flows () {<br>
+   if set X `ovs_vsctl list-br`; then<br>
+        shift<br>
+        if &quot;$datadir/scripts/ovs-save&quot; save-flows &quot;$@&quot; &gt; &quot;$script_flows&quot;; then<br>
+            chmod +x &quot;$script_flows&quot;<br>
<div class="im">+            return 0<br>
+        fi<br>
</div>+    fi<br>
+    script_flows=<br>
+    log_warning_msg &quot;Failed to save flows.&quot;<br>
+    return 1<br>
<div class="im">+}<br>
+<br>
 save_interfaces () {<br>
-    &quot;$datadir/scripts/ovs-save&quot; $ifaces &gt; &quot;$script&quot;<br>
+    &quot;$datadir/scripts/ovs-save&quot; save-interfaces ${ifaces} \<br>
+        &gt; &quot;${script_interfaces}&quot;<br>
+}<br>
+<br>
+save_datapaths () {<br>
+    &quot;$datadir/scripts/ovs-save&quot; save-datapaths ${datapaths} \<br>
+        &gt; &quot;${script_datapaths}&quot;<br>
</div>+}<br>
+<br>
+restore_flows () {<br>
<div class="im">+    [ -n &quot;${script_flows}&quot; ] &amp;&amp; \<br>
</div>+        action &quot;Restoring saved flows&quot; &quot;${script_flows}&quot;<br>
<div class="im"> }<br>
<br>
 force_reload_kmod () {<br>
     ifaces=`internal_interfaces`<br>
     action &quot;Detected internal interfaces: $ifaces&quot; true<br>
<br>
+    script_interfaces=`mktemp`<br>
+    script_datapaths=`mktemp`<br>
+    script_flows=`mktemp`<br>
+    trap &#39;rm -f &quot;${script_interfaces}&quot; &quot;${script_flows}&quot; \<br>
+        &quot;${script_datapaths}&quot;&#39; 0 1 2 13 15<br>
+<br>
</div>+    action &quot;Saving flows&quot; save_flows<br>
<div class="im">+<br>
     # Restart the database first, since a large database may take a<br>
     # while to load, and we want to minimize forwarding disruption.<br>
     stop_ovsdb<br>
</div>@@ -308,8 +349,6 @@ force_reload_kmod () {<br>
<div class="im"><br>
     stop_forwarding<br>
<br>
-    script=`mktemp`<br>
-    trap &#39;rm -f &quot;$script&quot;&#39; 0 1 2 13 15<br>
     if action &quot;Saving interface configuration&quot; save_interfaces; then<br>
         :<br>
     else<br>
</div>@@ -317,9 +356,18 @@ force_reload_kmod () {<br>
<div class="im">         start_forwarding<br>
         exit 1<br>
     fi<br>
-    chmod +x &quot;$script&quot;<br>
+    chmod +x &quot;$script_interfaces&quot;<br>
+<br>
+    datapaths=`ovs-dpctl dump-dps`<br>
+    if action &quot;Saving datapath configuration&quot; save_datapaths; then<br>
+        chmod +x &quot;${script_datapaths}&quot;<br>
+    else<br>
+        log_warning_msg &quot;Failed to save datapath configuration. The port\<br>
+                         numbers may change after the restart&quot;<br>
+        script_datapaths=&quot;&quot;<br>
+    fi<br>
<br>
-    for dp in `ovs-dpctl dump-dps`; do<br>
+    for dp in ${datapaths}; do<br>
         action &quot;Removing datapath: $dp&quot; ovs-dpctl del-dp &quot;$dp&quot;<br>
     done<br>
<br>
</div>@@ -337,7 +385,9 @@ force_reload_kmod () {<br>
<div class="im"><br>
     start_forwarding<br>
<br>
-    action &quot;Restoring interface configuration&quot; &quot;$script&quot;<br>
</div>+    restore_flows<br>
<div class="im">+<br>
+    action &quot;Restoring interface configuration&quot; &quot;$script_interfaces&quot;<br>
     rc=$?<br>
     if test $rc = 0; then<br>
         level=debug<br>
</div>@@ -346,11 +396,32 @@ force_reload_kmod () {<br>
     fi<br>
<div class="im">     log=&quot;logger -p daemon.$level -t ovs-save&quot;<br>
</div>     $log &quot;force-reload-kmod interface restore script exited with status $rc:&quot;<br>
-    $log -f &quot;$script&quot;<br>
+    $log -f &quot;$script_interfaces&quot;<br>
<br>
     &quot;$datadir/scripts/ovs-check-dead-ifs&quot;<br>
 }<br>
<br>
+## ------- ##<br>
+## restart ##<br>
+## ------- ##<br>
<div class="im">+<br>
+restart () {<br>
+    script_flows=`mktemp`<br>
+    trap &#39;rm -f &quot;${script_flows}&quot;&#39; 0 1 2 13 15<br>
+<br>
</div>+    action &quot;Saving flows&quot; save_flows<br>
<div class="im">+<br>
+    # Restart the database first, since a large database may take a<br>
+    # while to load, and we want to minimize forwarding disruption.<br>
+    stop_ovsdb<br>
+    start_ovsdb<br>
+<br>
+    stop_forwarding<br>
+    start_forwarding<br>
+<br>
</div>+    restore_flows<br>
<div class="im">+}<br>
+<br>
 ## --------------- ##<br>
 ## enable-protocol ##<br>
 ## --------------- ##<br>
</div>@@ -455,6 +526,7 @@ scripts.  System administrators should not normally invoke it directly.<br>
<div class="im"> Commands:<br>
   start              start Open vSwitch daemons<br>
   stop               stop Open vSwitch daemons<br>
+  restart            stop and start Open vSwitch daemons<br>
   status             check whether Open vSwitch daemons are running<br>
   version            print versions of Open vSwitch daemons<br>
   load-kmod          insert modules if not already present<br>
</div>@@ -463,18 +535,18 @@ Commands:<br>
<div class="im">   enable-protocol    enable protocol specified in options with iptables<br>
   help               display this help message<br>
<br>
-One of the following options is required for &quot;start&quot; and &quot;force-reload-kmod&quot;:<br>
+One of the following options is required for &quot;start&quot;, &quot;restart&quot; and &quot;force-reload-kmod&quot;:<br>
   --system-id=UUID   set specific ID to uniquely identify this system<br>
   --system-id=random  use a random but persistent UUID to identify this system<br>
<br>
-Other important options for &quot;start&quot; and &quot;force-reload-kmod&quot;:<br>
+Other important options for &quot;start&quot;, &quot;restart&quot; and &quot;force-reload-kmod&quot;:<br>
   --system-type=TYPE  set system type (e.g. &quot;XenServer&quot;)<br>
   --system-version=VERSION  set system version (e.g. &quot;5.6.100-39265p&quot;)<br>
   --external-id=&quot;key=value&quot;<br>
                      add given key-value pair to Open_vSwitch external-ids<br>
   --delete-bridges   delete all bridges just before starting ovs-vswitchd<br>
<br>
-Less important options for &quot;start&quot; and &quot;force-reload-kmod&quot;:<br>
+Less important options for &quot;start&quot;, &quot;restart&quot; and &quot;force-reload-kmod&quot;:<br>
   --daemon-cwd=DIR               set working dir for OVS daemons (default: $DAEMON_CWD)<br>
   --no-force-corefiles           do not force on core dumps for OVS daemons<br>
   --no-mlockall                  do not lock all of ovs-vswitchd into memory<br>
</div>@@ -482,13 +554,13 @@ Less important options for &quot;start&quot; and &quot;force-reload-kmod&quot;:<br>
<div class="im">   --ovs-vswitchd-priority=NICE   set ovs-vswitchd&#39;s niceness (default: $OVS_VSWITCHD_PRIORITY)<br>
   --ovs-brcompatd-priority=NICE  set ovs-brcompatd&#39;s niceness (default: $OVS_BRCOMPATD_PRIORITY)<br>
<br>
-Debugging options for &quot;start&quot; and &quot;force-reload-kmod&quot;:<br>
+Debugging options for &quot;start&quot;, &quot;restart&quot; and &quot;force-reload-kmod&quot;:<br>
   --ovsdb-server-wrapper=WRAPPER<br>
   --ovs-vswitchd-wrapper=WRAPPER<br>
   --ovs-vswitchd-wrapper=WRAPPER<br>
      run specified daemon under WRAPPER (either &#39;valgrind&#39; or &#39;strace&#39;)<br>
<br>
-Options for &quot;start&quot;, &quot;force-reload-kmod&quot;, &quot;load-kmod&quot;, &quot;status&quot;, and &quot;version&quot;:<br>
+Options for &quot;start&quot;, &quot;restart&quot;, &quot;force-reload-kmod&quot;, &quot;load-kmod&quot;, &quot;status&quot;, and &quot;version&quot;:<br>
   --brcompat         enable Linux bridge compatibility module and daemon<br>
<br>
 File location options:<br>
</div>@@ -606,6 +678,9 @@ case $command in<br>
<div class="im">         stop_forwarding<br>
         stop_ovsdb<br>
         ;;<br>
+    restart)<br>
+        restart<br>
+        ;;<br>
     status)<br>
         rc=0<br>
         for daemon in `daemons`; do<br>
</div>@@ -639,4 +714,3 @@ case $command in<br>
<div class="im">         exit 1<br>
         ;;<br>
 esac<br>
-<br>
diff --git a/utilities/ovs-save b/utilities/ovs-save<br>
</div>index 297c2fa..0a3dfc6 100755<br>
<div><div class="h5">--- a/utilities/ovs-save<br>
+++ b/utilities/ovs-save<br>
@@ -14,20 +14,25 @@<br>
 # See the License for the specific language governing permissions and<br>
 # limitations under the License.<br>
<br>
-if test &quot;X$1&quot; = X--help; then<br>
+usage() {<br>
+    UTIL=$(basename $0)<br>
     cat &lt;&lt;EOF<br>
-$0: saves the kernel configuration of network interfaces<br>
-usage: $0 NETDEV...<br>
+${UTIL}: Provides helper functions to save Open vSwitch&#39;s configuration.<br>
+usage: $0 COMMAND<br>
<br>
-Outputs a shell script on stdout that will restore the current<br>
-kernel configuration of the specified network interfaces, as<br>
-well as the system iptables configuration.<br>
+Commands:<br>
+ save-interfaces        Outputs a shell script on stdout that will restore<br>
+                        the current kernel configuration of the specified<br>
+                        network interfaces, as well as the system iptables<br>
+                        configuration.<br>
+ save-flows             Outputs a shell script on stdout that will restore<br>
+                        Openflow flows of each Open vSwitch bridge.<br>
+ save-datapaths         Outputs a shell script on stdout that will restore<br>
+                        the datapaths with the same port numbers as before.<br>
<br>
-This script is meant as a helper for the Open vSwitch init<br>
-script &quot;force-reload-kmod&quot; command.<br>
+This script is meant as a helper for the Open vSwitch init script commands.<br>
 EOF<br>
-    exit 0<br>
-fi<br>
+}<br>
<br>
 PATH=/sbin:/bin:/usr/sbin:/usr/bin<br>
<br>
</div></div>@@ -43,116 +48,235 @@ missing_program () {<br>
<div><div class="h5">     IFS=$save_IFS<br>
     return 0<br>
 }<br>
-if missing_program ip; then<br>
-    echo &quot;$0: ip not found in $PATH&quot; &gt;&amp;2<br>
-    exit 1<br>
-fi<br>
-<br>
-if test &quot;$#&quot; = 0; then<br>
-    echo &quot;# $0: no parameters given (use \&quot;$0 --help\&quot; for help)&quot;<br>
-fi<br>
-<br>
-devs=$*<br>
-for dev in $devs; do<br>
-    state=`ip link show dev $dev` || continue<br>
-<br>
-    echo &quot;# $dev&quot;<br>
-    # Link state (Ethernet addresses, up/down, ...)<br>
-    linkcmd=<br>
-    case $state in<br>
-        *&quot;state UP&quot;* | *[,\&lt;]&quot;UP&quot;[,\&gt;]* )<br>
-            linkcmd=&quot;$linkcmd up&quot;<br>
-            ;;<br>
-        *&quot;state DOWN&quot;*)<br>
-            linkcmd=&quot;$linkcmd down&quot;<br>
-            ;;<br>
-    esac<br>
-    if expr &quot;$state&quot; : &#39;.*\bdynamic\b&#39; &gt; /dev/null; then<br>
-        linkcmd=&quot;$linkcmd dynamic&quot;<br>
-    fi<br>
-    if qlen=`expr &quot;$state&quot; : &#39;.*qlen \([0-9]+\)&#39;`; then<br>
-        linkcmd=&quot;$linkcmd txqueuelen $qlen&quot;<br>
-    fi<br>
-    if hwaddr=`expr &quot;$state&quot; : &#39;.*link/ether \([^ ]*\)&#39;`; then<br>
-        linkcmd=&quot;$linkcmd address $hwaddr&quot;<br>
-    fi<br>
-    if brd=`expr &quot;$state&quot; : &#39;.*brd \([^ ]*\)&#39;`; then<br>
-        linkcmd=&quot;$linkcmd broadcast $brd&quot;<br>
-    fi<br>
-    if mtu=`expr &quot;$state&quot; : &#39;.*mtu \([0-9]+\)&#39;`; then<br>
-        linkcmd=&quot;$linkcmd mtu $mtu&quot;<br>
</div></div><div class="im">+<br>
+save_interfaces () {<br>
+    if missing_program ip; then<br>
+        echo &quot;$0: ip not found in $PATH&quot; &gt;&amp;2<br>
+        exit 1<br>
</div><div class="im">     fi<br>
-    if test -n &quot;$linkcmd&quot;; then<br>
-        echo ip link set dev $dev down # Required to change hwaddr.<br>
-        echo ip link set dev $dev $linkcmd<br>
</div><div class="im">+<br>
+    if test &quot;$#&quot; = 0; then<br>
+        exit 0<br>
</div>     fi<br>
<div class="im"><br>
-    # IP addresses (including IPv6).<br>
-    echo &quot;ip addr flush dev $dev 2&gt;/dev/null&quot; # Suppresses &quot;Nothing to flush&quot;.<br>
-    ip addr show dev $dev | while read addr; do<br>
-        set -- $addr<br>
-<br>
-        # Check and trim family.<br>
-        family=$1<br>
-        shift<br>
-        case $family in<br>
-            inet | inet6) ;;<br>
-            *) continue ;;<br>
</div><div class="im">+    devs=&quot;$@&quot;<br>
+    for dev in $devs; do<br>
+        state=`ip link show dev $dev` || continue<br>
+<br>
+        echo &quot;# $dev&quot;<br>
+        # Link state (Ethernet addresses, up/down, ...)<br>
+        linkcmd=<br>
+        case $state in<br>
+            *&quot;state UP&quot;* | *[,\&lt;]&quot;UP&quot;[,\&gt;]* )<br>
+                linkcmd=&quot;$linkcmd up&quot;<br>
+                ;;<br>
+            *&quot;state DOWN&quot;*)<br>
+                linkcmd=&quot;$linkcmd down&quot;<br>
+                ;;<br>
</div><div class="im">         esac<br>
+        if expr &quot;$state&quot; : &#39;.*\bdynamic\b&#39; &gt; /dev/null; then<br>
+            linkcmd=&quot;$linkcmd dynamic&quot;<br>
+        fi<br>
</div>+        if qlen=`expr &quot;$state&quot; : &#39;.*qlen \([0-9]+\)&#39;`; then<br>
<div class="im">+            linkcmd=&quot;$linkcmd txqueuelen $qlen&quot;<br>
+        fi<br>
+        if hwaddr=`expr &quot;$state&quot; : &#39;.*link/ether \([^ ]*\)&#39;`; then<br>
+            linkcmd=&quot;$linkcmd address $hwaddr&quot;<br>
+        fi<br>
+        if brd=`expr &quot;$state&quot; : &#39;.*brd \([^ ]*\)&#39;`; then<br>
+            linkcmd=&quot;$linkcmd broadcast $brd&quot;<br>
+        fi<br>
</div>+        if mtu=`expr &quot;$state&quot; : &#39;.*mtu \([0-9]+\)&#39;`; then<br>
<div class="im">+            linkcmd=&quot;$linkcmd mtu $mtu&quot;<br>
+        fi<br>
+        if test -n &quot;$linkcmd&quot;; then<br>
+            echo ip link set dev $dev down # Required to change hwaddr.<br>
+            echo ip link set dev $dev $linkcmd<br>
+        fi<br>
+<br>
+        # IP addresses (including IPv6).<br>
+        echo &quot;ip addr flush dev $dev 2&gt;/dev/null&quot; # Suppresses &quot;Nothing to flush&quot;.<br>
+        ip addr show dev $dev | while read addr; do<br>
+            set -- $addr<br>
+<br>
+            # Check and trim family.<br>
+            family=$1<br>
+            shift<br>
+            case $family in<br>
+                inet | inet6) ;;<br>
+                *) continue ;;<br>
+            esac<br>
<br>
</div><div class="im">-        # Trim device off the end--&quot;ip&quot; insists on having &quot;dev&quot; precede it.<br>
-        addrcmd=<br>
-        while test $# != 0; do<br>
-            case $1 in<br>
-                dynamic)<br>
-                    # Omit kernel-maintained route.<br>
-                    continue 2<br>
-                    ;;<br>
-                scope)<br>
-                    if test &quot;$2&quot; = link; then<br>
-                        # Omit route derived from IP address, e.g.<br>
-                        # <a href="http://172.16.0.0/16" target="_blank">172.16.0.0/16</a> derived from 172.16.12.34.<br>
</div><div class="im">+            # Trim device off the end--&quot;ip&quot; insists on having &quot;dev&quot; precede it.<br>
+            addrcmd=<br>
+            while test $# != 0; do<br>
+                case $1 in<br>
+                    dynamic)<br>
+                        # Omit kernel-maintained route.<br>
</div><div class="im">                         continue 2<br>
-                    fi<br>
-                    ;;<br>
-                &quot;$dev&quot;|&quot;$dev:&quot;*)<br>
-                    # Address label string<br>
-                    addrcmd=&quot;$addrcmd label $1&quot;<br>
-                    shift<br>
-                    continue<br>
-                    ;;<br>
</div><div><div class="h5">+                        ;;<br>
+                    scope)<br>
+                        if test &quot;$2&quot; = link; then<br>
+                            # Omit route derived from IP address, e.g.<br>
+                            # <a href="http://172.16.0.0/16" target="_blank">172.16.0.0/16</a> derived from 172.16.12.34.<br>
+                            continue 2<br>
+                        fi<br>
+                        ;;<br>
+                    &quot;$dev&quot;|&quot;$dev:&quot;*)<br>
+                        # Address label string<br>
+                        addrcmd=&quot;$addrcmd label $1&quot;<br>
+                        shift<br>
+                        continue<br>
+                        ;;<br>
+                esac<br>
+                addrcmd=&quot;$addrcmd $1&quot;<br>
+                shift<br>
+            done<br>
+            if test &quot;$1&quot; != &quot;$dev&quot;; then<br>
+                addrcmd=&quot;$addrcmd $1&quot;<br>
+            fi<br>
+<br>
+            echo ip -f $family addr add $addrcmd dev $dev<br>
+        done<br>
+<br>
+        # Routes.<br>
+        echo &quot;ip route flush dev $dev proto boot 2&gt;/dev/null&quot; # Suppresses &quot;Nothing to flush&quot;.<br>
+        ip route show dev $dev | while read route; do<br>
+            # &quot;proto kernel&quot; routes are installed by the kernel automatically.<br>
+            case $route in<br>
+                *&quot; proto kernel &quot;*) continue ;;<br>
</div></div><div class="im">             esac<br>
-            addrcmd=&quot;$addrcmd $1&quot;<br>
-            shift<br>
</div><div class="im">+<br>
+            echo &quot;ip route add $route dev $dev&quot;<br>
</div><div class="im">         done<br>
-        if test &quot;$1&quot; != &quot;$dev&quot;; then<br>
-            addrcmd=&quot;$addrcmd $1&quot;<br>
-        fi<br>
<br>
-        echo ip -f $family addr add $addrcmd dev $dev<br>
</div>+        echo<br>
     done<br>
<div class="im"><br>
-    # Routes.<br>
-    echo &quot;ip route flush dev $dev proto boot 2&gt;/dev/null&quot; # Suppresses &quot;Nothing to flush&quot;.<br>
-    ip route show dev $dev | while read route; do<br>
-        # &quot;proto kernel&quot; routes are installed by the kernel automatically.<br>
-        case $route in<br>
-            *&quot; proto kernel &quot;*) continue ;;<br>
-        esac<br>
</div>+    if missing_program iptables-save; then<br>
<div class="im">+        echo &quot;# iptables-save not found in $PATH, not saving iptables state&quot;<br>
+    else<br>
+        echo &quot;# global&quot;<br>
+        echo &quot;iptables-restore &lt;&lt;&#39;EOF&#39;&quot;<br>
+        iptables-save<br>
+        echo &quot;EOF&quot;<br>
+    fi<br>
+}<br>
+<br>
+save_flows () {<br>
+    if missing_program ovs-ofctl; then<br>
+        echo &quot;$0: ovs-ofctl not found in $PATH&quot; &gt;&amp;2<br>
+        exit 1<br>
+    fi<br>
<br>
</div><div class="im">-        echo &quot;ip route add $route dev $dev&quot;<br>
</div><div class="im">+    for bridge in &quot;$@&quot;; do<br>
</div><div class="im">+        echo &quot;ovs-ofctl add-flows ${bridge} - &lt;&lt; EOF&quot;<br>
</div>+        ovs-ofctl dump-flows &quot;${bridge}&quot; | sed -e &#39;/NXST_FLOW/d&#39; \<br>
+            -e &#39;s/\(idle\|hard\)_age=[^,]*,//g&#39;<br>
+        echo &quot;EOF&quot;<br>
     done<br>
+}<br>
<br>
-    echo<br>
-done<br>
<div class="im">+save_datapaths () {<br>
+    if missing_program ovs-dpctl; then<br>
+        echo &quot;$0: ovs-dpctl not found in $PATH&quot; &gt;&amp;2<br>
+        exit 1<br>
+    fi<br>
+    if missing_program ovs-vsctl; then<br>
+        echo &quot;$0: ovs-vsctl not found in $PATH&quot; &gt;&amp;2<br>
+        exit 1<br>
+    fi<br>
+<br>
+    for dp in &quot;$@&quot;; do<br>
+        echo &quot;ovs-dpctl add-dp ${dp}&quot;<br>
+        ovs-dpctl show $dp | while read line; do<br>
</div>+            # An example &#39;ovs-dpctl show&#39; output looks like this:<br>
+            # system@br1:<br>
+            # lookups: hit:0 missed:0 lost:0<br>
+            # flows: 0<br>
+            # port 0: br1 (internal)<br>
+            # port 1: stt2 (ipsec_stt: remote_ip=192.168.112.1)<br>
+            # port 2: sstt2886795521 (ipsec_stt: key=flow, pmtud=false, remote_ip=172.17.1.1, tos=inherit)<br>
+            # port 3: gre1 (ipsec_gre: remote_ip=192.168.113.1)<br>
+            # port 14: gre2 (gre: remote_ip=192.168.115.1)<br>
+            # port 15: gre3 (gre64: remote_ip=192.168.116.1)<br>
+            # port 16: stt3 (stt: out_key=12, remote_ip=192.168.114.1)<br>
+            # port 17: eth0<br>
+            # port 18: br1- (patch: peer=br1+)<br>
<div class="im"><br>
-if missing_program iptables-save; then<br>
-    echo &quot;# iptables-save not found in $PATH, not saving iptables state&quot;<br>
-else<br>
-    echo &quot;# global&quot;<br>
-    echo &quot;iptables-restore &lt;&lt;&#39;EOF&#39;&quot;<br>
-    iptables-save<br>
-    echo &quot;EOF&quot;<br>
-fi<br>
</div>+            # Skip lines which do not have &#39;port&#39;<br>
+            if port_no=`expr &quot;${line}&quot; : &#39;.*port \([0-9]\+\):&#39;`; then :; else<br>
<div class="im">+                continue<br>
+            fi<br>
+<br>
+            netdev=`echo ${line} | awk &#39;{print $3}&#39;`<br>
+<br>
</div>+            # Do not add port that has the same name as the datapath. It gets<br>
+            # added by default.<br>
<div class="im">+            [ &quot;${dp#system@}&quot; = &quot;${netdev}&quot; ] &amp;&amp; continue<br>
</div><div class="im">+<br>
+            type=`echo ${line} | awk &#39;{print $4}&#39; | sed &#39;s/[:)(]//g&#39;`<br>
+            [ ! -n &quot;${type}&quot; ] &amp;&amp; type=&quot;system&quot;<br>
</div>+<br>
<div class="im">+            command=&quot;ovs-dpctl add-if ${dp}\<br>
+                        ${netdev},type=${type},port_no=${port_no}&quot;<br>
+<br>
+            options=`echo ${line} | awk -F: &#39;{print $3}&#39; | sed &#39;s/[) ]//g&#39;`<br>
+            [ -n &quot;${options}&quot; ] &amp;&amp; command=&quot;${command},${options}&quot;<br>
+<br>
</div>+            # For ipsec, ovs-dpctl does not show the key value pairs related<br>
+            # to certificates. Get that information from ovs-vsctl.<br>
<div class="im">+            if [ &quot;${type}&quot; = &quot;ipsec_gre&quot; ] || [ &quot;${type}&quot; = &quot;ipsec_stt&quot; ]; then<br>
+                if peer_cert=`ovs-vsctl get interface \<br>
+                                &quot;${netdev}&quot; options:peer_cert 2&gt;/dev/null`; then<br>
</div>+                    # The option peer_cert comes with an accompanying<br>
+                    # &quot;certificate&quot; or &quot;use_ssl_cert&quot;<br>
<div class="im">+                    if (ovs-vsctl get interface &quot;${netdev}&quot; \<br>
+                            options:certificate &gt;/dev/null 2&gt;&amp;1) ; then<br>
+                        command=&quot;${command},peer_cert=${peer_cert},certificate=${certificate}&quot;<br>
+                    else<br>
+                        use_ssl_cert=`ovs-vsctl get interface &quot;${netdev}&quot; \<br>
+                                        options:use_ssl_cert 2&gt;/dev/null`<br>
+                        command=&quot;${command},peer_cert=${peer_cert},use_ssl_cert=${use_ssl_cert}&quot;<br>
+                    fi<br>
+                else<br>
+                    psk=`ovs-vsctl get interface &quot;${netdev}&quot; \<br>
+                            options:psk 2&gt;/dev/null`<br>
+                    command=&quot;${command},psk=${psk}&quot;<br>
+                fi<br>
+            fi<br>
+            echo ${command}<br>
+        done<br>
</div>+    done<br>
+}<br>
<div><div class="h5">+<br>
+while [ $# -ne 0 ]<br>
+do<br>
+    case $1 in<br>
+        &quot;save-datapaths&quot;)<br>
+            shift<br>
+            save_datapaths &quot;$@&quot;<br>
+            exit 0<br>
+            ;;<br>
+        &quot;save-flows&quot;)<br>
+            shift<br>
+            save_flows &quot;$@&quot;<br>
+            exit 0<br>
+            ;;<br>
+        &quot;save-interfaces&quot;)<br>
+            shift<br>
+            save_interfaces &quot;$@&quot;<br>
+            exit 0<br>
+            ;;<br>
+        -h | --help)<br>
+            usage<br>
+            exit 0<br>
+            ;;<br>
+        *)<br>
+            echo &gt;&amp;2 &quot;$0: unknown command \&quot;$1\&quot; (use --help for help)&quot;<br>
+            exit 1<br>
+            ;;<br>
+    esac<br>
</div></div>+done<br></blockquote><div>Please ignore this.</div><div>I will send an incremental</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
 exit 0<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.2.5<br>
<br>
</font></span></blockquote></div><br>