Skip to content

Commit

Permalink
ofproto-dpif-xlate: Clear out vlan flow fields while processing nativ…
Browse files Browse the repository at this point in the history
…e tunnel.

When a packet is received over an access port that needs to be sent
over a vxlan tunnel,the access port VLAN id is used in the lookup
leading to a wrong packet being crafted and sent over the tunnel.
Clear out the flow 's VLAN field as it should not be used while
performing mac lookup for the outer tunnel and also at this point
the VLAN action related to inner flow is already committed.

Fixes: 7c12dfc ("tunneling: Avoid datapath-recirc by combining recirc actions at xlate.")
Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2022-April/393566.html
Reported-at: https://bugzilla.redhat.com/2060552
Signed-off-by: Thilak Raj Surendra Babu <thilakraj.sb@nutanix.com>
Signed-off-by: Rosemarie O'Riorden <roriorden@redhat.com>
Co-authored-by: Rosemarie O'Riorden <roriorden@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
  • Loading branch information
2 people authored and igsilya committed Apr 27, 2022
1 parent 2080979 commit c1c8cb8
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ofproto/ofproto-dpif-xlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -3542,6 +3542,9 @@ propagate_tunnel_data_to_flow__(struct flow *dst_flow,
dst_flow->dl_dst = dmac;
dst_flow->dl_src = smac;

/* Clear VLAN entries which do not apply for tunnel flows. */
memset(dst_flow->vlans, 0, sizeof dst_flow->vlans);

dst_flow->packet_type = htonl(PT_ETH);
dst_flow->nw_dst = src_flow->tunnel.ip_dst;
dst_flow->nw_src = src_flow->tunnel.ip_src;
Expand Down
47 changes: 47 additions & 0 deletions tests/system-traffic.at
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,53 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PI
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP

AT_SETUP([datapath - ping vlan over vxlan tunnel])
OVS_CHECK_TUNNEL_TSO()
OVS_CHECK_VXLAN()

OVS_TRAFFIC_VSWITCHD_START()
ADD_BR([br-underlay])

AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"])

ADD_NAMESPACES(at_ns0)

dnl Set up underlay link from host into the namespace using veth pair.
ADD_VETH(p0, at_ns0, br-underlay, "172.31.2.1/24")
AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"])
AT_CHECK([ip link set dev br-underlay up])

dnl Set up tunnel endpoints on OVS outside the namespace and with a native
dnl linux device inside the namespace.
ADD_OVS_TUNNEL([vxlan], [br0], [at_vxlan0], [172.31.1.1], [10.1.1.100/24])
ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], [10.2.1.1/24],
[id 0 dstport 4789])

AT_CHECK([ovs-vsctl set port br0 tag=100])
AT_CHECK([ovs-vsctl set port br-underlay tag=42])

ADD_VLAN(at_vxlan1, at_ns0, 100, "10.1.1.1/24")
ADD_VLAN(p0, at_ns0, 42, "172.31.1.1/24")

dnl First, check the underlay
NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 172.31.1.100 | FORMAT_PING], [0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])
dnl Okay, now check the overlay with different packet sizes
NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])
NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])
NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])

OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP

AT_SETUP([datapath - ping over vxlan6 tunnel])
OVS_CHECK_TUNNEL_TSO()
OVS_CHECK_VXLAN_UDP6ZEROCSUM()
Expand Down
51 changes: 51 additions & 0 deletions tests/tunnel-push-pop.at
Original file line number Diff line number Diff line change
Expand Up @@ -864,3 +864,54 @@ Datapath actions: 7

OVS_VSWITCHD_STOP
AT_CLEANUP

AT_SETUP([tunnel_push_pop - VXLAN access port])

dnl Create bridge that has a MAC address.
OVS_VSWITCHD_START([set bridge br0 datapath_type=dummy dnl
-- set Interface br0 other-config:hwaddr=aa:55:aa:55:00:00])
AT_CHECK([ovs-vsctl add-port br0 p8 dnl
-- set Interface p8 type=dummy ofport_request=8])

dnl Create another bridge.
AT_CHECK([ovs-vsctl add-br ovs-tun0 -- set bridge ovs-tun0 datapath_type=dummy])

dnl Add VXLAN port to this bridge.
AT_CHECK([ovs-vsctl add-port ovs-tun0 tun0 dnl
-- set int tun0 type=vxlan options:remote_ip=10.0.0.11 dnl
-- add-port ovs-tun0 p7 dnl
-- set interface p7 type=dummy ofport_request=7])

dnl Set VLAN tags, so that br0 and its port p8 have the same tag,
dnl but ovs-tun0's port p7 has a different tag.
AT_CHECK([ovs-vsctl set port p8 tag=42 dnl
-- set port br0 tag=42 dnl
-- set port p7 tag=200])

dnl Set IP address and route for br0.
AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 10.0.0.2/24], [0], [OK
])
AT_CHECK([ovs-appctl ovs/route/add 10.0.0.11/24 br0], [0], [OK
])

dnl Send an ARP reply to port b8 on br0, so that packets will be forwarded
dnl to learned port.
AT_CHECK([ovs-ofctl add-flow br0 action=normal])

AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),dnl
eth(src=aa:55:aa:66:00:00,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),dnl
arp(sip=10.0.0.11,tip=10.0.0.2,op=2,sha=aa:55:aa:66:00:00,tha=00:00:00:00:00:00)'])

AT_CHECK([ovs-appctl ofproto/trace ovs-tun0 in_port=p7], [0], [stdout])
AT_CHECK([tail -2 stdout], [0], [dnl
Megaflow: recirc_id=0,eth,in_port=7,dl_src=00:00:00:00:00:00,dnl
dl_dst=00:00:00:00:00:00,dl_type=0x0000
Datapath actions: push_vlan(vid=200,pcp=0),1,clone(tnl_push(tnl_port(4789),dnl
header(size=50,type=4,eth(dst=aa:55:aa:66:00:00,src=aa:55:aa:55:00:00,dnl
dl_type=0x0800),ipv4(src=10.0.0.2,dst=10.0.0.11,proto=17,tos=0,ttl=64,dnl
frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x0)),dnl
out_port(100)),8)
])

OVS_VSWITCHD_STOP
AT_CLEANUP

0 comments on commit c1c8cb8

Please sign in to comment.