]> git.baikalelectronics.ru Git - kernel.git/commitdiff
bpf: sockmap sample, add data verification option
authorJohn Fastabend <john.fastabend@gmail.com>
Sun, 18 Mar 2018 19:57:51 +0000 (12:57 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 19 Mar 2018 20:14:40 +0000 (21:14 +0100)
To verify data is not being dropped or corrupted this adds an option
to verify test-patterns on recv.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
samples/sockmap/sockmap_user.c

index ec624a80130662446b3dd6dd62285d9fb96f5a82..8017ad7afea9343841bade33da5c80c95cb115b3 100644 (file)
@@ -68,6 +68,7 @@ static const struct option long_options[] = {
        {"iov_count",   required_argument,      NULL, 'i' },
        {"length",      required_argument,      NULL, 'l' },
        {"test",        required_argument,      NULL, 't' },
+       {"data_test",   no_argument,            NULL, 'd' },
        {"txmsg",               no_argument,    &txmsg_pass,  1  },
        {"txmsg_noisy",         no_argument,    &txmsg_noisy, 1  },
        {"txmsg_redir",         no_argument,    &txmsg_redir, 1  },
@@ -208,45 +209,49 @@ struct msg_stats {
 static int msg_loop_sendpage(int fd, int iov_length, int cnt,
                             struct msg_stats *s)
 {
-       off_t offset = 0;
+       unsigned char k = 0;
        FILE *file;
        int i, fp;
 
        file = fopen(".sendpage_tst.tmp", "w+");
-       fseek(file, iov_length * cnt, SEEK_CUR);
-       fprintf(file, "A");
+       for (i = 0; i < iov_length * cnt; i++, k++)
+               fwrite(&k, sizeof(char), 1, file);
+       fflush(file);
        fseek(file, 0, SEEK_SET);
+       fclose(file);
 
-       fp = fileno(file);
+       fp = open(".sendpage_tst.tmp", O_RDONLY);
        clock_gettime(CLOCK_MONOTONIC, &s->start);
        for (i = 0; i < cnt; i++) {
-               int sent = sendfile(fd, fp, &offset, iov_length);
+               int sent = sendfile(fd, fp, NULL, iov_length);
 
                if (sent < 0) {
                        perror("send loop error:");
-                       fclose(file);
+                       close(fp);
                        return sent;
                }
                s->bytes_sent += sent;
        }
        clock_gettime(CLOCK_MONOTONIC, &s->end);
-       fclose(file);
+       close(fp);
        return 0;
 }
 
 static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
-                   struct msg_stats *s, bool tx)
+                   struct msg_stats *s, bool tx, bool data_test)
 {
        struct msghdr msg = {0};
        int err, i, flags = MSG_NOSIGNAL;
        struct iovec *iov;
+       unsigned char k;
 
        iov = calloc(iov_count, sizeof(struct iovec));
        if (!iov)
                return errno;
 
+       k = 0;
        for (i = 0; i < iov_count; i++) {
-               char *d = calloc(iov_length, sizeof(char));
+               unsigned char *d = calloc(iov_length, sizeof(char));
 
                if (!d) {
                        fprintf(stderr, "iov_count %i/%i OOM\n", i, iov_count);
@@ -254,10 +259,18 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
                }
                iov[i].iov_base = d;
                iov[i].iov_len = iov_length;
+
+               if (data_test && tx) {
+                       int j;
+
+                       for (j = 0; j < iov_length; j++)
+                               d[j] = k++;
+               }
        }
 
        msg.msg_iov = iov;
        msg.msg_iovlen = iov_count;
+       k = 0;
 
        if (tx) {
                clock_gettime(CLOCK_MONOTONIC, &s->start);
@@ -311,6 +324,26 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,
                        }
 
                        s->bytes_recvd += recv;
+
+                       if (data_test) {
+                               int j;
+
+                               for (i = 0; i < msg.msg_iovlen; i++) {
+                                       unsigned char *d = iov[i].iov_base;
+
+                                       for (j = 0;
+                                            j < iov[i].iov_len && recv; j++) {
+                                               if (d[j] != k++) {
+                                                       errno = -EIO;
+                                                       fprintf(stderr,
+                                                               "detected data corruption @iov[%i]:%i %02x != %02x, %02x ?= %02x\n",
+                                                               i, j, d[j], k - 1, d[j+1], k + 1);
+                                                       goto out_errno;
+                                               }
+                                               recv--;
+                                       }
+                               }
+                       }
                }
                clock_gettime(CLOCK_MONOTONIC, &s->end);
        }
@@ -338,8 +371,15 @@ static inline float recvdBps(struct msg_stats s)
        return s.bytes_recvd / (s.end.tv_sec - s.start.tv_sec);
 }
 
