summaryrefslogtreecommitdiffstats
path: root/src/vnet/session
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/session')
-rw-r--r--src/vnet/session/transport.c17
-rw-r--r--src/vnet/session/transport.h8
2 files changed, 18 insertions, 7 deletions
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index 8554c730bda..0020d743d9b 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -566,7 +566,8 @@ transport_share_local_endpoint (u8 proto, ip46_address_t * lcl_ip, u16 port)
* table to mark the pair as used.
*/
int
-transport_alloc_local_port (u8 proto, ip46_address_t * ip)
+transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
+ transport_endpoint_cfg_t *rmt)
{
u16 min = 1024, max = 65535; /* XXX configurable ? */
transport_main_t *tm = &tp_main;
@@ -594,8 +595,18 @@ transport_alloc_local_port (u8 proto, ip46_address_t * ip)
break;
}
- if (!transport_endpoint_mark_used (proto, ip, port))
+ if (!transport_endpoint_mark_used (proto, lcl_addr, port))
return port;
+
+ /* IP:port pair already in use, check if 6-tuple available */
+ if (session_lookup_connection (rmt->fib_index, lcl_addr, &rmt->ip, port,
+ rmt->port, proto, rmt->is_ip4))
+ continue;
+
+ /* 6-tuple is available so increment lcl endpoint refcount */
+ transport_share_local_endpoint (proto, lcl_addr, port);
+
+ return port;
}
return -1;
}
@@ -683,7 +694,7 @@ transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt_cfg,
*/
if (rmt_cfg->peer.port == 0)
{
- port = transport_alloc_local_port (proto, lcl_addr);
+ port = transport_alloc_local_port (proto, lcl_addr, rmt_cfg);
if (port < 1)
return SESSION_E_NOPORT;
*lcl_port = port;
diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h
index 6e8b22a8cac..3cd64c90995 100644
--- a/src/vnet/session/transport.h
+++ b/src/vnet/session/transport.h
@@ -246,10 +246,10 @@ transport_register_new_protocol (const transport_proto_vft_t * vft,
transport_proto_vft_t *transport_protocol_get_vft (transport_proto_t tp);
void transport_update_time (clib_time_type_t time_now, u8 thread_index);
-int transport_alloc_local_port (u8 proto, ip46_address_t * ip);
-int transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt,
- ip46_address_t * lcl_addr,
- u16 * lcl_port);
+int transport_alloc_local_port (u8 proto, ip46_address_t *ip,
+ transport_endpoint_cfg_t *rmt);
+int transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t *rmt,
+ ip46_address_t *lcl_addr, u16 *lcl_port);
void transport_share_local_endpoint (u8 proto, ip46_address_t * lcl_ip,
u16 port);
int transport_release_local_endpoint (u8 proto, ip46_address_t *lcl_ip,