0001
0002
0003 #include <stddef.h>
0004 #include <string.h>
0005 #include <linux/bpf.h>
0006 #include <linux/if_ether.h>
0007 #include <linux/if_packet.h>
0008 #include <linux/ip.h>
0009 #include <linux/ipv6.h>
0010 #include <linux/in.h>
0011 #include <linux/udp.h>
0012 #include <linux/tcp.h>
0013 #include <linux/pkt_cls.h>
0014 #include <sys/socket.h>
0015 #include <bpf/bpf_helpers.h>
0016 #include <bpf/bpf_endian.h>
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 struct {
0032 __uint(type, TEST_MAP_TYPE);
0033 __uint(max_entries, 20);
0034 __uint(key_size, sizeof(int));
0035 __uint(value_size, sizeof(int));
0036 } sock_map SEC(".maps");
0037
0038 struct {
0039 __uint(type, TEST_MAP_TYPE);
0040 __uint(max_entries, 20);
0041 __uint(key_size, sizeof(int));
0042 __uint(value_size, sizeof(int));
0043 } sock_map_txmsg SEC(".maps");
0044
0045 struct {
0046 __uint(type, TEST_MAP_TYPE);
0047 __uint(max_entries, 20);
0048 __uint(key_size, sizeof(int));
0049 __uint(value_size, sizeof(int));
0050 } sock_map_redir SEC(".maps");
0051
0052 struct {
0053 __uint(type, BPF_MAP_TYPE_ARRAY);
0054 __uint(max_entries, 1);
0055 __type(key, int);
0056 __type(value, int);
0057 } sock_apply_bytes SEC(".maps");
0058
0059 struct {
0060 __uint(type, BPF_MAP_TYPE_ARRAY);
0061 __uint(max_entries, 1);
0062 __type(key, int);
0063 __type(value, int);
0064 } sock_cork_bytes SEC(".maps");
0065
0066 struct {
0067 __uint(type, BPF_MAP_TYPE_ARRAY);
0068 __uint(max_entries, 6);
0069 __type(key, int);
0070 __type(value, int);
0071 } sock_bytes SEC(".maps");
0072
0073 struct {
0074 __uint(type, BPF_MAP_TYPE_ARRAY);
0075 __uint(max_entries, 1);
0076 __type(key, int);
0077 __type(value, int);
0078 } sock_redir_flags SEC(".maps");
0079
0080 struct {
0081 __uint(type, BPF_MAP_TYPE_ARRAY);
0082 __uint(max_entries, 3);
0083 __type(key, int);
0084 __type(value, int);
0085 } sock_skb_opts SEC(".maps");
0086
0087 struct {
0088 __uint(type, TEST_MAP_TYPE);
0089 __uint(max_entries, 20);
0090 __uint(key_size, sizeof(int));
0091 __uint(value_size, sizeof(int));
0092 } tls_sock_map SEC(".maps");
0093
0094 SEC("sk_skb1")
0095 int bpf_prog1(struct __sk_buff *skb)
0096 {
0097 int *f, two = 2;
0098
0099 f = bpf_map_lookup_elem(&sock_skb_opts, &two);
0100 if (f && *f) {
0101 return *f;
0102 }
0103 return skb->len;
0104 }
0105
0106 SEC("sk_skb2")
0107 int bpf_prog2(struct __sk_buff *skb)
0108 {
0109 __u32 lport = skb->local_port;
0110 __u32 rport = skb->remote_port;
0111 int len, *f, ret, zero = 0;
0112 __u64 flags = 0;
0113
0114 if (lport == 10000)
0115 ret = 10;
0116 else
0117 ret = 1;
0118
0119 len = (__u32)skb->data_end - (__u32)skb->data;
0120 f = bpf_map_lookup_elem(&sock_skb_opts, &zero);
0121 if (f && *f) {
0122 ret = 3;
0123 flags = *f;
0124 }
0125
0126 #ifdef SOCKMAP
0127 return bpf_sk_redirect_map(skb, &sock_map, ret, flags);
0128 #else
0129 return bpf_sk_redirect_hash(skb, &sock_map, &ret, flags);
0130 #endif
0131
0132 }
0133
0134 static inline void bpf_write_pass(struct __sk_buff *skb, int offset)
0135 {
0136 int err = bpf_skb_pull_data(skb, 6 + offset);
0137 void *data_end;
0138 char *c;
0139
0140 if (err)
0141 return;
0142
0143 c = (char *)(long)skb->data;
0144 data_end = (void *)(long)skb->data_end;
0145
0146 if (c + 5 + offset < data_end)
0147 memcpy(c + offset, "PASS", 4);
0148 }
0149
0150 SEC("sk_skb3")
0151 int bpf_prog3(struct __sk_buff *skb)
0152 {
0153 int err, *f, ret = SK_PASS;
0154 const int one = 1;
0155
0156 f = bpf_map_lookup_elem(&sock_skb_opts, &one);
0157 if (f && *f) {
0158 __u64 flags = 0;
0159
0160 ret = 0;
0161 flags = *f;
0162
0163 err = bpf_skb_adjust_room(skb, -13, 0, 0);
0164 if (err)
0165 return SK_DROP;
0166 err = bpf_skb_adjust_room(skb, 4, 0, 0);
0167 if (err)
0168 return SK_DROP;
0169 bpf_write_pass(skb, 0);
0170 #ifdef SOCKMAP
0171 return bpf_sk_redirect_map(skb, &tls_sock_map, ret, flags);
0172 #else
0173 return bpf_sk_redirect_hash(skb, &tls_sock_map, &ret, flags);
0174 #endif
0175 }
0176 f = bpf_map_lookup_elem(&sock_skb_opts, &one);
0177 if (f && *f)
0178 ret = SK_DROP;
0179 err = bpf_skb_adjust_room(skb, 4, 0, 0);
0180 if (err)
0181 return SK_DROP;
0182 bpf_write_pass(skb, 13);
0183 tls_out:
0184 return ret;
0185 }
0186
0187 SEC("sockops")
0188 int bpf_sockmap(struct bpf_sock_ops *skops)
0189 {
0190 __u32 lport, rport;
0191 int op, err = 0, index, key, ret;
0192
0193
0194 op = (int) skops->op;
0195
0196 switch (op) {
0197 case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
0198 lport = skops->local_port;
0199 rport = skops->remote_port;
0200
0201 if (lport == 10000) {
0202 ret = 1;
0203 #ifdef SOCKMAP
0204 err = bpf_sock_map_update(skops, &sock_map, &ret,
0205 BPF_NOEXIST);
0206 #else
0207 err = bpf_sock_hash_update(skops, &sock_map, &ret,
0208 BPF_NOEXIST);
0209 #endif
0210 }
0211 break;
0212 case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
0213 lport = skops->local_port;
0214 rport = skops->remote_port;
0215
0216 if (bpf_ntohl(rport) == 10001) {
0217 ret = 10;
0218 #ifdef SOCKMAP
0219 err = bpf_sock_map_update(skops, &sock_map, &ret,
0220 BPF_NOEXIST);
0221 #else
0222 err = bpf_sock_hash_update(skops, &sock_map, &ret,
0223 BPF_NOEXIST);
0224 #endif
0225 }
0226 break;
0227 default:
0228 break;
0229 }
0230
0231 return 0;
0232 }
0233
0234 SEC("sk_msg1")
0235 int bpf_prog4(struct sk_msg_md *msg)
0236 {
0237 int *bytes, zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
0238 int *start, *end, *start_push, *end_push, *start_pop, *pop, err = 0;
0239
0240 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
0241 if (bytes)
0242 bpf_msg_apply_bytes(msg, *bytes);
0243 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
0244 if (bytes)
0245 bpf_msg_cork_bytes(msg, *bytes);
0246 start = bpf_map_lookup_elem(&sock_bytes, &zero);
0247 end = bpf_map_lookup_elem(&sock_bytes, &one);
0248 if (start && end)
0249 bpf_msg_pull_data(msg, *start, *end, 0);
0250 start_push = bpf_map_lookup_elem(&sock_bytes, &two);
0251 end_push = bpf_map_lookup_elem(&sock_bytes, &three);
0252 if (start_push && end_push) {
0253 err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
0254 if (err)
0255 return SK_DROP;
0256 }
0257 start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
0258 pop = bpf_map_lookup_elem(&sock_bytes, &five);
0259 if (start_pop && pop)
0260 bpf_msg_pop_data(msg, *start_pop, *pop, 0);
0261 return SK_PASS;
0262 }
0263
0264 SEC("sk_msg2")
0265 int bpf_prog6(struct sk_msg_md *msg)
0266 {
0267 int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, key = 0;
0268 int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop, *f;
0269 int err = 0;
0270 __u64 flags = 0;
0271
0272 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
0273 if (bytes)
0274 bpf_msg_apply_bytes(msg, *bytes);
0275 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
0276 if (bytes)
0277 bpf_msg_cork_bytes(msg, *bytes);
0278
0279 start = bpf_map_lookup_elem(&sock_bytes, &zero);
0280 end = bpf_map_lookup_elem(&sock_bytes, &one);
0281 if (start && end)
0282 bpf_msg_pull_data(msg, *start, *end, 0);
0283
0284 start_push = bpf_map_lookup_elem(&sock_bytes, &two);
0285 end_push = bpf_map_lookup_elem(&sock_bytes, &three);
0286 if (start_push && end_push) {
0287 err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
0288 if (err)
0289 return SK_DROP;
0290 }
0291
0292 start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
0293 pop = bpf_map_lookup_elem(&sock_bytes, &five);
0294 if (start_pop && pop)
0295 bpf_msg_pop_data(msg, *start_pop, *pop, 0);
0296
0297 f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
0298 if (f && *f) {
0299 key = 2;
0300 flags = *f;
0301 }
0302 #ifdef SOCKMAP
0303 return bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
0304 #else
0305 return bpf_msg_redirect_hash(msg, &sock_map_redir, &key, flags);
0306 #endif
0307 }
0308
0309 SEC("sk_msg3")
0310 int bpf_prog8(struct sk_msg_md *msg)
0311 {
0312 void *data_end = (void *)(long) msg->data_end;
0313 void *data = (void *)(long) msg->data;
0314 int ret = 0, *bytes, zero = 0;
0315
0316 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
0317 if (bytes) {
0318 ret = bpf_msg_apply_bytes(msg, *bytes);
0319 if (ret)
0320 return SK_DROP;
0321 } else {
0322 return SK_DROP;
0323 }
0324 return SK_PASS;
0325 }
0326 SEC("sk_msg4")
0327 int bpf_prog9(struct sk_msg_md *msg)
0328 {
0329 void *data_end = (void *)(long) msg->data_end;
0330 void *data = (void *)(long) msg->data;
0331 int ret = 0, *bytes, zero = 0;
0332
0333 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
0334 if (bytes) {
0335 if (((__u64)data_end - (__u64)data) >= *bytes)
0336 return SK_PASS;
0337 ret = bpf_msg_cork_bytes(msg, *bytes);
0338 if (ret)
0339 return SK_DROP;
0340 }
0341 return SK_PASS;
0342 }
0343
0344 SEC("sk_msg5")
0345 int bpf_prog10(struct sk_msg_md *msg)
0346 {
0347 int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop;
0348 int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, err = 0;
0349
0350 bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
0351 if (bytes)
0352 bpf_msg_apply_bytes(msg, *bytes);
0353 bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
0354 if (bytes)
0355 bpf_msg_cork_bytes(msg, *bytes);
0356 start = bpf_map_lookup_elem(&sock_bytes, &zero);
0357 end = bpf_map_lookup_elem(&sock_bytes, &one);
0358 if (start && end)
0359 bpf_msg_pull_data(msg, *start, *end, 0);
0360 start_push = bpf_map_lookup_elem(&sock_bytes, &two);
0361 end_push = bpf_map_lookup_elem(&sock_bytes, &three);
0362 if (start_push && end_push) {
0363 err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
0364 if (err)
0365 return SK_PASS;
0366 }
0367 start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
0368 pop = bpf_map_lookup_elem(&sock_bytes, &five);
0369 if (start_pop && pop)
0370 bpf_msg_pop_data(msg, *start_pop, *pop, 0);
0371 return SK_DROP;
0372 }
0373
0374 char _license[] SEC("license") = "GPL";