FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
session_node.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <math.h>
17 #include <vlib/vlib.h>
18 #include <vnet/vnet.h>
19 #include <vppinfra/elog.h>
20 #include <vnet/session/transport.h>
21 #include <vnet/session/session.h>
26 #include <svm/queue.h>
27 #include <sys/timerfd.h>
28 
29 #define app_check_thread_and_barrier(_fn, _arg) \
30  if (!vlib_thread_is_main_w_barrier ()) \
31  { \
32  vlib_rpc_call_main_thread (_fn, (u8 *) _arg, sizeof(*_arg)); \
33  return; \
34  }
35 
36 static void
38 {
39  struct itimerspec its;
40 
41  its.it_value.tv_sec = 0;
42  its.it_value.tv_nsec = time_ns;
43  its.it_interval.tv_sec = 0;
44  its.it_interval.tv_nsec = its.it_value.tv_nsec;
45 
46  if (timerfd_settime (wrk->timerfd, 0, &its, NULL) == -1)
47  clib_warning ("timerfd_settime");
48 }
49 
52 {
54  return thread_index ? 1e6 : vlib_num_workers () ? 5e8 : 1e6;
55  else if (state == SESSION_WRK_IDLE)
56  return thread_index ? 1e8 : vlib_num_workers () ? 5e8 : 1e8;
57  else
58  return 0;
59 }
60 
61 static inline void
63 {
64  u64 time_ns;
65 
66  wrk->state = state;
67  if (wrk->timerfd == -1)
68  return;
71 }
72 
75 {
77  fifo_segment_t *fs;
78 
80  c = fs_chunk_ptr (fs->h, offset);
81  return (transport_endpt_ext_cfg_t *) c->data;
82 }
83 
84 static void
86 {
88  fifo_segment_t *fs;
89 
91  c = fs_chunk_ptr (fs->h, offset);
92  fifo_segment_collect_chunk (fs, 0 /* only one slice */, c);
93 }
94 
95 static void
97 {
99  vnet_listen_args_t _a, *a = &_a;
100  app_worker_t *app_wrk;
101  application_t *app;
102  int rv;
103 
105 
106  app = application_lookup (mp->client_index);
107  if (!app)
108  return;
109 
110  clib_memset (a, 0, sizeof (*a));
111  a->sep.is_ip4 = mp->is_ip4;
112  ip_copy (&a->sep.ip, &mp->ip, mp->is_ip4);
113  a->sep.port = mp->port;
114  a->sep.fib_index = mp->vrf;
115  a->sep.sw_if_index = ENDPOINT_INVALID_INDEX;
116  a->sep.transport_proto = mp->proto;
117  a->app_index = app->app_index;
118  a->wrk_map_index = mp->wrk_index;
119  a->sep_ext.transport_flags = mp->flags;
120 
121  if (mp->ext_config)
122  a->sep_ext.ext_cfg = session_mq_get_ext_config (app, mp->ext_config);
123 
124  if ((rv = vnet_listen (a)))
125  clib_warning ("listen returned: %U", format_session_error, rv);
126 
127  app_wrk = application_get_worker (app, mp->wrk_index);
128  mq_send_session_bound_cb (app_wrk->wrk_index, mp->context, a->handle, rv);
129 
130  if (mp->ext_config)
132 }
133 
134 static void
136 {
138  vnet_listen_args_t _a, *a = &_a;
139  app_worker_t *app_wrk;
140  application_t *app;
141  int rv;
142 
144 
145  app = application_lookup (mp->client_index);
146  if (!app)
147  return;
148 
149  clib_memset (a, 0, sizeof (*a));
150  a->uri = (char *) mp->uri;
151  a->app_index = app->app_index;
152  rv = vnet_bind_uri (a);
153 
154  app_wrk = application_get_worker (app, 0);
155  mq_send_session_bound_cb (app_wrk->wrk_index, mp->context, a->handle, rv);
156 }
157 
158 static void
160 {
161  vnet_connect_args_t _a, *a = &_a;
162  app_worker_t *app_wrk;
163  application_t *app;
164  int rv;
165 
166  app = application_lookup (mp->client_index);
167  if (!app)
168  return;
169 
170  clib_memset (a, 0, sizeof (*a));
171  a->sep.is_ip4 = mp->is_ip4;
172  clib_memcpy_fast (&a->sep.ip, &mp->ip, sizeof (mp->ip));
173  a->sep.port = mp->port;
174  a->sep.transport_proto = mp->proto;
175  a->sep.peer.fib_index = mp->vrf;
176  clib_memcpy_fast (&a->sep.peer.ip, &mp->lcl_ip, sizeof (mp->lcl_ip));
177  if (mp->is_ip4)
178  {
179  ip46_address_mask_ip4 (&a->sep.ip);
180  ip46_address_mask_ip4 (&a->sep.peer.ip);
181  }
182  a->sep.peer.port = mp->lcl_port;
183  a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX;
184  a->sep_ext.parent_handle = mp->parent_handle;
185  a->sep_ext.transport_flags = mp->flags;
186  a->api_context = mp->context;
187  a->app_index = app->app_index;
188  a->wrk_map_index = mp->wrk_index;
189 
190  if (mp->ext_config)
191  a->sep_ext.ext_cfg = session_mq_get_ext_config (app, mp->ext_config);
192 
193  if ((rv = vnet_connect (a)))
194  {
195  clib_warning ("connect returned: %U", format_session_error, rv);
196  app_wrk = application_get_worker (app, mp->wrk_index);
197  mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, rv);
198  }
199 
200  if (mp->ext_config)
202 }
203 
204 static void
206 {
207  u32 max_connects = 32, n_connects = 0;
209  session_evt_elt_t *he, *elt, *next;
210  session_worker_t *fwrk, *wrk;
211 
212  ASSERT (vlib_get_thread_index () == 0);
213 
214  /* Pending connects on linked list pertaining to first worker */
215  fwrk = session_main_get_worker (1);
216  if (!fwrk->n_pending_connects)
217  goto update_state;
218 
220 
221  he = clib_llist_elt (fwrk->event_elts, fwrk->pending_connects);
222  elt = clib_llist_next (fwrk->event_elts, evt_list, he);
223 
224  /* Avoid holding the barrier for too long */
225  while (n_connects < max_connects && elt != he)
226  {
227  next = clib_llist_next (fwrk->event_elts, evt_list, elt);
228  clib_llist_remove (fwrk->event_elts, evt_list, elt);
231  clib_llist_put (fwrk->event_elts, elt);
232  elt = next;
233  n_connects += 1;
234  }
235 
236  /* Decrement with worker barrier */
237  fwrk->n_pending_connects -= n_connects;
238 
240 
241 update_state:
242 
243  /* Switch worker to poll mode if it was in interrupt mode and had work or
244  * back to interrupt if threshold of loops without a connect is passed.
245  * While in poll mode, reprogram connects rpc */
247  if (wrk->state != SESSION_WRK_POLLING)
248  {
249  if (n_connects)
250  {
253  VLIB_NODE_STATE_POLLING);
254  wrk->no_connect_loops = 0;
255  }
256  }
257  else
258  {
259  if (!n_connects)
260  {
261  if (++wrk->no_connect_loops > 1e5)
262  {
265  VLIB_NODE_STATE_INTERRUPT);
266  }
267  }
268  else
269  wrk->no_connect_loops = 0;
270  }
271 
272  if (wrk->state == SESSION_WRK_POLLING)
273  {
275  elt->evt.event_type = SESSION_CTRL_EVT_RPC;
276  elt->evt.rpc_args.fp = session_mq_handle_connects_rpc;
277  }
278 }
279 
280 static void
282 {
284  session_evt_elt_t *he;
285 
286  /* No workers, so just deal with the connect now */
288  {
290  return;
291  }
292 
293  if (PREDICT_FALSE (thread_index != 1))
294  {
295  clib_warning ("Connect on wrong thread. Dropping");
296  return;
297  }
298 
299  /* Add to pending list to be handled by main thread */
301  clib_llist_add_tail (wrk->event_elts, evt_list, elt, he);
302 
303  /* Decremented with worker barrier */
304  wrk->n_pending_connects += 1;
305  if (wrk->n_pending_connects == 1)
306  {
308  session_queue_node.index);
310  }
311 }
312 
313 static void
315 {
317  vnet_connect_args_t _a, *a = &_a;
318  app_worker_t *app_wrk;
319  application_t *app;
320  int rv;
321 
323 
324  app = application_lookup (mp->client_index);
325  if (!app)
326  return;
327 
328  clib_memset (a, 0, sizeof (*a));
329  a->uri = (char *) mp->uri;
330  a->api_context = mp->context;
331  a->app_index = app->app_index;
332  if ((rv = vnet_connect_uri (a)))
333  {
334  clib_warning ("connect_uri returned: %d", rv);
335  app_wrk = application_get_worker (app, 0 /* default wrk only */ );
336  mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, rv);
337  }
338 }
339 
340 static void
342 {
344  vnet_shutdown_args_t _a, *a = &_a;
345  application_t *app;
346 
347  app = application_lookup (mp->client_index);
348  if (!app)
349  return;
350 
351  a->app_index = app->app_index;
352  a->handle = mp->handle;
354 }
355 
356 static void
358 {
360  vnet_disconnect_args_t _a, *a = &_a;
361  application_t *app;
362 
363  app = application_lookup (mp->client_index);
364  if (!app)
365  return;
366 
367  a->app_index = app->app_index;
368  a->handle = mp->handle;
370 }
371 
372 static void
374 {
376  vnet_app_detach_args_t _a, *a = &_a;
377  application_t *app;
378 
380 
381  app = application_lookup (mp->client_index);
382  if (!app)
383  return;
384 
385  a->app_index = app->app_index;
386  a->api_client_index = mp->client_index;
388 }
389 
390 static void
392 {
394  vnet_unlisten_args_t _a, *a = &_a;
395  app_worker_t *app_wrk;
396  session_handle_t sh;
397  application_t *app;
398  u32 context;
399  int rv;
400 
401  sh = mp->handle;
402  context = mp->context;
403 
404  app = application_lookup (mp->client_index);
405  if (!app)
406  return;
407 
408  clib_memset (a, 0, sizeof (*a));
409  a->app_index = app->app_index;
410  a->handle = sh;
411  a->wrk_map_index = mp->wrk_index;
412 
414 
415  if ((rv = vnet_unlisten (a)))
416  clib_warning ("unlisten returned: %d", rv);
417 
419 
420  app_wrk = application_get_worker (app, a->wrk_map_index);
421  if (!app_wrk)
422  return;
423 
424  mq_send_unlisten_reply (app_wrk, sh, context, rv);
425  clib_mem_free (mp);
426 }
427 
428 static void
430 {
432  session_unlisten_msg_t *mp, *arg;
433 
434  mp = session_evt_ctrl_data (wrk, elt);
435  arg = clib_mem_alloc (sizeof (session_unlisten_msg_t));
436  clib_memcpy_fast (arg, mp, sizeof (*arg));
437 
439  {
441  return;
442  }
443 
445 }
446 
447 static void
449 {
451  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
452  session_state_t old_state;
453  app_worker_t *app_wrk;
454  session_t *s;
455 
456  /* Server isn't interested, kill the session */
457  if (mp->retval)
458  {
459  a->app_index = mp->context;
460  a->handle = mp->handle;
462  return;
463  }
464 
465  /* Mail this back from the main thread. We're not polling in main
466  * thread so we're using other workers for notifications. */
467  if (vlib_num_workers () && vlib_get_thread_index () != 0
468  && session_thread_from_handle (mp->handle) == 0)
469  {
471  (u8 *) mp, sizeof (*mp));
472  return;
473  }
474 
476  if (!s)
477  return;
478 
479  app_wrk = app_worker_get (s->app_wrk_index);
480  if (app_wrk->app_index != mp->context)
481  {
482  clib_warning ("app doesn't own session");
483  return;
484  }
485 
486  if (!session_has_transport (s))
487  {
488  s->session_state = SESSION_STATE_READY;
489  if (ct_session_connect_notify (s, SESSION_E_NONE))
490  return;
491  }
492  else
493  {
494  old_state = s->session_state;
495  s->session_state = SESSION_STATE_READY;
496 
499 
500  /* Closed while waiting for app to reply. Resend disconnect */
501  if (old_state >= SESSION_STATE_TRANSPORT_CLOSING)
502  {
503  app_worker_close_notify (app_wrk, s);
504  s->session_state = old_state;
505  return;
506  }
507  }
508 }
509 
510 static void
512 {
513  vnet_disconnect_args_t _a = { 0 }, *a = &_a;
515  app_worker_t *app_wrk;
516  session_t *s;
517  application_t *app;
519 
521  app = application_lookup (mp->context);
522  if (!app)
523  return;
524 
527 
528  /* No session or not the right session */
529  if (!s || s->session_state < SESSION_STATE_TRANSPORT_CLOSING)
530  return;
531 
532  app_wrk = app_worker_get (s->app_wrk_index);
533  if (!app_wrk || app_wrk->app_index != app->app_index)
534  {
535  clib_warning ("App %u does not own handle 0x%lx!", app->app_index,
536  mp->handle);
537  return;
538  }
539 
540  /* Client objected to resetting the session, log and continue */
541  if (mp->retval)
542  {
543  clib_warning ("client retval %d", mp->retval);
544  return;
545  }
546 
547  /* This comes as a response to a reset, transport only waiting for
548  * confirmation to remove connection state, no need to disconnect */
549  a->handle = mp->handle;
550  a->app_index = app->app_index;
552 }
553 
554 static void
556 {
558  vnet_disconnect_args_t _a, *a = &_a;
559  svm_msg_q_msg_t _msg, *msg = &_msg;
561  app_worker_t *app_wrk;
562  session_event_t *evt;
563  session_t *s;
564  application_t *app;
565  int rv = 0;
566 
568  if (!(s = session_get_from_handle_if_valid (mp->handle)))
569  {
570  clib_warning ("could not disconnect handle %llu", mp->handle);
571  return;
572  }
573  app_wrk = app_worker_get (s->app_wrk_index);
574  app = application_lookup (mp->client_index);
575  if (!(app_wrk && app && app->app_index == app_wrk->app_index))
576  {
577  clib_warning ("could not disconnect session: %llu app: %u",
578  mp->handle, mp->client_index);
579  return;
580  }
581 
582  a->handle = mp->handle;
583  a->app_index = app_wrk->wrk_index;
585 
588  SVM_Q_WAIT, msg);
589  evt = svm_msg_q_msg_data (app_wrk->event_queue, msg);
590  clib_memset (evt, 0, sizeof (*evt));
591  evt->event_type = SESSION_CTRL_EVT_DISCONNECTED_REPLY;
592  rmp = (session_disconnected_reply_msg_t *) evt->data;
593  rmp->handle = mp->handle;
594  rmp->context = mp->context;
595  rmp->retval = rv;
596  svm_msg_q_add_and_unlock (app_wrk->event_queue, msg);
597 }
598 
599 static void
601 {
603  vnet_disconnect_args_t _a, *a = &_a;
604  application_t *app;
605 
607 
608  /* Client objected to disconnecting the session, log and continue */
609  if (mp->retval)
610  {
611  clib_warning ("client retval %d", mp->retval);
612  return;
613  }
614 
615  /* Disconnect has been confirmed. Confirm close to transport */
616  app = application_lookup (mp->context);
617  if (app)
618  {
619  a->handle = mp->handle;
620  a->app_index = app->app_index;
622  }
623 }
624 
625 static void
627 {
630  svm_msg_q_msg_t _msg, *msg = &_msg;
631  app_worker_t *app_wrk;
632  u32 owner_app_wrk_map;
633  session_event_t *evt;
634  session_t *s;
635  application_t *app;
636 
637  app = application_lookup (mp->client_index);
638  if (!app)
639  return;
640  if (!(s = session_get_from_handle_if_valid (mp->handle)))
641  {
642  clib_warning ("invalid handle %llu", mp->handle);
643  return;
644  }
645  app_wrk = app_worker_get (s->app_wrk_index);
646  if (app_wrk->app_index != app->app_index)
647  {
648  clib_warning ("app %u does not own session %llu", app->app_index,
649  mp->handle);
650  return;
651  }
652  owner_app_wrk_map = app_wrk->wrk_map_index;
653  app_wrk = application_get_worker (app, mp->wrk_index);
654 
655  /* This needs to come from the new owner */
656  if (mp->req_wrk_index == owner_app_wrk_map)
657  {
659 
662  SVM_Q_WAIT, msg);
663  evt = svm_msg_q_msg_data (app_wrk->event_queue, msg);
664  clib_memset (evt, 0, sizeof (*evt));
665  evt->event_type = SESSION_CTRL_EVT_REQ_WORKER_UPDATE;
666  wump = (session_req_worker_update_msg_t *) evt->data;
667  wump->session_handle = mp->handle;
668  svm_msg_q_add_and_unlock (app_wrk->event_queue, msg);
669  return;
670  }
671 
672  app_worker_own_session (app_wrk, s);
673 
674  /*
675  * Send reply
676  */
679  SVM_Q_WAIT, msg);
680  evt = svm_msg_q_msg_data (app_wrk->event_queue, msg);
681  clib_memset (evt, 0, sizeof (*evt));
682  evt->event_type = SESSION_CTRL_EVT_WORKER_UPDATE_REPLY;
683  rmp = (session_worker_update_reply_msg_t *) evt->data;
684  rmp->handle = mp->handle;
685  if (s->rx_fifo)
687  if (s->tx_fifo)
690  svm_msg_q_add_and_unlock (app_wrk->event_queue, msg);
691 
692  /*
693  * Retransmit messages that may have been lost
694  */
695  if (s->tx_fifo && !svm_fifo_is_empty (s->tx_fifo))
697 
698  if (s->rx_fifo && !svm_fifo_is_empty (s->rx_fifo))
700 
701  if (s->session_state >= SESSION_STATE_TRANSPORT_CLOSING)
702  app_worker_close_notify (app_wrk, s);
703 }
704 
705 static void
707 {
709  svm_msg_q_msg_t _msg, *msg = &_msg;
711  app_worker_t *app_wrk;
712  session_event_t *evt;
713  application_t *app;
714 
715  app = application_lookup (mp->client_index);
716  if (!app)
717  return;
718 
719  app_wrk = application_get_worker (app, mp->wrk_index);
720 
723  msg);
724  evt = svm_msg_q_msg_data (app_wrk->event_queue, msg);
725  clib_memset (evt, 0, sizeof (*evt));
726  evt->event_type = SESSION_CTRL_EVT_APP_WRK_RPC;
727  rmp = (session_app_wrk_rpc_msg_t *) evt->data;
728  clib_memcpy (rmp->data, mp->data, sizeof (mp->data));
729  svm_msg_q_add_and_unlock (app_wrk->event_queue, msg);
730 }
731 
732 static void
734 {
737  svm_msg_q_msg_t _msg, *msg = &_msg;
738  app_worker_t *app_wrk;
739  session_event_t *evt;
740  application_t *app;
741  session_t *s;
742  int rv;
743 
744  app = application_lookup (mp->client_index);
745  if (!app)
746  return;
747 
748  if (!(s = session_get_from_handle_if_valid (mp->handle)))
749  {
750  clib_warning ("invalid handle %llu", mp->handle);
751  return;
752  }
753  app_wrk = app_worker_get (s->app_wrk_index);
754  if (app_wrk->app_index != app->app_index)
755  {
756  clib_warning ("app %u does not own session %llu", app->app_index,
757  mp->handle);
758  return;
759  }
760 
761  rv = session_transport_attribute (s, mp->is_get, &mp->attr);
762 
765  evt = svm_msg_q_msg_data (app_wrk->event_queue, msg);
766  clib_memset (evt, 0, sizeof (*evt));
767  evt->event_type = SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY;
768  rmp = (session_transport_attr_reply_msg_t *) evt->data;
769  rmp->handle = mp->handle;
770  rmp->retval = rv;
771  rmp->is_get = mp->is_get;
772  if (!rv && mp->is_get)
773  rmp->attr = mp->attr;
774  svm_msg_q_add_and_unlock (app_wrk->event_queue, msg);
775 }
776 
778 
779 typedef struct
780 {
784 
785 /* packet trace format function */
786 static u8 *
787 format_session_queue_trace (u8 * s, va_list * args)
788 {
789  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
790  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
791  session_queue_trace_t *t = va_arg (*args, session_queue_trace_t *);
792 
793  s = format (s, "session index %d thread index %d",
795  return s;
796 }
797 
798 #define foreach_session_queue_error \
799 _(TX, "Packets transmitted") \
800 _(TIMER, "Timer events") \
801 _(NO_BUFFER, "Out of buffers")
802 
803 typedef enum
804 {
805 #define _(sym,str) SESSION_QUEUE_ERROR_##sym,
807 #undef _
810 
811 static char *session_queue_error_strings[] = {
812 #define _(sym,string) string,
814 #undef _
815 };
816 
817 enum
818 {
822 };
823 
824 static void
826  u32 next_index, u32 * to_next, u16 n_segs,
827  session_t * s, u32 n_trace)
828 {
829  while (n_trace && n_segs)
830  {
831  vlib_buffer_t *b = vlib_get_buffer (vm, to_next[0]);
832  if (PREDICT_TRUE
834  (vm, node, next_index, b, 1 /* follow_chain */ )))
835  {
837  vlib_add_trace (vm, node, b, sizeof (*t));
840  n_trace--;
841  }
842  to_next++;
843  n_segs--;
844  }
845  vlib_set_trace_count (vm, node, n_trace);
846 }
847 
848 always_inline void
850  vlib_buffer_t * b, u16 * n_bufs, u8 peek_data)
851 {
852  vlib_buffer_t *chain_b, *prev_b;
853  u32 chain_bi0, to_deq, left_from_seg;
854  u16 len_to_deq, n_bytes_read;
855  u8 *data, j;
856 
857  b->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
859 
860  chain_b = b;
861  left_from_seg = clib_min (ctx->sp.snd_mss - b->current_length,
862  ctx->left_to_snd);
863  to_deq = left_from_seg;
864  for (j = 1; j < ctx->n_bufs_per_seg; j++)
865  {
866  prev_b = chain_b;
867  len_to_deq = clib_min (to_deq, ctx->deq_per_buf);
868 
869  *n_bufs -= 1;
870  chain_bi0 = ctx->tx_buffers[*n_bufs];
871  chain_b = vlib_get_buffer (vm, chain_bi0);
872  chain_b->current_data = 0;
873  data = vlib_buffer_get_current (chain_b);
874  if (peek_data)
875  {
876  n_bytes_read = svm_fifo_peek (ctx->s->tx_fifo,
877  ctx->sp.tx_offset, len_to_deq, data);
878  ctx->sp.tx_offset += n_bytes_read;
879  }
880  else
881  {
882  if (ctx->transport_vft->transport_options.tx_type ==
884  {
885  svm_fifo_t *f = ctx->s->tx_fifo;
886  session_dgram_hdr_t *hdr = &ctx->hdr;
887  u16 deq_now;
888  u32 offset;
889 
890  deq_now = clib_min (hdr->data_length - hdr->data_offset,
891  len_to_deq);
893  n_bytes_read = svm_fifo_peek (f, offset, deq_now, data);
894  ASSERT (n_bytes_read > 0);
895 
896  hdr->data_offset += n_bytes_read;
897  if (hdr->data_offset == hdr->data_length)
898  {
901  if (ctx->left_to_snd > n_bytes_read)
902  svm_fifo_peek (ctx->s->tx_fifo, 0, sizeof (ctx->hdr),
903  (u8 *) & ctx->hdr);
904  }
905  else if (ctx->left_to_snd == n_bytes_read)
906  svm_fifo_overwrite_head (ctx->s->tx_fifo, (u8 *) & ctx->hdr,
907  sizeof (session_dgram_pre_hdr_t));
908  }
909  else
910  n_bytes_read = svm_fifo_dequeue (ctx->s->tx_fifo,
911  len_to_deq, data);
912  }
913  ASSERT (n_bytes_read == len_to_deq);
914  chain_b->current_length = n_bytes_read;
916 
917  /* update previous buffer */
918  prev_b->next_buffer = chain_bi0;
919  prev_b->flags |= VLIB_BUFFER_NEXT_PRESENT;
920 
921  /* update current buffer */
922  chain_b->next_buffer = 0;
923 
924  to_deq -= n_bytes_read;
925  if (to_deq == 0)
926  break;
927  }
928  ASSERT (to_deq == 0
929  && b->total_length_not_including_first_buffer == left_from_seg);
930  ctx->left_to_snd -= left_from_seg;
931 }
932 
933 always_inline void
935  vlib_buffer_t * b, u16 * n_bufs, u8 peek_data)
936 {
937  u32 len_to_deq;
938  u8 *data0;
939  int n_bytes_read;
940 
941  /*
942  * Start with the first buffer in chain
943  */
944  b->error = 0;
945  b->flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
946  b->current_data = 0;
947 
949  len_to_deq = clib_min (ctx->left_to_snd, ctx->deq_per_first_buf);
950 
951  if (peek_data)
952  {
953  n_bytes_read = svm_fifo_peek (ctx->s->tx_fifo, ctx->sp.tx_offset,
954  len_to_deq, data0);
955  ASSERT (n_bytes_read > 0);
956  /* Keep track of progress locally, transport is also supposed to
957  * increment it independently when pushing the header */
958  ctx->sp.tx_offset += n_bytes_read;
959  }
960  else
961  {
962  if (ctx->transport_vft->transport_options.tx_type == TRANSPORT_TX_DGRAM)
963  {
964  session_dgram_hdr_t *hdr = &ctx->hdr;
965  svm_fifo_t *f = ctx->s->tx_fifo;
966  u16 deq_now;
967  u32 offset;
968 
969  ASSERT (hdr->data_length > hdr->data_offset);
970  deq_now = clib_min (hdr->data_length - hdr->data_offset,
971  len_to_deq);
973  n_bytes_read = svm_fifo_peek (f, offset, deq_now, data0);
974  ASSERT (n_bytes_read > 0);
975 
977  {
978  ip_copy (&ctx->tc->rmt_ip, &hdr->rmt_ip, ctx->tc->is_ip4);
979  ctx->tc->rmt_port = hdr->rmt_port;
980  }
981  hdr->data_offset += n_bytes_read;
982  if (hdr->data_offset == hdr->data_length)
983  {
986  if (ctx->left_to_snd > n_bytes_read)
987  svm_fifo_peek (ctx->s->tx_fifo, 0, sizeof (ctx->hdr),
988  (u8 *) & ctx->hdr);
989  }
990  else if (ctx->left_to_snd == n_bytes_read)
991  svm_fifo_overwrite_head (ctx->s->tx_fifo, (u8 *) & ctx->hdr,
992  sizeof (session_dgram_pre_hdr_t));
993  }
994  else
995  {
996  n_bytes_read = svm_fifo_dequeue (ctx->s->tx_fifo,
997  len_to_deq, data0);
998  ASSERT (n_bytes_read > 0);
999  }
1000  }
1001  b->current_length = n_bytes_read;
1002  ctx->left_to_snd -= n_bytes_read;
1003 
1004  /*
1005  * Fill in the remaining buffers in the chain, if any
1006  */
1007  if (PREDICT_FALSE (ctx->n_bufs_per_seg > 1 && ctx->left_to_snd))
1008  session_tx_fifo_chain_tail (vm, ctx, b, n_bufs, peek_data);
1009 }
1010 
1013 {
1014  if (peek_data)
1015  {
1016  if (PREDICT_TRUE (s->session_state == SESSION_STATE_READY))
1017  return 0;
1018  /* Can retransmit for closed sessions but can't send new data if
1019  * session is not ready or closed */
1020  else if (s->session_state < SESSION_STATE_READY)
1021  {
1022  /* Allow accepting session to send custom packets.
1023  * For instance, tcp want to send acks in established, but
1024  * the app has not called accept() yet */
1025  if (s->session_state == SESSION_STATE_ACCEPTING &&
1026  (s->flags & SESSION_F_CUSTOM_TX))
1027  return 0;
1028  return 1;
1029  }
1030  else if (s->session_state >= SESSION_STATE_TRANSPORT_CLOSED)
1031  {
1032  /* Allow closed transports to still send custom packets.
1033  * For instance, tcp may want to send acks in time-wait. */
1034  if (s->session_state != SESSION_STATE_TRANSPORT_DELETED
1035  && (s->flags & SESSION_F_CUSTOM_TX))
1036  return 0;
1037  return 2;
1038  }
1039  }
1040  return 0;
1041 }
1042 
1045 {
1046  if (peek_data)
1047  {
1048  return ctx->transport_vft->get_connection (ctx->s->connection_index,
1049  ctx->s->thread_index);
1050  }
1051  else
1052  {
1053  if (ctx->s->session_state == SESSION_STATE_LISTENING)
1054  return ctx->transport_vft->get_listener (ctx->s->connection_index);
1055  else
1056  {
1057  return ctx->transport_vft->get_connection (ctx->s->connection_index,
1058  ctx->s->thread_index);
1059  }
1060  }
1061 }
1062 
1063 always_inline void
1065  u32 max_segs, u8 peek_data)
1066 {
1067  u32 n_bytes_per_buf, n_bytes_per_seg;
1068 
1069  n_bytes_per_buf = vlib_buffer_get_default_data_size (vm);
1070  ctx->max_dequeue = svm_fifo_max_dequeue_cons (ctx->s->tx_fifo);
1071 
1072  if (peek_data)
1073  {
1074  /* Offset in rx fifo from where to peek data */
1075  if (PREDICT_FALSE (ctx->sp.tx_offset >= ctx->max_dequeue))
1076  {
1077  ctx->max_len_to_snd = 0;
1078  return;
1079  }
1080  ctx->max_dequeue -= ctx->sp.tx_offset;
1081  }
1082  else
1083  {
1084  if (ctx->transport_vft->transport_options.tx_type == TRANSPORT_TX_DGRAM)
1085  {
1086  u32 len, chain_limit;
1087 
1088  if (ctx->max_dequeue <= sizeof (ctx->hdr))
1089  {
1090  ctx->max_len_to_snd = 0;
1091  return;
1092  }
1093 
1094  svm_fifo_peek (ctx->s->tx_fifo, 0, sizeof (ctx->hdr),
1095  (u8 *) & ctx->hdr);
1096  ASSERT (ctx->hdr.data_length > ctx->hdr.data_offset);
1097  len = ctx->hdr.data_length - ctx->hdr.data_offset;
1098 
1099  /* Process multiple dgrams if smaller than min (buf_space, mss).
1100  * This avoids handling multiple dgrams if they require buffer
1101  * chains */
1102  chain_limit = clib_min (n_bytes_per_buf - TRANSPORT_MAX_HDRS_LEN,
1103  ctx->sp.snd_mss);
1104  if (ctx->hdr.data_length <= chain_limit)
1105  {
1106  u32 first_dgram_len, dgram_len, offset, max_offset;
1107  session_dgram_hdr_t hdr;
1108 
1109  ctx->sp.snd_mss = clib_min (ctx->sp.snd_mss, len);
1110  offset = ctx->hdr.data_length + sizeof (session_dgram_hdr_t);
1111  first_dgram_len = len;
1112  max_offset = clib_min (ctx->max_dequeue, 16 << 10);
1113 
1114  while (offset < max_offset)
1115  {
1116  svm_fifo_peek (ctx->s->tx_fifo, offset, sizeof (ctx->hdr),
1117  (u8 *) & hdr);
1118  ASSERT (hdr.data_length > hdr.data_offset);
1119  dgram_len = hdr.data_length - hdr.data_offset;
1120  if (len + dgram_len > ctx->max_dequeue
1121  || first_dgram_len != dgram_len)
1122  break;
1123  len += dgram_len;
1124  offset += sizeof (hdr) + hdr.data_length;
1125  }
1126  }
1127 
1128  ctx->max_dequeue = len;
1129  }
1130  }
1131  ASSERT (ctx->max_dequeue > 0);
1132 
1133  /* Ensure we're not writing more than transport window allows */
1134  if (ctx->max_dequeue < ctx->sp.snd_space)
1135  {
1136  /* Constrained by tx queue. Try to send only fully formed segments */
1137  ctx->max_len_to_snd = (ctx->max_dequeue > ctx->sp.snd_mss) ?
1138  (ctx->max_dequeue - (ctx->max_dequeue % ctx->sp.snd_mss)) :
1139  ctx->max_dequeue;
1140  /* TODO Nagle ? */
1141  }
1142  else
1143  {
1144  /* Expectation is that snd_space0 is already a multiple of snd_mss */
1145  ctx->max_len_to_snd = ctx->sp.snd_space;
1146  }
1147 
1148  /* Check if we're tx constrained by the node */
1149  ctx->n_segs_per_evt = ceil ((f64) ctx->max_len_to_snd / ctx->sp.snd_mss);
1150  if (ctx->n_segs_per_evt > max_segs)
1151  {
1152  ctx->n_segs_per_evt = max_segs;
1153  ctx->max_len_to_snd = max_segs * ctx->sp.snd_mss;
1154  }
1155 
1156  ASSERT (n_bytes_per_buf > TRANSPORT_MAX_HDRS_LEN);
1157  if (ctx->n_segs_per_evt > 1)
1158  {
1159  u32 n_bytes_last_seg, n_bufs_last_seg;
1160 
1161  n_bytes_per_seg = TRANSPORT_MAX_HDRS_LEN + ctx->sp.snd_mss;
1162  n_bytes_last_seg = TRANSPORT_MAX_HDRS_LEN + ctx->max_len_to_snd
1163  - ((ctx->n_segs_per_evt - 1) * ctx->sp.snd_mss);
1164  ctx->n_bufs_per_seg = ceil ((f64) n_bytes_per_seg / n_bytes_per_buf);
1165  n_bufs_last_seg = ceil ((f64) n_bytes_last_seg / n_bytes_per_buf);
1166  ctx->n_bufs_needed = ((ctx->n_segs_per_evt - 1) * ctx->n_bufs_per_seg)
1167  + n_bufs_last_seg;
1168  }
1169  else
1170  {
1171  n_bytes_per_seg = TRANSPORT_MAX_HDRS_LEN + ctx->max_len_to_snd;
1172  ctx->n_bufs_per_seg = ceil ((f64) n_bytes_per_seg / n_bytes_per_buf);
1173  ctx->n_bufs_needed = ctx->n_bufs_per_seg;
1174  }
1175 
1176  ctx->deq_per_buf = clib_min (ctx->sp.snd_mss, n_bytes_per_buf);
1177  ctx->deq_per_first_buf = clib_min (ctx->sp.snd_mss,
1178  n_bytes_per_buf -
1180 }
1181 
1182 always_inline void
1186 {
1187  session_t *s = ctx->s;
1188 
1190  if (svm_fifo_max_dequeue_cons (s->tx_fifo) > ctx->sp.tx_offset)
1191  if (svm_fifo_set_event (s->tx_fifo))
1193 }
1194 
1195 always_inline int
1199  int *n_tx_packets, u8 peek_data)
1200 {
1201  u32 n_trace, n_left, pbi, next_index, max_burst;
1203  session_main_t *smm = &session_main;
1204  session_event_t *e = &elt->evt;
1205  vlib_main_t *vm = wrk->vm;
1206  transport_proto_t tp;
1207  vlib_buffer_t *pb;
1208  u16 n_bufs, rv;
1209 
1210  if (PREDICT_FALSE ((rv = session_tx_not_ready (ctx->s, peek_data))))
1211  {
1212  if (rv < 2)
1214  return SESSION_TX_NO_DATA;
1215  }
1216 
1217  next_index = smm->session_type_to_next[ctx->s->session_type];
1218  max_burst = SESSION_NODE_FRAME_SIZE - *n_tx_packets;
1219 
1220  tp = session_get_transport_proto (ctx->s);
1221  ctx->transport_vft = transport_protocol_get_vft (tp);
1222  ctx->tc = session_tx_get_transport (ctx, peek_data);
1223 
1224  if (PREDICT_FALSE (e->event_type == SESSION_IO_EVT_TX_FLUSH))
1225  {
1226  if (ctx->transport_vft->flush_data)
1227  ctx->transport_vft->flush_data (ctx->tc);
1228  e->event_type = SESSION_IO_EVT_TX;
1229  }
1230 
1231  if (ctx->s->flags & SESSION_F_CUSTOM_TX)
1232  {
1233  u32 n_custom_tx;
1234  ctx->s->flags &= ~SESSION_F_CUSTOM_TX;
1235  ctx->sp.max_burst_size = max_burst;
1236  n_custom_tx = ctx->transport_vft->custom_tx (ctx->tc, &ctx->sp);
1237  *n_tx_packets += n_custom_tx;
1238  if (PREDICT_FALSE
1239  (ctx->s->session_state >= SESSION_STATE_TRANSPORT_CLOSED))
1240  return SESSION_TX_OK;
1241  max_burst -= n_custom_tx;
1242  if (!max_burst || (ctx->s->flags & SESSION_F_CUSTOM_TX))
1243  {
1245  return SESSION_TX_OK;
1246  }
1247  }
1248 
1250 
1251  if (!ctx->sp.snd_space)
1252  {
1253  /* If the deschedule flag was set, remove session from scheduler.
1254  * Transport is responsible for rescheduling this session. */
1255  if (ctx->sp.flags & TRANSPORT_SND_F_DESCHED)
1257  /* Request to postpone the session, e.g., zero-wnd and transport
1258  * is not currently probing */
1259  else if (ctx->sp.flags & TRANSPORT_SND_F_POSTPONE)
1261  /* This flow queue is "empty" so it should be re-evaluated before
1262  * the ones that have data to send. */
1263  else
1265 
1266  return SESSION_TX_NO_DATA;
1267  }
1268 
1270  {
1271  u32 snd_space = transport_connection_tx_pacer_burst (ctx->tc);
1272  if (snd_space < TRANSPORT_PACER_MIN_BURST)
1273  {
1275  return SESSION_TX_NO_DATA;
1276  }
1277  snd_space = clib_min (ctx->sp.snd_space, snd_space);
1278  ctx->sp.snd_space = snd_space >= ctx->sp.snd_mss ?
1279  snd_space - snd_space % ctx->sp.snd_mss : snd_space;
1280  }
1281 
1282  /* Check how much we can pull. */
1283  session_tx_set_dequeue_params (vm, ctx, max_burst, peek_data);
1284 
1285  if (PREDICT_FALSE (!ctx->max_len_to_snd))
1286  {
1289  return SESSION_TX_NO_DATA;
1290  }
1291 
1292  vec_validate_aligned (ctx->tx_buffers, ctx->n_bufs_needed - 1,
1294  n_bufs = vlib_buffer_alloc (vm, ctx->tx_buffers, ctx->n_bufs_needed);
1295  if (PREDICT_FALSE (n_bufs < ctx->n_bufs_needed))
1296  {
1297  if (n_bufs)
1298  vlib_buffer_free (vm, ctx->tx_buffers, n_bufs);
1300  vlib_node_increment_counter (wrk->vm, node->node_index,
1301  SESSION_QUEUE_ERROR_NO_BUFFER, 1);
1302  return SESSION_TX_NO_BUFFERS;
1303  }
1304 
1306  transport_connection_tx_pacer_update_bytes (ctx->tc, ctx->max_len_to_snd);
1307 
1308  ctx->left_to_snd = ctx->max_len_to_snd;
1309  n_left = ctx->n_segs_per_evt;
1310 
1311  while (n_left >= 4)
1312  {
1313  vlib_buffer_t *b0, *b1;
1314  u32 bi0, bi1;
1315 
1316  pbi = ctx->tx_buffers[n_bufs - 3];
1317  pb = vlib_get_buffer (vm, pbi);
1318  vlib_prefetch_buffer_header (pb, STORE);
1319  pbi = ctx->tx_buffers[n_bufs - 4];
1320  pb = vlib_get_buffer (vm, pbi);
1321  vlib_prefetch_buffer_header (pb, STORE);
1322 
1323  bi0 = ctx->tx_buffers[--n_bufs];
1324  bi1 = ctx->tx_buffers[--n_bufs];
1325 
1326  b0 = vlib_get_buffer (vm, bi0);
1327  b1 = vlib_get_buffer (vm, bi1);
1328 
1329  session_tx_fill_buffer (vm, ctx, b0, &n_bufs, peek_data);
1330  session_tx_fill_buffer (vm, ctx, b1, &n_bufs, peek_data);
1331 
1332  ctx->transport_vft->push_header (ctx->tc, b0);
1333  ctx->transport_vft->push_header (ctx->tc, b1);
1334 
1335  n_left -= 2;
1336 
1341  }
1342  while (n_left)
1343  {
1344  vlib_buffer_t *b0;
1345  u32 bi0;
1346 
1347  if (n_left > 1)
1348  {
1349  pbi = ctx->tx_buffers[n_bufs - 2];
1350  pb = vlib_get_buffer (vm, pbi);
1351  vlib_prefetch_buffer_header (pb, STORE);
1352  }
1353 
1354  bi0 = ctx->tx_buffers[--n_bufs];
1355  b0 = vlib_get_buffer (vm, bi0);
1356  session_tx_fill_buffer (vm, ctx, b0, &n_bufs, peek_data);
1357 
1358  /* Ask transport to push header after current_length and
1359  * total_length_not_including_first_buffer are updated */
1360  ctx->transport_vft->push_header (ctx->tc, b0);
1361 
1362  n_left -= 1;
1363 
1366  }
1367 
1368  if (PREDICT_FALSE ((n_trace = vlib_get_trace_count (vm, node)) > 0))
1370  ctx->n_segs_per_evt, ctx->s, n_trace);
1371 
1372  if (PREDICT_FALSE (n_bufs))
1373  vlib_buffer_free (vm, ctx->tx_buffers, n_bufs);
1374 
1375  *n_tx_packets += ctx->n_segs_per_evt;
1376 
1377  SESSION_EVT (SESSION_EVT_DEQ, ctx->s, ctx->max_len_to_snd, ctx->max_dequeue,
1378  ctx->s->tx_fifo->has_event, wrk->last_vlib_time);
1379 
1380  ASSERT (ctx->left_to_snd == 0);
1381 
1382  /* If we couldn't dequeue all bytes reschedule as old flow. Otherwise,
1383  * check if application enqueued more data and reschedule accordingly */
1384  if (ctx->max_len_to_snd < ctx->max_dequeue)
1386  else
1388 
1389  if (!peek_data)
1390  {
1391  u32 n_dequeued = ctx->max_len_to_snd;
1392  if (ctx->transport_vft->transport_options.tx_type == TRANSPORT_TX_DGRAM)
1393  n_dequeued += ctx->n_segs_per_evt * SESSION_CONN_HDR_LEN;
1394  if (svm_fifo_needs_deq_ntf (ctx->s->tx_fifo, n_dequeued))
1396  }
1397  return SESSION_TX_OK;
1398 }
1399 
1400 int
1403  session_evt_elt_t * e, int *n_tx_packets)
1404 {
1405  return session_tx_fifo_read_and_snd_i (wrk, node, e, n_tx_packets, 1);
1406 }
1407 
1408 int
1411  session_evt_elt_t * e, int *n_tx_packets)
1412 {
1413  return session_tx_fifo_read_and_snd_i (wrk, node, e, n_tx_packets, 0);
1414 }
1415 
1416 int
1419  session_evt_elt_t * elt, int *n_tx_packets)
1420 {
1422  session_t *s = wrk->ctx.s;
1423  u32 n_packets;
1424 
1425  if (PREDICT_FALSE (s->session_state >= SESSION_STATE_TRANSPORT_CLOSED))
1426  return 0;
1427 
1428  /* Clear custom-tx flag used to request reschedule for tx */
1429  s->flags &= ~SESSION_F_CUSTOM_TX;
1430 
1431  sp->max_burst_size = clib_min (SESSION_NODE_FRAME_SIZE - *n_tx_packets,
1433 
1434  n_packets = transport_custom_tx (session_get_transport_proto (s), s, sp);
1435  *n_tx_packets += n_packets;
1436 
1437  if (s->flags & SESSION_F_CUSTOM_TX)
1438  {
1440  }
1441  else if (!(sp->flags & TRANSPORT_SND_F_DESCHED))
1442  {
1445  if (svm_fifo_set_event (s->tx_fifo))
1447  }
1448 
1449  if (sp->max_burst_size &&
1452 
1453  return n_packets;
1454 }
1455 
1458 {
1460  return 0;
1461 
1462  ASSERT (session_is_valid (e->session_index, wrk->vm->thread_index));
1464 }
1465 
1466 always_inline void
1468 {
1469  clib_llist_index_t ei;
1470  void (*fp) (void *);
1471  session_event_t *e;
1472  session_t *s;
1473 
1475  e = &elt->evt;
1476 
1477  switch (e->event_type)
1478  {
1479  case SESSION_CTRL_EVT_RPC:
1480  fp = e->rpc_args.fp;
1481  (*fp) (e->rpc_args.arg);
1482  break;
1484  s = session_get_from_handle_if_valid (e->session_handle);
1485  if (PREDICT_FALSE (!s))
1486  break;
1488  break;
1490  s = session_get_from_handle_if_valid (e->session_handle);
1491  if (PREDICT_FALSE (!s))
1492  break;
1494  break;
1496  s = session_get_from_handle_if_valid (e->session_handle);
1497  if (PREDICT_FALSE (!s))
1498  break;
1500  break;
1503  break;
1506  break;
1509  break;
1512  break;
1515  break;
1518  break;
1521  break;
1524  break;
1527  break;
1530  elt));
1531  break;
1534  break;
1537  break;
1540  break;
1543  break;
1546  break;
1547  default:
1548  clib_warning ("unhandled event type %d", e->event_type);
1549  }
1550 
1551  /* Regrab elements in case pool moved */
1552  elt = clib_llist_elt (wrk->event_elts, ei);
1553  if (!clib_llist_elt_is_linked (elt, evt_list))
1554  {
1555  e = &elt->evt;
1556  if (e->event_type >= SESSION_CTRL_EVT_BOUND)
1559  }
1560  SESSION_EVT (SESSION_EVT_COUNTS, CNT_CTRL_EVTS, 1, wrk);
1561 }
1562 
1563 always_inline void
1565  session_evt_elt_t * elt, int *n_tx_packets)
1566 {
1567  session_main_t *smm = &session_main;
1568  app_worker_t *app_wrk;
1569  clib_llist_index_t ei;
1570  session_event_t *e;
1571  session_t *s;
1572 
1574  e = &elt->evt;
1575 
1576  switch (e->event_type)
1577  {
1579  case SESSION_IO_EVT_TX:
1580  s = session_event_get_session (wrk, e);
1581  if (PREDICT_FALSE (!s))
1582  break;
1583  CLIB_PREFETCH (s->tx_fifo, sizeof (*(s->tx_fifo)), LOAD);
1584  wrk->ctx.s = s;
1585  /* Spray packets in per session type frames, since they go to
1586  * different nodes */
1587  (smm->session_tx_fns[s->session_type]) (wrk, node, elt, n_tx_packets);
1588  break;
1589  case SESSION_IO_EVT_RX:
1590  s = session_event_get_session (wrk, e);
1591  if (!s)
1592  break;
1595  break;
1597  s = session_event_get_session (wrk, e);
1598  if (PREDICT_FALSE (!s || s->session_state >= SESSION_STATE_CLOSING))
1599  break;
1601  app_wrk = app_worker_get (s->app_wrk_index);
1602  app_worker_builtin_rx (app_wrk, s);
1603  break;
1605  s = session_get_from_handle_if_valid (e->session_handle);
1606  wrk->ctx.s = s;
1607  if (PREDICT_TRUE (s != 0))
1608  session_tx_fifo_dequeue_internal (wrk, node, elt, n_tx_packets);
1609  break;
1610  default:
1611  clib_warning ("unhandled event type %d", e->event_type);
1612  }
1613 
1614  SESSION_EVT (SESSION_IO_EVT_COUNTS, e->event_type, 1, wrk);
1615 
1616  /* Regrab elements in case pool moved */
1617  elt = clib_llist_elt (wrk->event_elts, ei);
1618  if (!clib_llist_elt_is_linked (elt, evt_list))
1620 }
1621 
1622 /* *INDENT-OFF* */
1623 static const u32 session_evt_msg_sizes[] = {
1624 #define _(symc, sym) \
1625  [SESSION_CTRL_EVT_ ## symc] = sizeof (session_ ## sym ##_msg_t),
1627 #undef _
1628 };
1629 /* *INDENT-ON* */
1630 
1631 always_inline void
1633 {
1635 
1636  if (evt->event_type >= SESSION_CTRL_EVT_RPC)
1637  {
1639  if (evt->event_type >= SESSION_CTRL_EVT_BOUND)
1640  {
1641  elt->evt.ctrl_data_index = session_evt_ctrl_data_alloc (wrk);
1642  elt->evt.event_type = evt->event_type;
1644  session_evt_msg_sizes[evt->event_type]);
1645  }
1646  else
1647  {
1648  /* Internal control events fit into io events footprint */
1649  clib_memcpy_fast (&elt->evt, evt, sizeof (elt->evt));
1650  }
1651  }
1652  else
1653  {
1655  clib_memcpy_fast (&elt->evt, evt, sizeof (elt->evt));
1656  }
1657 }
1658 
1659 static void
1662 {
1668 }
1669 
1670 int
1672 {
1673  svm_msg_q_msg_t _msg, *msg = &_msg;
1674  u32 i, n_to_dequeue = 0;
1675  session_event_t *evt;
1676 
1677  n_to_dequeue = svm_msg_q_size (mq);
1678  for (i = 0; i < n_to_dequeue; i++)
1679  {
1680  svm_msg_q_sub_raw (mq, msg);
1681  evt = svm_msg_q_msg_data (mq, msg);
1683  svm_msg_q_free_msg (mq, msg);
1684  }
1685 
1686  return n_to_dequeue;
1687 }
1688 
1689 static void
1691 {
1692  vlib_main_t *vm = wrk->vm;
1693 
1694  if (wrk->state == SESSION_WRK_POLLING)
1695  {
1696  if (clib_llist_elts (wrk->event_elts) == 4 &&
1698  {
1701  VLIB_NODE_STATE_INTERRUPT);
1702  }
1703  }
1704  else if (wrk->state == SESSION_WRK_INTERRUPT)
1705  {
1706  if (clib_llist_elts (wrk->event_elts) > 4 ||
1708  {
1711  VLIB_NODE_STATE_POLLING);
1712  }
1713  else if (PREDICT_FALSE (!pool_elts (wrk->sessions)))
1714  {
1716  }
1717  }
1718  else
1719  {
1721  {
1723  }
1724  }
1725 }
1726 
1727 static uword
1729  vlib_frame_t * frame)
1730 {
1731  u32 thread_index = vm->thread_index, __clib_unused n_evts;
1732  session_evt_elt_t *elt, *ctrl_he, *new_he, *old_he;
1735  clib_llist_index_t ei, next_ei, old_ti;
1736  int n_tx_packets;
1737 
1738  SESSION_EVT (SESSION_EVT_DISPATCH_START, wrk);
1739 
1741 
1742  /*
1743  * Update transport time
1744  */
1746  n_tx_packets = vec_len (wrk->pending_tx_buffers);
1747  SESSION_EVT (SESSION_EVT_DSP_CNTRS, UPDATE_TIME, wrk);
1748 
1749  /*
1750  * Dequeue new internal mq events
1751  */
1752 
1754  SESSION_EVT (SESSION_EVT_DSP_CNTRS, MQ_DEQ, wrk, n_evts);
1755 
1756  /*
1757  * Handle control events
1758  */
1759 
1760  ei = wrk->ctrl_head;
1761  ctrl_he = clib_llist_elt (wrk->event_elts, ei);
1762  next_ei = clib_llist_next_index (ctrl_he, evt_list);
1763  old_ti = clib_llist_prev_index (ctrl_he, evt_list);
1764  while (ei != old_ti)
1765  {
1766  ei = next_ei;
1767  elt = clib_llist_elt (wrk->event_elts, next_ei);
1768  next_ei = clib_llist_next_index (elt, evt_list);
1769  clib_llist_remove (wrk->event_elts, evt_list, elt);
1771  }
1772 
1773  SESSION_EVT (SESSION_EVT_DSP_CNTRS, CTRL_EVTS, wrk);
1774 
1775  /*
1776  * Handle the new io events.
1777  */
1778 
1779  new_he = clib_llist_elt (wrk->event_elts, wrk->new_head);
1780  old_he = clib_llist_elt (wrk->event_elts, wrk->old_head);
1781  old_ti = clib_llist_prev_index (old_he, evt_list);
1782 
1783  ei = clib_llist_next_index (new_he, evt_list);
1784  while (ei != wrk->new_head && n_tx_packets < SESSION_NODE_FRAME_SIZE)
1785  {
1786  elt = clib_llist_elt (wrk->event_elts, ei);
1787  ei = clib_llist_next_index (elt, evt_list);
1788  clib_llist_remove (wrk->event_elts, evt_list, elt);
1789  session_event_dispatch_io (wrk, node, elt, &n_tx_packets);
1790  }
1791 
1792  SESSION_EVT (SESSION_EVT_DSP_CNTRS, NEW_IO_EVTS, wrk);
1793 
1794  /*
1795  * Handle the old io events, if we had any prior to processing the new ones
1796  */
1797 
1798  if (old_ti != wrk->old_head)
1799  {
1800  old_he = clib_llist_elt (wrk->event_elts, wrk->old_head);
1801  ei = clib_llist_next_index (old_he, evt_list);
1802 
1803  while (n_tx_packets < SESSION_NODE_FRAME_SIZE)
1804  {
1805  elt = clib_llist_elt (wrk->event_elts, ei);
1806  next_ei = clib_llist_next_index (elt, evt_list);
1807  clib_llist_remove (wrk->event_elts, evt_list, elt);
1808 
1809  session_event_dispatch_io (wrk, node, elt, &n_tx_packets);
1810 
1811  if (ei == old_ti)
1812  break;
1813 
1814  ei = next_ei;
1815  };
1816  }
1817 
1818  SESSION_EVT (SESSION_EVT_DSP_CNTRS, OLD_IO_EVTS, wrk);
1819 
1822 
1824  SESSION_QUEUE_ERROR_TX, n_tx_packets);
1825 
1826  SESSION_EVT (SESSION_EVT_DISPATCH_END, wrk, n_tx_packets);
1827 
1830 
1831  return n_tx_packets;
1832 }
1833 
1834 /* *INDENT-OFF* */
1836 {
1837  .function = session_queue_node_fn,
1839  .name = "session-queue",
1840  .format_trace = format_session_queue_trace,
1841  .type = VLIB_NODE_TYPE_INPUT,
1842  .n_errors = ARRAY_LEN (session_queue_error_strings),
1843  .error_strings = session_queue_error_strings,
1844  .state = VLIB_NODE_STATE_DISABLED,
1845 };
1846 /* *INDENT-ON* */
1847 
1848 static clib_error_t *
1850 {
1852  u64 buf;
1853  int rv;
1854 
1856  rv = read (wrk->timerfd, &buf, sizeof (buf));
1857  if (rv < 0 && errno != EAGAIN)
1858  clib_unix_warning ("failed");
1859  return 0;
1860 }
1861 
1862 static clib_error_t *
1864 {
1865  return 0;
1866 }
1867 
1868 void
1870 {
1872  clib_file_t template = { 0 };
1873 
1874  if ((wrk->timerfd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK)) < 0)
1875  clib_warning ("timerfd_create");
1876 
1877  template.read_function = session_wrk_tfd_read_ready;
1878  template.write_function = session_wrk_tfd_write_ready;
1879  template.file_descriptor = wrk->timerfd;
1880  template.private_data = thread_index;
1881  template.polling_thread_index = thread_index;
1882  template.description = format (0, "session-wrk-tfd-%u", thread_index);
1883 
1884  wrk->timerfd_file = clib_file_add (&file_main, &template);
1886 }
1887 
1888 static clib_error_t *
1890 {
1891  if (vlib_get_n_threads () < 2)
1892  return 0;
1893 
1894  /*
1895  * Shut off (especially) worker-thread session nodes.
1896  * Otherwise, vpp can crash as the main thread unmaps the
1897  * API segment.
1898  */
1900  session_node_enable_disable (0 /* is_enable */ );
1902  return 0;
1903 }
1904 
1906 
1907 static uword
1909 {
1911 
1913  return session_queue_node_fn (vm, node, 0);
1914 }
1915 
1916 static uword
1918  vlib_frame_t * f)
1919 {
1920  uword *event_data = 0;
1921  f64 timeout = 1.0;
1922  uword event_type;
1923 
1924  while (1)
1925  {
1927  event_type = vlib_process_get_events (vm, (uword **) & event_data);
1928 
1929  switch (event_type)
1930  {
1932  /* Run session queue node on main thread */
1934  break;
1937  VLIB_NODE_STATE_DISABLED);
1938  timeout = 100000.0;
1939  break;
1940  case ~0:
1941  /* Timed out. Run on main to ensure all events are handled */
1943  break;
1944  }
1945  vec_reset_length (event_data);
1946  }
1947  return 0;
1948 }
1949 
1950 /* *INDENT-OFF* */
1952 {
1953  .function = session_queue_process,
1954  .type = VLIB_NODE_TYPE_PROCESS,
1955  .name = "session-queue-process",
1956  .state = VLIB_NODE_STATE_DISABLED,
1957 };
1958 /* *INDENT-ON* */
1959 
1962  vlib_frame_t * frame)
1963 {
1965  if (!sm->wrk[0].vpp_event_queue)
1966  return 0;
1968  return session_queue_node_fn (vm, node, frame);
1969 }
1970 
1971 /* *INDENT-OFF* */
1973 {
1974  .function = session_queue_pre_input_inline,
1975  .type = VLIB_NODE_TYPE_PRE_INPUT,
1976  .name = "session-queue-main",
1977  .state = VLIB_NODE_STATE_DISABLED,
1978 };
1979 /* *INDENT-ON* */
1980 
1981 /*
1982  * fd.io coding-style-patch-verification: ON
1983  *
1984  * Local Variables:
1985  * eval: (c-set-style "gnu")
1986  * End:
1987  */
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
session_worker_::timerfd_file
uword timerfd_file
Clib file for timerfd.
Definition: session.h:146
svm_msg_q_size
static u32 svm_msg_q_size(svm_msg_q_t *mq)
Check length of message queue.
Definition: message_queue.h:310
vlib.h
vnet_listen
int vnet_listen(vnet_listen_args_t *a)
Definition: application.c:1294
vlib_buffer_t::next_buffer
u32 next_buffer
Next buffer for this linked-list of buffers.
Definition: buffer.h:149
SESSION_CTRL_EVT_SHUTDOWN
@ SESSION_CTRL_EVT_SHUTDOWN
Definition: session_types.h:348
session_tx_trace_frame
static void session_tx_trace_frame(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 *to_next, u16 n_segs, session_t *s, u32 n_trace)
Definition: session_node.c:825
session_worker_update_reply_msg_::segment_handle
u64 segment_handle
Definition: application_interface.h:505
TRANSPORT_SND_F_POSTPONE
@ TRANSPORT_SND_F_POSTPONE
Definition: transport.h:41
session_connect_msg_::context
u32 context
Definition: application_interface.h:399
session_queue_run_on_main
static uword session_queue_run_on_main(vlib_main_t *vm)
Definition: session_node.c:1908
svm_fifo_set_event
static u8 svm_fifo_set_event(svm_fifo_t *f)
Set fifo event flag.
Definition: svm_fifo.h:733
session_tx_context_
Definition: session.h:42
vlib_buffer_free
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:979
SESSION_CTRL_EVT_RPC
@ SESSION_CTRL_EVT_RPC
Definition: session_types.h:333
vlib_num_workers
static u32 vlib_num_workers()
Definition: threads.h:333
app_worker_::wrk_index
u32 wrk_index
Worker index in global worker pool.
Definition: application.h:37
file_main
clib_file_main_t file_main
Definition: main.c:63
vlib_worker_thread_barrier_release
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1375
session_dgram_header_::data_length
u32 data_length
Definition: session_types.h:439
ip46_address_mask_ip4
static void ip46_address_mask_ip4(ip46_address_t *ip46)
Definition: ip46_address.h:61
clib_llist_next_index
#define clib_llist_next_index(E, name)
Definition: llist.h:107
session_app_detach_msg_
Definition: application_interface.h:508
session_mq_shutdown_handler
static void session_mq_shutdown_handler(void *data)
Definition: session_node.c:341
session_worker_::ctx
session_tx_context_t ctx
Context for session tx.
Definition: session.h:119
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:495
session_worker_update_reply_msg_::tx_fifo
uword tx_fifo
Definition: application_interface.h:504
vnet_connect
int vnet_connect(vnet_connect_args_t *a)
Definition: application.c:1348
session_unlisten_msg_
Definition: application_interface.h:359
session_tx_context_::s
session_t * s
Definition: session.h:45
session_dgram_header_
Definition: session_types.h:437
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
vlib_prefetch_buffer_header
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:231
session_dequeue_notify
int session_dequeue_notify(session_t *s)
Definition: session.c:816
clib_llist_remove
#define clib_llist_remove(LP, name, E)
Remove entry from list.
Definition: llist.h:231
session_wrk_tfd_timeout
static u64 session_wrk_tfd_timeout(session_wrk_state_t state, u32 thread_index)
Definition: session_node.c:51
transport_protocol_get_vft
transport_proto_vft_t * transport_protocol_get_vft(transport_proto_t transport_proto)
Get transport virtual function table.
Definition: transport.c:282
session_unlisten_msg_::wrk_index
u32 wrk_index
Definition: application_interface.h:363
session_::session_index
u32 session_index
Index in thread pool where session was allocated.
Definition: session_types.h:188
session_worker_update_reply_msg_::handle
u64 handle
Definition: application_interface.h:502
svm_fifo_unset_event
static void svm_fifo_unset_event(svm_fifo_t *f)
Unset fifo event flag.
Definition: svm_fifo.h:746
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
svm_msg_q_add_and_unlock
void svm_msg_q_add_and_unlock(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Producer enqueue one message to queue with mutex held.
Definition: message_queue.c:394
session_transport_half_close
void session_transport_half_close(session_t *s)
Notify transport the session can be half-disconnected.
Definition: session.c:1533
session_listen_uri_msg_::client_index
u32 client_index
Definition: application_interface.h:336
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
session_tx_context_::sp
transport_send_params_t sp
Definition: session.h:48
VLIB_NODE_TYPE_PRE_INPUT
@ VLIB_NODE_TYPE_PRE_INPUT
Definition: node.h:81
elog.h
session_queue_exit
static clib_error_t * session_queue_exit(vlib_main_t *vm)
Definition: session_node.c:1889
session_queue_pre_input_node
vlib_node_registration_t session_queue_pre_input_node
(constructor) VLIB_REGISTER_NODE (session_queue_pre_input_node)
Definition: session_node.c:1972
SESSION_TX_OK
@ SESSION_TX_OK
Definition: session_node.c:821
SESSION_CTRL_EVT_WORKER_UPDATE
@ SESSION_CTRL_EVT_WORKER_UPDATE
Definition: session_types.h:346
session_parse_handle
static void session_parse_handle(session_handle_t handle, u32 *index, u32 *thread_index)
Definition: session_types.h:301
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
session_connect_msg_::lcl_port
u16 lcl_port
Definition: application_interface.h:403
f
vlib_frame_t * f
Definition: interface_output.c:1098
vlib_node_set_state
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
Definition: node_funcs.h:175
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
session_req_worker_update_msg_
Definition: application_interface.h:486
vnet_unlisten
int vnet_unlisten(vnet_unlisten_args_t *a)
Definition: application.c:1387
session_worker_::timerfd
int timerfd
Timerfd used to periodically signal wrk session queue node.
Definition: session.h:110
session_shutdown_msg_::handle
session_handle_t handle
Definition: application_interface.h:448
session_wrk_update_time
static void session_wrk_update_time(session_worker_t *wrk, f64 now)
Definition: session.h:757
transport_update_time
void transport_update_time(clib_time_type_t time_now, u8 thread_index)
Definition: transport.c:815
SESSION_CTRL_EVT_DISCONNECTED
@ SESSION_CTRL_EVT_DISCONNECTED
Definition: session_types.h:342
SESSION_WRK_F_ADAPTIVE
@ SESSION_WRK_F_ADAPTIVE
Definition: session.h:84
session_dgram_hdr_t
struct session_dgram_header_ session_dgram_hdr_t
svm_msg_q_msg_data
void * svm_msg_q_msg_data(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Get data for message in queue.
Definition: message_queue.c:287
session_::tx_fifo
svm_fifo_t * tx_fifo
Definition: session_types.h:179
next
u16 * next
Definition: nat44_ei_out2in.c:718
svm_fifo_peek
int svm_fifo_peek(svm_fifo_t *f, u32 offset, u32 len, u8 *dst)
Peek data from fifo.
Definition: svm_fifo.c:1141
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:314
app_mq_detach_handler
static void app_mq_detach_handler(void *data)
Definition: session_node.c:373
svm_fifo_needs_deq_ntf
static u8 svm_fifo_needs_deq_ntf(svm_fifo_t *f, u32 n_last_deq)
Check if fifo needs dequeue notification.
Definition: svm_fifo.h:825
fifo_segment_t
Definition: fifo_segment.h:68
SESSION_CTRL_EVT_CONNECT
@ SESSION_CTRL_EVT_CONNECT
Definition: session_types.h:350
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
session_mq_connect_one
static void session_mq_connect_one(session_connect_msg_t *mp)
Definition: session_node.c:159
session_listen_msg_::proto
u8 proto
Definition: application_interface.h:324
session_segment_handle
u64 session_segment_handle(session_t *s)
Definition: session.c:1680
session_mq_worker_update_handler
static void session_mq_worker_update_handler(void *data)
Definition: session_node.c:626
SESSION_QUEUE_N_ERROR
@ SESSION_QUEUE_N_ERROR
Definition: session_node.c:808
session_
Definition: session_types.h:175
session_mq_unlisten_handler
static void session_mq_unlisten_handler(session_worker_t *wrk, session_evt_elt_t *elt)
Definition: session_node.c:429
transport_connection_is_tx_paced
static u8 transport_connection_is_tx_paced(transport_connection_t *tc)
Check if transport connection is paced.
Definition: transport.h:325
session_listen_msg_
Definition: application_interface.h:317
session_handle_t
u64 session_handle_t
Definition: session_types.h:111
VLIB_NODE_TYPE_INPUT
@ VLIB_NODE_TYPE_INPUT
Definition: node.h:76
wrk
session_worker_t * wrk
Definition: application.c:490
session_queue_trace_t::session_index
u32 session_index
Definition: session_node.c:781
vnet_connect_uri
int vnet_connect_uri(vnet_connect_args_t *a)
Definition: application_interface.c:149
svm_fifo_chunk_
Definition: fifo_types.h:38
session_queue_node_fn
static uword session_queue_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: session_node.c:1728
ct_session_connect_notify
int ct_session_connect_notify(session_t *ss, session_error_t err)
Definition: application_local.c:279
clib_llist_index_t
u32 clib_llist_index_t
Definition: llist.h:27
session_mq_disconnect_handler
static void session_mq_disconnect_handler(void *data)
Definition: session_node.c:357
session_reset_reply_msg_
Definition: application_interface.h:479
session_tx_maybe_reschedule
static void session_tx_maybe_reschedule(session_worker_t *wrk, session_tx_context_t *ctx, session_evt_elt_t *elt)
Definition: session_node.c:1183
session_queue_pre_input_inline
static_always_inline uword session_queue_pre_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: session_node.c:1961
u16
unsigned short u16
Definition: types.h:57
application_::app_index
u32 app_index
App index in app pool.
Definition: application.h:111
session_worker_update_msg_
Definition: application_interface.h:492
session_req_worker_update_msg_::session_handle
u64 session_handle
Definition: application_interface.h:488
SESSION_IO_EVT_RX
@ SESSION_IO_EVT_RX
Definition: session_types.h:328
clib_file::private_data
u64 private_data
Definition: file.h:64
vnet_application_detach
int vnet_application_detach(vnet_app_detach_args_t *a)
Detach application from vpp.
Definition: application.c:1216
svm_msg_q_msg_t
Definition: message_queue.h:93
session_::thread_index
u8 thread_index
Index of the thread that allocated the session.
Definition: session_types.h:194
session_::session_type
session_type_t session_type
Type built from transport and network protocol types.
Definition: session_types.h:182
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
SESSION_Q_PROCESS_RUN_ON_MAIN
@ SESSION_Q_PROCESS_RUN_ON_MAIN
Definition: session.h:254
session_accepted_reply_msg_::handle
u64 handle
Definition: application_interface.h:393
session_queue_error_t
session_queue_error_t
Definition: session_node.c:803
session_transport_attr_reply_msg_::handle
session_handle_t handle
Definition: application_interface.h:564
SESSION_IO_EVT_BUILTIN_TX
@ SESSION_IO_EVT_BUILTIN_TX
Definition: session_types.h:332
clib_llist_elts
#define clib_llist_elts(LP)
Get number of elements in supporting container.
Definition: llist.h:91
state
vl_api_dhcp_client_state_t state
Definition: dhcp.api:201
session_unlisten_msg_::client_index
u32 client_index
Definition: application_interface.h:361
vlib_get_trace_count
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
Definition: trace_funcs.h:212
session_queue_error_strings
static char * session_queue_error_strings[]
Definition: session_node.c:811
vnet_unlisten_args_t
struct _vnet_unlisten_args_t vnet_unlisten_args_t
session_disconnected_msg_::handle
u64 handle
Definition: application_interface.h:462
SESSION_NODE_FRAME_SIZE
#define SESSION_NODE_FRAME_SIZE
Definition: session_types.h:25
application_
Definition: application.h:108
session_thread_from_handle
static u32 session_thread_from_handle(session_handle_t handle)
Definition: session_types.h:295
session_main_::session_type_to_next
u32 * session_type_to_next
Per session type output nodes.
Definition: session.h:190
vnet_app_detach_args_t
struct _vnet_app_detach_args_t vnet_app_detach_args_t
transport_connection_t
struct _transport_connection transport_connection_t
transport_connection_tx_pacer_update_bytes
void transport_connection_tx_pacer_update_bytes(transport_connection_t *tc, u32 bytes)
Definition: transport.c:777
vlib_frame_t
Definition: node.h:372
session_transport_attr_reply_msg_::is_get
u8 is_get
Definition: application_interface.h:566
session_listen_msg_::vrf
u32 vrf
Definition: application_interface.h:322
svm_fifo_is_empty_prod
static int svm_fifo_is_empty_prod(svm_fifo_t *f)
Check if fifo is empty optimized for producer.
Definition: svm_fifo.h:566
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
session_wrk_enable_adaptive_mode
void session_wrk_enable_adaptive_mode(session_worker_t *wrk)
Definition: session_node.c:1869
session_connect_msg_::is_ip4
u8 is_ip4
Definition: application_interface.h:405
session_wrk_set_state
static void session_wrk_set_state(session_worker_t *wrk, session_wrk_state_t state)
Definition: session_node.c:62
session_connect_uri_msg_::uri
u8 uri[56]
Definition: application_interface.h:422
clib_llist_add_tail
#define clib_llist_add_tail(LP, name, E, H)
Add entry after tail.
Definition: llist.h:219
session_worker_::new_head
clib_llist_index_t new_head
Head of list of elements.
Definition: session.h:131
session_worker_update_reply_msg_
Definition: application_interface.h:500
clib_unix_warning
#define clib_unix_warning(format, args...)
Definition: error.h:68
transport_connection_tx_pacer_burst
u32 transport_connection_tx_pacer_burst(transport_connection_t *tc)
Get tx pacer max burst.
Definition: transport.c:757
fifo_segment_collect_chunk
void fifo_segment_collect_chunk(fifo_segment_t *fs, u32 slice_index, svm_fifo_chunk_t *c)
Definition: fifo_segment.c:1066
SESSION_CONN_HDR_LEN
#define SESSION_CONN_HDR_LEN
Definition: session_types.h:449
session_evt_alloc_new
static session_evt_elt_t * session_evt_alloc_new(session_worker_t *wrk)
Definition: session.h:309
session_evt_add_old
static void session_evt_add_old(session_worker_t *wrk, session_evt_elt_t *elt)
Definition: session.h:262
session_tx_fill_buffer
static void session_tx_fill_buffer(vlib_main_t *vm, session_tx_context_t *ctx, vlib_buffer_t *b, u16 *n_bufs, u8 peek_data)
Definition: session_node.c:934
session_main_::wrk
session_worker_t * wrk
Worker contexts.
Definition: session.h:176
vnet_shutdown_args_t
struct _vnet_shutdown_args_t vnet_shutdown_args_t
session_evt_ctrl_data
static void * session_evt_ctrl_data(session_worker_t *wrk, session_evt_elt_t *elt)
Definition: session.h:295
session_disconnected_msg_::client_index
u32 client_index
Definition: application_interface.h:460
session_queue_node
vlib_node_registration_t session_queue_node
(constructor) VLIB_REGISTER_NODE (session_queue_node)
Definition: session_node.c:777
session_worker_::last_vlib_time
clib_time_type_t last_vlib_time
vlib_time_now last time around the track
Definition: session.h:98
session_listen_msg_::context
u32 context
Definition: application_interface.h:320
session_wrk_handle_mq
int session_wrk_handle_mq(session_worker_t *wrk, svm_msg_q_t *mq)
Definition: session_node.c:1671
application_local.h
session_shutdown_msg_
Definition: application_interface.h:444
svm_fifo_t
struct _svm_fifo svm_fifo_t
session_worker_update_reply_msg_::rx_fifo
uword rx_fifo
Definition: application_interface.h:503
session_disconnect_msg_
Definition: application_interface.h:451
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
session_transport_close
void session_transport_close(session_t *s)
Notify transport the session can be disconnected.
Definition: session.c:1553
clib_llist_put
#define clib_llist_put(LP, E)
Free element.
Definition: llist.h:67
CLIB_PREFETCH
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:76
vlib_process_get_events
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type,...
Definition: node_funcs.h:583
session_worker_::pending_tx_buffers
u32 * pending_tx_buffers
Vector of buffers to be sent.
Definition: session.h:140
SESSION_CTRL_EVT_CLOSE
@ SESSION_CTRL_EVT_CLOSE
Definition: session_types.h:335
vlib_buffer_t::current_data
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
session_worker_::no_connect_loops
u32 no_connect_loops
Main thread loops in poll mode without a connect.
Definition: session.h:155
session_::app_wrk_index
u32 app_wrk_index
Index of the app worker that owns the session.
Definition: session_types.h:191
TRANSPORT_SND_F_DESCHED
@ TRANSPORT_SND_F_DESCHED
Definition: transport.h:40
SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY
@ SESSION_CTRL_EVT_TRANSPORT_ATTR_REPLY
Definition: session_types.h:362
svm_fifo_overwrite_head
void svm_fifo_overwrite_head(svm_fifo_t *f, u8 *src, u32 len)
Overwrite fifo head with new data.
Definition: svm_fifo.c:781
session_::rx_fifo
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
Definition: session_types.h:178
session_mq_listen_uri_handler
static void session_mq_listen_uri_handler(void *data)
Definition: session_node.c:135
SESSION_CTRL_EVT_UNLISTEN
@ SESSION_CTRL_EVT_UNLISTEN
Definition: session_types.h:354
SESSION_IO_EVT_BUILTIN_RX
@ SESSION_IO_EVT_BUILTIN_RX
Definition: session_types.h:331
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
session_tx_fifo_dequeue_and_snd
int session_tx_fifo_dequeue_and_snd(session_worker_t *wrk, vlib_node_runtime_t *node, session_evt_elt_t *e, int *n_tx_packets)
Definition: session_node.c:1409
session_evt_msg_sizes
static const u32 session_evt_msg_sizes[]
Definition: session_node.c:1623
math.h
vnet_get_session_main
static session_main_t * vnet_get_session_main()
Definition: session.h:697
session_disconnect_msg_::handle
session_handle_t handle
Definition: application_interface.h:455
transport_connection_tx_pacer_reset_bucket
void transport_connection_tx_pacer_reset_bucket(transport_connection_t *tc, u32 bucket)
Reset tx pacer bucket.
Definition: transport.c:732
len
u8 len
Definition: ip_types.api:103
session_queue_trace_t::server_thread_index
u32 server_thread_index
Definition: session_node.c:782
transport_endpt_ext_cfg_
Definition: transport_types.h:280
session_tx_set_dequeue_params
static void session_tx_set_dequeue_params(vlib_main_t *vm, session_tx_context_t *ctx, u32 max_segs, u8 peek_data)
Definition: session_node.c:1064
vnet_disconnect_args_t
struct _vnet_disconnect_args_t vnet_disconnect_args_t
SESSION_CTRL_EVT_HALF_CLOSE
@ SESSION_CTRL_EVT_HALF_CLOSE
Definition: session_types.h:334
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
session_queue_process
static uword session_queue_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: session_node.c:1917
session_node_enable_disable
void session_node_enable_disable(u8 is_en)
Definition: session.c:1883
clib_llist_elt_is_linked
#define clib_llist_elt_is_linked(E, name)
Check if element is linked in a list.
Definition: llist.h:167
vlib_last_vectors_per_main_loop
static u32 vlib_last_vectors_per_main_loop(vlib_main_t *vm)
Definition: main.h:431
session_listen_uri_msg_
Definition: application_interface.h:334
SESSION_CTRL_EVT_BOUND
@ SESSION_CTRL_EVT_BOUND
Definition: session_types.h:337
session_reset_reply_msg_::retval
i32 retval
Definition: application_interface.h:482
session_worker_update_msg_::req_wrk_index
u16 req_wrk_index
Definition: application_interface.h:496
vlib_buffer_alloc
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: buffer_funcs.h:702
session_accepted_reply_msg_
Definition: application_interface.h:389
session_transport_attr_msg_::is_get
u8 is_get
Definition: application_interface.h:558
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
svm_fifo_dequeue
int svm_fifo_dequeue(svm_fifo_t *f, u32 len, u8 *dst)
Dequeue data from fifo.
Definition: svm_fifo.c:1105
session_disconnected_reply_msg_::context
u32 context
Definition: application_interface.h:467
session_app_wrk_rpc_msg_
Definition: application_interface.h:546
session_evt_elt
Definition: session.h:64
session_worker_update_msg_::wrk_index
u16 wrk_index
Definition: application_interface.h:495
clib_file
Definition: file.h:51
ENDPOINT_INVALID_INDEX
#define ENDPOINT_INVALID_INDEX
Definition: transport_types.h:293
session_connect_msg_::ext_config
uword ext_config
Definition: application_interface.h:412
session_connect_msg_::client_index
u32 client_index
Definition: application_interface.h:398
offset
struct clib_bihash_value offset
template key/value backing page structure
app_worker_close_notify
int app_worker_close_notify(app_worker_t *app_wrk, session_t *s)
Definition: application_worker.c:407
SESSION_CTRL_EVT_LISTEN_URI
@ SESSION_CTRL_EVT_LISTEN_URI
Definition: session_types.h:353
vlib_worker_thread_barrier_sync
#define vlib_worker_thread_barrier_sync(X)
Definition: threads.h:173
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vlib_get_thread_index
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:187
session_mq_connect_handler
static void session_mq_connect_handler(session_worker_t *wrk, session_evt_elt_t *elt)
Definition: session_node.c:281
session_evt_add_to_list
static void session_evt_add_to_list(session_worker_t *wrk, session_event_t *evt)
Definition: session_node.c:1632
clib_llist_entry_index
#define clib_llist_entry_index(LP, E)
Get list entry index.
Definition: llist.h:53
session_shutdown_msg_::client_index
u32 client_index
Definition: application_interface.h:446
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vnet_listen_args_t
struct _vnet_bind_args_t vnet_listen_args_t
session_connect_uri_msg_::client_index
u32 client_index
Definition: application_interface.h:420
vlib_buffer_enqueue_to_next_vec
static_always_inline void vlib_buffer_enqueue_to_next_vec(vlib_main_t *vm, vlib_node_runtime_t *node, u32 **buffers, u16 **nexts, uword count)
Definition: buffer_node.h:359
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
transport_connection_snd_params
static u32 transport_connection_snd_params(transport_connection_t *tc, transport_send_params_t *sp)
Get send parameters for transport connection.
Definition: transport.h:202
session_app_detach_msg_::client_index
u32 client_index
Definition: application_interface.h:510
session_main_::session_tx_fns
session_fifo_rx_fn ** session_tx_fns
Per transport rx function that can either dequeue or peek.
Definition: session.h:185
session_accepted_reply_msg_::retval
i32 retval
Definition: application_interface.h:392
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
static_always_inline
#define static_always_inline
Definition: clib.h:112
session_connect_msg_::lcl_ip
ip46_address_t lcl_ip
Definition: application_interface.h:407
SESSION_CTRL_EVT_LISTEN
@ SESSION_CTRL_EVT_LISTEN
Definition: session_types.h:352
uword
u64 uword
Definition: types.h:112
application_get_rx_mqs_segment
fifo_segment_t * application_get_rx_mqs_segment(application_t *app)
Definition: application.c:683
session_transport_attr_msg_::handle
session_handle_t handle
Definition: application_interface.h:556
clib_llist_next
#define clib_llist_next(LP, name, E)
Get next pool entry.
Definition: llist.h:116
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
SESSION_IO_EVT_TX_FLUSH
@ SESSION_IO_EVT_TX_FLUSH
Definition: session_types.h:330
session_app_wrk_rpc_msg_::data
u8 data[64]
rpc data
Definition: application_interface.h:550
session_disconnected_reply_msg_::retval
i32 retval
Definition: application_interface.h:468
session_tx_fifo_peek_and_snd
int session_tx_fifo_peek_and_snd(session_worker_t *wrk, vlib_node_runtime_t *node, session_evt_elt_t *e, int *n_tx_packets)
Definition: session_node.c:1401
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:215
SESSION_CTRL_EVT_DISCONNECTED_REPLY
@ SESSION_CTRL_EVT_DISCONNECTED_REPLY
Definition: session_types.h:343
session_transport_attr_msg_
Definition: application_interface.h:553
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
session_evt_alloc_ctrl
static session_evt_elt_t * session_evt_alloc_ctrl(session_worker_t *wrk)
Definition: session.h:285
session_mq_accepted_reply_handler
static void session_mq_accepted_reply_handler(void *data)
Definition: session_node.c:448
session_transport_attr_msg_::attr
transport_endpt_attr_t attr
Definition: application_interface.h:557
SESSION_Q_PROCESS_STOP
@ SESSION_Q_PROCESS_STOP
Definition: session.h:255
session_evt_ctrl_data_alloc
static u32 session_evt_ctrl_data_alloc(session_worker_t *wrk)
Definition: session.h:277
session_main
session_main_t session_main
Definition: session.c:25
session_app_wrk_rpc_msg_::client_index
u32 client_index
app client index
Definition: application_interface.h:548
session_connect_msg_::flags
u8 flags
Definition: application_interface.h:411
session_send_rpc_evt_to_thread
void session_send_rpc_evt_to_thread(u32 thread_index, void *fp, void *rpc_args)
Definition: session.c:116
session_disconnected_reply_msg_::handle
u64 handle
Definition: application_interface.h:469
svm_fifo_dequeue_drop
int svm_fifo_dequeue_drop(svm_fifo_t *f, u32 len)
Dequeue and drop bytes from fifo.
Definition: svm_fifo.c:1168
VLIB_NODE_FLAG_TRACE_SUPPORTED
#define VLIB_NODE_FLAG_TRACE_SUPPORTED
Definition: node.h:295
f64
double f64
Definition: types.h:142
transport_custom_tx
static int transport_custom_tx(transport_proto_t tp, void *s, transport_send_params_t *sp)
Definition: transport.h:175
SESSION_TX_NO_BUFFERS
@ SESSION_TX_NO_BUFFERS
Definition: session_node.c:819
session_dgram_header_::data_offset
u32 data_offset
Definition: session_types.h:440
session_get_from_handle_if_valid
static session_t * session_get_from_handle_if_valid(session_handle_t handle)
Definition: session.h:366
session_worker_::flags
session_wrk_flag_t flags
Worker flags.
Definition: session.h:113
format_session_queue_trace
static u8 * format_session_queue_trace(u8 *s, va_list *args)
Definition: session_node.c:787
transport_app_rx_evt
static int transport_app_rx_evt(transport_proto_t tp, u32 conn_index, u32 thread_index)
Definition: transport.h:182
SESSION_IO_EVT_TX
@ SESSION_IO_EVT_TX
Definition: session_types.h:329
session_listen_msg_::client_index
u32 client_index
Definition: application_interface.h:319
SESSION_CTRL_EVT_APP_DETACH
@ SESSION_CTRL_EVT_APP_DETACH
Definition: session_types.h:355
session_listen_uri_msg_::uri
u8 uri[56]
Definition: application_interface.h:338
app_check_thread_and_barrier
#define app_check_thread_and_barrier(_fn, _arg)
Definition: session_node.c:29
SESSION_CTRL_EVT_REQ_WORKER_UPDATE
@ SESSION_CTRL_EVT_REQ_WORKER_UPDATE
Definition: session_types.h:345
app_worker_::event_queue
svm_msg_q_t * event_queue
Application listens for events on this svm queue.
Definition: application.h:46
session_evt_add_head_old
static void session_evt_add_head_old(session_worker_t *wrk, session_evt_elt_t *elt)
Definition: session.h:269
clib_min
#define clib_min(x, y)
Definition: clib.h:342
session_tx_fifo_dequeue_internal
int session_tx_fifo_dequeue_internal(session_worker_t *wrk, vlib_node_runtime_t *node, session_evt_elt_t *elt, int *n_tx_packets)
Definition: session_node.c:1417
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:58
vlib_set_trace_count
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
Definition: trace_funcs.h:226
session_mq_reset_reply_handler
static void session_mq_reset_reply_handler(void *data)
Definition: session_node.c:511
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vnet_disconnect_session
int vnet_disconnect_session(vnet_disconnect_args_t *a)
Definition: application.c:1439
session_wrk_tfd_read_ready
static clib_error_t * session_wrk_tfd_read_ready(clib_file_t *cf)
Definition: session_node.c:1849
svm_msg_q_
Definition: message_queue.h:72
session_reset_reply_msg_::handle
u64 handle
Definition: application_interface.h:483
queue.h
session_listen_msg_::flags
u8 flags
Definition: application_interface.h:327
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
session_tx_fifo_chain_tail
static void session_tx_fifo_chain_tail(vlib_main_t *vm, session_tx_context_t *ctx, vlib_buffer_t *b, u16 *n_bufs, u8 peek_data)
Definition: session_node.c:849
TRANSPORT_MAX_HDRS_LEN
#define TRANSPORT_MAX_HDRS_LEN
Definition: transport_types.h:25
session_worker_::vpp_event_queue
svm_msg_q_t * vpp_event_queue
vpp event message queue for worker
Definition: session.h:95
session_app_wrk_rpc_msg_::wrk_index
u32 wrk_index
dst worker index
Definition: application_interface.h:549
session_disconnected_msg_::context
u32 context
Definition: application_interface.h:461
foreach_session_queue_error
#define foreach_session_queue_error
Definition: session_node.c:798
session_unlisten_msg_::context
u32 context
Definition: application_interface.h:362
session_mq_free_ext_config
static void session_mq_free_ext_config(application_t *app, uword offset)
Definition: session_node.c:85
TRANSPORT_PACER_MAX_BURST_PKTS
#define TRANSPORT_PACER_MAX_BURST_PKTS
Definition: transport.h:25
session_listen_msg_::ext_config
uword ext_config
Definition: application_interface.h:328
SESSION_CTRL_EVT_RESET_REPLY
@ SESSION_CTRL_EVT_RESET_REPLY
Definition: session_types.h:344
transport_send_params_
Definition: transport.h:45
data
u8 data[128]
Definition: ipsec_types.api:95
session_tx_not_ready
static u8 session_tx_not_ready(session_t *s, u8 peek_data)
Definition: session_node.c:1012
session_listen_msg_::ip
ip46_address_t ip
Definition: application_interface.h:326
session_disconnected_msg_
Definition: application_interface.h:458
session_worker_::event_elts
session_evt_elt_t * event_elts
Pool of session event list elements.
Definition: session.h:122
session_connect_msg_::port
u16 port
Definition: application_interface.h:402
index
u32 index
Definition: flow_types.api:221
session_wrk_state_t
enum session_wrk_state_ session_wrk_state_t
session_connect_msg_::wrk_index
u32 wrk_index
Definition: application_interface.h:400
session_mq_listen_handler
static void session_mq_listen_handler(void *data)
Definition: session_node.c:96
svm_msg_q_free_msg
void svm_msg_q_free_msg(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Free message buffer.
Definition: message_queue.c:294
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
clib_bihash_value
template key/value backing page structure
Definition: bihash_doc.h:44
TRANSPORT_TX_DGRAM
@ TRANSPORT_TX_DGRAM
datagram mode
Definition: transport_types.h:33
session_connect_msg_::parent_handle
u64 parent_handle
Definition: application_interface.h:408
session_evt_ctrl_data_free
static void session_evt_ctrl_data_free(session_worker_t *wrk, session_evt_elt_t *elt)
Definition: session.h:302
session_mq_unlisten_rpc
static void session_mq_unlisten_rpc(session_unlisten_msg_t *mp)
Definition: session_node.c:391
application_lookup
application_t * application_lookup(u32 api_client_index)
Definition: application.c:420
session_wrk_tfd_write_ready
static clib_error_t * session_wrk_tfd_write_ready(clib_file_t *cf)
Definition: session_node.c:1863
u64
unsigned long u64
Definition: types.h:89
SESSION_WRK_IDLE
@ SESSION_WRK_IDLE
Definition: session.h:79
session_mq_get_ext_config
static transport_endpt_ext_cfg_t * session_mq_get_ext_config(application_t *app, uword offset)
Definition: session_node.c:74
vlib_process_wait_for_event_or_clock
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:755
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
mq_send_unlisten_reply
void mq_send_unlisten_reply(app_worker_t *app_wrk, session_handle_t sh, u32 context, int rv)
Definition: session_api.c:399
session_connect_uri_msg_::context
u32 context
Definition: application_interface.h:421
session_dgram_header_::rmt_port
u16 rmt_port
Definition: session_types.h:443
session_state_t
session_state_t
Definition: session_types.h:143
SESSION_WRK_POLLING
@ SESSION_WRK_POLLING
Definition: session.h:77
session_connect_msg_
Definition: application_interface.h:396
format_session_error
static u8 * format_session_error(u8 *s, va_list *args)
Definition: application_interface.h:799
session_get_if_valid
static session_t * session_get_if_valid(u64 si, u32 thread_index)
Definition: session.h:344
vlib_buffer_get_default_data_size
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
Definition: buffer_funcs.h:122
session_tx_fifo_read_and_snd_i
static int session_tx_fifo_read_and_snd_i(session_worker_t *wrk, vlib_node_runtime_t *node, session_evt_elt_t *elt, int *n_tx_packets, u8 peek_data)
Definition: session_node.c:1196
buf
u64 buf
Definition: application.c:493
u32
unsigned int u32
Definition: types.h:88
session_tx_get_transport
static transport_connection_t * session_tx_get_transport(session_tx_context_t *ctx, u8 peek_data)
Definition: session_node.c:1044
ip_copy
void ip_copy(ip46_address_t *dst, ip46_address_t *src, u8 is_ip4)
Definition: ip.c:83
vlib_buffer_make_headroom
static void * vlib_buffer_make_headroom(vlib_buffer_t *b, u8 size)
Make head room, typically for packet headers.
Definition: buffer.h:378
vlib_node_set_interrupt_pending
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:249
app_worker_lock_and_send_event
int app_worker_lock_and_send_event(app_worker_t *app, session_t *s, u8 evt_type)
Send event to application.
Definition: application_worker.c:706
transport_proto_t
enum _transport_proto transport_proto_t
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
session_transport_attr_msg_::client_index
u32 client_index
Definition: application_interface.h:555
app_worker_get
app_worker_t * app_worker_get(u32 wrk_index)
Definition: application_worker.c:41
session_worker_::vm
vlib_main_t * vm
Convenience pointer to this worker's vlib_main.
Definition: session.h:104
app_worker_
Definition: application.h:32
session_mq_disconnected_handler
static void session_mq_disconnected_handler(void *data)
Definition: session_node.c:555
vnet_shutdown_session
int vnet_shutdown_session(vnet_shutdown_args_t *a)
Definition: application.c:1418
n_left
u32 n_left
Definition: interface_output.c:1096
application_get_worker
app_worker_t * application_get_worker(application_t *app, u32 wrk_map_index)
Definition: application.c:976
VLIB_NODE_TYPE_PROCESS
@ VLIB_NODE_TYPE_PROCESS
Definition: node.h:84
vlib_get_main_by_index
static vlib_main_t * vlib_get_main_by_index(u32 thread_index)
Definition: global_funcs.h:29
session_transport_attr_reply_msg_::attr
transport_endpt_attr_t attr
Definition: application_interface.h:565
vnet_connect_args_t
struct _vnet_connect_args vnet_connect_args_t
pool_elts
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127
vlib_rpc_call_main_thread
void vlib_rpc_call_main_thread(void *callback, u8 *args, u32 arg_size)
Definition: threads.c:1616
SESSION_CTRL_EVT_APP_WRK_RPC
@ SESSION_CTRL_EVT_APP_WRK_RPC
Definition: session_types.h:360
session_listen_msg_::wrk_index
u32 wrk_index
Definition: application_interface.h:321
SESSION_TX_NO_DATA
@ SESSION_TX_NO_DATA
Definition: session_node.c:820
clib_file_add
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
vlib_node_get_runtime
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:116
session_event_get_session
static session_t * session_event_get_session(session_worker_t *wrk, session_event_t *e)
Definition: session_node.c:1457
session_transport_reset
void session_transport_reset(session_t *s)
Force transport close.
Definition: session.c:1581
TRANSPORT_PACER_MIN_BURST
#define TRANSPORT_PACER_MIN_BURST
Definition: transport.h:23
elt
app_rx_mq_elt_t * elt
Definition: application.c:488
session_event_dispatch_ctrl
static void session_event_dispatch_ctrl(session_worker_t *wrk, session_evt_elt_t *elt)
Definition: session_node.c:1467
session_worker_::pending_tx_nexts
u16 * pending_tx_nexts
Vector of nexts for the pending tx buffers.
Definition: session.h:143
session_worker_::pending_connects
clib_llist_index_t pending_connects
List of pending connects for first worker.
Definition: session.h:149
transport_connection_is_cless
static u8 transport_connection_is_cless(transport_connection_t *tc)
Definition: transport.h:221
session_worker_::sessions
session_t * sessions
Worker session pool.
Definition: session.h:92
session_connect_msg_::vrf
u32 vrf
Definition: application_interface.h:401
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
fs_chunk_ptr
static svm_fifo_chunk_t * fs_chunk_ptr(fifo_segment_header_t *fsh, fs_sptr_t cp)
Definition: fifo_types.h:170
vlib_main_t
Definition: main.h:102
svm_msg_q_lock_and_alloc_msg_w_ring
int svm_msg_q_lock_and_alloc_msg_w_ring(svm_msg_q_t *mq, u32 ring_index, u8 noblock, svm_msg_q_msg_t *msg)
Lock message queue and allocate message buffer on ring.
Definition: message_queue.c:239
session_worker_::old_head
clib_llist_index_t old_head
Head of list of pending events.
Definition: session.h:134
session_transport_attr_reply_msg_
Definition: application_interface.h:561
vlib_get_n_threads
static u32 vlib_get_n_threads()
Definition: global_funcs.h:23
session_get_transport_proto
static transport_proto_t session_get_transport_proto(session_t *s)
Definition: session_types.h:242
foreach_session_ctrl_evt
#define foreach_session_ctrl_evt
Definition: session_types.h:365
vlib_node_t
Definition: node.h:247
app_worker_::wrk_map_index
u32 wrk_map_index
Worker index in app's map pool.
Definition: application.h:40
mq_send_session_connected_cb
int mq_send_session_connected_cb(u32 app_wrk_index, u32 api_context, session_t *s, session_error_t err)
Definition: session_api.c:249
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
application_interface.h
transport_send_params_::max_burst_size
u32 max_burst_size
Definition: transport.h:59
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
vnet_bind_uri
int vnet_bind_uri(vnet_listen_args_t *a)
Definition: application_interface.c:110
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
session_wrk_update_state
static void session_wrk_update_state(session_worker_t *wrk)
Definition: session_node.c:1690
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
transport.h
a
a
Definition: bitmap.h:525
session_listen_uri_msg_::context
u32 context
Definition: application_interface.h:337
SESSION_CTRL_EVT_CONNECT_URI
@ SESSION_CTRL_EVT_CONNECT_URI
Definition: session_types.h:351
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:419
SESSION_CTRL_EVT_TRANSPORT_ATTR
@ SESSION_CTRL_EVT_TRANSPORT_ATTR
Definition: session_types.h:361
SESSION_CTRL_EVT_RESET
@ SESSION_CTRL_EVT_RESET
Definition: session_types.h:336
session_mq_app_wrk_rpc_handler
static void session_mq_app_wrk_rpc_handler(void *data)
Definition: session_node.c:706
session_worker_::n_pending_connects
u32 n_pending_connects
Flag that is set if main thread signaled to handle connects.
Definition: session.h:152
SESSION_CTRL_EVT_DISCONNECT
@ SESSION_CTRL_EVT_DISCONNECT
Definition: session_types.h:349
session.h
i
int i
Definition: flowhash_template.h:376
session_connect_msg_::ip
ip46_address_t ip
Definition: application_interface.h:406
transport_send_params_::flags
transport_snd_flags_t flags
Definition: transport.h:62
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
SESSION_CTRL_EVT_ACCEPTED_REPLY
@ SESSION_CTRL_EVT_ACCEPTED_REPLY
Definition: session_types.h:340
session_mq_transport_attr_handler
static void session_mq_transport_attr_handler(void *data)
Definition: session_node.c:733
app_worker_builtin_rx
int app_worker_builtin_rx(app_worker_t *app_wrk, session_t *s)
Definition: application_worker.c:442
session_reset_reply_msg_::context
u32 context
Definition: application_interface.h:481
context
u32 context
Definition: ip.api:852
session_::flags
u32 flags
Session flags.
Definition: session_types.h:197
rv
int __clib_unused rv
Definition: application.c:491
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
fifo_segment_fifo_offset
uword fifo_segment_fifo_offset(svm_fifo_t *f)
Definition: fifo_segment.c:1049
session_transport_attr_reply_msg_::retval
i32 retval
Definition: application_interface.h:563
session_listen_msg_::is_ip4
u8 is_ip4
Definition: application_interface.h:325
VLIB_MAIN_LOOP_EXIT_FUNCTION
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x)
Definition: init.h:177
vnet.h
session_wrk_timerfd_update
static void session_wrk_timerfd_update(session_worker_t *wrk, u64 time_ns)
Definition: session_node.c:37
SVM_Q_WAIT
@ SVM_Q_WAIT
blocking call - best used in combination with condvars, for eventfds we don't yield the cpu
Definition: queue.h:42
app_worker_::app_index
u32 app_index
Index of owning app.
Definition: application.h:43
session_queue_process_node
vlib_node_registration_t session_queue_process_node
(constructor) VLIB_REGISTER_NODE (session_queue_process_node)
Definition: session_node.c:1951
session_connect_msg_::proto
u8 proto
Definition: application_interface.h:404
vlib_node_runtime_t
Definition: node.h:454
session_main_
Definition: session.h:173
session_worker_::state
session_wrk_state_t state
Worker state.
Definition: session.h:116
session_has_transport
static u8 session_has_transport(session_t *s)
Definition: session_types.h:255
session_flush_pending_tx_buffers
static void session_flush_pending_tx_buffers(session_worker_t *wrk, vlib_node_runtime_t *node)
Definition: session_node.c:1660
session_worker_update_msg_::client_index
u32 client_index
Definition: application_interface.h:494
vlib_trace_buffer
static __clib_warn_unused_result int vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
Definition: trace_funcs.h:153
fifo_segment_t::h
fifo_segment_header_t * h
fifo segment data
Definition: fifo_segment.h:71
SESSION_MQ_CTRL_EVT_RING
@ SESSION_MQ_CTRL_EVT_RING
Definition: session_types.h:402
session_debug.h
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
session_queue_trace_t
Definition: session_node.c:779
vlib_buffer_t::total_length_not_including_first_buffer
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
Definition: buffer.h:176
svm_fifo_max_dequeue_cons
static u32 svm_fifo_max_dequeue_cons(svm_fifo_t *f)
Fifo max bytes to dequeue optimized for consumer.
Definition: svm_fifo.h:487
session_disconnected_reply_msg_
Definition: application_interface.h:465
svm_msg_q_sub_raw
int svm_msg_q_sub_raw(svm_msg_q_t *mq, svm_msg_q_msg_t *elem)
Consumer dequeue one message from queue.
Definition: message_queue.c:402
SESSION_WRK_INTERRUPT
@ SESSION_WRK_INTERRUPT
Definition: session.h:78
session_transport_attribute
int session_transport_attribute(session_t *s, u8 is_get, transport_endpt_attr_t *attr)
Definition: session.c:1766
SESSION_CTRL_EVT_WORKER_UPDATE_REPLY
@ SESSION_CTRL_EVT_WORKER_UPDATE_REPLY
Definition: session_types.h:347
session_worker_update_msg_::handle
u64 handle
Definition: application_interface.h:497
session_dgram_pre_hdr_
Definition: session_types.h:431
session_event_dispatch_io
static void session_event_dispatch_io(session_worker_t *wrk, vlib_node_runtime_t *node, session_evt_elt_t *elt, int *n_tx_packets)
Definition: session_node.c:1564
session_send_io_evt_to_thread
int session_send_io_evt_to_thread(svm_fifo_t *f, session_evt_type_t evt_type)
Definition: session.c:84
session_::session_state
volatile u8 session_state
State in session layer state machine.
Definition: session_types.h:185
session_main_get_worker
static session_worker_t * session_main_get_worker(u32 thread_index)
Definition: session.h:703
session_connect_uri_msg_
Definition: application_interface.h:418
svm_fifo_is_empty
static int svm_fifo_is_empty(svm_fifo_t *f)
Check if fifo is empty.
Definition: svm_fifo.h:579
app_worker_own_session
int app_worker_own_session(app_worker_t *app_wrk, session_t *s)
Definition: application_worker.c:471
session_listen_msg_::port
u16 port
Definition: application_interface.h:323
session_::connection_index
u32 connection_index
Index of the transport connection associated to the session.
Definition: session_types.h:200
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
clib_llist_prev_index
#define clib_llist_prev_index(E, name)
Definition: llist.h:99
session_mq_handle_connects_rpc
static void session_mq_handle_connects_rpc(void *arg)
Definition: session_node.c:205
session_mq_disconnected_reply_handler
static void session_mq_disconnected_reply_handler(void *data)
Definition: session_node.c:600
session_is_valid
u8 session_is_valid(u32 si, u8 thread_index)
Definition: session.c:241
session_unlisten_msg_::handle
session_handle_t handle
Definition: application_interface.h:364
mq_send_session_bound_cb
int mq_send_session_bound_cb(u32 app_wrk_index, u32 api_context, session_handle_t handle, int rv)
Definition: session_api.c:336
session_dgram_header_::rmt_ip
ip46_address_t rmt_ip
Definition: session_types.h:441
session_worker_
Definition: session.h:87
session_mq_connect_uri_handler
static void session_mq_connect_uri_handler(void *data)
Definition: session_node.c:314
session_disconnect_msg_::client_index
u32 client_index
Definition: application_interface.h:453
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
application.h
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
session_send_rpc_evt_to_thread_force
void session_send_rpc_evt_to_thread_force(u32 thread_index, void *fp, void *rpc_args)
Definition: session.c:108
session_accepted_reply_msg_::context
u32 context
Definition: application_interface.h:391
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
session_worker_::ctrl_head
clib_llist_index_t ctrl_head
Head of control events list.
Definition: session.h:128
clib_llist_elt
#define clib_llist_elt(LP, EI)
Get list elt at index.
Definition: llist.h:81
SESSION_EVT
#define SESSION_EVT(_evt, _args...)
Definition: session_debug.h:328
transport_connection_deschedule
static void transport_connection_deschedule(transport_connection_t *tc)
Definition: transport.h:215