Skip to content

Commit

Permalink
controller: Restore MAC and vlan for DVR scenario
Browse files Browse the repository at this point in the history
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 <amusil@redhat.com>
Acked-by: Mark Michelson <mmichels@redhat.com>
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
(cherry picked from commit 36a7073)
  • Loading branch information
almusil authored and dceara committed Sep 30, 2022
1 parent 9ab1316 commit 33e3be7
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
8 changes: 8 additions & 0 deletions controller/physical.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,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);
Expand Down
74 changes: 74 additions & 0 deletions tests/system-ovn.at
Original file line number Diff line number Diff line change
Expand Up @@ -8420,3 +8420,77 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
/removing policing failed: No such device/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
])

0 comments on commit 33e3be7

Please sign in to comment.