aboutsummaryrefslogtreecommitdiffstats
path: root/samples/bpf
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 12:00:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 12:00:47 -0400
commit6c373ca89399c5a3f7ef210ad8f63dc3437da345 (patch)
tree74d1ec65087df1da1021b43ac51acc1ee8601809 /samples/bpf
parentbb0fd7ab0986105765d11baa82e619c618a235aa (diff)
parent9f9151412dd7aae0e3f51a89ae4a1f8755fdb4d0 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) Add BQL support to via-rhine, from Tino Reichardt. 2) Integrate SWITCHDEV layer support into the DSA layer, so DSA drivers can support hw switch offloading. From Floria Fainelli. 3) Allow 'ip address' commands to initiate multicast group join/leave, from Madhu Challa. 4) Many ipv4 FIB lookup optimizations from Alexander Duyck. 5) Support EBPF in cls_bpf classifier and act_bpf action, from Daniel Borkmann. 6) Remove the ugly compat support in ARP for ugly layers like ax25, rose, etc. And use this to clean up the neigh layer, then use it to implement MPLS support. All from Eric Biederman. 7) Support L3 forwarding offloading in switches, from Scott Feldman. 8) Collapse the LOCAL and MAIN ipv4 FIB tables when possible, to speed up route lookups even further. From Alexander Duyck. 9) Many improvements and bug fixes to the rhashtable implementation, from Herbert Xu and Thomas Graf. In particular, in the case where an rhashtable user bulk adds a large number of items into an empty table, we expand the table much more sanely. 10) Don't make the tcp_metrics hash table per-namespace, from Eric Biederman. 11) Extend EBPF to access SKB fields, from Alexei Starovoitov. 12) Split out new connection request sockets so that they can be established in the main hash table. Much less false sharing since hash lookups go direct to the request sockets instead of having to go first to the listener then to the request socks hashed underneath. From Eric Dumazet. 13) Add async I/O support for crytpo AF_ALG sockets, from Tadeusz Struk. 14) Support stable privacy address generation for RFC7217 in IPV6. From Hannes Frederic Sowa. 15) Hash network namespace into IP frag IDs, also from Hannes Frederic Sowa. 16) Convert PTP get/set methods to use 64-bit time, from Richard Cochran. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1816 commits) fm10k: Bump driver version to 0.15.2 fm10k: corrected VF multicast update fm10k: mbx_update_max_size does not drop all oversized messages fm10k: reset head instead of calling update_max_size fm10k: renamed mbx_tx_dropped to mbx_tx_oversized fm10k: update xcast mode before synchronizing multicast addresses fm10k: start service timer on probe fm10k: fix function header comment fm10k: comment next_vf_mbx flow fm10k: don't handle mailbox events in iov_event path and always process mailbox fm10k: use separate workqueue for fm10k driver fm10k: Set PF queues to unlimited bandwidth during virtualization fm10k: expose tx_timeout_count as an ethtool stat fm10k: only increment tx_timeout_count in Tx hang path fm10k: remove extraneous "Reset interface" message fm10k: separate PF only stats so that VF does not display them fm10k: use hw->mac.max_queues for stats fm10k: only show actual queues, not the maximum in hardware fm10k: allow creation of VLAN on default vid fm10k: fix unused warnings ...
Diffstat (limited to 'samples/bpf')
-rw-r--r--samples/bpf/Makefile1
-rw-r--r--samples/bpf/bpf_helpers.h7
-rw-r--r--samples/bpf/libbpf.h4
-rw-r--r--samples/bpf/sockex1_kern.c8
-rw-r--r--samples/bpf/sockex1_user.c2
-rw-r--r--samples/bpf/sockex2_kern.c26
-rw-r--r--samples/bpf/sockex2_user.c11
-rw-r--r--samples/bpf/tcbpf1_kern.c71
-rw-r--r--samples/bpf/test_verifier.c84
9 files changed, 195 insertions, 19 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index fe98fb226e6e..76e3458a5419 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -29,6 +29,7 @@ always += tracex1_kern.o
29always += tracex2_kern.o 29always += tracex2_kern.o
30always += tracex3_kern.o 30always += tracex3_kern.o
31always += tracex4_kern.o 31always += tracex4_kern.o
32always += tcbpf1_kern.o
32 33
33HOSTCFLAGS += -I$(objtree)/usr/include 34HOSTCFLAGS += -I$(objtree)/usr/include
34 35
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h
index 1c872bcf5a80..f960b5fb3ed8 100644
--- a/samples/bpf/bpf_helpers.h
+++ b/samples/bpf/bpf_helpers.h
@@ -43,4 +43,11 @@ struct bpf_map_def {
43 unsigned int max_entries; 43 unsigned int max_entries;
44}; 44};
45 45
46static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) =
47 (void *) BPF_FUNC_skb_store_bytes;
48static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flags) =
49 (void *) BPF_FUNC_l3_csum_replace;
50static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flags) =
51 (void *) BPF_FUNC_l4_csum_replace;
52
46#endif 53#endif
diff --git a/samples/bpf/libbpf.h b/samples/bpf/libbpf.h
index ac7b09672b46..7235e292a03b 100644
--- a/samples/bpf/libbpf.h
+++ b/samples/bpf/libbpf.h
@@ -92,7 +92,9 @@ extern char bpf_log_buf[LOG_BUF_SIZE];
92 .off = 0, \ 92 .off = 0, \
93 .imm = ((__u64) (IMM)) >> 32 }) 93 .imm = ((__u64) (IMM)) >> 32 })
94 94
95#define BPF_PSEUDO_MAP_FD 1 95#ifndef BPF_PSEUDO_MAP_FD
96# define BPF_PSEUDO_MAP_FD 1
97#endif
96 98
97/* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */ 99/* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
98#define BPF_LD_MAP_FD(DST, MAP_FD) \ 100#define BPF_LD_MAP_FD(DST, MAP_FD) \
diff --git a/samples/bpf/sockex1_kern.c b/samples/bpf/sockex1_kern.c
index 066892662915..ed18e9a4909c 100644
--- a/samples/bpf/sockex1_kern.c
+++ b/samples/bpf/sockex1_kern.c
@@ -1,5 +1,6 @@
1#include <uapi/linux/bpf.h> 1#include <uapi/linux/bpf.h>
2#include <uapi/linux/if_ether.h> 2#include <uapi/linux/if_ether.h>
3#include <uapi/linux/if_packet.h>
3#include <uapi/linux/ip.h> 4#include <uapi/linux/ip.h>
4#include "bpf_helpers.h" 5#include "bpf_helpers.h"
5 6
@@ -11,14 +12,17 @@ struct bpf_map_def SEC("maps") my_map = {
11}; 12};
12 13
13SEC("socket1") 14SEC("socket1")
14int bpf_prog1(struct sk_buff *skb) 15int bpf_prog1(struct __sk_buff *skb)
15{ 16{
16 int index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol)); 17 int index = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
17 long *value; 18 long *value;
18 19
20 if (skb->pkt_type != PACKET_OUTGOING)
21 return 0;
22
19 value = bpf_map_lookup_elem(&my_map, &index); 23 value = bpf_map_lookup_elem(&my_map, &index);
20 if (value) 24 if (value)
21 __sync_fetch_and_add(value, 1); 25 __sync_fetch_and_add(value, skb->len);
22 26
23 return 0; 27 return 0;
24} 28}
diff --git a/samples/bpf/sockex1_user.c b/samples/bpf/sockex1_user.c
index 34a443ff3831..678ce4693551 100644
--- a/samples/bpf/sockex1_user.c
+++ b/samples/bpf/sockex1_user.c
@@ -40,7 +40,7 @@ int main(int ac, char **argv)
40 key = IPPROTO_ICMP; 40 key = IPPROTO_ICMP;
41 assert(bpf_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0); 41 assert(bpf_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0);
42 42
43 printf("TCP %lld UDP %lld ICMP %lld packets\n", 43 printf("TCP %lld UDP %lld ICMP %lld bytes\n",
44 tcp_cnt, udp_cnt, icmp_cnt); 44 tcp_cnt, udp_cnt, icmp_cnt);
45 sleep(1); 45 sleep(1);
46 } 46 }
diff --git a/samples/bpf/sockex2_kern.c b/samples/bpf/sockex2_kern.c
index 6f0135f0f217..ba0e177ff561 100644
--- a/samples/bpf/sockex2_kern.c
+++ b/samples/bpf/sockex2_kern.c
@@ -42,13 +42,13 @@ static inline int proto_ports_offset(__u64 proto)
42 } 42 }
43} 43}
44 44
45static inline int ip_is_fragment(struct sk_buff *ctx, __u64 nhoff) 45static inline int ip_is_fragment(struct __sk_buff *ctx, __u64 nhoff)
46{ 46{
47 return load_half(ctx, nhoff + offsetof(struct iphdr, frag_off)) 47 return load_half(ctx, nhoff + offsetof(struct iphdr, frag_off))
48 & (IP_MF | IP_OFFSET); 48 & (IP_MF | IP_OFFSET);
49} 49}
50 50
51static inline __u32 ipv6_addr_hash(struct sk_buff *ctx, __u64 off) 51static inline __u32 ipv6_addr_hash(struct __sk_buff *ctx, __u64 off)
52{ 52{
53 __u64 w0 = load_word(ctx, off); 53 __u64 w0 = load_word(ctx, off);
54 __u64 w1 = load_word(ctx, off + 4); 54 __u64 w1 = load_word(ctx, off + 4);
@@ -58,7 +58,7 @@ static inline __u32 ipv6_addr_hash(struct sk_buff *ctx, __u64 off)
58 return (__u32)(w0 ^ w1 ^ w2 ^ w3); 58 return (__u32)(w0 ^ w1 ^ w2 ^ w3);
59} 59}
60 60
61static inline __u64 parse_ip(struct sk_buff *skb, __u64 nhoff, __u64 *ip_proto, 61static inline __u64 parse_ip(struct __sk_buff *skb, __u64 nhoff, __u64 *ip_proto,
62 struct flow_keys *flow) 62 struct flow_keys *flow)
63{ 63{
64 __u64 verlen; 64 __u64 verlen;
@@ -82,7 +82,7 @@ static inline __u64 parse_ip(struct sk_buff *skb, __u64 nhoff, __u64 *ip_proto,
82 return nhoff; 82 return nhoff;
83} 83}
84 84
85static inline __u64 parse_ipv6(struct sk_buff *skb, __u64 nhoff, __u64 *ip_proto, 85static inline __u64 parse_ipv6(struct __sk_buff *skb, __u64 nhoff, __u64 *ip_proto,
86 struct flow_keys *flow) 86 struct flow_keys *flow)
87{ 87{
88 *ip_proto = load_byte(skb, 88 *ip_proto = load_byte(skb,
@@ -96,7 +96,7 @@ static inline __u64 parse_ipv6(struct sk_buff *skb, __u64 nhoff, __u64 *ip_proto
96 return nhoff; 96 return nhoff;
97} 97}
98 98
99static inline bool flow_dissector(struct sk_buff *skb, struct flow_keys *flow) 99static inline bool flow_dissector(struct __sk_buff *skb, struct flow_keys *flow)
100{ 100{
101 __u64 nhoff = ETH_HLEN; 101 __u64 nhoff = ETH_HLEN;
102 __u64 ip_proto; 102 __u64 ip_proto;
@@ -183,18 +183,23 @@ static inline bool flow_dissector(struct sk_buff *skb, struct flow_keys *flow)
183 return true; 183 return true;
184} 184}
185 185
186struct pair {
187 long packets;
188 long bytes;
189};
190
186struct bpf_map_def SEC("maps") hash_map = { 191struct bpf_map_def SEC("maps") hash_map = {
187 .type = BPF_MAP_TYPE_HASH, 192 .type = BPF_MAP_TYPE_HASH,
188 .key_size = sizeof(__be32), 193 .key_size = sizeof(__be32),
189 .value_size = sizeof(long), 194 .value_size = sizeof(struct pair),
190 .max_entries = 1024, 195 .max_entries = 1024,
191}; 196};
192 197
193SEC("socket2") 198SEC("socket2")
194int bpf_prog2(struct sk_buff *skb) 199int bpf_prog2(struct __sk_buff *skb)
195{ 200{
196 struct flow_keys flow; 201 struct flow_keys flow;
197 long *value; 202 struct pair *value;
198 u32 key; 203 u32 key;
199 204
200 if (!flow_dissector(skb, &flow)) 205 if (!flow_dissector(skb, &flow))
@@ -203,9 +208,10 @@ int bpf_prog2(struct sk_buff *skb)
203 key = flow.dst; 208 key = flow.dst;
204 value = bpf_map_lookup_elem(&hash_map, &key); 209 value = bpf_map_lookup_elem(&hash_map, &key);
205 if (value) { 210 if (value) {
206 __sync_fetch_and_add(value, 1); 211 __sync_fetch_and_add(&value->packets, 1);
212 __sync_fetch_and_add(&value->bytes, skb->len);
207 } else { 213 } else {
208 long val = 1; 214 struct pair val = {1, skb->len};
209 215
210 bpf_map_update_elem(&hash_map, &key, &val, BPF_ANY); 216 bpf_map_update_elem(&hash_map, &key, &val, BPF_ANY);
211 } 217 }
diff --git a/samples/bpf/sockex2_user.c b/samples/bpf/sockex2_user.c
index d2d5f5a790d3..29a276d766fc 100644
--- a/samples/bpf/sockex2_user.c
+++ b/samples/bpf/sockex2_user.c
@@ -6,6 +6,11 @@
6#include <unistd.h> 6#include <unistd.h>
7#include <arpa/inet.h> 7#include <arpa/inet.h>
8 8
9struct pair {
10 __u64 packets;
11 __u64 bytes;
12};
13
9int main(int ac, char **argv) 14int main(int ac, char **argv)
10{ 15{
11 char filename[256]; 16 char filename[256];
@@ -29,13 +34,13 @@ int main(int ac, char **argv)
29 34
30 for (i = 0; i < 5; i++) { 35 for (i = 0; i < 5; i++) {
31 int key = 0, next_key; 36 int key = 0, next_key;
32 long long value; 37 struct pair value;
33 38
34 while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) { 39 while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
35 bpf_lookup_elem(map_fd[0], &next_key, &value); 40 bpf_lookup_elem(map_fd[0], &next_key, &value);
36 printf("ip %s count %lld\n", 41 printf("ip %s bytes %lld packets %lld\n",
37 inet_ntoa((struct in_addr){htonl(next_key)}), 42 inet_ntoa((struct in_addr){htonl(next_key)}),
38 value); 43 value.bytes, value.packets);
39 key = next_key; 44 key = next_key;
40 } 45 }
41 sleep(1); 46 sleep(1);
diff --git a/samples/bpf/tcbpf1_kern.c b/samples/bpf/tcbpf1_kern.c
new file mode 100644
index 000000000000..7cf3f42a6e39
--- /dev/null
+++ b/samples/bpf/tcbpf1_kern.c
@@ -0,0 +1,71 @@
1#include <uapi/linux/bpf.h>
2#include <uapi/linux/if_ether.h>
3#include <uapi/linux/if_packet.h>
4#include <uapi/linux/ip.h>
5#include <uapi/linux/in.h>
6#include <uapi/linux/tcp.h>
7#include "bpf_helpers.h"
8
9/* compiler workaround */
10#define _htonl __builtin_bswap32
11
12static inline void set_dst_mac(struct __sk_buff *skb, char *mac)
13{
14 bpf_skb_store_bytes(skb, 0, mac, ETH_ALEN, 1);
15}
16
17/* use 1 below for ingress qdisc and 0 for egress */
18#if 0
19#undef ETH_HLEN
20#define ETH_HLEN 0
21#endif
22
23#define IP_CSUM_OFF (ETH_HLEN + offsetof(struct iphdr, check))
24#define TOS_OFF (ETH_HLEN + offsetof(struct iphdr, tos))
25
26static inline void set_ip_tos(struct __sk_buff *skb, __u8 new_tos)
27{
28 __u8 old_tos = load_byte(skb, TOS_OFF);
29
30 bpf_l3_csum_replace(skb, IP_CSUM_OFF, htons(old_tos), htons(new_tos), 2);
31 bpf_skb_store_bytes(skb, TOS_OFF, &new_tos, sizeof(new_tos), 0);
32}
33
34#define TCP_CSUM_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, check))
35#define IP_SRC_OFF (ETH_HLEN + offsetof(struct iphdr, saddr))
36
37#define IS_PSEUDO 0x10
38
39static inline void set_tcp_ip_src(struct __sk_buff *skb, __u32 new_ip)
40{
41 __u32 old_ip = _htonl(load_word(skb, IP_SRC_OFF));
42
43 bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_ip, new_ip, IS_PSEUDO | sizeof(new_ip));
44 bpf_l3_csum_replace(skb, IP_CSUM_OFF, old_ip, new_ip, sizeof(new_ip));
45 bpf_skb_store_bytes(skb, IP_SRC_OFF, &new_ip, sizeof(new_ip), 0);
46}
47
48#define TCP_DPORT_OFF (ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest))
49static inline void set_tcp_dest_port(struct __sk_buff *skb, __u16 new_port)
50{
51 __u16 old_port = htons(load_half(skb, TCP_DPORT_OFF));
52
53 bpf_l4_csum_replace(skb, TCP_CSUM_OFF, old_port, new_port, sizeof(new_port));
54 bpf_skb_store_bytes(skb, TCP_DPORT_OFF, &new_port, sizeof(new_port), 0);
55}
56
57SEC("classifier")
58int bpf_prog1(struct __sk_buff *skb)
59{
60 __u8 proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
61 long *value;
62
63 if (proto == IPPROTO_TCP) {
64 set_ip_tos(skb, 8);
65 set_tcp_ip_src(skb, 0xA010101);
66 set_tcp_dest_port(skb, 5001);
67 }
68
69 return 0;
70}
71char _license[] SEC("license") = "GPL";
diff --git a/samples/bpf/test_verifier.c b/samples/bpf/test_verifier.c
index 740ce97cda5e..9ab645698ffb 100644
--- a/samples/bpf/test_verifier.c
+++ b/samples/bpf/test_verifier.c
@@ -14,6 +14,7 @@
14#include <linux/unistd.h> 14#include <linux/unistd.h>
15#include <string.h> 15#include <string.h>
16#include <linux/filter.h> 16#include <linux/filter.h>
17#include <stddef.h>
17#include "libbpf.h" 18#include "libbpf.h"
18 19
19#define MAX_INSNS 512 20#define MAX_INSNS 512
@@ -288,7 +289,8 @@ static struct bpf_test tests[] = {
288 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8), 289 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
289 290
290 /* should be able to access R0 = *(R2 + 8) */ 291 /* should be able to access R0 = *(R2 + 8) */
291 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), 292 /* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
293 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
292 BPF_EXIT_INSN(), 294 BPF_EXIT_INSN(),
293 }, 295 },
294 .result = ACCEPT, 296 .result = ACCEPT,
@@ -641,6 +643,84 @@ static struct bpf_test tests[] = {
641 }, 643 },
642 .result = ACCEPT, 644 .result = ACCEPT,
643 }, 645 },
646 {
647 "access skb fields ok",
648 .insns = {
649 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
650 offsetof(struct __sk_buff, len)),
651 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
652 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
653 offsetof(struct __sk_buff, mark)),
654 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
655 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
656 offsetof(struct __sk_buff, pkt_type)),
657 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 1),
658 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
659 offsetof(struct __sk_buff, queue_mapping)),
660 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
661 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
662 offsetof(struct __sk_buff, protocol)),
663 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
664 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
665 offsetof(struct __sk_buff, vlan_present)),
666 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
667 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
668 offsetof(struct __sk_buff, vlan_tci)),
669 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 0, 0),
670 BPF_EXIT_INSN(),
671 },
672 .result = ACCEPT,
673 },
674 {
675 "access skb fields bad1",
676 .insns = {
677 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -4),
678 BPF_EXIT_INSN(),
679 },
680 .errstr = "invalid bpf_context access",
681 .result = REJECT,
682 },
683 {
684 "access skb fields bad2",
685 .insns = {
686 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 9),
687 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
688 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
689 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
690 BPF_LD_MAP_FD(BPF_REG_1, 0),
691 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
692 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
693 BPF_EXIT_INSN(),
694 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
695 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
696 offsetof(struct __sk_buff, pkt_type)),
697 BPF_EXIT_INSN(),
698 },
699 .fixup = {4},
700 .errstr = "different pointers",
701 .result = REJECT,
702 },
703 {
704 "access skb fields bad3",
705 .insns = {
706 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 2),
707 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
708 offsetof(struct __sk_buff, pkt_type)),
709 BPF_EXIT_INSN(),
710 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
711 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
712 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
713 BPF_LD_MAP_FD(BPF_REG_1, 0),
714 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
715 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
716 BPF_EXIT_INSN(),
717 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
718 BPF_JMP_IMM(BPF_JA, 0, 0, -12),
719 },
720 .fixup = {6},
721 .errstr = "different pointers",
722 .result = REJECT,
723 },
644}; 724};
645 725
646static int probe_filter_length(struct bpf_insn *fp) 726static int probe_filter_length(struct bpf_insn *fp)
@@ -687,7 +767,7 @@ static int test(void)
687 } 767 }
688 printf("#%d %s ", i, tests[i].descr); 768 printf("#%d %s ", i, tests[i].descr);
689 769
690 prog_fd = bpf_prog_load(BPF_PROG_TYPE_UNSPEC, prog, 770 prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog,
691 prog_len * sizeof(struct bpf_insn), 771 prog_len * sizeof(struct bpf_insn),
692 "GPL", 0); 772 "GPL", 0);
693 773