summaryrefslogtreecommitdiff
path: root/ovn
diff options
context:
space:
mode:
authorNuman Siddique <nusiddiq@redhat.com>2017-09-21 21:22:16 +0530
committerBen Pfaff <blp@ovn.org>2017-10-27 10:49:04 -0700
commit6f39e18df4e1230be25e2e43bea2cf9fa548142a (patch)
tree8e743655473766b0d8515c2389e606f7f49a0317 /ovn
parent43e9c263d9e38c4c445c89dba458f1ff7d6d5dde (diff)
downloadopenvswitch-6f39e18df4e1230be25e2e43bea2cf9fa548142a.tar.gz
ovn: Add LB flows for logical router with gateway port
This patch adds support for associating a load balancer to a logical router with gateway router port which was missing earlier. Acked-by: Mark Michelson <mmichels@redhat.com> Signed-off-by: Numan Siddique <nusiddiq@redhat.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ovn')
-rw-r--r--ovn/northd/ovn-northd.8.xml70
-rw-r--r--ovn/northd/ovn-northd.c82
2 files changed, 123 insertions, 29 deletions
diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
index 0d85ec0d2..e9799e18a 100644
--- a/ovn/northd/ovn-northd.8.xml
+++ b/ovn/northd/ovn-northd.8.xml
@@ -1459,61 +1459,69 @@ icmp4 {
in the reverse direction needs to be unDNATed.
</p>
- <p>Ingress Table 4: DNAT on Gateway Routers</p>
+ <p>Ingress Table 4: Load balancing DNAT rules</p>
+
+ <p>
+ Following load balancing DNAT flows are added for Gateway router or
+ Router with gateway port. These flows are programmed only on the
+ <code>redirect-chassis</code>.
+ </p>
<ul>
<li>
- For all the configured load balancing rules for Gateway router in
- <code>OVN_Northbound</code> database that includes a L4 port
- <var>PORT</var> of protocol <var>P</var> and IPv4 address
- <var>VIP</var>, a priority-120 flow that matches on
+ For all the configured load balancing rules for a Gateway router or
+ Router with gateway port in <code>OVN_Northbound</code> database that
+ includes a L4 port <var>PORT</var> of protocol <var>P</var> and IPv4
+ address <var>VIP</var>, a priority-120 flow that matches on
<code>ct.new &amp;&amp; ip &amp;&amp; ip4.dst == <var>VIP</var>
&amp;&amp; <var>P</var> &amp;&amp; <var>P</var>.dst == <var>PORT
</var></code> with an action of <code>ct_lb(<var>args</var>)</code>,
where <var>args</var> contains comma separated IPv4 addresses (and
- optional port numbers) to load balance to. If the Gateway router
- is configured to force SNAT any load-balanced packets, the above
- action will be replaced by <code>flags.force_snat_for_lb = 1;
+ optional port numbers) to load balance to. If the router is configured
+ to force SNAT any load-balanced packets, the above action will be
+ replaced by <code>flags.force_snat_for_lb = 1;
ct_lb(<var>args</var>);</code>.
</li>
<li>
- For all the configured load balancing rules for Gateway router in
+ For all the configured load balancing rules for a router in
<code>OVN_Northbound</code> database that includes a L4 port
<var>PORT</var> of protocol <var>P</var> and IPv4 address
<var>VIP</var>, a priority-120 flow that matches on
<code>ct.est &amp;&amp; ip &amp;&amp; ip4.dst == <var>VIP</var>
&amp;&amp; <var>P</var> &amp;&amp; <var>P</var>.dst == <var>PORT
- </var></code> with an action of <code>ct_dnat;</code>.
- If the Gateway router is configured to force SNAT any load-balanced
- packets, the above action will be replaced by
- <code>flags.force_snat_for_lb = 1; ct_dnat;</code>.
+ </var></code> with an action of <code>ct_dnat;</code>. If the router is
+ configured to force SNAT any load-balanced packets, the above action
+ will be replaced by <code>flags.force_snat_for_lb = 1; ct_dnat;</code>.
</li>
<li>
- For all the configured load balancing rules for Gateway router in
+ For all the configured load balancing rules for a router in
<code>OVN_Northbound</code> database that includes just an IP address
<var>VIP</var> to match on, a priority-110 flow that matches on
<code>ct.new &amp;&amp; ip &amp;&amp; ip4.dst ==
<var>VIP</var></code> with an action of
<code>ct_lb(<var>args</var>)</code>, where <var>args</var> contains
- comma separated IPv4 addresses. If the Gateway router
- is configured to force SNAT any load-balanced packets, the above
- action will be replaced by <code>flags.force_snat_for_lb = 1;
- ct_lb(<var>args</var>);</code>.
+ comma separated IPv4 addresses. If the router is configured to force
+ SNAT any load-balanced packets, the above action will be replaced by
+ <code>flags.force_snat_for_lb = 1; ct_lb(<var>args</var>);</code>.
</li>
<li>
- For all the configured load balancing rules for Gateway router in
+ For all the configured load balancing rules for a router in
<code>OVN_Northbound</code> database that includes just an IP address
<var>VIP</var> to match on, a priority-110 flow that matches on
<code>ct.est &amp;&amp; ip &amp;&amp; ip4.dst ==
<var>VIP</var></code> with an action of <code>ct_dnat;</code>.
- If the Gateway router is configured to force SNAT any load-balanced
+ If the router is configured to force SNAT any load-balanced
packets, the above action will be replaced by
<code>flags.force_snat_for_lb = 1; ct_dnat;</code>.
</li>
+ </ul>
+ <p>Ingress Table 4: DNAT on Gateway Routers</p>
+
+ <ul>
<li>
For each configuration in the OVN Northbound database, that asks
to change the destination IP address of a packet from <var>A</var> to
@@ -1892,6 +1900,28 @@ arp {
<ul>
<li>
<p>
+ For all the configured load balancing rules for a router with gateway
+ port in <code>OVN_Northbound</code> database that includes an IPv4
+ address <code>VIP</code>, for every backend IPv4 address <var>B</var>
+ defined for the <code>VIP</code> a priority-120 flow is programmed on
+ <code>redirect-chassis</code> that matches
+ <code>ip &amp;&amp; ip4.src == <var>B</var> &amp;&amp;
+ outport == <var>GW</var></code>, where <var>GW</var> is the logical
+ router gateway port with an action <code>ct_dnat;</code>. If the
+ backend IPv4 address <var>B</var> is also configured with L4 port
+ <var>PORT</var> of protocol <var>P</var>, then the
+ match also includes <code>P.src</code> == <var>PORT</var>.
+ </p>
+
+ <p>
+ If the router is configured to force SNAT any load-balanced packets,
+ above action will be replaced by
+ <code>flags.force_snat_for_lb = 1; ct_dnat;</code>.
+ </p>
+ </li>
+
+ <li>
+ <p>
For each configuration in the OVN Northbound database that asks
to change the destination IP address of a packet from an IP
address of <var>A</var> to <var>B</var>, a priority-100 flow
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index c1a76480a..b250eb4fa 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -4339,7 +4339,8 @@ get_force_snat_ip(struct ovn_datapath *od, const char *key_type, ovs_be32 *ip)
static void
add_router_lb_flow(struct hmap *lflows, struct ovn_datapath *od,
struct ds *match, struct ds *actions, int priority,
- const char *lb_force_snat_ip)
+ const char *lb_force_snat_ip, char *backend_ips,
+ bool is_udp)
{
/* A match and actions for new connections. */
char *new_match = xasprintf("ct.new && %s", ds_cstr(match));
@@ -4366,6 +4367,63 @@ add_router_lb_flow(struct hmap *lflows, struct ovn_datapath *od,
free(new_match);
free(est_match);
+
+ if (!od->l3dgw_port || !od->l3redirect_port || !backend_ips) {
+ return;
+ }
+
+ /* Add logical flows to UNDNAT the load balanced reverse traffic in
+ * the router egress pipleine stage - S_ROUTER_OUT_UNDNAT if the logical
+ * router has a gateway router port associated.
+ */
+ struct ds undnat_match = DS_EMPTY_INITIALIZER;
+ ds_put_cstr(&undnat_match, "ip4 && (");
+ char *start, *next, *ip_str;
+ start = next = xstrdup(backend_ips);
+ ip_str = strsep(&next, ",");
+ bool backend_ips_found = false;
+ while (ip_str && ip_str[0]) {
+ char *ip_address = NULL;
+ uint16_t port = 0;
+ ip_address_and_port_from_lb_key(ip_str, &ip_address, &port);
+ if (!ip_address) {
+ break;
+ }
+
+ ds_put_format(&undnat_match, "(ip4.src == %s", ip_address);
+ free(ip_address);
+ if (port) {
+ ds_put_format(&undnat_match, " && %s.src == %d) || ",
+ is_udp ? "udp" : "tcp", port);
+ } else {
+ ds_put_cstr(&undnat_match, ") || ");
+ }
+ ip_str = strsep(&next, ",");
+ backend_ips_found = true;
+ }
+
+ free(start);
+ if (!backend_ips_found) {
+ ds_destroy(&undnat_match);
+ return;
+ }
+ ds_chomp(&undnat_match, ' ');
+ ds_chomp(&undnat_match, '|');
+ ds_chomp(&undnat_match, '|');
+ ds_chomp(&undnat_match, ' ');
+ ds_put_format(&undnat_match, ") && outport == %s && "
+ "is_chassis_resident(%s)", od->l3dgw_port->json_key,
+ od->l3redirect_port->json_key);
+ if (lb_force_snat_ip) {
+ ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 120,
+ ds_cstr(&undnat_match),
+ "flags.force_snat_for_lb = 1; ct_dnat;");
+ } else {
+ ovn_lflow_add(lflows, od, S_ROUTER_OUT_UNDNAT, 120,
+ ds_cstr(&undnat_match), "ct_dnat;");
+ }
+
+ ds_destroy(&undnat_match);
}
static void
@@ -5243,8 +5301,8 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
}
/* Load balancing and packet defrag are only valid on
- * Gateway routers. */
- if (!smap_get(&od->nbr->options, "chassis")) {
+ * Gateway routers or router with gateway port. */
+ if (!smap_get(&od->nbr->options, "chassis") && !od->l3dgw_port) {
continue;
}
@@ -5283,20 +5341,26 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
ip_address);
free(ip_address);
+ int prio = 110;
+ bool is_udp = lb->protocol && !strcmp(lb->protocol, "udp") ?
+ true : false;
if (port) {
- if (lb->protocol && !strcmp(lb->protocol, "udp")) {
+ if (is_udp) {
ds_put_format(&match, " && udp && udp.dst == %d",
port);
} else {
ds_put_format(&match, " && tcp && tcp.dst == %d",
port);
}
- add_router_lb_flow(lflows, od, &match, &actions, 120,
- lb_force_snat_ip);
- } else {
- add_router_lb_flow(lflows, od, &match, &actions, 110,
- lb_force_snat_ip);
+ prio = 120;
+ }
+
+ if (od->l3redirect_port) {
+ ds_put_format(&match, " && is_chassis_resident(%s)",
+ od->l3redirect_port->json_key);
}
+ add_router_lb_flow(lflows, od, &match, &actions, prio,
+ lb_force_snat_ip, node->value, is_udp);
}
}