/* Handle output to multicast groups, in tables 32 and 33. */
const struct sbrec_multicast_group *mc;
+ struct ofpbuf remote_ofpacts;
+ ofpbuf_init(&remote_ofpacts, 0);
SBREC_MULTICAST_GROUP_FOR_EACH (mc, ctx->ovnsb_idl) {
struct sset remote_chassis = SSET_INITIALIZER(&remote_chassis);
struct match match;
/* Go through all of the ports in the multicast group:
*
- * - For local ports, add actions to 'ofpacts' to set the output
- * port and resubmit.
+ * - For remote ports, add the chassis to 'remote_chassis'.
*
- * - For remote ports, add the chassis to 'remote_chassis'. */
+ * - For local ports (other than logical patch ports), add actions
+ * to 'ofpacts' to set the output port and resubmit.
+ *
+ * - For logical patch ports, add actions to 'remote_ofpacts'
+ * instead. (If we put them in 'ofpacts', then the output
+ * would happen on every hypervisor in the multicast group,
+ * effectively duplicating the packet.)
+ */
ofpbuf_clear(&ofpacts);
+ ofpbuf_clear(&remote_ofpacts);
for (size_t i = 0; i < mc->n_ports; i++) {
struct sbrec_port_binding *port = mc->ports[i];
put_load(zone_id, MFF_LOG_CT_ZONE, 0, 32, &ofpacts);
}
- if (simap_contains(&localvif_to_ofport,
+ if (!strcmp(port->type, "patch")) {
+ put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32,
+ &remote_ofpacts);
+ put_resubmit(OFTABLE_DROP_LOOPBACK, &remote_ofpacts);
+ } else if (simap_contains(&localvif_to_ofport,
port->parent_port
? port->parent_port : port->logical_port)) {
put_load(port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, &ofpacts);
*
* Handle output to the remote chassis in the multicast group, if
* any. */
- if (!sset_is_empty(&remote_chassis)) {
- ofpbuf_clear(&ofpacts);
+ if (!sset_is_empty(&remote_chassis) || remote_ofpacts.size > 0) {
+ if (remote_ofpacts.size > 0) {
+ /* Following delivery to logical patch ports, restore the
+ * multicast group as the logical output port. */
+ put_load(mc->tunnel_key, MFF_LOG_OUTPORT, 0, 32,
+ &remote_ofpacts);
+ }
const char *chassis;
const struct chassis_tunnel *prev = NULL;
}
if (!prev || tun->type != prev->type) {
- put_encapsulation(mff_ovn_geneve, tun,
- mc->datapath, mc->tunnel_key, &ofpacts);
+ put_encapsulation(mff_ovn_geneve, tun, mc->datapath,
+ mc->tunnel_key, &remote_ofpacts);
prev = tun;
}
- ofpact_put_OUTPUT(&ofpacts)->port = tun->ofport;
+ ofpact_put_OUTPUT(&remote_ofpacts)->port = tun->ofport;
}
- if (ofpacts.size) {
+ if (remote_ofpacts.size) {
if (local_ports) {
- put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts);
+ put_resubmit(OFTABLE_LOCAL_OUTPUT, &remote_ofpacts);
}
ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100,
- &match, &ofpacts);
+ &match, &remote_ofpacts);
}
}
sset_destroy(&remote_chassis);
}
+ ofpbuf_uninit(&remote_ofpacts);
/* Table 0, priority 100.
* ======================
egress port are the same.
</p>
+ <p>
+ Logical patch ports are a special case. Logical patch ports do not
+ have a physical location and effectively reside on every hypervisor.
+ Thus, flow table 33, for output to ports on the local hypervisor,
+ naturally implements output to unicast logical patch ports too.
+ However, applying the same logic to a logical patch port that is part
+ of a logical multicast group yields packet duplication, because each
+ hypervisor that contains a logical port in the multicast group will
+ also output the packet to the logical patch port. Thus, multicast
+ groups implement output to logical patch ports in table 32.
+ </p>
+
<p>
Each flow in table 32 matches on a logical output port for unicast or
multicast logical ports that include a logical port on a remote
<p>
Flows in table 33 resemble those in table 32 but for logical ports that
- reside locally rather than remotely. (This includes logical patch
- ports, which do not have a physical location and effectively reside on
- every hypervisor.) For unicast logical output ports
+ reside locally rather than remotely. For unicast logical output ports
on the local hypervisor, the actions just resubmit to table 34. For
multicast output ports that include one or more logical ports on the
local hypervisor, for each such logical port <var>P</var>, the actions