[ovs-dev] [PATCH] ovs: skip ephemeral port for icmp and SNAT in which port range is specified
solomon
liwei.solomon at gmail.com
Tue Feb 26 02:46:37 UTC 2019
Darrell Ball wrote:
> Thanks for the report
>
> I think there are two separate issues:
> 1/ Fallback to ephemeral ports for SNAT being less restrictive than in
> kernel
> 2/ Wasted local variable port incrementing work for ICMPv4/v6
>
> I sent an alternative series here:
> https://mail.openvswitch.org/pipermail/ovs-dev/2019-February/356654.html
>
Thanks for your quick ack.
I have seen the accepted patch-set in the upstream.
--
Thanks
Solomon
> Darrell
>
>
> On Mon, Feb 25, 2019 at 7:03 AM solomon <liwei.solomon at gmail.com> wrote:
>
>>
>> If setting the port range in SNAT, we expect that the selected port is in
>> the range we set.
>> At the same time, this behavior is consistent with the kernel-datapath.
>>
>> The port has no meaning for the icmp/icmpv6 protocol.
>> If no key is available, it will exit early.
>>
>> Signed-off-by: LiWei <liwei.solomon at gmail.com>
>> ---
>> lib/conntrack.c | 12 +++++++++---
>> 1 file changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/lib/conntrack.c b/lib/conntrack.c
>> index 4028ba9a0..c3fd7d63d 100644
>> --- a/lib/conntrack.c
>> +++ b/lib/conntrack.c
>> @@ -2115,6 +2115,12 @@ nat_range_hash(const struct conn *conn, uint32_t
>> basis)
>> return hash_finish(hash, 0);
>> }
>>
>> +/* This function selects a unique new connection key based on the ip and
>> port
>> + * settings in the nat tuple. For the case where the port range is not
>> + * specified, the ephemeral port from 1024 to 65535 can be selected when
>> the
>> + * address is exhausted.
>> + * However, the ephemeral ports are not enabled by ICMP/ICMPv6 and DNAT.
>> + */
>> static bool
>> nat_select_range_tuple(struct conntrack *ct, const struct conn *conn,
>> struct conn *nat_conn)
>> @@ -2126,12 +2132,14 @@ nat_select_range_tuple(struct conntrack *ct, const
>> struct conn *conn,
>> uint16_t max_port;
>> uint16_t first_port;
>> uint32_t hash = nat_range_hash(conn, ct->hash_basis);
>> + bool ephemeral_ports_tried = true;
>>
>> if ((conn->nat_info->nat_action & NAT_ACTION_SRC) &&
>> (!(conn->nat_info->nat_action & NAT_ACTION_SRC_PORT))) {
>> min_port = ntohs(conn->key.src.port);
>> max_port = ntohs(conn->key.src.port);
>> first_port = min_port;
>> + ephemeral_ports_tried = false;
>> } else if ((conn->nat_info->nat_action & NAT_ACTION_DST) &&
>> (!(conn->nat_info->nat_action & NAT_ACTION_DST_PORT))) {
>> min_port = ntohs(conn->key.dst.port);
>> @@ -2175,9 +2183,6 @@ nat_select_range_tuple(struct conntrack *ct, const
>> struct conn *conn,
>>
>> uint16_t port = first_port;
>> bool all_ports_tried = false;
>> - /* For DNAT, we don't use ephemeral ports. */
>> - bool ephemeral_ports_tried = conn->nat_info->nat_action &
>> NAT_ACTION_DST
>> - ? true : false;
>> union ct_addr first_addr = ct_addr;
>>
>> while (true) {
>> @@ -2190,6 +2195,7 @@ nat_select_range_tuple(struct conntrack *ct, const
>> struct conn *conn,
>> if ((conn->key.nw_proto == IPPROTO_ICMP) ||
>> (conn->key.nw_proto == IPPROTO_ICMPV6)) {
>> all_ports_tried = true;
>> + ephemeral_ports_tried = true;
>> } else if (conn->nat_info->nat_action & NAT_ACTION_SRC) {
>> nat_conn->rev_key.dst.port = htons(port);
>> } else {
>> --
>> 2.11.0
>>
>
More information about the dev
mailing list