int
transport_connect (transport_proto_t tp, transport_endpoint_cfg_t * tep)
{
+ if (PREDICT_FALSE (!tp_vfts[tp].connect))
+ return SESSION_E_TRANSPORT_NO_REG;
return tp_vfts[tp].connect (tep);
}
transport_start_listen (transport_proto_t tp, u32 session_index,
transport_endpoint_cfg_t *tep)
{
+ if (PREDICT_FALSE (!tp_vfts[tp].start_listen))
+ return SESSION_E_TRANSPORT_NO_REG;
return tp_vfts[tp].start_listen (session_index, tep);
}
void
transport_endpoint_free (u32 tepi)
{
- /* All workers can free connections. Synchronize access to pool */
- clib_spinlock_lock (&local_endpoints_lock);
pool_put_index (local_endpoints, tepi);
- clib_spinlock_unlock (&local_endpoints_lock);
-}
-
-static void
-transport_endpoint_pool_realloc_rpc (void *rpc_args)
-{
- pool_realloc_safe_aligned (local_endpoints, 0);
}
always_inline local_endpoint_t *
local_endpoint_t *lep;
ASSERT (vlib_get_thread_index () <= transport_cl_thread ());
- pool_get_aligned_safe (local_endpoints, lep, transport_cl_thread (),
- transport_endpoint_pool_realloc_rpc, 0);
- pool_get_zero (local_endpoints, lep);
+ pool_get_aligned_safe (local_endpoints, lep, 0);
return lep;
}
/* Cleanup local endpoint if this was an active connect */
lepi = transport_endpoint_lookup (&local_endpoints_table, proto, lcl_ip,
clib_net_to_host_u16 (port));
- if (lepi != ENDPOINT_INVALID_INDEX)
+ if (lepi == ENDPOINT_INVALID_INDEX)
+ return;
+
+ lep = pool_elt_at_index (local_endpoints, lepi);
+ if (!clib_atomic_sub_fetch (&lep->refcnt, 1))
{
- lep = pool_elt_at_index (local_endpoints, lepi);
- if (!clib_atomic_sub_fetch (&lep->refcnt, 1))
- {
- transport_endpoint_table_del (&local_endpoints_table, proto,
- &lep->ep);
- transport_endpoint_free (lepi);
- }
+ transport_endpoint_table_del (&local_endpoints_table, proto, &lep->ep);
+
+ /* All workers can free connections. Synchronize access to pool */
+ clib_spinlock_lock (&local_endpoints_lock);
+ transport_endpoint_free (lepi);
+ clib_spinlock_unlock (&local_endpoints_lock);
}
}
-static void
-transport_endpoint_mark_used (u8 proto, ip46_address_t * ip, u16 port)
+static int
+transport_endpoint_mark_used (u8 proto, ip46_address_t *ip, u16 port)
{
local_endpoint_t *lep;
+ u32 tei;
ASSERT (vlib_get_thread_index () <= transport_cl_thread ());
+ tei = transport_endpoint_lookup (&local_endpoints_table, proto, ip, port);
+ if (tei != ENDPOINT_INVALID_INDEX)
+ return SESSION_E_PORTINUSE;
+
/* Pool reallocs with worker barrier */
lep = transport_endpoint_alloc ();
clib_memcpy_fast (&lep->ep.ip, ip, sizeof (*ip));
lep->ep.port = port;
lep->refcnt = 1;
+
transport_endpoint_table_add (&local_endpoints_table, proto, &lep->ep,
lep - local_endpoints);
+
+ return 0;
}
void
{
u16 min = 1024, max = 65535; /* XXX configurable ? */
int tries, limit;
- u32 tei;
limit = max - min;
break;
}
- /* Look it up. If not found, we're done */
- tei = transport_endpoint_lookup (&local_endpoints_table, proto, ip,
- port);
- if (tei == ENDPOINT_INVALID_INDEX)
- {
- transport_endpoint_mark_used (proto, ip, port);
- return port;
- }
+ if (!transport_endpoint_mark_used (proto, ip, port))
+ return port;
}
return -1;
}
transport_endpoint_t *rmt = (transport_endpoint_t *) rmt_cfg;
session_error_t error;
int port;
- u32 tei;
/*
* Find the local address
{
port = clib_net_to_host_u16 (rmt_cfg->peer.port);
*lcl_port = port;
- tei = transport_endpoint_lookup (&local_endpoints_table, proto,
- lcl_addr, port);
- if (tei != ENDPOINT_INVALID_INDEX)
- return SESSION_E_PORTINUSE;
- transport_endpoint_mark_used (proto, lcl_addr, port);
+ return transport_endpoint_mark_used (proto, lcl_addr, port);
}
return 0;