From: Paolo Valerio <[email protected]>
Date: 2021-11-17 23:09:29
To: [email protected],[email protected]
Cc: [email protected]
Subject: Re: [PATCH v6 2/3] conntrack: split the dst and src port range
iterations>Hi wenxu,
>
>[email protected] writes:
>
>> From: wenxu <[email protected]>
>>
>> Splitting the two port range iterations instead of keeping it nested. And
>> the dst port (in case of DNAT) range would have precedence over the src
>> manipulation in the resolution.
>>
>> Signed-off-by: wenxu <[email protected]>
>> ---
>> lib/conntrack.c | 65
>> +++++++++++++++++++++++++++------------------------------
>> 1 file changed, 31 insertions(+), 34 deletions(-)
>>
>> diff --git a/lib/conntrack.c b/lib/conntrack.c
>> index 44f99f3..a6784ba 100644
>> --- a/lib/conntrack.c
>> +++ b/lib/conntrack.c
>> @@ -1036,6 +1036,17 @@ conn_not_found(struct conntrack *ct, struct dp_packet
>> *pkt,
>> nat_action_info);
>>
>> if (!nat_res) {
>> + if (nat_action_info->nat_action & NAT_ACTION_DST) {
>> + struct nat_action_info_t tmp_nat_info;
>> +
>> + memset(&tmp_nat_info, 0, sizeof tmp_nat_info);
>> + tmp_nat_info.nat_action = NAT_ACTION_SRC;
>> + nat_res = nat_get_unique_tuple(ct, nc, nat_conn,
>> + &tmp_nat_info);
>> + if (!nat_res) {
>> + goto nat_res_exhaustion;
>> + }
>> + }
>> goto nat_res_exhaustion;
>> }
>
>is there any particular reason that brought you to call
>nat_get_unique_tuple() twice instead of splitting the FOR_EACH with a
>single call of nat_get_unique_tuple() ?
>
>Something like:
>
>FOR_EACH_PORT_IN_RANGE(curr_dport, min_dport, max_dport) {
> ...
>}
>
>FOR_EACH_PORT_IN_RANGE(curr_sport, min_sport, max_sport) {
> ...
>}
>
>That was my initial understanding. I suspect that approach would require
>fewer changes as well.
And I also think this splitting the FOR_EACH twice method can't handle the both
dst port
and src port nat case. For eample: do dnat case dport range {100..200} and
sport {MIN_NAT_EPHEMERAL_PORT..
MAX_NAT_EPHEMERAL_PORT } . This shuld be chain each FOR-EACH together but not
separate it.
>
>>
>> @@ -2258,12 +2269,12 @@ nat_range_hash(const struct conn *conn, 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,
>> - uint16_t *max)
>> +set_port_range(const struct nat_action_info_t *ni, const struct conn_key *k,
>> + uint32_t hash, uint16_t *curr, uint16_t *min,
>> + uint16_t *max)
>> {
>> - if (((ni->nat_action & NAT_ACTION_SNAT_ALL) == NAT_ACTION_SRC) ||
>> - ((ni->nat_action & NAT_ACTION_DST))) {
>> + if ((ni->nat_action & NAT_ACTION_SRC) &&
>> + (!(ni->nat_action & NAT_ACTION_SRC_PORT))) {
>> *curr = ntohs(k->src.port);
>> if (*curr < 512) {
>> *min = 1;
>> @@ -2275,6 +2286,10 @@ set_sport_range(const struct nat_action_info_t *ni,
>> const struct conn_key *k,
>> *min = MIN_NAT_EPHEMERAL_PORT;
>> *max = MAX_NAT_EPHEMERAL_PORT;
>> }
>> + } else if ((ni->nat_action & NAT_ACTION_DST) &&
>> + (!(ni->nat_action & NAT_ACTION_DST_PORT))) {
>> + *curr = ntohs(k->dst.port);
>> + *min = *max = *curr;
>> } else {
>> *min = ni->min_port;
>> *max = ni->max_port;
>> @@ -2282,21 +2297,6 @@ set_sport_range(const struct nat_action_info_t *ni,
>> const struct conn_key *k,
>> }
>> }
>>
>> -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,
>> - 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));
>> - } else {
>> - *curr = ntohs(k->dst.port);
>> - *min = *max = *curr;
>> - }
>> -}
>> -
>> /* Gets the initial in range address based on the hash.
>> * Addresses are kept in network order. */
>> static void
>> @@ -2426,8 +2426,7 @@ nat_get_unique_tuple(struct conntrack *ct, const
>> struct conn *conn,
>> uint32_t hash = nat_range_hash(conn, ct->hash_basis, nat_info);
>> bool pat_proto = conn->key.nw_proto == IPPROTO_TCP ||
>> conn->key.nw_proto == IPPROTO_UDP;
>> - uint16_t min_dport, max_dport, curr_dport;
>> - uint16_t min_sport, max_sport, curr_sport;
>> + uint16_t min_port, max_port, curr_port;
>>
>> min_addr = nat_info->min_addr;
>> max_addr = nat_info->max_addr;
>> @@ -2439,10 +2438,8 @@ nat_get_unique_tuple(struct conntrack *ct, const
>> struct conn *conn,
>> * we can stop once we reach it. */
>> guard_addr = curr_addr;
>>
>> - set_sport_range(nat_info, &conn->key, hash, &curr_sport,
>> - &min_sport, &max_sport);
>> - set_dport_range(nat_info, &conn->key, hash, &curr_dport,
>> - &min_dport, &max_dport);
>> + set_port_range(nat_info, &conn->key, hash, &curr_port,
>> + &min_port, &max_port);
>>
>> another_round:
>> store_addr_to_key(&curr_addr, &nat_conn->rev_key,
>> @@ -2457,14 +2454,14 @@ another_round:
>> goto next_addr;
>> }
>>
>> - FOR_EACH_PORT_IN_RANGE(curr_dport, min_dport, max_dport) {
>> - nat_conn->rev_key.src.port = htons(curr_dport);
>> - FOR_EACH_PORT_IN_RANGE(curr_sport, min_sport, max_sport) {
>> - nat_conn->rev_key.dst.port = htons(curr_sport);
>> - if (!conn_lookup(ct, &nat_conn->rev_key,
>> - time_msec(), NULL, NULL)) {
>> - return true;
>> - }
>> + FOR_EACH_PORT_IN_RANGE(curr_port, min_port, max_port) {
>> + if (nat_info->nat_action & NAT_ACTION_SRC) {
>> + nat_conn->rev_key.dst.port = htons(curr_port);
>> + } else {
>> + nat_conn->rev_key.src.port = htons(curr_port);
>> + }
>> + if (!conn_lookup(ct, &nat_conn->rev_key, time_msec(), NULL, NULL)) {
>> + return true;
>> }
>> }
>>
>> --
>> 1.8.3.1
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev