for (i = 0; i < br->n_ports; i++) {
struct port *port = br->ports[i];
if (port_includes_vlan(port, m->out_vlan)
- && set_dst(dst, flow, in_port, port, tags)
- && !dst_is_duplicate(dsts, dst - dsts, dst))
+ && set_dst(dst, flow, in_port, port, tags))
{
if (port->vlan < 0) {
dst->vlan = m->out_vlan;
}
+ if (dst_is_duplicate(dsts, dst - dsts, dst)) {
+ continue;
+ }
if (dst->dp_ifidx == flow->in_port
&& dst->vlan == vlan) {
/* Don't send out input port on same VLAN. */
int *vlans;
size_t i;
bool mirror_all_ports;
+ bool any_ports_specified;
/* Get output port. */
out_port_name = cfg_get_key(0, "mirror.%s.%s.output.port",
cfg_get_all_keys(&src_ports, "%s.select.src-port", pfx);
cfg_get_all_keys(&dst_ports, "%s.select.dst-port", pfx);
cfg_get_all_keys(&ports, "%s.select.port", pfx);
+ any_ports_specified = src_ports.n || dst_ports.n || ports.n;
svec_append(&src_ports, &ports);
svec_append(&dst_ports, &ports);
svec_destroy(&ports);
prune_ports(m, &src_ports);
prune_ports(m, &dst_ports);
+ if (any_ports_specified && !src_ports.n && !dst_ports.n) {
+ VLOG_ERR("%s: none of the specified ports exist; "
+ "disabling port mirror %s", pfx, pfx);
+ mirror_destroy(m);
+ goto exit;
+ }
/* Get all the vlans, and drop duplicate and invalid vlans. */
svec_init(&vlan_strings);
}
/* Clean up. */
+exit:
svec_destroy(&src_ports);
svec_destroy(&dst_ports);
free(pfx);