@@ -499,9 +499,6 @@ struct ovnact_encode_params {
/* 'true' if the flow is for a switch. */
bool is_switch;
- /* 'true' if the flow is for a gateway router. */
- bool is_gateway_router;
-
/* A struct to figure out the group_id for group actions. */
struct ovn_extend_table *group_table;
@@ -131,15 +131,6 @@ is_switch(const struct sbrec_datapath_binding *ldp)
}
-static bool
-is_gateway_router(const struct sbrec_datapath_binding *ldp,
- const struct hmap *local_datapaths)
-{
- struct local_datapath *ld =
- get_local_datapath(local_datapaths, ldp->tunnel_key);
- return ld ? ld->has_local_l3gateway : false;
-}
-
/* Adds the logical flows from the Logical_Flow table to flow tables. */
static void
add_logical_flows(struct controller_ctx *ctx,
@@ -303,7 +294,6 @@ consider_logical_flow(struct controller_ctx *ctx,
.lookup_port = lookup_port_cb,
.aux = &aux,
.is_switch = is_switch(ldp),
- .is_gateway_router = is_gateway_router(ldp, local_datapaths),
.group_table = group_table,
.meter_table = meter_table,
@@ -832,17 +832,6 @@ encode_ct_nat(const struct ovnact_ct_nat *cn,
ct = ofpacts->header;
if (cn->ip) {
ct->flags |= NX_CT_F_COMMIT;
- } else if (snat && ep->is_gateway_router) {
- /* For performance reasons, we try to prevent additional
- * recirculations. ct_snat which is used in a gateway router
- * does not need a recirculation. ct_snat(IP) does need a
- * recirculation. ct_snat in a distributed router needs
- * recirculation regardless of whether an IP address is
- * specified.
- * XXX Should we consider a method to let the actions specify
- * whether an action needs recirculation if there are more use
- * cases?. */
- ct->recirc_table = NX_CT_RECIRC_NONE;
}
ofpact_finish(ofpacts, &ct->ofpact);
ofpbuf_push_uninit(ofpacts, ct_offset);
@@ -1428,14 +1428,14 @@ icmp4 {
If the Gateway router has been configured to force SNAT any
previously DNATted packets to <var>B</var>, a priority-110 flow
matches <code>ip && ip4.dst == <var>B</var></code> with
- an action <code>ct_snat; next;</code>.
+ an action <code>ct_snat; </code>.
</p>
<p>
If the Gateway router has been configured to force SNAT any
previously load-balanced packets to <var>B</var>, a priority-100 flow
matches <code>ip && ip4.dst == <var>B</var></code> with
- an action <code>ct_snat; next;</code>.
+ an action <code>ct_snat; </code>.
</p>
<p>
@@ -1443,7 +1443,7 @@ icmp4 {
to change the source IP address of a packet from <var>A</var> to
<var>B</var>, a priority-90 flow matches <code>ip &&
ip4.dst == <var>B</var></code> with an action
- <code>ct_snat; next;</code>.
+ <code>ct_snat; </code>.
</p>
<p>
@@ -5190,7 +5190,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&match, "ip && ip4.dst == %s",
nat->external_ip);
ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 90,
- ds_cstr(&match), "ct_snat; next;");
+ ds_cstr(&match), "ct_snat;");
} else {
/* Distributed router. */
@@ -5422,7 +5422,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_clear(&match);
ds_put_format(&match, "ip && ip4.dst == %s", dnat_force_snat_ip);
ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 110,
- ds_cstr(&match), "ct_snat; next;");
+ ds_cstr(&match), "ct_snat;");
/* Higher priority rules to force SNAT with the IP addresses
* configured in the Gateway router. This only takes effect
@@ -5441,7 +5441,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ds_clear(&match);
ds_put_format(&match, "ip && ip4.dst == %s", lb_force_snat_ip);
ovn_lflow_add(lflows, od, S_ROUTER_IN_UNSNAT, 100,
- ds_cstr(&match), "ct_snat; next;");
+ ds_cstr(&match), "ct_snat;");
/* Load balanced traffic will have flags.force_snat_for_lb set.
* Force SNAT it. */
@@ -5455,19 +5455,14 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
if (!od->l3dgw_port) {
/* For gateway router, re-circulate every packet through
- * the DNAT zone. This helps with two things.
+ * the DNAT zone. This helps with the following.
*
- * 1. Any packet that needs to be unDNATed in the reverse
+ * Any packet that needs to be unDNATed in the reverse
* direction gets unDNATed. Ideally this could be done in
* the egress pipeline. But since the gateway router
* does not have any feature that depends on the source
* ip address being external IP address for IP routing,
- * we can do it here, saving a future re-circulation.
- *
- * 2. Any packet that was sent through SNAT zone in the
- * previous table automatically gets re-circulated to get
- * back the new destination IP address that is needed for
- * routing in the openflow pipeline. */
+ * we can do it here, saving a future re-circulation. */
ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 50,
"ip", "flags.loopback = 1; ct_dnat;");
} else {
@@ -1151,25 +1151,10 @@
<p>
<code>ct_snat</code> sends the packet through the SNAT zone to
unSNAT any packet that was SNATed in the opposite direction. The
- behavior on gateway routers differs from the behavior on a
- distributed router:
+ packet is automatically sent to the next tables as if followed by
+ the <code>next;</code> action. The next tables will see the
+ changes in the packet caused by the connection tracker.
</p>
- <ul>
- <li>
- On a gateway router, if the packet needs to be sent to the next
- tables, then it should be followed by a <code>next;</code>
- action. The next tables will not see the changes in the packet
- caused by the connection tracker.
- </li>
- <li>
- On a distributed router, if the connection tracker finds a
- connection that was SNATed in the opposite direction, then the
- destination IP address of the packet is UNSNATed. The packet is
- automatically sent to the next tables as if followed by the
- <code>next;</code> action. The next tables will see the changes
- in the packet caused by the connection tracker.
- </li>
- </ul>
<p>
<code>ct_snat(<var>IP</var>)</code> sends the packet through the
SNAT zone to change the source IP address of the packet to
@@ -855,6 +855,11 @@ ovn-nbctl set logical_router R2 load_balancer=$uuid
# Config OVN load-balancer with another VIP (this time with ports).
ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:80,192.168.2.2:80"'
+# Add SNAT rule to make sure that Load-balancing still works with a SNAT rule.
+ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
+ external_ip=30.0.0.2 -- add logical_router R2 nat @nat
+
+
# Wait for ovn-controller to catch up.
ovn-nbctl --wait=hv sync
OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \
commit f6fabcc6245 (ofproto-dpif: Mark packets as "untracked" after call to ct().) changed the behavior after a call to ct(). The +trk bit would automatically be unset if packet is sent to ct() and not forked. This caused a bug in the OVN gateway pipeline when there is SNAT rule as well as load-balancing rule. In the OVN gateway pipeline for the gateway router, we had an optimization where the packets sent to unSNAT need not go through a recirculation. But since doing this now means that the +trk bit gets unset, the DNAT rules for load-balancing a new packet in the next table won't get hit. This commit removes the optimization for unSNAT packets so that there is always a recirculation. Signed-off-by: Gurucharan Shetty <guru@ovn.org> --- include/ovn/actions.h | 3 --- ovn/controller/lflow.c | 10 ---------- ovn/lib/actions.c | 11 ----------- ovn/northd/ovn-northd.8.xml | 6 +++--- ovn/northd/ovn-northd.c | 17 ++++++----------- ovn/ovn-sb.xml | 21 +++------------------ tests/system-ovn.at | 5 +++++ 7 files changed, 17 insertions(+), 56 deletions(-)