diff mbox series

[ovs-dev,v2] northd: do not centralize FIP traffic if redirect-type is set to fixed

Message ID 660a9954df90398d93b6f754faac449f193acc9c.1664377841.git.lorenzo.bianconi@redhat.com
State Accepted
Delegated to: Dumitru Ceara
Headers show
Series [ovs-dev,v2] northd: do not centralize FIP traffic if redirect-type is set to fixed | expand

Commit Message

Lorenzo Bianconi Sept. 28, 2022, 3:13 p.m. UTC
Keep FIP traffic distributed and do not centralize it even if the
CMS sets redirect-type option to bridged for distributed gateway port.

Tested-by: Jianlin Shi <jishi@redhat.com>
Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2007120
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
Changes since v1:
- add unit-test
- fix typos
---
 northd/northd.c         | 29 +++++++++++++++++++++++++++++
 northd/northd.h         |  2 ++
 northd/ovn-northd.8.xml | 17 +++++++++++++++++
 tests/ovn-northd.at     | 37 +++++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+)

Comments

Mark Michelson Sept. 29, 2022, 6:23 p.m. UTC | #1
Thanks Lorenzo,

Acked-by: Mark Michelson <mmichels@redhat.com>

On 9/28/22 11:13, Lorenzo Bianconi wrote:
> Keep FIP traffic distributed and do not centralize it even if the
> CMS sets redirect-type option to bridged for distributed gateway port.
> 
> Tested-by: Jianlin Shi <jishi@redhat.com>
> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2007120
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
> ---
> Changes since v1:
> - add unit-test
> - fix typos
> ---
>   northd/northd.c         | 29 +++++++++++++++++++++++++++++
>   northd/northd.h         |  2 ++
>   northd/ovn-northd.8.xml | 17 +++++++++++++++++
>   tests/ovn-northd.at     | 37 +++++++++++++++++++++++++++++++++++++
>   4 files changed, 85 insertions(+)
> 
> diff --git a/northd/northd.c b/northd/northd.c
> index 84440a47f..a60467963 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -2616,6 +2616,13 @@ join_logical_ports(struct northd_input *input_data,
>                   op->od = od;
>                   ovs_list_push_back(&od->port_list, &op->dp_node);
>   
> +                if (!od->redirect_bridged) {
> +                    const char *redirect_type =
> +                        smap_get(&nbrp->options, "redirect-type");
> +                    od->redirect_bridged =
> +                        redirect_type && !strcasecmp(redirect_type, "bridged");
> +                }
> +
>                   if (op->nbrp->ha_chassis_group ||
>                       op->nbrp->n_gateway_chassis) {
>                       /* Additional "derived" ovn_port crp represents the
> @@ -13731,6 +13738,28 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows,
>                                           100, ds_cstr(match),
>                                           ds_cstr(actions),
>                                           &nat->header_);
> +                if (od->redirect_bridged && distributed) {
> +                    ds_clear(match);
> +                    ds_put_format(
> +                            match,
> +                            "outport == %s && ip%s.src == %s "
> +                            "&& is_chassis_resident(\"%s\")",
> +                            od->l3dgw_ports[0]->json_key,
> +                            is_v6 ? "6" : "4", nat->logical_ip,
> +                            nat->logical_port);
> +                    ds_clear(actions);
> +                    if (is_v6) {
> +                        ds_put_cstr(actions,
> +                            "get_nd(outport, " REG_NEXT_HOP_IPV6 "); next;");
> +                    } else {
> +                        ds_put_cstr(actions,
> +                            "get_arp(outport, " REG_NEXT_HOP_IPV4 "); next;");
> +                    }
> +                    ovn_lflow_add_with_hint(lflows, od,
> +                                            S_ROUTER_IN_ARP_RESOLVE, 90,
> +                                            ds_cstr(match), ds_cstr(actions),
> +                                            &nat->header_);
> +                }
>                   sset_add(&nat_entries, nat->external_ip);
>               }
>           }
> diff --git a/northd/northd.h b/northd/northd.h
> index aa9a3ae6e..60601803f 100644
> --- a/northd/northd.h
> +++ b/northd/northd.h
> @@ -229,6 +229,8 @@ struct ovn_datapath {
>       size_t n_nat_entries;
>   
>       bool has_distributed_nat;
> +    /* router datapath has a logical port with redirect-type set to bridged. */
> +    bool redirect_bridged;
>   
>       /* Set of nat external ips on the router. */
>       struct sset external_ips;
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index d9e9a7345..009a380bd 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -4053,6 +4053,23 @@ outport = <var>P</var>
>           </p>
>         </li>
>   
> +      <li>
> +        <p>
> +          If the router datapath runs a port with <code>redirect-type</code>
> +          set to <code>bridged</code>, for each distributed NAT rule with IP
> +          <var>A</var> in the
> +          <ref column="logical_ip" table="NAT" db="OVN_Northbound"/> column
> +          and logical port <var>P</var> in the
> +          <ref column="logical_port" table="NAT" db="OVN_Northbound"/> column
> +          of <ref table="NAT" db="OVN_Northbound"/> table, a priority-90 flow
> +          with the match <code>outport == <var>Q</var> &amp;&amp; ip.src ===
> +          <var>A</var> &amp;&amp; is_chassis_resident(<var>P</var>)</code>,
> +          where <code>Q</code> is the distributed logical router port and
> +          action <code>get_arp(outport, reg0); next;</code> for IPv4 and
> +          <code>get_nd(outport, xxreg0); next;</code> for IPv6.
> +        </p>
> +      </li>
> +
>         <li>
>           <p>
>             Traffic with IP destination an address owned by the router should be
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 093e01c6d..a210fc575 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -7861,3 +7861,40 @@ check_column "" sb:load_balancer datapaths name=lb0
>   
>   AT_CLEANUP
>   ])
> +
> +AT_SETUP([check fip flows with redirect-type bridged])
> +AT_KEYWORDS([fip-redirect-type-bridged])
> +ovn_start
> +
> +ovn-nbctl lr-add R1
> +ovn-nbctl lrp-add R1 R1-S0 02:ac:10:01:00:01 10.0.0.1/24 1000::a/64
> +ovn-nbctl lrp-add R1 R1-PUB 02:ac:20:01:01:01 172.16.0.1/24 3000::a/64
> +ovn-nbctl lrp-set-gateway-chassis R1-PUB hv1 20
> +
> +ovn-nbctl ls-add S0
> +ovn-nbctl lsp-add S0 S0-R1
> +ovn-nbctl lsp-set-type S0-R1 router
> +ovn-nbctl lsp-set-addresses S0-R1 02:ac:10:01:00:01
> +ovn-nbctl lsp-set-options S0-R1 router-port=R1-S0
> +ovn-nbctl lsp-add S0 S0-P0
> +ovn-nbctl lsp-set-addresses S0-P0 "50:54:00:00:00:03 10.0.0.3 1000::3"
> +
> +ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.0.110 10.0.0.3 S0-P0 30:54:00:00:00:03
> +ovn-nbctl lr-nat-add R1 dnat_and_snat 3000::c 1000::3 S0-P0 40:54:00:00:00:03
> +
> +ovn-sbctl dump-flows R1 > R1flows
> +AT_CAPTURE_FILE([R1flows])
> +AT_CHECK([grep "lr_in_arp_resolve" R1flows | grep priority=90 | sort], [0], [dnl
> +])
> +
> +ovn-nbctl --wait=sb set logical_router_port R1-PUB options:redirect-type=bridged
> +ovn-sbctl dump-flows R1 > R1flows
> +AT_CAPTURE_FILE([R1flows])
> +
> +AT_CHECK([grep "lr_in_arp_resolve" R1flows | grep priority=90 | sort], [0], [dnl
> +  table=15(lr_in_arp_resolve  ), priority=90   , match=(outport == "R1-PUB" && ip4.src == 10.0.0.3 && is_chassis_resident("S0-P0")), action=(get_arp(outport, reg0); next;)
> +  table=15(lr_in_arp_resolve  ), priority=90   , match=(outport == "R1-PUB" && ip6.src == 1000::3 && is_chassis_resident("S0-P0")), action=(get_nd(outport, xxreg0); next;)
> +])
> +
> +AT_CLEANUP
> +])
Dumitru Ceara Sept. 30, 2022, 10:43 a.m. UTC | #2
On 9/29/22 20:23, Mark Michelson wrote:
> Thanks Lorenzo,
> 
> Acked-by: Mark Michelson <mmichels@redhat.com>

Thanks, Lorenzo and Mark!

I applied this to the main branch.
Dumitru Ceara March 22, 2023, 9:13 a.m. UTC | #3
On 9/30/22 12:43, Dumitru Ceara wrote:
> On 9/29/22 20:23, Mark Michelson wrote:
>> Thanks Lorenzo,
>>
>> Acked-by: Mark Michelson <mmichels@redhat.com>
> 
> Thanks, Lorenzo and Mark!
> 
> I applied this to the main branch.

We received a request to backport this bug fix all the way down to
branch-21.12 (from Luis in CC).  I'm planning to do that but I'll wait a
day or two to give people some time to raise any points they may have.

Regards,
Dumitru
Dumitru Ceara March 28, 2023, 2:01 p.m. UTC | #4
On 3/22/23 10:13, Dumitru Ceara wrote:
> On 9/30/22 12:43, Dumitru Ceara wrote:
>> On 9/29/22 20:23, Mark Michelson wrote:
>>> Thanks Lorenzo,
>>>
>>> Acked-by: Mark Michelson <mmichels@redhat.com>
>>
>> Thanks, Lorenzo and Mark!
>>
>> I applied this to the main branch.
> 
> We received a request to backport this bug fix all the way down to
> branch-21.12 (from Luis in CC).  I'm planning to do that but I'll wait a
> day or two to give people some time to raise any points they may have.
> 

