[ovs-discuss] vhost communication between virtio drivers in vms

David Christensen drc at linux.vnet.ibm.com
Wed Oct 21 19:53:41 UTC 2020


> I'm trying to achieve communication across an OVS switch between to VMs 
> connected together via an ovs bridge.  I was able to do this with a ovs 
> bridge with to generic libvirt 'network' types.  I'm failing to 
> replicate using DPDK vhost.
> 
> In libvirt 'network' scenario vnet[0,1] ports are added to the bridge 
> that also has a port for the physical NIC on the system.  The switch 
> defaults to its L2 function and I can access the system's IP addresses.
> 
> In the DPDK vhost scenario, the client server connections get made, but 
> the host running the switch doesn't put the ports on the IP stack.  I 
> haven't been able to route a packet between the VMs.  Do I need to 
> create "flows" to mimic a single wire type of connection?  I don't need 
> L2 function, but I did think it might be possible to move IP packets 
> through DPDK.  Any pointers appreciated.
> 
> 
> [root at cn03 openvswitch]# ovs-vsctl show
> d78a22bb-84c7-46d4-9625-6c9c38aeeff7
>      Bridge br0
>          Port br0
>              Interface br0
>                  type: internal
>          Port vnet1
>              Interface vnet1
>          Port vnet0
>              Interface vnet0
>          Port enP5p1s0f0
>              Interface enP5p1s0f0
>      Bridge ovs-br0
>          datapath_type: netdev
>          Port dpdkvhostclient0
>              Interface dpdkvhostclient0
>                  type: dpdkvhostuserclient
>                  options: 
> {vhost-server-path="/usr/local/var/run/openvswitch/dpdkvhostclient0"}
>          Port dpdkvhostclient1
>              Interface dpdkvhostclient1
>                  type: dpdkvhostuserclient
>                  options: 
> {vhost-server-path="/usr/local/var/run/openvswitch/dpdkvhostclient1"}
>          Port ovs-br0
>              Interface ovs-br0
>                  type: internal
>      ovs_version: "2.13.1"

Yes, you definitely need to setup flow rules once you connect the VMs 
with OVS/DPDK.  Here's the script I use to setup a learning switch which 
should get you base functionality you're looking for:

#!/bin/bash
PATH=/usr/share/openvswitch/scripts:$PATH
MAX_PORT=2

# Make sure we're running as root
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root"
    exit 1
fi

# Check command line arguments for the bridge name
BRIDGE=$1
[ -z "$BRIDGE" ] && BRIDGE=ovsbr0

# Verify that OVS is running and the bridge exists
ovs-vsctl br-exists $BRIDGE > /dev/null 2>&1
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
	echo "Can't find OVS bridge $BRIDGE, exiting ..."
	exit 1
fi

# For example, "0-3,7" becomes "0,1,2,3,7".
# Requires two arguments:
# $1 - The string to be expanded
# $2 - The list of CPUs being returned
function parse_range {
         arr=()
   IFS=', ' read -a ranges <<< $1
   for range in "${ranges[@]}"; do
     IFS=- read start end <<< "$range"
     [ -z "$start" ] && continue
     [ -z "$end" ] && end=$start
     for ((i = start; i <= end; i++)); do
                         arr+=($i)
     done
   done
   eval $2=$(IFS=,;printf "%s" "${arr[*]}")
}

# Set the OFPORTS flows for the learning switch
PORT_RANGE="1-${MAX_PORT}"
PORT_LIST=""
parse_range $PORT_RANGE PORT_LIST
echo "Configuring learning switch for ports $PORT_RANGE ..."

#######################################################################
# Bridge is setup, program the flow configuration
#######################################################################
echo "Clearing current flow setup for $BRIDGE..."
ovs-ofctl del-flows $BRIDGE

echo "Configuring flows on $BRIDGE for learning switch..."

#=======================================================================
# Setup table0, admission control
#=======================================================================

# Drop packets with a multicast source address (illegal packet)
ovs-ofctl add-flow $BRIDGE \
     "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop"
# Drop spanning tree packets
ovs-ofctl add-flow $BRIDGE \
     "table=0, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0, actions=drop"
# Pass all other frames onto table1
ovs-ofctl add-flow $BRIDGE "table=0, priority=0, actions=resubmit(,1)"

#=======================================================================
# Setup table1, MAC learning
#=======================================================================
ovs-ofctl add-flow $BRIDGE \
     "table=1 actions=learn(table=10, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
                            load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]), \
                      resubmit(,2)"

#=======================================================================
# Setup table2, destination lookup
#=======================================================================

# Always forward multicast/broadcast packets
ovs-ofctl add-flow $BRIDGE \
     "table=2 priority=99 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 \
       actions=resubmit(,3)"

# Lookup the destination in table 10, move the packet on to table 3
ovs-ofctl add-flow $BRIDGE \
     "table=2 priority=50 actions=resubmit(,10), resubmit(,3)"

#=======================================================================
# Setup table3, output processing
#=======================================================================
# Handle broadcast/multicast packets (OpenFlow will prevent
# the packet from being re-transmitted out the ingress port)
ovs-ofctl add-flow $BRIDGE "table=3 reg0=0 actions=${BRIDGE},${PORT_LIST}"

# Setup the unicast flows for the vhost interfaces
for i in $(seq 1 $MAX_PORT); do
	ovs-ofctl add-flow $BRIDGE "table=3 reg0=$i actions=$i"
done

# Don't forget the bridge's tap interface to the host
ovs-ofctl add-flow $BRIDGE "table=3 reg0=65534 actions=local"

echo "New flow configuration for $BRIDGE..."
ovs-ofctl dump-flows $BRIDGE


More information about the discuss mailing list