summaryrefslogtreecommitdiff
path: root/ovn
diff options
context:
space:
mode:
authorGurucharan Shetty <gshetty@nicira.com>2015-07-24 11:31:28 -0700
committerGurucharan Shetty <gshetty@nicira.com>2015-07-28 15:24:14 -0700
commit26acc5a31ada0420fc77a961d8fad4fadfd37518 (patch)
tree9f1b17b15ac3e149d3073febcae76b6f13edf546 /ovn
parent8811fc0ae150f51078321798b22d49e9f98fa454 (diff)
downloadopenvswitch-26acc5a31ada0420fc77a961d8fad4fadfd37518.tar.gz
ovn-controller: Fix flow generation for container traffic.
In table 64, when a vlan tag is set on a packet destined to a container running inside a VM, we currently don't revert it. This has an unintended consequence for broadcast traffic when one endpoint of the braodcast traffic is a plain VM (without containers running inside) where the previously set tag would remain in the packets sent to the VM. This commit fixes the above problem by popping the VLAN and resetting the input port after outputting the packet with a vlan tag to a container logical port. Signed-off-by: Gurucharan Shetty <gshetty@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'ovn')
-rw-r--r--ovn/controller/physical.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index febeaaa02..3a1d44794 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -230,18 +230,43 @@ physical_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
/* For containers sitting behind a local vif, tag the packets
* before delivering them. Since there is a possibility of
* packets needing to hair-pin back into the same vif from
- * which it came, make the in_port as zero. */
+ * which it came, push the in_port to stack and make the
+ * in_port as zero. */
struct ofpact_vlan_vid *vlan_vid;
vlan_vid = ofpact_put_SET_VLAN_VID(&ofpacts);
vlan_vid->vlan_vid = tag;
vlan_vid->push_vlan_if_needed = true;
+ struct ofpact_stack *stack_action;
+ const struct mf_field *field;
+ stack_action = ofpact_put_STACK_PUSH(&ofpacts);
+ field = mf_from_id(MFF_IN_PORT);
+ stack_action->subfield.field = field;
+ stack_action->subfield.ofs = 0;
+ stack_action->subfield.n_bits = field->n_bits;
+
struct ofpact_set_field *sf = ofpact_put_SET_FIELD(&ofpacts);
sf->field = mf_from_id(MFF_IN_PORT);
sf->value.be16 = 0;
sf->mask.be16 = OVS_BE16_MAX;
}
ofpact_put_OUTPUT(&ofpacts)->port = ofport;
+ if (tag) {
+ /* Revert the tag added to the packets headed to containers
+ * in the previous step. If we don't do this, the packets
+ * that are to be broadcasted to a VM in the same logical
+ * switch will also contain the tag. Also revert the zero'd
+ * in_port. */
+ ofpact_put_STRIP_VLAN(&ofpacts);
+
+ struct ofpact_stack *stack_action;
+ const struct mf_field *field;
+ stack_action = ofpact_put_STACK_POP(&ofpacts);
+ field = mf_from_id(MFF_IN_PORT);
+ stack_action->subfield.field = field;
+ stack_action->subfield.ofs = 0;
+ stack_action->subfield.n_bits = field->n_bits;
+ }
ofctrl_add_flow(flow_table, 64, 50, &match, &ofpacts);
}