I backported this all the way down to branch-21.12.

Regards,
Dumitru
diff mbox series

Patch

diff --git a/northd/northd.c b/northd/northd.c
index 84440a47f..a60467963 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -2616,6 +2616,13 @@  join_logical_ports(struct northd_input *input_data,
                 op->od = od;
                 ovs_list_push_back(&od->port_list, &op->dp_node);
 
+                if (!od->redirect_bridged) {
+                    const char *redirect_type =
+                        smap_get(&nbrp->options, "redirect-type");
+                    od->redirect_bridged =
+                        redirect_type && !strcasecmp(redirect_type, "bridged");
+                }
+
                 if (op->nbrp->ha_chassis_group ||
                     op->nbrp->n_gateway_chassis) {
                     /* Additional "derived" ovn_port crp represents the
@@ -13731,6 +13738,28 @@  build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows,
                                         100, ds_cstr(match),
                                         ds_cstr(actions),
                                         &nat->header_);
+                if (od->redirect_bridged && distributed) {
+                    ds_clear(match);
+                    ds_put_format(
+                            match,
+                            "outport == %s && ip%s.src == %s "
+                            "&& is_chassis_resident(\"%s\")",
+                            od->l3dgw_ports[0]->json_key,
+                            is_v6 ? "6" : "4", nat->logical_ip,
+                            nat->logical_port);
+                    ds_clear(actions);
+                    if (is_v6) {
+                        ds_put_cstr(actions,
+                            "get_nd(outport, " REG_NEXT_HOP_IPV6 "); next;");
+                    } else {
+                        ds_put_cstr(actions,
+                            "get_arp(outport, " REG_NEXT_HOP_IPV4 "); next;");
+                    }
+                    ovn_lflow_add_with_hint(lflows, od,
+                                            S_ROUTER_IN_ARP_RESOLVE, 90,
+                                            ds_cstr(match), ds_cstr(actions),
+                                            &nat->header_);
+                }
                 sset_add(&nat_entries, nat->external_ip);
             }
         }
diff --git a/northd/northd.h b/northd/northd.h
index aa9a3ae6e..60601803f 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -229,6 +229,8 @@  struct ovn_datapath {
     size_t n_nat_entries;
 
     bool has_distributed_nat;
+    /* router datapath has a logical port with redirect-type set to bridged. */
+    bool redirect_bridged;
 
     /* Set of nat external ips on the router. */
     struct sset external_ips;
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index d9e9a7345..009a380bd 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -4053,6 +4053,23 @@  outport = <var>P</var>
         </p>
       </li>
 
+      <li>
+        <p>
+          If the router datapath runs a port with <code>redirect-type</code>
+          set to <code>bridged</code>, for each distributed NAT rule with IP
+          <var>A</var> in the
+          <ref column="logical_ip" table="NAT" db="OVN_Northbound"/> column
+          and logical port <var>P</var> in the
+          <ref column="logical_port" table="NAT" db="OVN_Northbound"/> column
+          of <ref table="NAT" db="OVN_Northbound"/> table, a priority-90 flow
+          with the match <code>outport == <var>Q</var> &amp;&amp; ip.src ===
+          <var>A</var> &amp;&amp; is_chassis_resident(<var>P</var>)</code>,
+          where <code>Q</code> is the distributed logical router port and
+          action <code>get_arp(outport, reg0); next;</code> for IPv4 and
+          <code>get_nd(outport, xxreg0); next;</code> for IPv6.
+        </p>
+      </li>
+
       <li>
         <p>
           Traffic with IP destination an address owned by the router should be
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 093e01c6d..a210fc575 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -7861,3 +7861,40 @@  check_column "" sb:load_balancer datapaths name=lb0
 
 AT_CLEANUP
 ])
