Paolo Valerio <[email protected]> writes:

> The userspace conntrack only supported hash for port selection.
> With the patch, both userspace and kernel datapath support the random
> flag.
>
> The default behavior remains the same, that is, if no flags are
> specified, hash is selected.
>
> Signed-off-by: Paolo Valerio <[email protected]>
> Acked-by: Simon Horman <[email protected]>
> ---

Acked-by: Aaron Conole <[email protected]>

>  Documentation/ref/ovs-actions.7.rst |  3 +--
>  NEWS                                |  3 +++
>  lib/conntrack.c                     | 15 ++++++++-------
>  lib/conntrack.h                     |  5 +++++
>  lib/dpif-netdev.c                   |  4 +++-
>  5 files changed, 20 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/ref/ovs-actions.7.rst 
> b/Documentation/ref/ovs-actions.7.rst
> index 36adcc5db..80acd9070 100644
> --- a/Documentation/ref/ovs-actions.7.rst
> +++ b/Documentation/ref/ovs-actions.7.rst
> @@ -1551,8 +1551,7 @@ following arguments:
>          should be selected. When a port range is specified, fallback to
>          ephemeral ports does not happen, else, it will.  The port number
>          selection can be informed by the optional ``random`` and ``hash`` 
> flags
> -        described below.  The userspace datapath only supports the ``hash``
> -        behavior.
> +        described below.
>  
>      The optional *flags* are:
>  
> diff --git a/NEWS b/NEWS
> index a6617546c..93046b963 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -1,5 +1,8 @@
>  Post-v3.3.0
>  --------------------
> +   - Userspace datapath:
> +     * Conntrack now supports 'random' flag for selecting ports in a range
> +       while natting.
>  
>  
>  v3.3.0 - xx xxx xxxx
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index 013709bd6..e09ecdf33 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -2222,7 +2222,7 @@ nat_range_hash(const struct conn_key *key, uint32_t 
> basis,
>  /* Ports are stored in host byte order for convenience. */
>  static void
>  set_sport_range(const struct nat_action_info_t *ni, const struct conn_key *k,
> -                uint32_t hash, uint16_t *curr, uint16_t *min,
> +                uint32_t off, uint16_t *curr, uint16_t *min,
>                  uint16_t *max)
>  {
>      if (((ni->nat_action & NAT_ACTION_SNAT_ALL) == NAT_ACTION_SRC) ||
> @@ -2241,19 +2241,19 @@ set_sport_range(const struct nat_action_info_t *ni, 
> const struct conn_key *k,
>      } else {
>          *min = ni->min_port;
>          *max = ni->max_port;
> -        *curr = *min + (hash % ((*max - *min) + 1));
> +        *curr =  *min + (off % ((*max - *min) + 1));
>      }
>  }
>  
>  static void
>  set_dport_range(const struct nat_action_info_t *ni, const struct conn_key *k,
> -                uint32_t hash, uint16_t *curr, uint16_t *min,
> +                uint32_t off, uint16_t *curr, uint16_t *min,
>                  uint16_t *max)
>  {
>      if (ni->nat_action & NAT_ACTION_DST_PORT) {
>          *min = ni->min_port;
>          *max = ni->max_port;
> -        *curr = *min + (hash % ((*max - *min) + 1));
> +        *curr = *min + (off % ((*max - *min) + 1));
>      } else {
>          *curr = ntohs(k->dst.port);
>          *min = *max = *curr;
> @@ -2388,18 +2388,19 @@ nat_get_unique_tuple(struct conntrack *ct, struct 
> conn *conn,
>                       fwd_key->nw_proto == IPPROTO_SCTP;
>      uint16_t min_dport, max_dport, curr_dport;
>      uint16_t min_sport, max_sport, curr_sport;
> -    uint32_t hash;
> +    uint32_t hash, port_off;
>  
>      hash = nat_range_hash(fwd_key, ct->hash_basis, nat_info);
> +    port_off = nat_info->nat_flags & NAT_RANGE_RANDOM ? random_uint32() : 
> hash;
>      min_addr = nat_info->min_addr;
>      max_addr = nat_info->max_addr;
>  
>      find_addr(fwd_key, &min_addr, &max_addr, &addr, hash,
>                (fwd_key->dl_type == htons(ETH_TYPE_IP)), nat_info);
>  
> -    set_sport_range(nat_info, fwd_key, hash, &curr_sport,
> +    set_sport_range(nat_info, fwd_key, port_off, &curr_sport,
>                      &min_sport, &max_sport);
> -    set_dport_range(nat_info, fwd_key, hash, &curr_dport,
> +    set_dport_range(nat_info, fwd_key, port_off, &curr_dport,
>                      &min_dport, &max_dport);
>  
>      if (pat_proto) {
> diff --git a/lib/conntrack.h b/lib/conntrack.h
> index 0a888be45..9b0c6aa88 100644
> --- a/lib/conntrack.h
> +++ b/lib/conntrack.h
> @@ -77,12 +77,17 @@ enum nat_action_e {
>      NAT_ACTION_DST_PORT = 1 << 3,
>  };
>  
> +enum nat_flags_e {
> +    NAT_RANGE_RANDOM = 1 << 0,
> +};
> +
>  struct nat_action_info_t {
>      union ct_addr min_addr;
>      union ct_addr max_addr;
>      uint16_t min_port;
>      uint16_t max_port;
>      uint16_t nat_action;
> +    uint16_t nat_flags;
>  };
>  
>  struct conntrack *conntrack_init(void);
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index c1981137f..c3334c667 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -9409,9 +9409,11 @@ dp_execute_cb(void *aux_, struct dp_packet_batch 
> *packets_,
>                              nl_attr_get_u16(b_nest);
>                          proto_num_max_specified = true;
>                          break;
> +                    case OVS_NAT_ATTR_PROTO_RANDOM:
> +                        nat_action_info.nat_flags |= NAT_RANGE_RANDOM;
> +                        break;
>                      case OVS_NAT_ATTR_PERSISTENT:
>                      case OVS_NAT_ATTR_PROTO_HASH:
> -                    case OVS_NAT_ATTR_PROTO_RANDOM:
>                          break;
>                      case OVS_NAT_ATTR_UNSPEC:
>                      case __OVS_NAT_ATTR_MAX:

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to