root/tools/testing/selftests/bpf/test_sockmap_kern.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. SEC
  2. SEC
  3. SEC
  4. SEC
  5. SEC
  6. SEC
  7. SEC
  8. SEC
  9. SEC
  10. SEC

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /* Copyright (c) 2017-2018 Covalent IO, Inc. http://covalent.io */
   3 #include <stddef.h>
   4 #include <string.h>
   5 #include <linux/bpf.h>
   6 #include <linux/if_ether.h>
   7 #include <linux/if_packet.h>
   8 #include <linux/ip.h>
   9 #include <linux/ipv6.h>
  10 #include <linux/in.h>
  11 #include <linux/udp.h>
  12 #include <linux/tcp.h>
  13 #include <linux/pkt_cls.h>
  14 #include <sys/socket.h>
  15 #include "bpf_helpers.h"
  16 #include "bpf_endian.h"
  17 
  18 /* Sockmap sample program connects a client and a backend together
  19  * using cgroups.
  20  *
  21  *    client:X <---> frontend:80 client:X <---> backend:80
  22  *
  23  * For simplicity we hard code values here and bind 1:1. The hard
  24  * coded values are part of the setup in sockmap.sh script that
  25  * is associated with this BPF program.
  26  *
  27  * The bpf_printk is verbose and prints information as connections
  28  * are established and verdicts are decided.
  29  */
  30 
  31 struct {
  32         __uint(type, TEST_MAP_TYPE);
  33         __uint(max_entries, 20);
  34         __uint(key_size, sizeof(int));
  35         __uint(value_size, sizeof(int));
  36 } sock_map SEC(".maps");
  37 
  38 struct {
  39         __uint(type, TEST_MAP_TYPE);
  40         __uint(max_entries, 20);
  41         __uint(key_size, sizeof(int));
  42         __uint(value_size, sizeof(int));
  43 } sock_map_txmsg SEC(".maps");
  44 
  45 struct {
  46         __uint(type, TEST_MAP_TYPE);
  47         __uint(max_entries, 20);
  48         __uint(key_size, sizeof(int));
  49         __uint(value_size, sizeof(int));
  50 } sock_map_redir SEC(".maps");
  51 
  52 struct {
  53         __uint(type, BPF_MAP_TYPE_ARRAY);
  54         __uint(max_entries, 1);
  55         __type(key, int);
  56         __type(value, int);
  57 } sock_apply_bytes SEC(".maps");
  58 
  59 struct {
  60         __uint(type, BPF_MAP_TYPE_ARRAY);
  61         __uint(max_entries, 1);
  62         __type(key, int);
  63         __type(value, int);
  64 } sock_cork_bytes SEC(".maps");
  65 
  66 struct {
  67         __uint(type, BPF_MAP_TYPE_ARRAY);
  68         __uint(max_entries, 6);
  69         __type(key, int);
  70         __type(value, int);
  71 } sock_bytes SEC(".maps");
  72 
  73 struct {
  74         __uint(type, BPF_MAP_TYPE_ARRAY);
  75         __uint(max_entries, 1);
  76         __type(key, int);
  77         __type(value, int);
  78 } sock_redir_flags SEC(".maps");
  79 
  80 struct {
  81         __uint(type, BPF_MAP_TYPE_ARRAY);
  82         __uint(max_entries, 1);
  83         __type(key, int);
  84         __type(value, int);
  85 } sock_skb_opts SEC(".maps");
  86 
  87 SEC("sk_skb1")
  88 int bpf_prog1(struct __sk_buff *skb)
  89 {
  90         return skb->len;
  91 }
  92 
  93 SEC("sk_skb2")
  94 int bpf_prog2(struct __sk_buff *skb)
  95 {
  96         __u32 lport = skb->local_port;
  97         __u32 rport = skb->remote_port;
  98         int len, *f, ret, zero = 0;
  99         __u64 flags = 0;
 100 
 101         if (lport == 10000)
 102                 ret = 10;
 103         else
 104                 ret = 1;
 105 
 106         len = (__u32)skb->data_end - (__u32)skb->data;
 107         f = bpf_map_lookup_elem(&sock_skb_opts, &zero);
 108         if (f && *f) {
 109                 ret = 3;
 110                 flags = *f;
 111         }
 112 
 113         bpf_printk("sk_skb2: redirect(%iB) flags=%i\n",
 114                    len, flags);
 115 #ifdef SOCKMAP
 116         return bpf_sk_redirect_map(skb, &sock_map, ret, flags);
 117 #else
 118         return bpf_sk_redirect_hash(skb, &sock_map, &ret, flags);
 119 #endif
 120 
 121 }
 122 
 123 SEC("sockops")
 124 int bpf_sockmap(struct bpf_sock_ops *skops)
 125 {
 126         __u32 lport, rport;
 127         int op, err = 0, index, key, ret;
 128 
 129 
 130         op = (int) skops->op;
 131 
 132         switch (op) {
 133         case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
 134                 lport = skops->local_port;
 135                 rport = skops->remote_port;
 136 
 137                 if (lport == 10000) {
 138                         ret = 1;
 139 #ifdef SOCKMAP
 140                         err = bpf_sock_map_update(skops, &sock_map, &ret,
 141                                                   BPF_NOEXIST);
 142 #else
 143                         err = bpf_sock_hash_update(skops, &sock_map, &ret,
 144                                                    BPF_NOEXIST);
 145 #endif
 146                         bpf_printk("passive(%i -> %i) map ctx update err: %d\n",
 147                                    lport, bpf_ntohl(rport), err);
 148                 }
 149                 break;
 150         case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
 151                 lport = skops->local_port;
 152                 rport = skops->remote_port;
 153 
 154                 if (bpf_ntohl(rport) == 10001) {
 155                         ret = 10;
 156 #ifdef SOCKMAP
 157                         err = bpf_sock_map_update(skops, &sock_map, &ret,
 158                                                   BPF_NOEXIST);
 159 #else
 160                         err = bpf_sock_hash_update(skops, &sock_map, &ret,
 161                                                    BPF_NOEXIST);
 162 #endif
 163                         bpf_printk("active(%i -> %i) map ctx update err: %d\n",
 164                                    lport, bpf_ntohl(rport), err);
 165                 }
 166                 break;
 167         default:
 168                 break;
 169         }
 170 
 171         return 0;
 172 }
 173 
 174 SEC("sk_msg1")
 175 int bpf_prog4(struct sk_msg_md *msg)
 176 {
 177         int *bytes, zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
 178         int *start, *end, *start_push, *end_push, *start_pop, *pop;
 179 
 180         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
 181         if (bytes)
 182                 bpf_msg_apply_bytes(msg, *bytes);
 183         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
 184         if (bytes)
 185                 bpf_msg_cork_bytes(msg, *bytes);
 186         start = bpf_map_lookup_elem(&sock_bytes, &zero);
 187         end = bpf_map_lookup_elem(&sock_bytes, &one);
 188         if (start && end)
 189                 bpf_msg_pull_data(msg, *start, *end, 0);
 190         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
 191         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
 192         if (start_push && end_push)
 193                 bpf_msg_push_data(msg, *start_push, *end_push, 0);
 194         start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
 195         pop = bpf_map_lookup_elem(&sock_bytes, &five);
 196         if (start_pop && pop)
 197                 bpf_msg_pop_data(msg, *start_pop, *pop, 0);
 198         return SK_PASS;
 199 }
 200 
 201 SEC("sk_msg2")
 202 int bpf_prog5(struct sk_msg_md *msg)
 203 {
 204         int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
 205         int *start, *end, *start_push, *end_push, *start_pop, *pop;
 206         int *bytes, len1, len2 = 0, len3, len4;
 207         int err1 = -1, err2 = -1;
 208 
 209         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
 210         if (bytes)
 211                 err1 = bpf_msg_apply_bytes(msg, *bytes);
 212         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
 213         if (bytes)
 214                 err2 = bpf_msg_cork_bytes(msg, *bytes);
 215         len1 = (__u64)msg->data_end - (__u64)msg->data;
 216         start = bpf_map_lookup_elem(&sock_bytes, &zero);
 217         end = bpf_map_lookup_elem(&sock_bytes, &one);
 218         if (start && end) {
 219                 int err;
 220 
 221                 bpf_printk("sk_msg2: pull(%i:%i)\n",
 222                            start ? *start : 0, end ? *end : 0);
 223                 err = bpf_msg_pull_data(msg, *start, *end, 0);
 224                 if (err)
 225                         bpf_printk("sk_msg2: pull_data err %i\n",
 226                                    err);
 227                 len2 = (__u64)msg->data_end - (__u64)msg->data;
 228                 bpf_printk("sk_msg2: length update %i->%i\n",
 229                            len1, len2);
 230         }
 231 
 232         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
 233         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
 234         if (start_push && end_push) {
 235                 int err;
 236 
 237                 bpf_printk("sk_msg2: push(%i:%i)\n",
 238                            start_push ? *start_push : 0,
 239                            end_push ? *end_push : 0);
 240                 err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
 241                 if (err)
 242                         bpf_printk("sk_msg2: push_data err %i\n", err);
 243                 len3 = (__u64)msg->data_end - (__u64)msg->data;
 244                 bpf_printk("sk_msg2: length push_update %i->%i\n",
 245                            len2 ? len2 : len1, len3);
 246         }
 247         start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
 248         pop = bpf_map_lookup_elem(&sock_bytes, &five);
 249         if (start_pop && pop) {
 250                 int err;
 251 
 252                 bpf_printk("sk_msg2: pop(%i@%i)\n",
 253                            start_pop, pop);
 254                 err = bpf_msg_pop_data(msg, *start_pop, *pop, 0);
 255                 if (err)
 256                         bpf_printk("sk_msg2: pop_data err %i\n", err);
 257                 len4 = (__u64)msg->data_end - (__u64)msg->data;
 258                 bpf_printk("sk_msg2: length pop_data %i->%i\n",
 259                            len1 ? len1 : 0,  len4);
 260         }
 261 
 262         bpf_printk("sk_msg2: data length %i err1 %i err2 %i\n",
 263                    len1, err1, err2);
 264         return SK_PASS;
 265 }
 266 
 267 SEC("sk_msg3")
 268 int bpf_prog6(struct sk_msg_md *msg)
 269 {
 270         int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, key = 0;
 271         int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop, *f;
 272         __u64 flags = 0;
 273 
 274         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
 275         if (bytes)
 276                 bpf_msg_apply_bytes(msg, *bytes);
 277         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
 278         if (bytes)
 279                 bpf_msg_cork_bytes(msg, *bytes);
 280 
 281         start = bpf_map_lookup_elem(&sock_bytes, &zero);
 282         end = bpf_map_lookup_elem(&sock_bytes, &one);
 283         if (start && end)
 284                 bpf_msg_pull_data(msg, *start, *end, 0);
 285 
 286         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
 287         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
 288         if (start_push && end_push)
 289                 bpf_msg_push_data(msg, *start_push, *end_push, 0);
 290 
 291         start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
 292         pop = bpf_map_lookup_elem(&sock_bytes, &five);
 293         if (start_pop && pop)
 294                 bpf_msg_pop_data(msg, *start_pop, *pop, 0);
 295 
 296         f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
 297         if (f && *f) {
 298                 key = 2;
 299                 flags = *f;
 300         }
 301 #ifdef SOCKMAP
 302         return bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
 303 #else
 304         return bpf_msg_redirect_hash(msg, &sock_map_redir, &key, flags);
 305 #endif
 306 }
 307 
 308 SEC("sk_msg4")
 309 int bpf_prog7(struct sk_msg_md *msg)
 310 {
 311         int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop, *f;
 312         int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
 313         int len1, len2 = 0, len3, len4;
 314         int err1 = 0, err2 = 0, key = 0;
 315         __u64 flags = 0;
 316 
 317                 int err;
 318         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
 319         if (bytes)
 320                 err1 = bpf_msg_apply_bytes(msg, *bytes);
 321         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
 322         if (bytes)
 323                 err2 = bpf_msg_cork_bytes(msg, *bytes);
 324         len1 = (__u64)msg->data_end - (__u64)msg->data;
 325 
 326         start = bpf_map_lookup_elem(&sock_bytes, &zero);
 327         end = bpf_map_lookup_elem(&sock_bytes, &one);
 328         if (start && end) {
 329                 bpf_printk("sk_msg2: pull(%i:%i)\n",
 330                            start ? *start : 0, end ? *end : 0);
 331                 err = bpf_msg_pull_data(msg, *start, *end, 0);
 332                 if (err)
 333                         bpf_printk("sk_msg2: pull_data err %i\n",
 334                                    err);
 335                 len2 = (__u64)msg->data_end - (__u64)msg->data;
 336                 bpf_printk("sk_msg2: length update %i->%i\n",
 337                            len1, len2);
 338         }
 339 
 340         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
 341         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
 342         if (start_push && end_push) {
 343                 bpf_printk("sk_msg4: push(%i:%i)\n",
 344                            start_push ? *start_push : 0,
 345                            end_push ? *end_push : 0);
 346                 err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
 347                 if (err)
 348                         bpf_printk("sk_msg4: push_data err %i\n",
 349                                    err);
 350                 len3 = (__u64)msg->data_end - (__u64)msg->data;
 351                 bpf_printk("sk_msg4: length push_update %i->%i\n",
 352                            len2 ? len2 : len1, len3);
 353         }
 354 
 355         start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
 356         pop = bpf_map_lookup_elem(&sock_bytes, &five);
 357         if (start_pop && pop) {
 358                 int err;
 359 
 360                 bpf_printk("sk_msg4: pop(%i@%i)\n",
 361                            start_pop, pop);
 362                 err = bpf_msg_pop_data(msg, *start_pop, *pop, 0);
 363                 if (err)
 364                         bpf_printk("sk_msg4: pop_data err %i\n", err);
 365                 len4 = (__u64)msg->data_end - (__u64)msg->data;
 366                 bpf_printk("sk_msg4: length pop_data %i->%i\n",
 367                            len1 ? len1 : 0,  len4);
 368         }
 369 
 370 
 371         f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
 372         if (f && *f) {
 373                 key = 2;
 374                 flags = *f;
 375         }
 376         bpf_printk("sk_msg3: redirect(%iB) flags=%i err=%i\n",
 377                    len1, flags, err1 ? err1 : err2);
 378 #ifdef SOCKMAP
 379         err = bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
 380 #else
 381         err = bpf_msg_redirect_hash(msg, &sock_map_redir, &key, flags);
 382 #endif
 383         bpf_printk("sk_msg3: err %i\n", err);
 384         return err;
 385 }
 386 
 387 SEC("sk_msg5")
 388 int bpf_prog8(struct sk_msg_md *msg)
 389 {
 390         void *data_end = (void *)(long) msg->data_end;
 391         void *data = (void *)(long) msg->data;
 392         int ret = 0, *bytes, zero = 0;
 393 
 394         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
 395         if (bytes) {
 396                 ret = bpf_msg_apply_bytes(msg, *bytes);
 397                 if (ret)
 398                         return SK_DROP;
 399         } else {
 400                 return SK_DROP;
 401         }
 402         return SK_PASS;
 403 }
 404 SEC("sk_msg6")
 405 int bpf_prog9(struct sk_msg_md *msg)
 406 {
 407         void *data_end = (void *)(long) msg->data_end;
 408         void *data = (void *)(long) msg->data;
 409         int ret = 0, *bytes, zero = 0;
 410 
 411         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
 412         if (bytes) {
 413                 if (((__u64)data_end - (__u64)data) >= *bytes)
 414                         return SK_PASS;
 415                 ret = bpf_msg_cork_bytes(msg, *bytes);
 416                 if (ret)
 417                         return SK_DROP;
 418         }
 419         return SK_PASS;
 420 }
 421 
 422 SEC("sk_msg7")
 423 int bpf_prog10(struct sk_msg_md *msg)
 424 {
 425         int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop;
 426         int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
 427 
 428         bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
 429         if (bytes)
 430                 bpf_msg_apply_bytes(msg, *bytes);
 431         bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
 432         if (bytes)
 433                 bpf_msg_cork_bytes(msg, *bytes);
 434         start = bpf_map_lookup_elem(&sock_bytes, &zero);
 435         end = bpf_map_lookup_elem(&sock_bytes, &one);
 436         if (start && end)
 437                 bpf_msg_pull_data(msg, *start, *end, 0);
 438         start_push = bpf_map_lookup_elem(&sock_bytes, &two);
 439         end_push = bpf_map_lookup_elem(&sock_bytes, &three);
 440         if (start_push && end_push)
 441                 bpf_msg_push_data(msg, *start_push, *end_push, 0);
 442         start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
 443         pop = bpf_map_lookup_elem(&sock_bytes, &five);
 444         if (start_pop && pop)
 445                 bpf_msg_pop_data(msg, *start_pop, *pop, 0);
 446         bpf_printk("return sk drop\n");
 447         return SK_DROP;
 448 }
 449 
 450 int _version SEC("version") = 1;
 451 char _license[] SEC("license") = "GPL";

/* [<][>][^][v][top][bottom][index][help] */