diff options
Diffstat (limited to 'samples')
| -rw-r--r-- | samples/sockmap/sockmap_user.c | 148 |
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 | ||
| 188 | struct msg_stats { | ||
| 189 | size_t bytes_sent; | ||
| 190 | size_t bytes_recvd; | ||
| 191 | }; | ||
| 192 | |||
| 193 | static 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; | ||
| 269 | out_errno: | ||
| 270 | for (i = 0; i < iov_count; i++) | ||
| 271 | free(iov[i].iov_base); | ||
| 272 | free(iov); | ||
| 273 | return errno; | ||
| 274 | } | ||
| 275 | |||
| 276 | static 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 | |||
| 185 | static int forever_ping_pong(int rate, int verbose) | 300 | static 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 | ||
| 375 | enum { | ||
| 376 | PING_PONG, | ||
| 377 | SENDMSG, | ||
| 378 | }; | ||
| 379 | |||
| 260 | int main(int argc, char **argv) | 380 | int 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"); | ||
| 343 | out: | 485 | out: |
| 344 | close(s1); | 486 | close(s1); |
| 345 | close(s2); | 487 | close(s2); |
