RegisterVppProxySoloTests(VppProxyHttpGetTcpMTTest, VppProxyHttpPutTcpMTTest, VppProxyTcpIperfMTTest,
VppProxyUdpIperfMTTest, VppConnectProxyStressTest, VppConnectProxyStressMTTest)
RegisterVppUdpProxyTests(VppProxyUdpTest)
+ RegisterVppUdpProxySoloTests(VppProxyUdpMigrationMTTest)
RegisterEnvoyProxyTests(EnvoyProxyHttpGetTcpTest, EnvoyProxyHttpPutTcpTest)
RegisterNginxProxyTests(NginxMirroringTest)
RegisterNginxProxySoloTests(MirrorMultiThreadTest)
s.AssertNil(err, fmt.Sprint(err))
s.AssertEqual([]byte("hello"), b[:n])
}
+
+func VppProxyUdpMigrationMTTest(s *VppUdpProxySuite) {
+ remoteServerConn := s.StartEchoServer()
+ defer remoteServerConn.Close()
+
+ vppProxy := s.Containers.VppProxy.VppInstance
+ cmd := fmt.Sprintf("test proxy server fifo-size 512k server-uri udp://%s/%d", s.VppProxyAddr(), s.ProxyPort())
+ cmd += fmt.Sprintf(" client-uri udp://%s/%d", s.ServerAddr(), s.ServerPort())
+ s.Log(vppProxy.Vppctl(cmd))
+
+ b := make([]byte, 1500)
+
+ n, err := s.ClientSendReceive([]byte("hello"), b)
+ s.AssertNil(err, fmt.Sprint(err))
+ s.AssertEqual([]byte("hello"), b[:n])
+
+ n, err = s.ClientSendReceive([]byte("world"), b)
+ s.AssertNil(err, fmt.Sprint(err))
+ s.AssertEqual([]byte("world"), b[:n])
+
+ s.Log(s.Containers.VppProxy.VppInstance.Vppctl("show session verbose 2"))
+}
#define TCP_MSS 1460
+#define PROXY_DEBUG 0
+
+#if PROXY_DEBUG
+#define PROXY_DBG(_fmt, _args...) clib_warning (_fmt, ##_args)
+#else
+#define PROXY_DBG(_fmt, _args...)
+#endif
+
static proxy_session_side_ctx_t *
proxy_session_side_ctx_alloc (proxy_worker_t *wrk)
{
clib_spinlock_lock_if_init (&pm->sessions_lock);
+ PROXY_DBG ("[%u] ps %u postponed free", vlib_get_thread_index (), ps_index);
+
ps = proxy_session_get (ps_index);
segment_manager_dealloc_fifos (ps->po.rx_fifo, ps->po.tx_fifo);
proxy_session_free (ps);
wrk = proxy_worker_get (s->thread_index);
sc = proxy_session_side_ctx_get (wrk, s->opaque);
+ PROXY_DBG ("[%u] ps %u close (is ao %u)", vlib_get_thread_index (),
+ sc->ps_index, is_active_open);
+
clib_spinlock_lock_if_init (&pm->sessions_lock);
ps = proxy_session_get (sc->ps_index);
if (sc->state == PROXY_SC_S_CREATED)
return;
+ PROXY_DBG ("[%u] ps %u side ctx cleanup", vlib_get_thread_index (),
+ sc->ps_index);
clib_spinlock_lock_if_init (&pm->sessions_lock);
ps = proxy_session_get (sc->ps_index);
sc = proxy_session_side_ctx_get (wrk, s->opaque);
ps_index = sc->ps_index;
+ PROXY_DBG ("[%u] ps %u delete (is ao %u)", vlib_get_thread_index (),
+ sc->ps_index, is_active_open);
+
proxy_session_side_ctx_free (wrk, sc);
clib_spinlock_lock_if_init (&pm->sessions_lock);
ps = proxy_session_alloc ();
+ PROXY_DBG ("[%u] ps %u new", vlib_get_thread_index (), ps->ps_index);
+
ps->po.session_handle = session_handle (s);
ps->po.rx_fifo = s->rx_fifo;
ps->po.tx_fifo = s->tx_fifo;
if (sc->state == PROXY_SC_S_CREATED)
{
+ PROXY_DBG ("[%u] ps %u start connect", vlib_get_thread_index (),
+ sc->ps_index);
proxy_session_start_connect (sc, s);
sc->state = PROXY_SC_S_CONNECTING;
return 0;
svm_fifo_t *rxf, *txf;
proxy_session_t *ps;
+ PROXY_DBG ("[%u] ps %u ao alloc fifos", vlib_get_thread_index (), s->opaque);
+
clib_spinlock_lock_if_init (&pm->sessions_lock);
/* Active open opaque is pointing at proxy session */
/* Connection failed */
if (err)
{
+ PROXY_DBG ("[%u] ps %u connect failed: %d", vlib_get_thread_index (),
+ opaque, err);
clib_spinlock_lock_if_init (&pm->sessions_lock);
ps = proxy_session_get (opaque);
return 0;
}
+ PROXY_DBG ("[%u] ps %u connected", vlib_get_thread_index (), opaque);
+
wrk = proxy_worker_get (s->thread_index);
clib_spinlock_lock_if_init (&pm->sessions_lock);
proxy_session_t *ps;
session_t *po_s;
+ PROXY_DBG ("[%u] ps %u migrate (po fixup)", vlib_get_thread_index (),
+ ps_index);
+
wrk = proxy_worker_get (vlib_get_thread_index ());
clib_spinlock_lock_if_init (&pm->sessions_lock);
ps = proxy_session_get (ps_index);
po_s = session_get_from_handle (ps->po.session_handle);
- po_s->rx_fifo = ps->po.rx_fifo;
- po_s->tx_fifo = ps->po.tx_fifo;
po_sc = proxy_session_side_ctx_get (wrk, po_s->opaque);
po_sc->pair = ps->ao;
proxy_session_t *ps;
session_t *s;
+ PROXY_DBG ("[%u] ps %u migrate (alloc new sc)", vlib_get_thread_index (),
+ ps_index);
+
wrk = proxy_worker_get (vlib_get_thread_index ());
sc = proxy_session_side_ctx_alloc (wrk);
s->opaque = sc->sc_index;
s->flags &= ~SESSION_F_IS_MIGRATING;
- /* Fixup passive open session because of migration and zc */
- ps->ao.rx_fifo = ps->po.tx_fifo = s->rx_fifo;
- ps->ao.tx_fifo = ps->po.rx_fifo = s->tx_fifo;
-
- ps->po.tx_fifo->shr->master_session_index =
- session_index_from_handle (ps->po.session_handle);
- ps->po.tx_fifo->master_thread_index =
- session_thread_from_handle (ps->po.session_handle);
-
sc->pair = ps->po;
clib_spinlock_unlock_if_init (&pm->sessions_lock);
wrk = proxy_worker_get (s->thread_index);
sc = proxy_session_side_ctx_get (wrk, s->opaque);
+ PROXY_DBG ("[%u] ps %u migrate (free sc)", vlib_get_thread_index (),
+ sc->ps_index);
+
/* NOTE: this is just an example. ZC makes this migration rather
* tedious. Probably better approaches could be found */
clib_spinlock_lock_if_init (&pm->sessions_lock);
ps = proxy_session_get (sc->ps_index);
ps->ao.session_handle = new_sh;
- ps->ao.rx_fifo = 0;
- ps->ao.tx_fifo = 0;
+ ps->ao.tx_fifo->shr->master_session_index =
+ session_index_from_handle (new_sh);
+ ps->ao.tx_fifo->master_thread_index = session_thread_from_handle (new_sh);
clib_spinlock_unlock_if_init (&pm->sessions_lock);
if (!app_wrk)
goto app_closed;
- /* Cleanup fifo segment slice state for fifos */
- sm = app_worker_get_connect_segment_manager (app_wrk);
- segment_manager_detach_fifo (sm, &s->rx_fifo);
- segment_manager_detach_fifo (sm, &s->tx_fifo);
+ if (!(s->flags & SESSION_F_PROXY))
+ {
+ /* Cleanup fifo segment slice state for fifos */
+ sm = app_worker_get_connect_segment_manager (app_wrk);
+ segment_manager_detach_fifo (sm, &s->rx_fifo);
+ segment_manager_detach_fifo (sm, &s->tx_fifo);
+ }
/* Check if session closed during migration */
if (s->session_state >= SESSION_STATE_TRANSPORT_CLOSING)
session_lookup_add_connection (tc, session_handle (new_s));
app_wrk = app_worker_get_if_valid (new_s->app_wrk_index);
- if (app_wrk)
+ if (app_wrk && !(new_s->flags & SESSION_F_PROXY))
{
/* New set of fifos attached to the same shared memory */
sm = app_worker_get_connect_segment_manager (app_wrk);