networking-ovn uses nested transactions, and some of the code for DVR relies on the result of a call to lsp_get_up.execute() inside a nested transaction. The result doesn't get set until the parent transaction is complete, so execute() returns None which prevents the external_mac from being set, so traffic ends up being sent to the controller instead of the through the compute node. Although this isn't technically a bug in ovsdbapp, the behavior is not documented at all and is surprising. Luckily, it is very easy to safely work around in ovsdbapp and should lead to increased performance as well. All that needs to be done is to allow Command.execute() to run read-only Commands outside of a transaction. This is safe because execute() is designed for single-command transactions and read-only Commands only access the in-memory copy of the database.
ovsbapp rocky release 0.12.3 contains these changes.
Verified on 14.0-RHEL-7/2019-04-12.1 with python2-ovsdbapp-0.12.3-1.el7ost.noarch Verified that DVR functionality works properly. Scenario: Created a router, connected it to the external network. Created internal network, subnet, connected network to the router. Created a security group with icp/ssh allowed. Created a VM with the security rules applied, connected to the internal network. Created a floating IP for the VM. Verified that traffic from the VM goes out via compute node. Also verified that when VM does not have a FIP traffic from it goes out via controller node which is master chassis for the router.
*** Bug 1668746 has been marked as a duplicate of this bug. ***
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2019:0944