Skip to content

Commit

Permalink
ovn-controller: Reset flow processing after (re)connection to switch
Browse files Browse the repository at this point in the history
When ovn-controller reconnects to the ovs-vswitchd, it deletes all the
OF flows in the switch. It doesn't install the flows again, leaving
the datapath broken unless ovn-controller is restarted or ovn-northd
updates the SB DB.

The reason for this is
  - lflow_reset_processing() is not called after the reconnection
  - the hmap "installed_flows" is not cleared, because of which
    ofctrl_put skips adding the flows to the switch.

This patch fixes the issue and also adds a test case to test
this scenario.

Signed-off-by: Numan Siddique <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
Acked-by: Ryan Moats <[email protected]>
  • Loading branch information
numansiddique authored and blp committed Aug 15, 2016
1 parent 2c96044 commit f5792c3
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
7 changes: 7 additions & 0 deletions ovn/controller/ofctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "flow.h"
#include "hash.h"
#include "hindex.h"
#include "lflow.h"
#include "ofctrl.h"
#include "openflow/openflow.h"
#include "openvswitch/dynamic-string.h"
Expand Down Expand Up @@ -368,6 +369,7 @@ run_S_CLEAR_FLOWS(void)

/* Clear installed_flows, to match the state of the switch. */
ovn_flow_table_clear();
lflow_reset_processing();

/* Clear existing groups, to match the state of the switch. */
if (groups) {
Expand Down Expand Up @@ -807,6 +809,11 @@ ovn_flow_table_clear(void)
hindex_remove(&uuid_flow_table, &f->uuid_hindex_node);
ovn_flow_destroy(f);
}

HMAP_FOR_EACH_SAFE (f, next, match_hmap_node, &installed_flows) {
hmap_remove(&installed_flows, &f->match_hmap_node);
ovn_flow_destroy(f);
}
}

static void
Expand Down
95 changes: 95 additions & 0 deletions tests/ovn.at
Original file line number Diff line number Diff line change
Expand Up @@ -4309,3 +4309,98 @@ AT_CHECK([cat received2.packets], [0], [expout])
OVN_CLEANUP([hv1])

AT_CLEANUP

AT_SETUP([ovn -- ovs-vswitchd restart])
AT_KEYWORDS([vswitchd restart])
AT_SKIP_IF([test $HAVE_PYTHON = no])
ovn_start

ovn-nbctl ls-add ls1

ovn-nbctl lsp-add ls1 ls1-lp1 \
-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"

ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"

net_add n1
sim_add hv1

as hv1
ovs-vsctl add-br br-phys
ovn_attach n1 br-phys 192.168.0.1
ovs-vsctl -- add-port br-int hv1-vif1 -- \
set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
options:tx_pcap=hv1/vif1-tx.pcap \
options:rxq_pcap=hv1/vif1-rx.pcap \
ofport-request=1

ovn_populate_arp
sleep 2

as hv1 ovs-vsctl show

echo "---------------------"
ovn-sbctl dump-flows
echo "---------------------"

echo "------ hv1 dump ----------"
as hv1 ovs-ofctl dump-flows br-int
total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`

echo "Total flows before vswitchd restart = " $total_flows

# Code taken from ovs-save utility
save_flows () {
echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
-e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
echo "EOF" >> restore_flows.sh
}

restart_vswitchd () {
restore_flows=$1

if test $restore_flows = true; then
save_flows
fi

as hv1
OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])

if test $restore_flows = true; then
as hv1
ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
fi

as hv1
start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
ovs-ofctl dump-flows br-int

if test $restore_flows = true; then
sh ./restore_flows.sh
echo "Flows after restore"
as hv1
ovs-ofctl dump-flows br-int
ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
flow-restore-wait="true"
fi
}

# Save the flows, restart vswitchd and restore the flows
restart_vswitchd true
OVS_WAIT_UNTIL([
total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
echo "Total flows after vswitchd restart = " $total_flows_after_restart
test "${total_flows}" = "${total_flows_after_restart}"
])

# Restart vswitchd without restoring
restart_vswitchd false
OVS_WAIT_UNTIL([
total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
echo "Total flows after vswitchd restart = " $total_flows_after_restart
test "${total_flows}" = "${total_flows_after_restart}"
])

OVN_CLEANUP([hv1])
AT_CLEANUP

0 comments on commit f5792c3

Please sign in to comment.