0

I'm running Xen on Debian with five guest VM:s. I've used the following command to setup port mirroring to two of the VM:s

 ovs-vsctl \
  -- --id=@m1 create mirror name=detector \
  -- add bridge xenbr1 mirrors @m1 \
  -- --id=@m2 create mirror name=recorder \
  -- add bridge xenbr1 mirrors @m2 \
  -- --id=@eth1 get port eth1 \
  -- [email protected] get port vif2.0 \
  -- [email protected] get port vif5.0 \
  -- set mirror detector select_src_port=@eth1 select_dst_port=@eth1 \
  -- set mirror detector [email protected] \
  -- set mirror recorder select_src_port=@eth1 select_dst_port=@eth1 \
  -- set mirror recorder [email protected]

This seems to work fine. All of these VM:s have their networking setup with something like this in the config:

vif = [ "script=vif-openvswitch,bridge=xenbr1", ...]

The problem is that when I reboot the host machine, all virtual ports (vifX.Y) are assigned new UUID:s and therefore the "output_port" on the mirrors are cleared.

How do I configure the mirror ports to properly persist through reboot?

2 Answers 2

1

I assume this is running XenServer.

Use a @reboot cron task.

@reboot root /usr/bin/bash <path_to_script> > /dev/null 2>&1

Unfortunately the script may have to be a little complicated as you'll have to predict what the domIDs are for the vifs (maybe check the VIF MAC addresses?).

There are a few issues with XS and persisting across reboots as XS rebuilds OVSdb from scratch on reboot. I've used a similar approach for patch port creation on boot.

Note - you may have to use a udev script if you want the VM reboots to do the port mirroring.

0

I recently ran across this question while trying to solve nearly the same problem, albeit wanting to create a SPAN port to mirror all traffic to single port. I solved it by creating a custom "vif-script" for use in the XEN .cfg file for the domU.

By example, you need only modify the XEN .cfg VIF entry to include:

'mac=xx:xx:xx:xx:xx:xx,script=vif-ovs-spanport,bridge=ovsbr0'

On startup, the script will create a new mirror with a unique name combining the bridge and device/vif, add that mirror to the bridge, mirroring all traffic on that switch to the new specified port/VIF. Conversely, on shutdown, the script will remove the mirror from the bridge and as a side-effect, destroy the mirror.

You should be able to modify the script to your specific needs, albeit you'd have to know the names of the ports for all the relevant domUs. You could make use of the vifname=string directive to ensure you had consistent names for the interfaces, but you'd still likely have an ordering issue w.r.t. which domU is brought up first to ensure that the ports are created before being used.

It might also be possible to use the vif-post.d/* scripts to accomplish something similar; YMMV.


vif-ovs-spanport script

#!/bin/bash
#============================================================================
# ${XEN_SCRIPT_DIR}/vif-ovs-spanport
#
# Script for configuring a Open VSwitch (OvS) VIF to be a spanport; 
# i.e. on a (new) mirror, sending all traffic on the bridge to the port.
#
# Usage:
# vif-ovs-spanport (add|remove|online|offline)
#
# Requires the same environment as is required by vif-openvswitch.
# Assumes that vif-openvswitch has already added the port to the bridge.
#
# XEN .cfg file recipie: modify VIF entry
#    'mac=xx:xx:xx:xx:xx:xx,script=vif-ovs-spanport,bridge=ovsbr0'
# On startup, the script will create a new mirror with a unique name
# combinging the bridge and device/vif, add that mirror to the bridge,
# mirroring all traffic on that switch to the new specified port/VIF.
#
# On shutdown, the script will remove the mirror from the bridge and
# as a side-effect, destroy the mirror.
#============================================================================

dir=$(dirname "$0")
prg=$(basename "$0")

# We inherit base behavior, and this should add the port to the bridge for us.
. "$dir/vif-openvswitch"

add_ovsmirror () {
  local dev=$1
  local mirror=$2
  local bridge=$3

  do_or_die \
    ovs-vsctl --timeout=30 \
              -- --id=@m create mirror name=${mirror} \
              -- add bridge ${bridge} mirrors @m \
              -- --id=@p get port ${dev} \
              -- set mirror ${mirror} select_all=true output-port=@p
}

remove_ovsmirror () {
  local mirror=$1
  local bridge=$2

  do_without_error \
    ovs-vsctl --timeout=30 \
              -- --id=@m get mirror ${mirror} \
              -- remove bridge ${bridge} mirrors @m
}

#dev= set in environment
bridge="$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")"

# code stolen from vif-openvswitch
if [[ $bridge =~ ^([^.:]+)(\.([[:digit:]]+))?(:([[:digit:]]+(:[[:digit:]]+)*))?$ ]]; then
  bridge="${BASH_REMATCH[1]}"
  #tag="${BASH_REMATCH[3]}"
  #trunk="${BASH_REMATCH[5]//:/,}"
else
  fatal "No valid bridge was specified"
fi

mirror="${bridge}-mirror-span-${dev}"

case "$command" in
    add|online)
        check_tools
        log debug "$prg creating $mirror on $bridge, then adding $dev to mirror."
        add_ovsmirror $dev $mirror $bridge
        ;;

    remove|offline)
        log debug "$prg removing mirror $mirror."
        remove_ovsmirror $mirror $bridge
        ;;
esac

log debug "Successful vif-ovs-spanport $command for $dev on $bridge ($mirror)."
if [ "$type_if" = vif -a "$command" = "online" ]; then
    success
fi

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .