On Tue, Oct 8, 2024 at 6:12 AM Ales Musil <[email protected]> wrote:
>
> Most of the functions that are building logical flows
> for NATs did type comparison via strcmp. Store the type
> in enum instead in the nat record and compare the enum instead.
>
> Signed-off-by: Ales Musil <[email protected]>

Thanks for the patch.  It makes sense to do this way,

Applied the patch to main.

Numan

> ---
>  northd/en-lr-nat.c |  10 +++--
>  northd/en-lr-nat.h |   7 +++
>  northd/northd.c    | 110 ++++++++++++++++++++++++---------------------
>  3 files changed, 74 insertions(+), 53 deletions(-)
>
> diff --git a/northd/en-lr-nat.c b/northd/en-lr-nat.c
> index 215d924e4..bdbb2c860 100644
> --- a/northd/en-lr-nat.c
> +++ b/northd/en-lr-nat.c
> @@ -313,10 +313,14 @@ lr_nat_record_init(struct lr_nat_record *lrnat_rec,
>                              nat_entry->ext_addrs.ipv6_addrs[0].addr_s,
>                              nat_entry);
>              }
> +            nat_entry->type = SNAT;
>          } else {
> -            if (!strcmp(nat->type, "dnat_and_snat")
> -                    && nat->logical_port && nat->external_mac) {
> -                lrnat_rec->has_distributed_nat = true;
> +            nat_entry->type = DNAT;
> +            if (!strcmp(nat->type, "dnat_and_snat")) {
> +                nat_entry->type = DNAT_AND_SNAT;
> +                if (nat->logical_port && nat->external_mac) {
> +                    lrnat_rec->has_distributed_nat = true;
> +                }
>              }
>
>              if (nat->external_mac) {
> diff --git a/northd/en-lr-nat.h b/northd/en-lr-nat.h
> index 81a7b0abd..120ceeca9 100644
> --- a/northd/en-lr-nat.h
> +++ b/northd/en-lr-nat.h
> @@ -29,6 +29,12 @@
>  #include "lib/ovn-sb-idl.h"
>  #include "lib/ovn-util.h"
>
> +enum ovn_nat_type {
> +    SNAT,
> +    DNAT,
> +    DNAT_AND_SNAT,
> +};
> +
>  /* Contains a NAT entry with the external addresses pre-parsed. */
>  struct ovn_nat {
>      const struct nbrec_nat *nb;
> @@ -39,6 +45,7 @@ struct ovn_nat {
>                                           */
>      bool is_router_ip; /* Indicates if the NAT external_ip is also one of
>                          * router's lrp ip.  Can be 'true' only for SNAT. */
> +    enum ovn_nat_type type;
>  };
>
>  /* Stores the list of SNAT entries referencing a unique SNAT IP address.
> diff --git a/northd/northd.c b/northd/northd.c
> index 2c4703301..0364dd766 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -8950,7 +8950,7 @@ build_lswitch_rport_arp_req_flows_for_lbnats(
>              continue;
>          }
>
> -        if (!strcmp(nat->type, "snat")) {
> +        if (nat_entry->type == SNAT) {
>              continue;
>          }
>
> @@ -10356,8 +10356,8 @@ build_lswitch_ip_unicast_lookup_for_nats(
>          const struct ovn_nat *nat =
>              &lr_stateful_rec->lrnat_rec->nat_entries[i];
>
> -        if (!strcmp(nat->nb->type, "dnat_and_snat")
> -            && nat->nb->logical_port && nat->nb->external_mac
> +        if (nat->type == DNAT_AND_SNAT && nat->nb->logical_port
> +            && nat->nb->external_mac
>              && eth_addr_from_string(nat->nb->external_mac, &mac)) {
>
>              ds_clear(match);
> @@ -12307,10 +12307,10 @@ copy_ra_to_sb(struct ovn_port *op, const char 
> *address_mode)
>  }
>
>  static inline bool
> -lrouter_dnat_and_snat_is_stateless(const struct nbrec_nat *nat)
> +lrouter_dnat_and_snat_is_stateless(const struct ovn_nat *nat)
>  {
> -    return smap_get_bool(&nat->options, "stateless", false) &&
> -           !strcmp(nat->type, "dnat_and_snat");
> +    return smap_get_bool(&nat->nb->options, "stateless", false) &&
> +           nat->type == DNAT_AND_SNAT;
>  }
>
>  #define NAT_PRIORITY_MATCH_OFFSET 300
> @@ -14587,7 +14587,7 @@ build_lr_gateway_redirect_flows_for_nats(
>          for (int j = 0; j < lrnat_rec->n_nat_entries; j++) {
>              const struct ovn_nat *nat = &lrnat_rec->nat_entries[j];
>
> -            if (!lrouter_dnat_and_snat_is_stateless(nat->nb) ||
> +            if (!lrouter_dnat_and_snat_is_stateless(nat) ||
>                  (!nat->nb->allowed_ext_ips && !nat->nb->exempted_ext_ips)) {
>                  continue;
>              }
> @@ -15237,7 +15237,7 @@ build_lrouter_arp_nd_for_datapath(const struct 
> ovn_datapath *od,
>          /* Skip SNAT entries for now, we handle unique SNAT IPs separately
>          * below.
>          */
> -        if (!strcmp(nat_entry->nb->type, "snat")) {
> +        if (nat_entry->type == SNAT) {
>              continue;
>          }
>          build_lrouter_nat_arp_nd_flow(od, nat_entry, lflows, meter_groups,
> @@ -15544,7 +15544,7 @@ build_lrouter_ipv4_ip_input_for_lbnats(
>          /* Skip SNAT entries for now, we handle unique SNAT IPs separately
>          * below.
>          */
> -        if (!strcmp(nat_entry->nb->type, "snat")) {
> +        if (nat_entry->type == SNAT) {
>              continue;
>          }
>          build_lrouter_port_nat_arp_nd_flow(op, nat_entry, lflows,
> @@ -15597,16 +15597,17 @@ build_lrouter_in_unsnat_match(const struct 
> ovn_datapath *od,
>  static void
>  build_lrouter_in_unsnat_stateless_flow(struct lflow_table *lflows,
>                                         const struct ovn_datapath *od,
> -                                       const struct nbrec_nat *nat,
> +                                       const struct ovn_nat *nat_entry,
>                                         struct ds *match,
>                                         bool distributed_nat, bool is_v6,
>                                         struct ovn_port *l3dgw_port,
>                                         struct lflow_ref *lflow_ref)
>  {
> -    if (strcmp(nat->type, "snat") && strcmp(nat->type, "dnat_and_snat")) {
> +    if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      uint16_t priority = od->is_gw_router ? 90 : 100;
>
>      build_lrouter_in_unsnat_match(od, nat, match, distributed_nat, is_v6,
> @@ -15620,15 +15621,16 @@ build_lrouter_in_unsnat_stateless_flow(struct 
> lflow_table *lflows,
>  static void
>  build_lrouter_in_unsnat_in_czone_flow(struct lflow_table *lflows,
>                                        const struct ovn_datapath *od,
> -                                      const struct nbrec_nat *nat,
> +                                      const struct ovn_nat *nat_entry,
>                                        struct ds *match, bool distributed_nat,
>                                        bool is_v6, struct ovn_port 
> *l3dgw_port,
>                                        struct lflow_ref *lflow_ref)
>  {
> -    if (strcmp(nat->type, "snat") && strcmp(nat->type, "dnat_and_snat")) {
> +    if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      build_lrouter_in_unsnat_match(od, nat, match, distributed_nat, is_v6,
>                                    l3dgw_port);
>
> @@ -15655,16 +15657,16 @@ build_lrouter_in_unsnat_in_czone_flow(struct 
> lflow_table *lflows,
>  static void
>  build_lrouter_in_unsnat_flow(struct lflow_table *lflows,
>                               const struct ovn_datapath *od,
> -                             const struct nbrec_nat *nat, struct ds *match,
> +                             const struct ovn_nat *nat_entry, struct ds 
> *match,
>                               bool distributed_nat, bool is_v6,
>                               struct ovn_port *l3dgw_port,
>                               struct lflow_ref *lflow_ref)
>  {
> -
> -    if (strcmp(nat->type, "snat") && strcmp(nat->type, "dnat_and_snat")) {
> +    if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      uint16_t priority = od->is_gw_router ? 90 : 100;
>
>      build_lrouter_in_unsnat_match(od, nat, match, distributed_nat, is_v6,
> @@ -15679,7 +15681,7 @@ static void
>  build_lrouter_in_dnat_flow(struct lflow_table *lflows,
>                             const struct ovn_datapath *od,
>                             const struct lr_nat_record *lrnat_rec,
> -                           const struct nbrec_nat *nat, struct ds *match,
> +                           const struct ovn_nat *nat_entry, struct ds *match,
>                             struct ds *actions, bool distributed_nat,
>                             int cidr_bits, bool is_v6,
>                             struct ovn_port *l3dgw_port, bool stateless,
> @@ -15688,13 +15690,14 @@ build_lrouter_in_dnat_flow(struct lflow_table 
> *lflows,
>      /* Ingress DNAT table: Packets enter the pipeline with destination
>      * IP address that needs to be DNATted from a external IP address
>      * to a logical IP address. */
> -    if (strcmp(nat->type, "dnat") && strcmp(nat->type, "dnat_and_snat")) {
> +    if (!(nat_entry->type == DNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
>      ds_clear(match);
>      ds_clear(actions);
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      const char *nat_action = lrouter_use_common_zone(od)
>                               ? "ct_dnat_in_czone"
>                               : "ct_dnat";
> @@ -15757,11 +15760,11 @@ build_lrouter_in_dnat_flow(struct lflow_table 
> *lflows,
>  static void
>  build_lrouter_out_undnat_flow(struct lflow_table *lflows,
>                                const struct ovn_datapath *od,
> -                              const struct nbrec_nat *nat, struct ds *match,
> -                              struct ds *actions, bool distributed_nat,
> -                              struct eth_addr mac, bool is_v6,
> -                              struct ovn_port *l3dgw_port, bool stateless,
> -                              struct lflow_ref *lflow_ref)
> +                              const struct ovn_nat *nat_entry,
> +                              struct ds *match, struct ds *actions,
> +                              bool distributed_nat, struct eth_addr mac,
> +                              bool is_v6, struct ovn_port *l3dgw_port,
> +                              bool stateless, struct lflow_ref *lflow_ref)
>  {
>      /* Egress UNDNAT table: It is for already established connections'
>      * reverse traffic. i.e., DNAT has already been done in ingress
> @@ -15771,13 +15774,14 @@ build_lrouter_out_undnat_flow(struct lflow_table 
> *lflows,
>      * Note that this only applies for NAT on a distributed router.
>      */
>      if (!od->n_l3dgw_ports ||
> -        (strcmp(nat->type, "dnat") && strcmp(nat->type, "dnat_and_snat"))) {
> +        !(nat_entry->type == DNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
>      ds_clear(match);
>      ds_clear(actions);
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      ds_put_format(match, "ip && ip%c.src == %s && outport == %s",
>                    is_v6 ? '6' : '4', nat->logical_ip,
>                    l3dgw_port->json_key);
> @@ -15883,19 +15887,20 @@ build_lrouter_out_snat_match(struct lflow_table 
> *lflows,
>  static void
>  build_lrouter_out_snat_stateless_flow(struct lflow_table *lflows,
>                                        const struct ovn_datapath *od,
> -                                      const struct nbrec_nat *nat,
> +                                      const struct ovn_nat *nat_entry,
>                                        struct ds *match, struct ds *actions,
>                                        bool distributed_nat,
>                                        struct eth_addr mac, int cidr_bits,
>                                        bool is_v6, struct ovn_port 
> *l3dgw_port,
>                                        struct lflow_ref *lflow_ref)
>  {
> -    if (strcmp(nat->type, "snat") && strcmp(nat->type, "dnat_and_snat")) {
> +    if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
>      ds_clear(actions);
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      uint16_t priority = lrouter_nat_get_priority(od, nat, false, cidr_bits);
>      build_lrouter_out_snat_match(lflows, od, nat, match, distributed_nat,
>                                   cidr_bits, is_v6, l3dgw_port, lflow_ref,
> @@ -15918,19 +15923,20 @@ build_lrouter_out_snat_stateless_flow(struct 
> lflow_table *lflows,
>  static void
>  build_lrouter_out_snat_in_czone_flow(struct lflow_table *lflows,
>                                       const struct ovn_datapath *od,
> -                                     const struct nbrec_nat *nat,
> +                                     const struct ovn_nat *nat_entry,
>                                       struct ds *match,
>                                       struct ds *actions, bool 
> distributed_nat,
>                                       struct eth_addr mac, int cidr_bits,
>                                       bool is_v6, struct ovn_port *l3dgw_port,
>                                       struct lflow_ref *lflow_ref)
>  {
> -    if (strcmp(nat->type, "snat") && strcmp(nat->type, "dnat_and_snat")) {
> +    if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
>      ds_clear(actions);
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      uint16_t priority = lrouter_nat_get_priority(od, nat, false, cidr_bits);
>      struct ds zone_actions = DS_EMPTY_INITIALIZER;
>
> @@ -15977,19 +15983,20 @@ build_lrouter_out_snat_in_czone_flow(struct 
> lflow_table *lflows,
>  static void
>  build_lrouter_out_snat_flow(struct lflow_table *lflows,
>                              const struct ovn_datapath *od,
> -                            const struct nbrec_nat *nat, struct ds *match,
> +                            const struct ovn_nat *nat_entry, struct ds 
> *match,
>                              struct ds *actions, bool distributed_nat,
>                              struct eth_addr mac, int cidr_bits, bool is_v6,
>                              struct ovn_port *l3dgw_port,
>                              struct lflow_ref *lflow_ref,
>                              const struct chassis_features *features)
>  {
> -    if (strcmp(nat->type, "snat") && strcmp(nat->type, "dnat_and_snat")) {
> +    if (!(nat_entry->type == SNAT || nat_entry->type == DNAT_AND_SNAT)) {
>          return;
>      }
>
>      ds_clear(actions);
>
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      uint16_t priority = lrouter_nat_get_priority(od, nat, false, cidr_bits);
>
>      build_lrouter_out_snat_match(lflows, od, nat, match, distributed_nat,
> @@ -16017,7 +16024,7 @@ build_lrouter_out_snat_flow(struct lflow_table 
> *lflows,
>       * properly tracked so we can decide whether to perform SNAT on traffic
>       * exiting the network. */
>      if (features->ct_commit_to_zone && features->ct_next_zone &&
> -        !strcmp(nat->type, "snat") && !od->is_gw_router) {
> +        nat_entry->type == SNAT && !od->is_gw_router) {
>          /* For traffic that comes from SNAT network, initiate CT state before
>           * entering S_ROUTER_OUT_SNAT to allow matching on various CT states.
>           */
> @@ -16120,14 +16127,15 @@ build_lrouter_ingress_nat_check_pkt_len(struct 
> lflow_table *lflows,
>  static void
>  build_lrouter_ingress_flow(struct lflow_table *lflows,
>                             const struct ovn_datapath *od,
> -                           const struct nbrec_nat *nat, struct ds *match,
> +                           const struct ovn_nat *nat_entry, struct ds *match,
>                             struct ds *actions, struct eth_addr mac,
>                             bool distributed_nat, bool is_v6,
>                             struct ovn_port *l3dgw_port,
>                             const struct shash *meter_groups,
>                             struct lflow_ref *lflow_ref)
>  {
> -    if (od->n_l3dgw_ports && !strcmp(nat->type, "snat")) {
> +    const struct nbrec_nat *nat = nat_entry->nb;
> +    if (od->n_l3dgw_ports && nat_entry->type == SNAT) {
>          ds_clear(match);
>          ds_put_format(
>              match, "inport == %s && %s == %s",
> @@ -16173,11 +16181,12 @@ build_lrouter_ingress_flow(struct lflow_table 
> *lflows,
>
>  static int
>  lrouter_check_nat_entry(const struct ovn_datapath *od,
> -                        const struct nbrec_nat *nat,
> +                        const struct ovn_nat *nat_entry,
>                          const struct hmap *lr_ports, ovs_be32 *mask,
>                          bool *is_v6, int *cidr_bits, struct eth_addr *mac,
>                          bool *distributed, struct ovn_port **nat_l3dgw_port)
>  {
> +    const struct nbrec_nat *nat = nat_entry->nb;
>      struct in6_addr ipv6, mask_v6, v6_exact = IN6ADDR_EXACT_INIT;
>      ovs_be32 ip;
>
> @@ -16255,7 +16264,7 @@ lrouter_check_nat_entry(const struct ovn_datapath *od,
>          error = ip_parse_masked(nat->logical_ip, &ip, mask);
>          *cidr_bits = ip_count_cidr_bits(*mask);
>      }
> -    if (!strcmp(nat->type, "snat")) {
> +    if (nat_entry->type == SNAT) {
>          if (error) {
>              /* Invalid for both IPv4 and IPv6 */
>              static struct vlog_rate_limit rl =
> @@ -16293,7 +16302,7 @@ lrouter_check_nat_entry(const struct ovn_datapath *od,
>          return 0;
>      }
>
> -    if (od->n_l3dgw_ports && !strcmp(nat->type, "dnat_and_snat") &&
> +    if (od->n_l3dgw_ports && nat_entry->type == DNAT_AND_SNAT &&
>          nat->logical_port && nat->external_mac) {
>          if (eth_addr_from_string(nat->external_mac, mac)) {
>              *distributed = true;
> @@ -16460,9 +16469,9 @@ build_lrouter_nat_defrag_and_lb(
>          int cidr_bits;
>          struct ovn_port *l3dgw_port;
>
> -        bool stateless = lrouter_dnat_and_snat_is_stateless(nat);
> +        bool stateless = lrouter_dnat_and_snat_is_stateless(nat_entry);
>
> -        if (lrouter_check_nat_entry(od, nat, lr_ports, &mask, &is_v6,
> +        if (lrouter_check_nat_entry(od, nat_entry, lr_ports, &mask, &is_v6,
>                                      &cidr_bits,
>                                      &mac, &distributed_nat, &l3dgw_port) < 
> 0) {
>              continue;
> @@ -16479,21 +16488,22 @@ build_lrouter_nat_defrag_and_lb(
>           * not know about the possibility of eventual additional SNAT in
>           * egress pipeline. */
>          if (stateless) {
> -            build_lrouter_in_unsnat_stateless_flow(lflows, od, nat, match,
> -                                                   distributed_nat, is_v6,
> -                                                   l3dgw_port, lflow_ref);
> +            build_lrouter_in_unsnat_stateless_flow(lflows, od, nat_entry,
> +                                                   match, distributed_nat,
> +                                                   is_v6, l3dgw_port,
> +                                                   lflow_ref);
>          } else if (lrouter_use_common_zone(od)) {
> -            build_lrouter_in_unsnat_in_czone_flow(lflows, od, nat, match,
> +            build_lrouter_in_unsnat_in_czone_flow(lflows, od, nat_entry, 
> match,
>                                                    distributed_nat, is_v6,
>                                                    l3dgw_port, lflow_ref);
>          } else {
> -            build_lrouter_in_unsnat_flow(lflows, od, nat, match,
> +            build_lrouter_in_unsnat_flow(lflows, od, nat_entry, match,
>                                           distributed_nat, is_v6, l3dgw_port,
>                                           lflow_ref);
>          }
>          /* S_ROUTER_IN_DNAT */
> -        build_lrouter_in_dnat_flow(lflows, od, lrnat_rec, nat, match, 
> actions,
> -                                   distributed_nat, cidr_bits, is_v6,
> +        build_lrouter_in_dnat_flow(lflows, od, lrnat_rec, nat_entry, match,
> +                                   actions, distributed_nat, cidr_bits, 
> is_v6,
>                                     l3dgw_port, stateless, lflow_ref);
>
>          /* ARP resolve for NAT IPs. */
> @@ -16569,7 +16579,7 @@ build_lrouter_nat_defrag_and_lb(
>          }
>
>          /* S_ROUTER_OUT_UNDNAT */
> -        build_lrouter_out_undnat_flow(lflows, od, nat, match, actions,
> +        build_lrouter_out_undnat_flow(lflows, od, nat_entry, match, actions,
>                                        distributed_nat, mac, is_v6, 
> l3dgw_port,
>                                        stateless, lflow_ref);
>          /* S_ROUTER_OUT_SNAT
> @@ -16577,23 +16587,23 @@ build_lrouter_nat_defrag_and_lb(
>           * source ip address that needs to be SNATted to a external ip
>           * address. */
>          if (stateless) {
> -            build_lrouter_out_snat_stateless_flow(lflows, od, nat, match,
> +            build_lrouter_out_snat_stateless_flow(lflows, od, nat_entry, 
> match,
>                                                    actions, distributed_nat,
>                                                    mac, cidr_bits, is_v6,
>                                                    l3dgw_port, lflow_ref);
>          } else if (lrouter_use_common_zone(od)) {
> -            build_lrouter_out_snat_in_czone_flow(lflows, od, nat, match,
> +            build_lrouter_out_snat_in_czone_flow(lflows, od, nat_entry, 
> match,
>                                                   actions, distributed_nat, 
> mac,
>                                                   cidr_bits, is_v6, 
> l3dgw_port,
>                                                   lflow_ref);
>          } else {
> -            build_lrouter_out_snat_flow(lflows, od, nat, match, actions,
> +            build_lrouter_out_snat_flow(lflows, od, nat_entry, match, 
> actions,
>                                          distributed_nat, mac, cidr_bits, 
> is_v6,
>                                          l3dgw_port, lflow_ref, features);
>          }
>
>          /* S_ROUTER_IN_ADMISSION - S_ROUTER_IN_IP_INPUT */
> -        build_lrouter_ingress_flow(lflows, od, nat, match, actions, mac,
> +        build_lrouter_ingress_flow(lflows, od, nat_entry, match, actions, 
> mac,
>                                     distributed_nat, is_v6, l3dgw_port,
>                                     meter_groups, lflow_ref);
>
> --
> 2.46.2
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to