Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.4-rc1 451 lines 12 kB view raw
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 31struct { 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 38struct { 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 45struct { 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 52struct { 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 59struct { 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 66struct { 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 73struct { 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 80struct { 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 87SEC("sk_skb1") 88int bpf_prog1(struct __sk_buff *skb) 89{ 90 return skb->len; 91} 92 93SEC("sk_skb2") 94int 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 123SEC("sockops") 124int 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 174SEC("sk_msg1") 175int 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 201SEC("sk_msg2") 202int 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 267SEC("sk_msg3") 268int 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 308SEC("sk_msg4") 309int 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 387SEC("sk_msg5") 388int 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} 404SEC("sk_msg6") 405int 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 422SEC("sk_msg7") 423int 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 450int _version SEC("version") = 1; 451char _license[] SEC("license") = "GPL";