+struct sockmap_options {
+       int verbose;
+       bool base;
+       bool sendpage;
+       bool data_test;
+};
+
 static int sendmsg_test(int iov_count, int iov_buf, int cnt,
-                       int verbose, bool base, bool sendpage)
+                       struct sockmap_options *opt)
 {
        float sent_Bps = 0, recvd_Bps = 0;
        int rx_fd, txpid, rxpid, err = 0;
@@ -348,16 +388,17 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt,
 
        errno = 0;
 
-       if (base)
+       if (opt->base)
                rx_fd = p1;
        else
                rx_fd = p2;
 
        rxpid = fork();
        if (rxpid == 0) {
-               if (sendpage)
+               if (opt->sendpage)
                        iov_count = 1;
-               err = msg_loop(rx_fd, iov_count, iov_buf, cnt, &s, false);
+               err = msg_loop(rx_fd, iov_count, iov_buf,
+                              cnt, &s, false, opt->data_test);
                if (err)
                        fprintf(stderr,
                                "msg_loop_rx: iov_count %i iov_buf %i cnt %i err %i\n",
@@ -380,10 +421,11 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt,
 
        txpid = fork();
        if (txpid == 0) {
-               if (sendpage)
+               if (opt->sendpage)
                        err = msg_loop_sendpage(c1, iov_buf, cnt, &s);
                else
-                       err = msg_loop(c1, iov_count, iov_buf, cnt, &s, true);
+                       err = msg_loop(c1, iov_count, iov_buf,
+                                      cnt, &s, true, opt->data_test);
 
                if (err)
                        fprintf(stderr,
@@ -409,7 +451,7 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt,
        return err;
 }
 
-static int forever_ping_pong(int rate, int verbose)
+static int forever_ping_pong(int rate, struct sockmap_options *opt)
 {
        struct timeval timeout;
        char buf[1024] = {0};
@@ -474,7 +516,7 @@ static int forever_ping_pong(int rate, int verbose)
                if (rate)
                        sleep(rate);
 
-               if (verbose) {
+               if (opt->verbose) {
                        printf(".");
                        fflush(stdout);
 
@@ -494,13 +536,14 @@ enum {
 
 int main(int argc, char **argv)
 {
-       int iov_count = 1, length = 1024, rate = 1, verbose = 0, tx_prog_fd;
+       int iov_count = 1, length = 1024, rate = 1, tx_prog_fd;
        struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY};
        int opt, longindex, err, cg_fd = 0;
+       struct sockmap_options options = {0};
        int test = PING_PONG;
        char filename[256];
 
-       while ((opt = getopt_long(argc, argv, ":hvc:r:i:l:t:",
+       while ((opt = getopt_long(argc, argv, ":dhvc:r:i:l:t:",
                                  long_options, &longindex)) != -1) {
                switch (opt) {
                /* Cgroup configuration */
@@ -517,7 +560,7 @@ int main(int argc, char **argv)
                        rate = atoi(optarg);
                        break;
                case 'v':
-                       verbose = 1;
+                       options.verbose = 1;
                        break;
                case 'i':
                        iov_count = atoi(optarg);
@@ -525,6 +568,9 @@ int main(int argc, char **argv)
                case 'l':
                        length = atoi(optarg);
                        break;
+               case 'd':
+                       options.data_test = true;
+                       break;
                case 't':
                        if (strcmp(optarg, "ping") == 0) {
                                test = PING_PONG;
@@ -655,20 +701,24 @@ run:
                }
        }
        if (test == PING_PONG)
-               err = forever_ping_pong(rate, verbose);
-       else if (test == SENDMSG)
-               err = sendmsg_test(iov_count, length, rate,
-                                  verbose, false, false);
-       else if (test == SENDPAGE)
-               err = sendmsg_test(iov_count, length, rate,
-                                  verbose, false, true);
-       else if (test == BASE)
-               err = sendmsg_test(iov_count, length, rate,
-                                  verbose, true, false);
-       else if (test == BASE_SENDPAGE)
-               err = sendmsg_test(iov_count, length, rate,
-                                  verbose, true, true);
-       else
+               err = forever_ping_pong(rate, &options);
+       else if (test == SENDMSG) {
+               options.base = false;
+               options.sendpage = false;
+               err = sendmsg_test(iov_count, length, rate, &options);
+       } else if (test == SENDPAGE) {
+               options.base = false;
+               options.sendpage = true;
+               err = sendmsg_test(iov_count, length, rate, &options);
+       } else if (test == BASE) {
+               options.base = true;
+               options.sendpage = false;
+               err = sendmsg_test(iov_count, length, rate, &options);
+       } else if (test == BASE_SENDPAGE) {
+               options.base = true;
+               options.sendpage = true;
+               err = sendmsg_test(iov_count, length, rate, &options);
+       } else
                fprintf(stderr, "unknown test\n");
 out:
        bpf_prog_detach2(prog_fd[2], cg_fd, BPF_CGROUP_SOCK_OPS);