Add sample application support for the bpf_msg_cork_bytes helper. This
lets the user specify how many bytes each verdict should apply to.

Signed-off-by: John Fastabend <john.fastab...@gmail.com>
---
 include/uapi/linux/bpf_common.h           |    7 ++--
 samples/sockmap/sockmap_kern.c            |   53 +++++++++++++++++++++++++----
 samples/sockmap/sockmap_user.c            |   19 ++++++++++
 tools/include/uapi/linux/bpf.h            |    3 +-
 tools/testing/selftests/bpf/bpf_helpers.h |    2 +
 5 files changed, 71 insertions(+), 13 deletions(-)

diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h
index ee97668..18be907 100644
--- a/include/uapi/linux/bpf_common.h
+++ b/include/uapi/linux/bpf_common.h
@@ -15,10 +15,9 @@
 
 /* ld/ldx fields */
 #define BPF_SIZE(code)  ((code) & 0x18)
-#define                BPF_W           0x00 /* 32-bit */
-#define                BPF_H           0x08 /* 16-bit */
-#define                BPF_B           0x10 /*  8-bit */
-/* eBPF                BPF_DW          0x18    64-bit */
+#define                BPF_W           0x00
+#define                BPF_H           0x08
+#define                BPF_B           0x10
 #define BPF_MODE(code)  ((code) & 0xe0)
 #define                BPF_IMM         0x00
 #define                BPF_ABS         0x20
diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c
index 5a51f15..1c430926 100644
--- a/samples/sockmap/sockmap_kern.c
+++ b/samples/sockmap/sockmap_kern.c
@@ -64,6 +64,13 @@ struct bpf_map_def SEC("maps") sock_apply_bytes = {
        .max_entries = 1
 };
 
+struct bpf_map_def SEC("maps") sock_cork_bytes = {
+       .type = BPF_MAP_TYPE_ARRAY,
+       .key_size = sizeof(int),
+       .value_size = sizeof(int),
+       .max_entries = 1
+};
+
 SEC("sk_skb1")
 int bpf_prog1(struct __sk_buff *skb)
 {
@@ -135,6 +142,9 @@ int bpf_prog4(struct sk_msg_md *msg)
        bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
        if (bytes)
                bpf_msg_apply_bytes(msg, *bytes);
+       bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
+       if (bytes)
+               bpf_msg_cork_bytes(msg, *bytes);
        return SK_PASS;
 }
 
@@ -143,13 +153,16 @@ int bpf_prog5(struct sk_msg_md *msg)
 {
        void *data_end = (void *)(long) msg->data_end;
        void *data = (void *)(long) msg->data;
-       int *bytes, err = 0, zero = 0;
+       int *bytes, err1 = -1, err2 = -1, zero = 0;
 
        bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
        if (bytes)
-               err = bpf_msg_apply_bytes(msg, *bytes);
-       bpf_printk("sk_msg2: data length %i err %i\n",
-                  (__u32)data_end - (__u32)data, err);
+               err1 = bpf_msg_apply_bytes(msg, *bytes);
+       bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
+       if (bytes)
+               err2 = bpf_msg_cork_bytes(msg, *bytes);
+       bpf_printk("sk_msg2: data length %i err1 %i err2 %i\n",
+                  (__u32)data_end - (__u32)data, err1, err2);
        return SK_PASS;
 }
 
@@ -163,6 +176,9 @@ int bpf_prog6(struct sk_msg_md *msg)
        bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
        if (bytes)
                bpf_msg_apply_bytes(msg, *bytes);
+       bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
+       if (bytes)
+               bpf_msg_cork_bytes(msg, *bytes);
        return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
 }
 
@@ -171,13 +187,17 @@ int bpf_prog7(struct sk_msg_md *msg)
 {
        void *data_end = (void *)(long) msg->data_end;
        void *data = (void *)(long) msg->data;
-       int *bytes, err = 0, zero = 0;
+       int *bytes, err1 = 0, err2 = 0, zero = 0;
 
        bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
        if (bytes)
-               err = bpf_msg_apply_bytes(msg, *bytes);
-       bpf_printk("sk_msg3: redirect(%iB) err=%i\n",
-                  (__u32)data_end - (__u32)data, err);
+               err1 = bpf_msg_apply_bytes(msg, *bytes);
+       bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
+       if (bytes)
+               err2 = bpf_msg_cork_bytes(msg, *bytes);
+
+       bpf_printk("sk_msg3: redirect(%iB) err1=%i err2=%i\n",
+                  (__u32)data_end - (__u32)data, err1, err2);
        return bpf_msg_redirect_map(msg, &sock_map_redir, zero, 0);
 }
 
