mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
conntrack: Handle random selection for port ranges.
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 <pvalerio@redhat.com> Acked-by: Aaron Conole <aconole@redhat.com> Signed-off-by: Simon Horman <horms@ovn.org>
This commit is contained in:
parent
5f2af0b7a3
commit
99413ec261
@ -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:
|
||||
|
||||
|
3
NEWS
3
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 - 16 Feb 2024
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user