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 v4.17-rc3 341 lines 8.7 kB view raw
1/* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io 2 * 3 * This program is free software; you can redistribute it and/or 4 * modify it under the terms of version 2 of the GNU General Public 5 * License as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, but 8 * WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 * General Public License for more details. 11 */ 12#include <uapi/linux/bpf.h> 13#include <uapi/linux/if_ether.h> 14#include <uapi/linux/if_packet.h> 15#include <uapi/linux/ip.h> 16#include "../../tools/testing/selftests/bpf/bpf_helpers.h" 17#include "../../tools/testing/selftests/bpf/bpf_endian.h" 18 19/* Sockmap sample program connects a client and a backend together 20 * using cgroups. 21 * 22 * client:X <---> frontend:80 client:X <---> backend:80 23 * 24 * For simplicity we hard code values here and bind 1:1. The hard 25 * coded values are part of the setup in sockmap.sh script that 26 * is associated with this BPF program. 27 * 28 * The bpf_printk is verbose and prints information as connections 29 * are established and verdicts are decided. 30 */ 31 32#define bpf_printk(fmt, ...) \ 33({ \ 34 char ____fmt[] = fmt; \ 35 bpf_trace_printk(____fmt, sizeof(____fmt), \ 36 ##__VA_ARGS__); \ 37}) 38 39struct bpf_map_def SEC("maps") sock_map = { 40 .type = BPF_MAP_TYPE_SOCKMAP, 41 .key_size = sizeof(int), 42 .value_size = sizeof(int), 43 .max_entries = 20, 44}; 45 46struct bpf_map_def SEC("maps") sock_map_txmsg = { 47 .type = BPF_MAP_TYPE_SOCKMAP, 48 .key_size = sizeof(int), 49 .value_size = sizeof(int), 50 .max_entries = 20, 51}; 52 53struct bpf_map_def SEC("maps") sock_map_redir = { 54 .type = BPF_MAP_TYPE_SOCKMAP, 55 .key_size = sizeof(int), 56 .value_size = sizeof(int), 57 .max_entries = 20, 58}; 59 60struct bpf_map_def SEC("maps") sock_apply_bytes = { 61 .type = BPF_MAP_TYPE_ARRAY, 62 .key_size = sizeof(int), 63 .value_size = sizeof(int), 64 .max_entries = 1 65}; 66 67struct bpf_map_def SEC("maps") sock_cork_bytes = { 68 .type = BPF_MAP_TYPE_ARRAY, 69 .key_size = sizeof(int), 70 .value_size = sizeof(int), 71 .max_entries = 1 72}; 73 74struct bpf_map_def SEC("maps") sock_pull_bytes = { 75 .type = BPF_MAP_TYPE_ARRAY, 76 .key_size = sizeof(int), 77 .value_size = sizeof(int), 78 .max_entries = 2 79}; 80 81struct bpf_map_def SEC("maps") sock_redir_flags = { 82 .type = BPF_MAP_TYPE_ARRAY, 83 .key_size = sizeof(int), 84 .value_size = sizeof(int), 85 .max_entries = 1 86}; 87 88struct bpf_map_def SEC("maps") sock_skb_opts = { 89 .type = BPF_MAP_TYPE_ARRAY, 90 .key_size = sizeof(int), 91 .value_size = sizeof(int), 92 .max_entries = 1 93}; 94 95SEC("sk_skb1") 96int bpf_prog1(struct __sk_buff *skb) 97{ 98 return skb->len; 99} 100 101SEC("sk_skb2") 102int bpf_prog2(struct __sk_buff *skb) 103{ 104 __u32 lport = skb->local_port; 105 __u32 rport = skb->remote_port; 106 int len, *f, ret, zero = 0; 107 __u64 flags = 0; 108 109 if (lport == 10000) 110 ret = 10; 111 else 112 ret = 1; 113 114 len = (__u32)skb->data_end - (__u32)skb->data; 115 f = bpf_map_lookup_elem(&sock_skb_opts, &zero); 116 if (f && *f) { 117 ret = 3; 118 flags = *f; 119 } 120 121 bpf_printk("sk_skb2: redirect(%iB) flags=%i\n", 122 len, flags); 123 return bpf_sk_redirect_map(skb, &sock_map, ret, flags); 124} 125 126SEC("sockops") 127int bpf_sockmap(struct bpf_sock_ops *skops) 128{ 129 __u32 lport, rport; 130 int op, err = 0, index, key, ret; 131 132 133 op = (int) skops->op; 134 135 switch (op) { 136 case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: 137 lport = skops->local_port; 138 rport = skops->remote_port; 139 140 if (lport == 10000) { 141 ret = 1; 142 err = bpf_sock_map_update(skops, &sock_map, &ret, 143 BPF_NOEXIST); 144 bpf_printk("passive(%i -> %i) map ctx update err: %d\n", 145 lport, bpf_ntohl(rport), err); 146 } 147 break; 148 case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: 149 lport = skops->local_port; 150 rport = skops->remote_port; 151 152 if (bpf_ntohl(rport) == 10001) { 153 ret = 10; 154 err = bpf_sock_map_update(skops, &sock_map, &ret, 155 BPF_NOEXIST); 156 bpf_printk("active(%i -> %i) map ctx update err: %d\n", 157 lport, bpf_ntohl(rport), err); 158 } 159 break; 160 default: 161 break; 162 } 163 164 return 0; 165} 166 167SEC("sk_msg1") 168int bpf_prog4(struct sk_msg_md *msg) 169{ 170 int *bytes, zero = 0, one = 1; 171 int *start, *end; 172 173 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 174 if (bytes) 175 bpf_msg_apply_bytes(msg, *bytes); 176 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); 177 if (bytes) 178 bpf_msg_cork_bytes(msg, *bytes); 179 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero); 180 end = bpf_map_lookup_elem(&sock_pull_bytes, &one); 181 if (start && end) 182 bpf_msg_pull_data(msg, *start, *end, 0); 183 return SK_PASS; 184} 185 186SEC("sk_msg2") 187int bpf_prog5(struct sk_msg_md *msg) 188{ 189 int err1 = -1, err2 = -1, zero = 0, one = 1; 190 int *bytes, *start, *end, len1, len2; 191 192 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 193 if (bytes) 194 err1 = bpf_msg_apply_bytes(msg, *bytes); 195 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); 196 if (bytes) 197 err2 = bpf_msg_cork_bytes(msg, *bytes); 198 len1 = (__u64)msg->data_end - (__u64)msg->data; 199 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero); 200 end = bpf_map_lookup_elem(&sock_pull_bytes, &one); 201 if (start && end) { 202 int err; 203 204 bpf_printk("sk_msg2: pull(%i:%i)\n", 205 start ? *start : 0, end ? *end : 0); 206 err = bpf_msg_pull_data(msg, *start, *end, 0); 207 if (err) 208 bpf_printk("sk_msg2: pull_data err %i\n", 209 err); 210 len2 = (__u64)msg->data_end - (__u64)msg->data; 211 bpf_printk("sk_msg2: length update %i->%i\n", 212 len1, len2); 213 } 214 bpf_printk("sk_msg2: data length %i err1 %i err2 %i\n", 215 len1, err1, err2); 216 return SK_PASS; 217} 218 219SEC("sk_msg3") 220int bpf_prog6(struct sk_msg_md *msg) 221{ 222 int *bytes, zero = 0, one = 1, key = 0; 223 int *start, *end, *f; 224 __u64 flags = 0; 225 226 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 227 if (bytes) 228 bpf_msg_apply_bytes(msg, *bytes); 229 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); 230 if (bytes) 231 bpf_msg_cork_bytes(msg, *bytes); 232 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero); 233 end = bpf_map_lookup_elem(&sock_pull_bytes, &one); 234 if (start && end) 235 bpf_msg_pull_data(msg, *start, *end, 0); 236 f = bpf_map_lookup_elem(&sock_redir_flags, &zero); 237 if (f && *f) { 238 key = 2; 239 flags = *f; 240 } 241 return bpf_msg_redirect_map(msg, &sock_map_redir, key, flags); 242} 243 244SEC("sk_msg4") 245int bpf_prog7(struct sk_msg_md *msg) 246{ 247 int err1 = 0, err2 = 0, zero = 0, one = 1, key = 0; 248 int *f, *bytes, *start, *end, len1, len2; 249 __u64 flags = 0; 250 251 int err; 252 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 253 if (bytes) 254 err1 = bpf_msg_apply_bytes(msg, *bytes); 255 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); 256 if (bytes) 257 err2 = bpf_msg_cork_bytes(msg, *bytes); 258 len1 = (__u64)msg->data_end - (__u64)msg->data; 259 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero); 260 end = bpf_map_lookup_elem(&sock_pull_bytes, &one); 261 if (start && end) { 262 263 bpf_printk("sk_msg2: pull(%i:%i)\n", 264 start ? *start : 0, end ? *end : 0); 265 err = bpf_msg_pull_data(msg, *start, *end, 0); 266 if (err) 267 bpf_printk("sk_msg2: pull_data err %i\n", 268 err); 269 len2 = (__u64)msg->data_end - (__u64)msg->data; 270 bpf_printk("sk_msg2: length update %i->%i\n", 271 len1, len2); 272 } 273 f = bpf_map_lookup_elem(&sock_redir_flags, &zero); 274 if (f && *f) { 275 key = 2; 276 flags = *f; 277 } 278 bpf_printk("sk_msg3: redirect(%iB) flags=%i err=%i\n", 279 len1, flags, err1 ? err1 : err2); 280 err = bpf_msg_redirect_map(msg, &sock_map_redir, key, flags); 281 bpf_printk("sk_msg3: err %i\n", err); 282 return err; 283} 284 285SEC("sk_msg5") 286int bpf_prog8(struct sk_msg_md *msg) 287{ 288 void *data_end = (void *)(long) msg->data_end; 289 void *data = (void *)(long) msg->data; 290 int ret = 0, *bytes, zero = 0; 291 292 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 293 if (bytes) { 294 ret = bpf_msg_apply_bytes(msg, *bytes); 295 if (ret) 296 return SK_DROP; 297 } else { 298 return SK_DROP; 299 } 300 return SK_PASS; 301} 302SEC("sk_msg6") 303int bpf_prog9(struct sk_msg_md *msg) 304{ 305 void *data_end = (void *)(long) msg->data_end; 306 void *data = (void *)(long) msg->data; 307 int ret = 0, *bytes, zero = 0; 308 309 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); 310 if (bytes) { 311 if (((__u64)data_end - (__u64)data) >= *bytes) 312 return SK_PASS; 313 ret = bpf_msg_cork_bytes(msg, *bytes); 314 if (ret) 315 return SK_DROP; 316 } 317 return SK_PASS; 318} 319 320SEC("sk_msg7") 321int bpf_prog10(struct sk_msg_md *msg) 322{ 323 int *bytes, zero = 0, one = 1; 324 int *start, *end; 325 326 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero); 327 if (bytes) 328 bpf_msg_apply_bytes(msg, *bytes); 329 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero); 330 if (bytes) 331 bpf_msg_cork_bytes(msg, *bytes); 332 start = bpf_map_lookup_elem(&sock_pull_bytes, &zero); 333 end = bpf_map_lookup_elem(&sock_pull_bytes, &one); 334 if (start && end) 335 bpf_msg_pull_data(msg, *start, *end, 0); 336 337 return SK_DROP; 338} 339 340 341char _license[] SEC("license") = "GPL";