Commit e4522c09 authored by Tatyana Nikolova's avatar Tatyana Nikolova Committed by Leon Romanovsky

RDMA/irdma: Add ipv4 check to irdma_find_listener()

Add ipv4 check to irdma_find_listener(). Otherwise the function
incorrectly finds and returns a listener with a different addr family for
the zero IP addr, if a listener with a zero IP addr and the same port as
the one searched for has already been created.

Fixes: 146b9756 ("RDMA/irdma: Add connection manager")
Signed-off-by: default avatarTatyana Nikolova <tatyana.e.nikolova@intel.com>
Signed-off-by: default avatarShiraz Saleem <shiraz.saleem@intel.com>
Link: https://lore.kernel.org/r/20230315145231.931-5-shiraz.saleem@intel.comSigned-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 8385a875
...@@ -1458,13 +1458,15 @@ static int irdma_send_fin(struct irdma_cm_node *cm_node) ...@@ -1458,13 +1458,15 @@ static int irdma_send_fin(struct irdma_cm_node *cm_node)
* irdma_find_listener - find a cm node listening on this addr-port pair * irdma_find_listener - find a cm node listening on this addr-port pair
* @cm_core: cm's core * @cm_core: cm's core
* @dst_addr: listener ip addr * @dst_addr: listener ip addr
* @ipv4: flag indicating IPv4 when true
* @dst_port: listener tcp port num * @dst_port: listener tcp port num
* @vlan_id: virtual LAN ID * @vlan_id: virtual LAN ID
* @listener_state: state to match with listen node's * @listener_state: state to match with listen node's
*/ */
static struct irdma_cm_listener * static struct irdma_cm_listener *
irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port, irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, bool ipv4,
u16 vlan_id, enum irdma_cm_listener_state listener_state) u16 dst_port, u16 vlan_id,
enum irdma_cm_listener_state listener_state)
{ {
struct irdma_cm_listener *listen_node; struct irdma_cm_listener *listen_node;
static const u32 ip_zero[4] = { 0, 0, 0, 0 }; static const u32 ip_zero[4] = { 0, 0, 0, 0 };
...@@ -1477,7 +1479,7 @@ irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port, ...@@ -1477,7 +1479,7 @@ irdma_find_listener(struct irdma_cm_core *cm_core, u32 *dst_addr, u16 dst_port,
list_for_each_entry (listen_node, &cm_core->listen_list, list) { list_for_each_entry (listen_node, &cm_core->listen_list, list) {
memcpy(listen_addr, listen_node->loc_addr, sizeof(listen_addr)); memcpy(listen_addr, listen_node->loc_addr, sizeof(listen_addr));
listen_port = listen_node->loc_port; listen_port = listen_node->loc_port;
if (listen_port != dst_port || if (listen_node->ipv4 != ipv4 || listen_port != dst_port ||
!(listener_state & listen_node->listener_state)) !(listener_state & listen_node->listener_state))
continue; continue;
/* compare node pair, return node handle if a match */ /* compare node pair, return node handle if a match */
...@@ -2902,9 +2904,10 @@ irdma_make_listen_node(struct irdma_cm_core *cm_core, ...@@ -2902,9 +2904,10 @@ irdma_make_listen_node(struct irdma_cm_core *cm_core,
unsigned long flags; unsigned long flags;
/* cannot have multiple matching listeners */ /* cannot have multiple matching listeners */
listener = irdma_find_listener(cm_core, cm_info->loc_addr, listener =
cm_info->loc_port, cm_info->vlan_id, irdma_find_listener(cm_core, cm_info->loc_addr, cm_info->ipv4,
IRDMA_CM_LISTENER_EITHER_STATE); cm_info->loc_port, cm_info->vlan_id,
IRDMA_CM_LISTENER_EITHER_STATE);
if (listener && if (listener &&
listener->listener_state == IRDMA_CM_LISTENER_ACTIVE_STATE) { listener->listener_state == IRDMA_CM_LISTENER_ACTIVE_STATE) {
refcount_dec(&listener->refcnt); refcount_dec(&listener->refcnt);
...@@ -3153,6 +3156,7 @@ void irdma_receive_ilq(struct irdma_sc_vsi *vsi, struct irdma_puda_buf *rbuf) ...@@ -3153,6 +3156,7 @@ void irdma_receive_ilq(struct irdma_sc_vsi *vsi, struct irdma_puda_buf *rbuf)
listener = irdma_find_listener(cm_core, listener = irdma_find_listener(cm_core,
cm_info.loc_addr, cm_info.loc_addr,
cm_info.ipv4,
cm_info.loc_port, cm_info.loc_port,
cm_info.vlan_id, cm_info.vlan_id,
IRDMA_CM_LISTENER_ACTIVE_STATE); IRDMA_CM_LISTENER_ACTIVE_STATE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment