aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
Diffstat (limited to 'samples')
-rw-r--r--samples/sockmap/sockmap_user.c148
1 files changed, 145 insertions, 3 deletions
diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c
index ffd1d127a9d3..ccc717349eba 100644
--- a/samples/sockmap/sockmap_user.c
+++ b/samples/sockmap/sockmap_user.c
@@ -56,6 +56,9 @@ static const struct option long_options[] = {
56 {"cgroup", required_argument, NULL, 'c' }, 56 {"cgroup", required_argument, NULL, 'c' },
57 {"rate", required_argument, NULL, 'r' }, 57 {"rate", required_argument, NULL, 'r' },
58 {"verbose", no_argument, NULL, 'v' }, 58 {"verbose", no_argument, NULL, 'v' },
59 {"iov_count", required_argument, NULL, 'i' },
60 {"length", required_argument, NULL, 'l' },
61 {"test", required_argument, NULL, 't' },
59 {0, 0, NULL, 0 } 62 {0, 0, NULL, 0 }
60}; 63};
61 64
@@ -182,6 +185,118 @@ static int sockmap_init_sockets(void)
182 return 0; 185 return 0;
183} 186}
184 187
188struct msg_stats {
189 size_t bytes_sent;
190 size_t bytes_recvd;
191};
192
193static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
194 struct msg_stats *s, bool tx)
195{
196 struct msghdr msg = {0};
197 struct iovec *iov;
198 int i, flags = 0;
199
200 iov = calloc(iov_count, sizeof(struct iovec));
201 if (!iov)
202 return errno;
203
204 for (i = 0; i < iov_count; i++) {
205 char *d = calloc(iov_length, sizeof(char));
206
207 if (!d) {
208 fprintf(stderr, "iov_count %i/%i OOM\n", i, iov_count);
209 goto out_errno;
210 }
211 iov[i].iov_base = d;
212 iov[i].iov_len = iov_length;
213 }
214
215 msg.msg_iov = iov;
216 msg.msg_iovlen = iov_count;
217
218 if (tx) {
219 for (i = 0; i < cnt; i++) {
220 int sent = sendmsg(fd, &msg, flags);
221
222 if (sent < 0) {
223 perror("send loop error:");
224 goto out_errno;
225 }
226 s->bytes_sent += sent;
227 }
228 } else {
229 int slct, recv, max_fd = fd;
230 struct timeval timeout;
231 float total_bytes;
232 fd_set w;
233
234 total_bytes = (float)iov_count * (float)iov_length * (float)cnt;
235 while (s->bytes_recvd < total_bytes) {
236 timeout.tv_sec = 1;
237 timeout.tv_usec = 0;
238
239 /* FD sets */
240 FD_ZERO(&w);
241 FD_SET(fd, &w);
242
243 slct = select(max_fd + 1, &w, NULL, NULL, &timeout);
244 if (slct == -1) {
245 perror("select()");
246 goto out_errno;
247 } else if (!slct) {
248 fprintf(stderr, "unexpected timeout\n");
249 errno = -EIO;
250 goto out_errno;
251 }
252
253 recv = recvmsg(fd, &msg, flags);
254 if (recv < 0) {
255 if (errno != EWOULDBLOCK) {
256 perror("recv failed()\n");
257 goto out_errno;
258 }
259 }
260
261 s->bytes_recvd += recv;
262 }
263 }
264
265 for (i = 0; i < iov_count; i++)
266 free(iov[i].iov_base);
267 free(iov);
268 return 0;
269out_errno:
270 for (i = 0; i < iov_count; i++)
271 free(iov[i].iov_base);
272 free(iov);
273 return errno;
274}
275
276static int sendmsg_test(int iov_count, int iov_buf, int cnt, int verbose)
277{
278 struct msg_stats s = {0};
279 int err;
280
281 err = msg_loop(c1, iov_count, iov_buf, cnt, &s, true);
282 if (err) {
283 fprintf(stderr,
284 "msg_loop_tx: iov_count %i iov_buf %i cnt %i err %i\n",
285 iov_count, iov_buf, cnt, err);
286 return err;
287 }
288
289 err = msg_loop(p2, iov_count, iov_buf, cnt, &s, false);
290 if (err)
291 fprintf(stderr,
292 "msg_loop_rx: iov_count %i iov_buf %i cnt %i err %i\n",
293 iov_count, iov_buf, cnt, err);
294
295 fprintf(stdout, "sendmsg: TX_bytes %zu RX_bytes %zu\n",
296 s.bytes_sent, s.bytes_recvd);
297 return err;
298}
299
185static int forever_ping_pong(int rate, int verbose) 300static int forever_ping_pong(int rate, int verbose)
186{ 301{
187 struct timeval timeout; 302 struct timeval timeout;
@@ -257,13 +372,19 @@ static int forever_ping_pong(int rate, int verbose)
257 return 0; 372 return 0;
258} 373}
259 374
375enum {
376 PING_PONG,
377 SENDMSG,
378};
379
260int main(int argc, char **argv) 380int main(int argc, char **argv)
261{ 381{
262 int rate = 1, verbose = 0; 382 int iov_count = 1, length = 1024, rate = 1, verbose = 0;
263 int opt, longindex, err, cg_fd = 0; 383 int opt, longindex, err, cg_fd = 0;
384 int test = PING_PONG;
264 char filename[256]; 385 char filename[256];
265 386
266 while ((opt = getopt_long(argc, argv, "hvc:r:", 387 while ((opt = getopt_long(argc, argv, "hvc:r:i:l:t:",
267 long_options, &longindex)) != -1) { 388 long_options, &longindex)) != -1) {
268 switch (opt) { 389 switch (opt) {
269 /* Cgroup configuration */ 390 /* Cgroup configuration */
@@ -282,6 +403,22 @@ int main(int argc, char **argv)
282 case 'v': 403 case 'v':
283 verbose = 1; 404 verbose = 1;
284 break; 405 break;
406 case 'i':
407 iov_count = atoi(optarg);
408 break;
409 case 'l':
410 length = atoi(optarg);
411 break;
412 case 't':
413 if (strcmp(optarg, "ping") == 0) {
414 test = PING_PONG;
415 } else if (strcmp(optarg, "sendmsg") == 0) {
416 test = SENDMSG;
417 } else {
418 usage(argv);
419 return -1;
420 }
421 break;
285 case 'h': 422 case 'h':
286 default: 423 default:
287 usage(argv); 424 usage(argv);
@@ -339,7 +476,12 @@ int main(int argc, char **argv)
339 goto out; 476 goto out;
340 } 477 }
341 478
342 err = forever_ping_pong(rate, verbose); 479 if (test == PING_PONG)
480 err = forever_ping_pong(rate, verbose);
481 else if (test == SENDMSG)
482 err = sendmsg_test(iov_count, length, rate, verbose);
483 else
484 fprintf(stderr, "unknown test\n");
343out: 485out:
344 close(s1); 486 close(s1);
345 close(s2); 487 close(s2);