Type: feature
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I6aaaec20a2b6d4c6ddfbe659d9402acc1be2f7e2
app = application_get (app_wrk->app_index);
ctx->parent_app_id = app_wrk->app_index;
cargs->sep_ext.ns_index = app->ns_index;
app = application_get (app_wrk->app_index);
ctx->parent_app_id = app_wrk->app_index;
cargs->sep_ext.ns_index = app->ns_index;
- cargs->sep_ext.flags = TRANSPORT_CFG_F_CONNECTED;
+ cargs->sep_ext.transport_flags = TRANSPORT_CFG_F_CONNECTED;
ctx->crypto_engine = sep->crypto_engine;
ctx->ckpair_index = sep->ckpair_index;
ctx->crypto_engine = sep->crypto_engine;
ctx->ckpair_index = sep->ckpair_index;
int
vcl_session_read_ready (vcl_session_t * session)
{
int
vcl_session_read_ready (vcl_session_t * session)
{
/* Assumes caller has acquired spinlock: vcm->sessions_lockp */
if (PREDICT_FALSE (session->is_vep))
{
/* Assumes caller has acquired spinlock: vcm->sessions_lockp */
if (PREDICT_FALSE (session->is_vep))
{
if (vcl_session_is_ct (session))
return svm_fifo_max_dequeue_cons (session->ct_rx_fifo);
if (vcl_session_is_ct (session))
return svm_fifo_max_dequeue_cons (session->ct_rx_fifo);
- return svm_fifo_max_dequeue_cons (session->rx_fifo);
+ max_deq = svm_fifo_max_dequeue_cons (session->rx_fifo);
+
+ if (session->is_dgram)
+ {
+ session_dgram_pre_hdr_t ph;
+
+ if (max_deq <= SESSION_CONN_HDR_LEN)
+ return 0;
+ if (svm_fifo_peek (session->rx_fifo, 0, sizeof (ph), (u8 *) & ph) < 0)
+ return 0;
+ if (ph.data_length + SESSION_CONN_HDR_LEN > max_deq)
+ return 0;
+
+ return ph.data_length;
+ }
+
+ return max_deq;
#define VCL_SESS_ATTR_TEST(ATTR, VAL) \
((ATTR) & (1 << (VAL)) ? 1 : 0)
#define VCL_SESS_ATTR_TEST(ATTR, VAL) \
((ATTR) & (1 << (VAL)) ? 1 : 0)
+typedef enum vcl_session_flags_
+{
+ VCL_SESSION_F_CONNECTED,
+} __clib_packed vcl_session_flags_t;
+
typedef struct
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
typedef struct
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
/* Socket configuration state */
u8 is_vep;
u8 is_vep_session;
/* Socket configuration state */
u8 is_vep;
u8 is_vep_session;
+ vcl_session_flags_t flags;
/* VCL session index of the listening session (if any) */
u32 listener_index;
/* Accepted sessions on this listener */
/* VCL session index of the listening session (if any) */
u32 listener_index;
/* Accepted sessions on this listener */
clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip));
clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip));
mp->port = s->transport.rmt_port;
clib_memcpy_fast (&mp->ip, &s->transport.rmt_ip, sizeof (mp->ip));
clib_memcpy_fast (&mp->lcl_ip, &s->transport.lcl_ip, sizeof (mp->lcl_ip));
mp->port = s->transport.rmt_port;
+ mp->lcl_port = s->transport.lcl_port;
mp->proto = s->session_type;
mp->proto = s->session_type;
+ if (s->flags & VCL_SESSION_F_CONNECTED)
+ mp->flags |= TRANSPORT_CFG_F_CONNECTED;
app_send_ctrl_evt_to_vpp (mq, app_evt);
}
app_send_ctrl_evt_to_vpp (mq, app_evt);
}
vcl_session_t *s;
s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
vcl_session_t *s;
s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
- if (!s || s->session_state != STATE_DISCONNECT)
{
VDBG (0, "Unlisten reply with wrong handle %llx", mp->handle);
return;
}
{
VDBG (0, "Unlisten reply with wrong handle %llx", mp->handle);
return;
}
+ if (s->session_state != STATE_DISCONNECT)
+ {
+ /* Connected udp listener */
+ if (s->session_type == VPPCOM_PROTO_UDP
+ && s->session_state == STATE_CLOSED)
+ return;
+
+ VDBG (0, "Unlisten session in wrong state %llx", mp->handle);
+ return;
+ }
if (mp->retval)
VDBG (0, "ERROR: session %u [0xllx]: unlisten failed: %U",
if (mp->retval)
VDBG (0, "ERROR: session %u [0xllx]: unlisten failed: %U",
+ /* Attempt to connect a connectionless listener */
+ if (PREDICT_FALSE (session->session_state & STATE_LISTEN))
+ {
+ if (session->session_type != VPPCOM_PROTO_UDP)
+ return VPPCOM_EINVAL;
+ vcl_send_session_unlisten (wrk, session);
+ session->session_state = STATE_CLOSED;
+ }
+
session->transport.is_ip4 = server_ep->is_ip4;
vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep);
session->transport.rmt_port = server_ep->port;
session->parent_handle = VCL_INVALID_SESSION_HANDLE;
session->transport.is_ip4 = server_ep->is_ip4;
vcl_ip_copy_from_ep (&session->transport.rmt_ip, server_ep);
session->transport.rmt_port = server_ep->port;
session->parent_handle = VCL_INVALID_SESSION_HANDLE;
+ session->flags |= VCL_SESSION_F_CONNECTED;
- VDBG (0, "session handle %u: connecting to server %s %U "
+ VDBG (0, "session handle %u (%s): connecting to peer %s %U "
"port %d proto %s", session_handle,
"port %d proto %s", session_handle,
+ vppcom_session_state_str (session->session_state),
session->transport.is_ip4 ? "IPv4" : "IPv6",
format_ip46_address,
&session->transport.rmt_ip, session->transport.is_ip4 ?
session->transport.is_ip4 ? "IPv4" : "IPv6",
format_ip46_address,
&session->transport.rmt_ip, session->transport.is_ip4 ?
return VPPCOM_EAFNOSUPPORT;
}
return VPPCOM_EAFNOSUPPORT;
}
{
session = vcl_session_get_w_handle (wrk, session_handle);
if (session->transport.is_ip4)
{
session = vcl_session_get_w_handle (wrk, session_handle);
if (session->transport.is_ip4)
if (!s)
return VPPCOM_EBADFD;
if (!s)
return VPPCOM_EBADFD;
- if (s->session_type != VPPCOM_PROTO_UDP)
+ if (s->session_type != VPPCOM_PROTO_UDP
+ || (s->flags & VCL_SESSION_F_CONNECTED))
return VPPCOM_EINVAL;
/* Session not connected/bound in vpp. Create it by 'connecting' it */
return VPPCOM_EINVAL;
/* Session not connected/bound in vpp. Create it by 'connecting' it */
u32 wrk_index;
u32 vrf;
u16 port;
u32 wrk_index;
u32 vrf;
u16 port;
u8 proto;
u8 is_ip4;
ip46_address_t ip;
u8 proto;
u8 is_ip4;
ip46_address_t ip;
int rv;
max_deq = svm_fifo_max_dequeue_cons (f);
int rv;
max_deq = svm_fifo_max_dequeue_cons (f);
- if (max_deq < sizeof (session_dgram_hdr_t))
+ if (max_deq <= sizeof (session_dgram_hdr_t))
{
if (clear_evt)
svm_fifo_unset_event (f);
{
if (clear_evt)
svm_fifo_unset_event (f);
rv = svm_fifo_peek (f, ph.data_offset + SESSION_CONN_HDR_LEN, len, buf);
if (peek)
return rv;
rv = svm_fifo_peek (f, ph.data_offset + SESSION_CONN_HDR_LEN, len, buf);
if (peek)
return rv;
ph.data_offset += rv;
if (ph.data_offset == ph.data_length)
svm_fifo_dequeue_drop (f, ph.data_length + SESSION_CONN_HDR_LEN);
ph.data_offset += rv;
if (ph.data_offset == ph.data_length)
svm_fifo_dequeue_drop (f, ph.data_length + SESSION_CONN_HDR_LEN);
a->sep.transport_proto = mp->proto;
a->sep.peer.fib_index = mp->vrf;
clib_memcpy_fast (&a->sep.peer.ip, &mp->lcl_ip, sizeof (mp->lcl_ip));
a->sep.transport_proto = mp->proto;
a->sep.peer.fib_index = mp->vrf;
clib_memcpy_fast (&a->sep.peer.ip, &mp->lcl_ip, sizeof (mp->lcl_ip));
+ a->sep.peer.port = mp->lcl_port;
a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX;
a->sep_ext.parent_handle = mp->parent_handle;
a->sep_ext.ckpair_index = mp->ckpair_index;
a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX;
a->sep_ext.parent_handle = mp->parent_handle;
a->sep_ext.ckpair_index = mp->ckpair_index;
#define SESSION_INVALID_INDEX ((u32)~0)
#define SESSION_INVALID_HANDLE ((u64)~0)
#define SESSION_INVALID_INDEX ((u32)~0)
#define SESSION_INVALID_HANDLE ((u64)~0)
-#define SESSION_CTRL_MSG_MAX_SIZE 84
+#define SESSION_CTRL_MSG_MAX_SIZE 86
#define foreach_session_endpoint_fields \
foreach_transport_endpoint_cfg_fields \
#define foreach_session_endpoint_fields \
foreach_transport_endpoint_cfg_fields \