When traffic originated from router port the MAC,
in DVR setup, the router MAC was replaced by one specified
in "ovn-chassis-mac-mappings" option. Along with that
the vlan tag of the localnet port was pushed.

When the traffic unicast it didn't cause any issue,
however during l2 flooding, which happens mainly
during ARP/ND, the MAC and vlan tag was also
present during output to other ports present in
the _MC_flood_l2 e.g.
set(eth(src=ee:00:00:00:00:10,dst=ff:ff:ff:ff:ff:ff)),push_vlan(vid=100,pcp=0),3,4,5

This caused that all flooded traffic had the vlan tag
and src MAC replaced, which should not happen for regular
VIFs.

To prevent that restore MAC address and strip the vlan
as part of the replacement flow in table 65 generated by
put_replace_router_port_mac_flows. So when we flood
the final flow looks like:
set(eth(src=ee:00:00:00:00:10,dst=ff:ff:ff:ff:ff:ff)),push_vlan(vid=100,pcp=0),3,4,set(eth(src=00:00:00:00:20:00)),pop_vlan,5

Reported-at: https://bugzilla.redhat.com/2123837
Signed-off-by: Ales Musil <[email protected]>
---
 controller/physical.c |  8 +++++
 tests/system-ovn.at   | 74 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/controller/physical.c b/controller/physical.c
index f3c8bddce..705146316 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -803,6 +803,14 @@ put_replace_router_port_mac_flows(struct ovsdb_idl_index
 
         ofpact_put_OUTPUT(ofpacts_p)->port = ofport;
 
+        /* Replace the MAC back and strip vlan. In case of l2 flooding
+         * traffic (ARP/ND) we need to restore previous state so other ports
+         * do not receive the traffic tagged and with wrong MAC. */
+        ofpact_put_SET_ETH_SRC(ofpacts_p)->mac = router_port_mac;
+        if (tag) {
+            ofpact_put_STRIP_VLAN(ofpacts_p);
+        }
+
         ofctrl_add_flow(flow_table, OFTABLE_LOG_TO_PHY, 150,
                         localnet_port->header_.uuid.parts[0],
                         &match, ofpacts_p, &localnet_port->header_.uuid);
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 992813614..e34e88753 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -8266,3 +8266,77 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port 
patch-.*/d
 
 AT_CLEANUP
 ])
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([DVR ping router port])
+AT_KEYWORDS([dvr])
+
+ovn_start
+
+OVS_TRAFFIC_VSWITCHD_START()
+ADD_BR([br-int])
+ADD_BR([br-ext])
+
+check ovs-ofctl add-flow br-ext action=normal
+# Set external-ids in br-int needed for ovn-controller
+ovs-vsctl \
+        -- set Open_vSwitch . external-ids:system-id=hv1 \
+        -- set Open_vSwitch . 
external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
+        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
+        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
+        -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
+
+# Start ovn-controller
+start_daemon ovn-controller
+
+check ovs-vsctl set open . external_ids:ovn-bridge-mappings=phys:br-ext
+check ovs-vsctl set open . 
external-ids:ovn-chassis-mac-mappings="phys:ee:00:00:00:00:10"
+
+
+check ovn-nbctl ls-add internal
+
+check ovn-nbctl lsp-add internal ln_internal "" 100
+check ovn-nbctl lsp-set-addresses ln_internal unknown
+check ovn-nbctl lsp-set-type ln_internal localnet
+check ovn-nbctl lsp-set-options ln_internal network_name=phys
+
+check ovn-nbctl lsp-add internal internal-gw
+check ovn-nbctl lsp-set-type internal-gw router
+check ovn-nbctl lsp-set-addresses internal-gw router
+check ovn-nbctl lsp-set-options internal-gw router-port=gw-internal
+
+check ovn-nbctl lsp-add internal vif0
+# Set address as unknown so that LRP has to generate ARP request
+check ovn-nbctl lsp-set-addresses vif0 unknown
+
+check ovn-nbctl lr-add gw
+check ovn-nbctl lrp-add gw gw-internal 00:00:00:00:20:00 192.168.20.1/24
+
+ADD_NAMESPACES(vif0)
+ADD_VETH(vif0, vif0, br-int, "192.168.20.10/24", "00:00:00:00:20:10", 
"192.168.20.1")
+
+check ovn-nbctl --wait=sb sync
+check ovn-nbctl --wait=hv sync
+
+NS_CHECK_EXEC([vif0], [ping -q -c 3 -i 0.3 -w 1 192.168.20.1 | FORMAT_PING], \
+[0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+OVS_APP_EXIT_AND_WAIT([ovn-controller])
+
+as ovn-sb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as ovn-nb
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
+
+as northd
+OVS_APP_EXIT_AND_WAIT([NORTHD_TYPE])
+
+as
+OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
+/connection dropped.*/d"])
+
+AT_CLEANUP
+])
-- 
2.37.2

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to