From ccd16e3f7b5525dafdc29f043e0ba8faef57eb12 Mon Sep 17 00:00:00 2001 From: Semir Sionek Date: Tue, 22 Jul 2025 13:47:30 +0000 Subject: [PATCH] session: enable sending segmented dgrams Split app_send_dgram_raw_gso into app_send_dgram_segs_raw and app_gen_dgram_header. The former sends out previously prepared segmented dgram, while the latter fills in the header in a prepared segment array. Additionally, app_send_dgram_segs was introduced as an easier API for sending out segmented data. Type: improvement Change-Id: I3afdd9b974a7dbf936b7b7c07873ac72262525d9 Signed-off-by: Semir Sionek --- src/vnet/session/application_interface.h | 87 ++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 21 deletions(-) diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index 28963923764..fe83265d3e3 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -627,32 +627,44 @@ app_send_io_evt_to_vpp (svm_msg_q_t * mq, u32 session_index, u8 evt_type, } } -#define app_send_dgram_raw(f, at, vpp_evt_q, data, len, evt_type, do_evt, \ - noblock) \ - app_send_dgram_raw_gso (f, at, vpp_evt_q, data, len, 0, evt_type, do_evt, \ - noblock) +/* NOTE: Make sure the segs parameter has the first element of the array empty +to write-in the header */ +always_inline u32 +app_gen_dgram_header (svm_fifo_seg_t *segs, u32 data_len, + app_session_transport_t *at, u16 gso_size) +{ + session_dgram_hdr_t *hdr = (session_dgram_hdr_t *) segs[0].data; + u32 dgram_len = data_len; + + ASSERT (segs != NULL); + ASSERT (segs[0].data != NULL); + ASSERT (segs[0].len == sizeof (session_dgram_hdr_t)); + + hdr->data_length = data_len; + hdr->data_offset = 0; + clib_memcpy_fast (&hdr->rmt_ip, &at->rmt_ip, sizeof (ip46_address_t)); + hdr->is_ip4 = at->is_ip4; + hdr->rmt_port = at->rmt_port; + clib_memcpy_fast (&hdr->lcl_ip, &at->lcl_ip, sizeof (ip46_address_t)); + hdr->lcl_port = at->lcl_port; + hdr->gso_size = gso_size; + dgram_len += segs[0].len; + + return dgram_len; +} always_inline int -app_send_dgram_raw_gso (svm_fifo_t *f, app_session_transport_t *at, - svm_msg_q_t *vpp_evt_q, u8 *data, u32 len, - u16 gso_size, u8 evt_type, u8 do_evt, u8 noblock) +app_send_dgram_segs_raw (svm_fifo_t *f, app_session_transport_t *at, + svm_msg_q_t *vpp_evt_q, svm_fifo_seg_t *segs, + u32 nsegs, u32 seg_len, u8 evt_type, u8 do_evt, + u8 noblock) { - session_dgram_hdr_t hdr; int rv; - if (svm_fifo_max_enqueue_prod (f) < (sizeof (session_dgram_hdr_t) + len)) + + if (svm_fifo_max_enqueue_prod (f) < seg_len) return 0; - hdr.data_length = len; - hdr.data_offset = 0; - clib_memcpy_fast (&hdr.rmt_ip, &at->rmt_ip, sizeof (ip46_address_t)); - hdr.is_ip4 = at->is_ip4; - hdr.rmt_port = at->rmt_port; - clib_memcpy_fast (&hdr.lcl_ip, &at->lcl_ip, sizeof (ip46_address_t)); - hdr.lcl_port = at->lcl_port; - hdr.gso_size = gso_size; - svm_fifo_seg_t segs[2] = {{ (u8 *) &hdr, sizeof (hdr) }, { data, len }}; - - rv = svm_fifo_enqueue_segments (f, segs, 2, 0 /* allow partial */ ); + rv = svm_fifo_enqueue_segments (f, segs, nsegs, 0 /* allow partial */); if (PREDICT_FALSE (rv < 0)) return 0; @@ -662,9 +674,26 @@ app_send_dgram_raw_gso (svm_fifo_t *f, app_session_transport_t *at, app_send_io_evt_to_vpp (vpp_evt_q, f->vpp_session_index, evt_type, noblock); } - return len; + return seg_len - sizeof (session_dgram_hdr_t); +} + +always_inline int +app_send_dgram_raw_gso (svm_fifo_t *f, app_session_transport_t *at, + svm_msg_q_t *vpp_evt_q, u8 *data, u32 len, + u16 gso_size, u8 evt_type, u8 do_evt, u8 noblock) +{ + session_dgram_hdr_t hdr; + svm_fifo_seg_t segs[2] = { { (u8 *) &hdr, sizeof (hdr) }, { data, len } }; + u32 seg_len = app_gen_dgram_header (segs, len, at, gso_size); + return app_send_dgram_segs_raw (f, at, vpp_evt_q, segs, 2, seg_len, evt_type, + do_evt, noblock); } +#define app_send_dgram_raw(f, at, vpp_evt_q, data, len, evt_type, do_evt, \ + noblock) \ + app_send_dgram_raw_gso (f, at, vpp_evt_q, data, len, 0, evt_type, do_evt, \ + noblock) + always_inline int app_send_dgram (app_session_t * s, u8 * data, u32 len, u8 noblock) { @@ -673,6 +702,22 @@ app_send_dgram (app_session_t * s, u8 * data, u32 len, u8 noblock) noblock); } +always_inline int +app_send_dgram_segs (app_session_t *s, svm_fifo_seg_t *segs, u32 data_nsegs, + u32 data_len, u8 noblock) +{ + session_dgram_hdr_t hdr; + ASSERT (segs != NULL); + ASSERT (segs[0].len == 0); + segs[0].data = (u8 *) &hdr; + segs[0].len = sizeof (hdr); + + u32 seg_len = app_gen_dgram_header (segs, data_len, &s->transport, 0); + return app_send_dgram_segs_raw (s->tx_fifo, &s->transport, s->vpp_evt_q, + segs, data_nsegs, seg_len, SESSION_IO_EVT_TX, + 1 /* do_evt */, noblock); +} + always_inline int app_send_stream_raw (svm_fifo_t * f, svm_msg_q_t * vpp_evt_q, u8 * data, u32 len, u8 evt_type, u8 do_evt, u8 noblock) -- 2.16.6