aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vcl/vcl_private.h16
-rw-r--r--src/vcl/vppcom.c98
-rw-r--r--src/vcl/vppcom.h1
-rw-r--r--src/vnet/session/application_interface.h1
-rw-r--r--src/vnet/session/transport_types.h3
5 files changed, 96 insertions, 23 deletions
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index b89052f96af..0f1a6d24516 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -181,8 +181,7 @@ typedef struct vcl_session_
elog_track_t elog_track;
#endif
- u16 original_dst_port; /**< original dst port (network order) */
- u32 original_dst_ip4; /**< original dst ip4 (network order) */
+ transport_endpt_attr_t *tep_attrs; /**< vector of attributes */
} vcl_session_t;
typedef struct vppcom_cfg_t_
@@ -409,6 +408,7 @@ vcl_session_free (vcl_worker_t * wrk, vcl_session_t * s)
vcl_session_detach_fifos (s);
if (s->ext_config)
clib_mem_free (s->ext_config);
+ vec_free (s->tep_attrs);
pool_put (wrk->sessions, s);
}
@@ -664,6 +664,18 @@ vcl_session_clear_attr (vcl_session_t * s, u8 attr)
s->attributes &= ~(1 << attr);
}
+static inline transport_endpt_attr_t *
+vcl_session_tep_attr_get (vcl_session_t *s, transport_endpt_attr_type_t at)
+{
+ transport_endpt_attr_t *tepa;
+ vec_foreach (tepa, s->tep_attrs)
+ {
+ if (tepa->type == at)
+ return tepa;
+ }
+ return 0;
+}
+
static inline session_evt_type_t
vcl_session_dgram_tx_evt (vcl_session_t *s, session_evt_type_t et)
{
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 2ebb1d8e5b6..1db0a961092 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -351,10 +351,16 @@ vcl_session_accepted_handler (vcl_worker_t * wrk, session_accepted_msg_t * mp,
session->vpp_handle = mp->handle;
session->session_state = VCL_STATE_READY;
- if (mp->rmt.is_ip4)
+ if (mp->rmt.is_ip4 && mp->original_dst_port)
{
- session->original_dst_ip4 = mp->original_dst_ip4;
- session->original_dst_port = mp->original_dst_port;
+ transport_endpt_attr_t *tep_attr;
+ vec_add2 (session->tep_attrs, tep_attr, 1);
+ /* Expecting to receive this on accepted connections
+ * and the external transport endpoint received is
+ * the local one, prior to something like nat */
+ tep_attr->type = TRANSPORT_ENDPT_ATTR_EXT_ENDPT;
+ tep_attr->ext_endpt.port = mp->original_dst_port;
+ tep_attr->ext_endpt.ip.ip4.as_u32 = mp->original_dst_ip4;
}
session->transport.rmt_port = mp->rmt.port;
session->transport.is_ip4 = mp->rmt.is_ip4;
@@ -989,6 +995,24 @@ vcl_worker_rpc_handler (vcl_worker_t * wrk, void *data)
}
static void
+vcl_session_transport_attr_handler (vcl_worker_t *wrk, void *data)
+{
+ session_transport_attr_msg_t *mp = (session_transport_attr_msg_t *) data;
+ vcl_session_t *s;
+
+ s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
+ if (!s)
+ {
+ VDBG (0, "session transport attr with wrong handle %llx", mp->handle);
+ return;
+ }
+
+ VDBG (0, "session %u [0x%llx]: transport attr %u", s->session_index,
+ s->vpp_handle, mp->attr.type);
+ vec_add1 (s->tep_attrs, mp->attr);
+}
+
+static void
vcl_session_transport_attr_reply_handler (vcl_worker_t *wrk, void *data)
{
session_transport_attr_reply_msg_t *mp;
@@ -1129,6 +1153,9 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e)
case SESSION_CTRL_EVT_APP_WRK_RPC:
vcl_worker_rpc_handler (wrk, e->data);
break;
+ case SESSION_CTRL_EVT_TRANSPORT_ATTR:
+ vcl_session_transport_attr_handler (wrk, e->data);
+ break;
case SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY:
vcl_session_transport_attr_reply_handler (wrk, e->data);
break;
@@ -2607,6 +2634,9 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
case SESSION_CTRL_EVT_APP_WRK_RPC:
vcl_worker_rpc_handler (wrk, e->data);
break;
+ case SESSION_CTRL_EVT_TRANSPORT_ATTR:
+ vcl_session_transport_attr_handler (wrk, e->data);
+ break;
default:
clib_warning ("unhandled: %u", e->event_type);
break;
@@ -3382,6 +3412,9 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
case SESSION_CTRL_EVT_APP_WRK_RPC:
vcl_worker_rpc_handler (wrk, e->data);
break;
+ case SESSION_CTRL_EVT_TRANSPORT_ATTR:
+ vcl_session_transport_attr_handler (wrk, e->data);
+ break;
default:
VDBG (0, "unhandled: %u", e->event_type);
break;
@@ -3672,7 +3705,7 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
vcl_worker_t *wrk = vcl_worker_get_current ();
u32 *flags = buffer;
vppcom_endpt_t *ep = buffer;
- transport_endpt_attr_t tea;
+ transport_endpt_attr_t tea, *tepap;
vcl_session_t *session;
int rv = VPPCOM_OK;
@@ -3795,24 +3828,49 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
rv = VPPCOM_EAFNOSUPPORT;
break;
}
- if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*ep)) &&
- ep->ip))
+ if (PREDICT_FALSE (!buffer || !buflen || (*buflen < sizeof (*ep)) ||
+ !ep->ip))
{
- ep->is_ip4 = session->transport.is_ip4;
- ep->port = session->original_dst_port;
- clib_memcpy_fast (ep->ip, &session->original_dst_ip4,
- sizeof (ip4_address_t));
- *buflen = sizeof (*ep);
- VDBG (1,
- "VPPCOM_ATTR_GET_ORIGINAL_DST: sh %u, is_ip4 = %u, addr = %U"
- " port %d",
- session_handle, ep->is_ip4, vcl_format_ip4_address,
- (ip4_address_t *) (&session->original_dst_ip4),
- ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
- clib_net_to_host_u16 (ep->port));
+ rv = VPPCOM_EINVAL;
+ break;
}
- else
- rv = VPPCOM_EINVAL;
+
+ tepap =
+ vcl_session_tep_attr_get (session, TRANSPORT_ENDPT_ATTR_EXT_ENDPT);
+ if (!tepap)
+ {
+ rv = VPPCOM_EINVAL;
+ break;
+ }
+ vcl_ip_copy_to_ep (&tepap->ext_endpt.ip, ep, tepap->ext_endpt.is_ip4);
+ ep->port = tepap->ext_endpt.port;
+ *buflen = sizeof (*ep);
+
+ VDBG (1,
+ "VPPCOM_ATTR_GET_ORIGINAL_DST: sh %u, is_ip4 = %u, "
+ "addr = %U port %d",
+ session_handle, ep->is_ip4, vcl_format_ip4_address,
+ (ip4_address_t *) ep->ip,
+ ep->is_ip4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6,
+ clib_net_to_host_u16 (ep->port));
+ break;
+
+ case VPPCOM_ATTR_GET_EXT_ENDPT:
+ if (PREDICT_FALSE (!buffer || !buflen || (*buflen < sizeof (*ep)) ||
+ !ep->ip))
+ {
+ rv = VPPCOM_EINVAL;
+ break;
+ }
+ tepap =
+ vcl_session_tep_attr_get (session, TRANSPORT_ENDPT_ATTR_EXT_ENDPT);
+ if (!tepap)
+ {
+ rv = VPPCOM_EINVAL;
+ break;
+ }
+ vcl_ip_copy_to_ep (&tepap->ext_endpt.ip, ep, tepap->ext_endpt.is_ip4);
+ ep->port = tepap->ext_endpt.port;
break;
case VPPCOM_ATTR_SET_LCL_ADDR:
diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h
index 164dc376ad8..a11db951749 100644
--- a/src/vcl/vppcom.h
+++ b/src/vcl/vppcom.h
@@ -186,6 +186,7 @@ typedef enum
VPPCOM_ATTR_GET_IP_PKTINFO,
VPPCOM_ATTR_GET_ORIGINAL_DST,
VPPCOM_ATTR_GET_NWRITEQ,
+ VPPCOM_ATTR_GET_EXT_ENDPT,
} vppcom_attr_op_t;
typedef struct _vcl_poll
diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h
index f175e4a58c6..1702a3727de 100644
--- a/src/vnet/session/application_interface.h
+++ b/src/vnet/session/application_interface.h
@@ -396,6 +396,7 @@ typedef struct session_accepted_msg_
transport_endpoint_t lcl;
transport_endpoint_t rmt;
u8 flags;
+ /* TODO(fcoras) maybe refactor to pass as transport attr */
u32 original_dst_ip4;
u16 original_dst_port;
} __clib_packed session_accepted_msg_t;
diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h
index c92cb7939ae..f6058c6cef6 100644
--- a/src/vnet/session/transport_types.h
+++ b/src/vnet/session/transport_types.h
@@ -259,7 +259,8 @@ typedef enum transport_endpt_attr_flag_
_ (u64, next_output_node, NEXT_OUTPUT_NODE) \
_ (u16, mss, MSS) \
_ (u8, flags, FLAGS) \
- _ (u8, cc_algo, CC_ALGO)
+ _ (u8, cc_algo, CC_ALGO) \
+ _ (transport_endpoint_t, ext_endpt, EXT_ENDPT)
typedef enum transport_endpt_attr_type_
{