+
+AT_SETUP([check fip flows with redirect-type bridged])
+AT_KEYWORDS([fip-redirect-type-bridged])
+ovn_start
+
+ovn-nbctl lr-add R1
+ovn-nbctl lrp-add R1 R1-S0 02:ac:10:01:00:01 10.0.0.1/24 1000::a/64
+ovn-nbctl lrp-add R1 R1-PUB 02:ac:20:01:01:01 172.16.0.1/24 3000::a/64
+ovn-nbctl lrp-set-gateway-chassis R1-PUB hv1 20
+
+ovn-nbctl ls-add S0
+ovn-nbctl lsp-add S0 S0-R1
+ovn-nbctl lsp-set-type S0-R1 router
+ovn-nbctl lsp-set-addresses S0-R1 02:ac:10:01:00:01
+ovn-nbctl lsp-set-options S0-R1 router-port=R1-S0
+ovn-nbctl lsp-add S0 S0-P0
+ovn-nbctl lsp-set-addresses S0-P0 "50:54:00:00:00:03 10.0.0.3 1000::3"
+
+ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.0.110 10.0.0.3 S0-P0 30:54:00:00:00:03
+ovn-nbctl lr-nat-add R1 dnat_and_snat 3000::c 1000::3 S0-P0 40:54:00:00:00:03
+
+ovn-sbctl dump-flows R1 > R1flows
+AT_CAPTURE_FILE([R1flows])
+AT_CHECK([grep "lr_in_arp_resolve" R1flows | grep priority=90 | sort], [0], [dnl
+])
+
+ovn-nbctl --wait=sb set logical_router_port R1-PUB options:redirect-type=bridged
+ovn-sbctl dump-flows R1 > R1flows
+AT_CAPTURE_FILE([R1flows])
+
+AT_CHECK([grep "lr_in_arp_resolve" R1flows | grep priority=90 | sort], [0], [dnl
+  table=15(lr_in_arp_resolve  ), priority=90   , match=(outport == "R1-PUB" && ip4.src == 10.0.0.3 && is_chassis_resident("S0-P0")), action=(get_arp(outport, reg0); next;)
+  table=15(lr_in_arp_resolve  ), priority=90   , match=(outport == "R1-PUB" && ip6.src == 1000::3 && is_chassis_resident("S0-P0")), action=(get_nd(outport, xxreg0); next;)
+])
+
+AT_CLEANUP
+])