@@ -198,5 +218,22 @@ int bpf_prog8(struct sk_msg_md *msg)
        }
        return SK_PASS;
 }
+SEC("sk_msg6")
+int bpf_prog9(struct sk_msg_md *msg)
+{
+       void *data_end = (void *)(long) msg->data_end;
+       void *data = (void *)(long) msg->data;
+       int ret = 0, *bytes, zero = 0;
+
+       bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
+       if (bytes) {
+               if (((__u32)data_end - (__u32)data) >= *bytes)
+                       return SK_PASS;
+               ret = bpf_msg_cork_bytes(msg, *bytes);
+               if (ret)
+                       return SK_DROP;
+       }
+       return SK_PASS;
+}
 
 char _license[] SEC("license") = "GPL";
diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c
index 41774ec..4e0a3d8 100644
--- a/samples/sockmap/sockmap_user.c
+++ b/samples/sockmap/sockmap_user.c
@@ -60,6 +60,7 @@
 int txmsg_redir;
 int txmsg_redir_noisy;
 int txmsg_apply;
+int txmsg_cork;
 
 static const struct option long_options[] = {
        {"help",        no_argument,            NULL, 'h' },
@@ -75,6 +76,7 @@
        {"txmsg_redir",         no_argument,    &txmsg_redir, 1  },
        {"txmsg_redir_noisy",   no_argument,    &txmsg_redir_noisy, 1},
        {"txmsg_apply", required_argument,      NULL, 'a'},
+       {"txmsg_cork",  required_argument,      NULL, 'k'},
        {0, 0, NULL, 0 }
 };
 
@@ -551,6 +553,9 @@ int main(int argc, char **argv)
                case 'a':
                        txmsg_apply = atoi(optarg);
                        break;
+               case 'k':
+                       txmsg_cork = atoi(optarg);
+                       break;
                case 'c':
                        cg_fd = open(optarg, O_DIRECTORY, O_RDONLY);
                        if (cg_fd < 0) {
@@ -671,6 +676,8 @@ int main(int argc, char **argv)
                tx_prog_fd = prog_fd[6];
        else if (txmsg_apply)
                tx_prog_fd = prog_fd[7];
+       else if (txmsg_cork)
+               tx_prog_fd = prog_fd[8];
        else
                tx_prog_fd = 0;
 
@@ -716,6 +723,18 @@ int main(int argc, char **argv)
                                return err;
                        }
                }
+
+               if (txmsg_cork) {
+                       err = bpf_map_update_elem(map_fd[4],
+                                                 &i, &txmsg_cork, BPF_ANY);
+                       if (err) {
+                               fprintf(stderr,
+                                       "ERROR: bpf_map_update_elem 
(cork_bytes):  %d (%s\n",
+                                       err, strerror(errno));
+                               return err;
+                       }
+               }
+
        }
        if (test == PING_PONG)
                err = forever_ping_pong(rate, &options);
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 609456f..ce07a13 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -770,7 +770,8 @@ enum bpf_attach_type {
        FN(override_return),            \
        FN(sock_ops_cb_flags_set),      \
        FN(msg_redirect_map),           \
-       FN(msg_apply_bytes),
+       FN(msg_apply_bytes),            \
+       FN(msg_cork_bytes),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h 
b/tools/testing/selftests/bpf/bpf_helpers.h
index 4713de4..b5b45ff 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -90,6 +90,8 @@ static int (*bpf_msg_redirect_map)(void *ctx, void *map, int 
key, int flags) =
        (void *) BPF_FUNC_msg_redirect_map;
 static int (*bpf_msg_apply_bytes)(void *ctx, int len) =
        (void *) BPF_FUNC_msg_apply_bytes;
+static int (*bpf_msg_cork_bytes)(void *ctx, int len) =
+       (void *) BPF_FUNC_msg_cork_bytes;
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions

Reply via email to