aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-02-09 14:05:10 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-09 14:05:10 -0500
commit437a4db66df3bc9f139cfbfc66913ea207d9162a (patch)
tree24c796fd31a3298da7d4ea75652afc5e22dc28f8
parent08f5138512180a479ce6b9d23b825c9f4cd3be77 (diff)
parentd977ae593b2d3f9ef0df795eda93f4e6bc92b323 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2018-02-09 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) Two fixes for BPF sockmap in order to break up circular map references from programs attached to sockmap, and detaching related sockets in case of socket close() event. For the latter we get rid of the smap_state_change() and plug into ULP infrastructure, which will later also be used for additional features anyway such as TX hooks. For the second issue, dependency chain is broken up via map release callback to free parse/verdict programs, all from John. 2) Fix a libbpf relocation issue that was found while implementing XDP support for Suricata project. Issue was that when clang was invoked with default target instead of bpf target, then various other e.g. debugging relevant sections are added to the ELF file that contained relocation entries pointing to non-BPF related sections which libbpf trips over instead of skipping them. Test cases for libbpf are added as well, from Jesper. 3) Various misc fixes for bpftool and one for libbpf: a small addition to libbpf to make sure it recognizes all standard section prefixes. Then, the Makefile in bpftool/Documentation is improved to explicitly check for rst2man being installed on the system as we otherwise risk installing empty man pages; the man page for bpftool-map is corrected and a set of missing bash completions added in order to avoid shipping bpftool where the completions are only partially working, from Quentin. 4) Fix applying the relocation to immediate load instructions in the nfp JIT which were missing a shift, from Jakub. 5) Two fixes for the BPF kernel selftests: handle CONFIG_BPF_JIT_ALWAYS_ON=y gracefully in test_bpf.ko module and mark them as FLAG_EXPECTED_FAIL in this case; and explicitly delete the veth devices in the two tests test_xdp_{meta,redirect}.sh before dismantling the netnses as when selftests are run in batch mode, then workqueue to handle destruction might not have finished yet and thus veth creation in next test under same dev name would fail, from Yonghong. 6) Fix test_kmod.sh to check the test_bpf.ko module path before performing an insmod, and fallback to modprobe. Especially the latter is useful when having a device under test that has the modules installed instead, from Naresh. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_asm.c2
-rw-r--r--include/net/tcp.h8
-rw-r--r--kernel/bpf/sockmap.c187
-rw-r--r--lib/test_bpf.c31
-rw-r--r--net/ipv4/tcp_ulp.c59
-rw-r--r--net/tls/tls_main.c2
-rw-r--r--tools/bpf/bpftool/Documentation/Makefile5
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-cgroup.rst4
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-map.rst3
-rw-r--r--tools/bpf/bpftool/bash-completion/bpftool72
-rw-r--r--tools/include/uapi/linux/bpf_common.h7
-rw-r--r--tools/lib/bpf/libbpf.c56
-rw-r--r--tools/testing/selftests/bpf/Makefile12
-rwxr-xr-xtools/testing/selftests/bpf/test_kmod.sh18
-rwxr-xr-xtools/testing/selftests/bpf/test_libbpf.sh49
-rw-r--r--tools/testing/selftests/bpf/test_libbpf_open.c150
-rwxr-xr-xtools/testing/selftests/bpf/test_xdp_meta.sh1
-rwxr-xr-xtools/testing/selftests/bpf/test_xdp_redirect.sh2
18 files changed, 557 insertions, 111 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_asm.c b/drivers/net/ethernet/netronome/nfp/nfp_asm.c
index 3f6952b66a49..1e597600c693 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_asm.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_asm.c
@@ -107,7 +107,7 @@ u16 immed_get_value(u64 instr)
107 if (!unreg_is_imm(reg)) 107 if (!unreg_is_imm(reg))
108 reg = FIELD_GET(OP_IMMED_B_SRC, instr); 108 reg = FIELD_GET(OP_IMMED_B_SRC, instr);
109 109
110 return (reg & 0xff) | FIELD_GET(OP_IMMED_IMM, instr); 110 return (reg & 0xff) | FIELD_GET(OP_IMMED_IMM, instr) << 8;
111} 111}
112 112
113void immed_set_value(u64 *instr, u16 immed) 113void immed_set_value(u64 *instr, u16 immed)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 58278669cc55..e3fc667f9ac2 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1983,6 +1983,11 @@ enum hrtimer_restart tcp_pace_kick(struct hrtimer *timer);
1983#define TCP_ULP_MAX 128 1983#define TCP_ULP_MAX 128
1984#define TCP_ULP_BUF_MAX (TCP_ULP_NAME_MAX*TCP_ULP_MAX) 1984#define TCP_ULP_BUF_MAX (TCP_ULP_NAME_MAX*TCP_ULP_MAX)
1985 1985
1986enum {
1987 TCP_ULP_TLS,
1988 TCP_ULP_BPF,
1989};
1990
1986struct tcp_ulp_ops { 1991struct tcp_ulp_ops {
1987 struct list_head list; 1992 struct list_head list;
1988 1993
@@ -1991,12 +1996,15 @@ struct tcp_ulp_ops {
1991 /* cleanup ulp */ 1996 /* cleanup ulp */
1992 void (*release)(struct sock *sk); 1997 void (*release)(struct sock *sk);
1993 1998
1999 int uid;
1994 char name[TCP_ULP_NAME_MAX]; 2000 char name[TCP_ULP_NAME_MAX];
2001 bool user_visible;
1995 struct module *owner; 2002 struct module *owner;
1996}; 2003};
1997int tcp_register_ulp(struct tcp_ulp_ops *type); 2004int tcp_register_ulp(struct tcp_ulp_ops *type);
1998void tcp_unregister_ulp(struct tcp_ulp_ops *type); 2005void tcp_unregister_ulp(struct tcp_ulp_ops *type);
1999int tcp_set_ulp(struct sock *sk, const char *name); 2006int tcp_set_ulp(struct sock *sk, const char *name);
2007int tcp_set_ulp_id(struct sock *sk, const int ulp);
2000void tcp_get_available_ulp(char *buf, size_t len); 2008void tcp_get_available_ulp(char *buf, size_t len);
2001void tcp_cleanup_ulp(struct sock *sk); 2009void tcp_cleanup_ulp(struct sock *sk);
2002 2010
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
index 0314d1783d77..48c33417d13c 100644
--- a/kernel/bpf/sockmap.c
+++ b/kernel/bpf/sockmap.c
@@ -86,9 +86,10 @@ struct smap_psock {
86 struct work_struct tx_work; 86 struct work_struct tx_work;
87 struct work_struct gc_work; 87 struct work_struct gc_work;
88 88
89 struct proto *sk_proto;
90 void (*save_close)(struct sock *sk, long timeout);
89 void (*save_data_ready)(struct sock *sk); 91 void (*save_data_ready)(struct sock *sk);
90 void (*save_write_space)(struct sock *sk); 92 void (*save_write_space)(struct sock *sk);
91 void (*save_state_change)(struct sock *sk);
92}; 93};
93 94
94static inline struct smap_psock *smap_psock_sk(const struct sock *sk) 95static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
@@ -96,12 +97,102 @@ static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
96 return rcu_dereference_sk_user_data(sk); 97 return rcu_dereference_sk_user_data(sk);
97} 98}
98 99
100static struct proto tcp_bpf_proto;
101static int bpf_tcp_init(struct sock *sk)
102{
103 struct smap_psock *psock;
104
105 rcu_read_lock();
106 psock = smap_psock_sk(sk);
107 if (unlikely(!psock)) {
108 rcu_read_unlock();
109 return -EINVAL;
110 }
111
112 if (unlikely(psock->sk_proto)) {
113 rcu_read_unlock();
114 return -EBUSY;
115 }
116
117 psock->save_close = sk->sk_prot->close;
118 psock->sk_proto = sk->sk_prot;
119 sk->sk_prot = &tcp_bpf_proto;
120 rcu_read_unlock();
121 return 0;
122}
123
124static void bpf_tcp_release(struct sock *sk)
125{
126 struct smap_psock *psock;
127
128 rcu_read_lock();
129 psock = smap_psock_sk(sk);
130
131 if (likely(psock)) {
132 sk->sk_prot = psock->sk_proto;
133 psock->sk_proto = NULL;
134 }
135 rcu_read_unlock();
136}
137
138static void smap_release_sock(struct smap_psock *psock, struct sock *sock);
139
140static void bpf_tcp_close(struct sock *sk, long timeout)
141{
142 void (*close_fun)(struct sock *sk, long timeout);
143 struct smap_psock_map_entry *e, *tmp;
144 struct smap_psock *psock;
145 struct sock *osk;
146
147 rcu_read_lock();
148 psock = smap_psock_sk(sk);
149 if (unlikely(!psock)) {
150 rcu_read_unlock();
151 return sk->sk_prot->close(sk, timeout);
152 }
153
154 /* The psock may be destroyed anytime after exiting the RCU critial
155 * section so by the time we use close_fun the psock may no longer
156 * be valid. However, bpf_tcp_close is called with the sock lock
157 * held so the close hook and sk are still valid.
158 */
159 close_fun = psock->save_close;
160
161 write_lock_bh(&sk->sk_callback_lock);
162 list_for_each_entry_safe(e, tmp, &psock->maps, list) {
163 osk = cmpxchg(e->entry, sk, NULL);
164 if (osk == sk) {
165 list_del(&e->list);
166 smap_release_sock(psock, sk);
167 }
168 }
169 write_unlock_bh(&sk->sk_callback_lock);
170 rcu_read_unlock();
171 close_fun(sk, timeout);
172}
173
99enum __sk_action { 174enum __sk_action {
100 __SK_DROP = 0, 175 __SK_DROP = 0,
101 __SK_PASS, 176 __SK_PASS,
102 __SK_REDIRECT, 177 __SK_REDIRECT,
103}; 178};
104 179
180static struct tcp_ulp_ops bpf_tcp_ulp_ops __read_mostly = {
181 .name = "bpf_tcp",
182 .uid = TCP_ULP_BPF,
183 .user_visible = false,
184 .owner = NULL,
185 .init = bpf_tcp_init,
186 .release = bpf_tcp_release,
187};
188
189static int bpf_tcp_ulp_register(void)
190{
191 tcp_bpf_proto = tcp_prot;
192 tcp_bpf_proto.close = bpf_tcp_close;
193 return tcp_register_ulp(&bpf_tcp_ulp_ops);
194}
195
105static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb) 196static int smap_verdict_func(struct smap_psock *psock, struct sk_buff *skb)
106{ 197{
107 struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict); 198 struct bpf_prog *prog = READ_ONCE(psock->bpf_verdict);
@@ -166,68 +257,6 @@ static void smap_report_sk_error(struct smap_psock *psock, int err)
166 sk->sk_error_report(sk); 257 sk->sk_error_report(sk);
167} 258}
168 259
169static void smap_release_sock(struct smap_psock *psock, struct sock *sock);
170
171/* Called with lock_sock(sk) held */
172static void smap_state_change(struct sock *sk)
173{
174 struct smap_psock_map_entry *e, *tmp;
175 struct smap_psock *psock;
176 struct socket_wq *wq;
177 struct sock *osk;
178
179 rcu_read_lock();
180
181 /* Allowing transitions into an established syn_recv states allows
182 * for early binding sockets to a smap object before the connection
183 * is established.
184 */
185 switch (sk->sk_state) {
186 case TCP_SYN_SENT:
187 case TCP_SYN_RECV:
188 case TCP_ESTABLISHED:
189 break;
190 case TCP_CLOSE_WAIT:
191 case TCP_CLOSING:
192 case TCP_LAST_ACK:
193 case TCP_FIN_WAIT1:
194 case TCP_FIN_WAIT2:
195 case TCP_LISTEN:
196 break;
197 case TCP_CLOSE:
198 /* Only release if the map entry is in fact the sock in
199 * question. There is a case where the operator deletes
200 * the sock from the map, but the TCP sock is closed before
201 * the psock is detached. Use cmpxchg to verify correct
202 * sock is removed.
203 */
204 psock = smap_psock_sk(sk);
205 if (unlikely(!psock))
206 break;
207 write_lock_bh(&sk->sk_callback_lock);
208 list_for_each_entry_safe(e, tmp, &psock->maps, list) {
209 osk = cmpxchg(e->entry, sk, NULL);
210 if (osk == sk) {
211 list_del(&e->list);
212 smap_release_sock(psock, sk);
213 }
214 }
215 write_unlock_bh(&sk->sk_callback_lock);
216 break;
217 default:
218 psock = smap_psock_sk(sk);
219 if (unlikely(!psock))
220 break;
221 smap_report_sk_error(psock, EPIPE);
222 break;
223 }
224
225 wq = rcu_dereference(sk->sk_wq);
226 if (skwq_has_sleeper(wq))
227 wake_up_interruptible_all(&wq->wait);
228 rcu_read_unlock();
229}
230
231static void smap_read_sock_strparser(struct strparser *strp, 260static void smap_read_sock_strparser(struct strparser *strp,
232 struct sk_buff *skb) 261 struct sk_buff *skb)
233{ 262{
@@ -322,10 +351,8 @@ static void smap_stop_sock(struct smap_psock *psock, struct sock *sk)
322 return; 351 return;
323 sk->sk_data_ready = psock->save_data_ready; 352 sk->sk_data_ready = psock->save_data_ready;
324 sk->sk_write_space = psock->save_write_space; 353 sk->sk_write_space = psock->save_write_space;
325 sk->sk_state_change = psock->save_state_change;
326 psock->save_data_ready = NULL; 354 psock->save_data_ready = NULL;
327 psock->save_write_space = NULL; 355 psock->save_write_space = NULL;
328 psock->save_state_change = NULL;
329 strp_stop(&psock->strp); 356 strp_stop(&psock->strp);
330 psock->strp_enabled = false; 357 psock->strp_enabled = false;
331} 358}
@@ -350,6 +377,7 @@ static void smap_release_sock(struct smap_psock *psock, struct sock *sock)
350 if (psock->refcnt) 377 if (psock->refcnt)
351 return; 378 return;
352 379
380 tcp_cleanup_ulp(sock);
353 smap_stop_sock(psock, sock); 381 smap_stop_sock(psock, sock);
354 clear_bit(SMAP_TX_RUNNING, &psock->state); 382 clear_bit(SMAP_TX_RUNNING, &psock->state);
355 rcu_assign_sk_user_data(sock, NULL); 383 rcu_assign_sk_user_data(sock, NULL);
@@ -427,10 +455,8 @@ static void smap_start_sock(struct smap_psock *psock, struct sock *sk)
427 return; 455 return;
428 psock->save_data_ready = sk->sk_data_ready; 456 psock->save_data_ready = sk->sk_data_ready;
429 psock->save_write_space = sk->sk_write_space; 457 psock->save_write_space = sk->sk_write_space;
430 psock->save_state_change = sk->sk_state_change;
431 sk->sk_data_ready = smap_data_ready; 458 sk->sk_data_ready = smap_data_ready;
432 sk->sk_write_space = smap_write_space; 459 sk->sk_write_space = smap_write_space;
433 sk->sk_state_change = smap_state_change;
434 psock->strp_enabled = true; 460 psock->strp_enabled = true;
435} 461}
436 462
@@ -509,6 +535,10 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
509 if (attr->value_size > KMALLOC_MAX_SIZE) 535 if (attr->value_size > KMALLOC_MAX_SIZE)
510 return ERR_PTR(-E2BIG); 536 return ERR_PTR(-E2BIG);
511 537
538 err = bpf_tcp_ulp_register();
539 if (err && err != -EEXIST)
540 return ERR_PTR(err);
541
512 stab = kzalloc(sizeof(*stab), GFP_USER); 542 stab = kzalloc(sizeof(*stab), GFP_USER);
513 if (!stab) 543 if (!stab)
514 return ERR_PTR(-ENOMEM); 544 return ERR_PTR(-ENOMEM);
@@ -590,11 +620,6 @@ static void sock_map_free(struct bpf_map *map)
590 } 620 }
591 rcu_read_unlock(); 621 rcu_read_unlock();
592 622
593 if (stab->bpf_verdict)
594 bpf_prog_put(stab->bpf_verdict);
595 if (stab->bpf_parse)
596 bpf_prog_put(stab->bpf_parse);
597
598 sock_map_remove_complete(stab); 623 sock_map_remove_complete(stab);
599} 624}
600 625
@@ -754,6 +779,10 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
754 goto out_progs; 779 goto out_progs;
755 } 780 }
756 781
782 err = tcp_set_ulp_id(sock, TCP_ULP_BPF);
783 if (err)
784 goto out_progs;
785
757 set_bit(SMAP_TX_RUNNING, &psock->state); 786 set_bit(SMAP_TX_RUNNING, &psock->state);
758 } 787 }
759 788
@@ -866,6 +895,19 @@ static int sock_map_update_elem(struct bpf_map *map,
866 return err; 895 return err;
867} 896}
868 897
898static void sock_map_release(struct bpf_map *map, struct file *map_file)
899{
900 struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
901 struct bpf_prog *orig;
902
903 orig = xchg(&stab->bpf_parse, NULL);
904 if (orig)
905 bpf_prog_put(orig);
906 orig = xchg(&stab->bpf_verdict, NULL);
907 if (orig)
908 bpf_prog_put(orig);
909}
910
869const struct bpf_map_ops sock_map_ops = { 911const struct bpf_map_ops sock_map_ops = {
870 .map_alloc = sock_map_alloc, 912 .map_alloc = sock_map_alloc,
871 .map_free = sock_map_free, 913 .map_free = sock_map_free,
@@ -873,6 +915,7 @@ const struct bpf_map_ops sock_map_ops = {
873 .map_get_next_key = sock_map_get_next_key, 915 .map_get_next_key = sock_map_get_next_key,
874 .map_update_elem = sock_map_update_elem, 916 .map_update_elem = sock_map_update_elem,
875 .map_delete_elem = sock_map_delete_elem, 917 .map_delete_elem = sock_map_delete_elem,
918 .map_release = sock_map_release,
876}; 919};
877 920
878BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock, 921BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,
diff --git a/lib/test_bpf.c b/lib/test_bpf.c
index 4cd9ea9b3449..b4e22345963f 100644
--- a/lib/test_bpf.c
+++ b/lib/test_bpf.c
@@ -83,6 +83,7 @@ struct bpf_test {
83 __u32 result; 83 __u32 result;
84 } test[MAX_SUBTESTS]; 84 } test[MAX_SUBTESTS];
85 int (*fill_helper)(struct bpf_test *self); 85 int (*fill_helper)(struct bpf_test *self);
86 int expected_errcode; /* used when FLAG_EXPECTED_FAIL is set in the aux */
86 __u8 frag_data[MAX_DATA]; 87 __u8 frag_data[MAX_DATA];
87 int stack_depth; /* for eBPF only, since tests don't call verifier */ 88 int stack_depth; /* for eBPF only, since tests don't call verifier */
88}; 89};
@@ -2026,7 +2027,9 @@ static struct bpf_test tests[] = {
2026 }, 2027 },
2027 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, 2028 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
2028 { }, 2029 { },
2029 { } 2030 { },
2031 .fill_helper = NULL,
2032 .expected_errcode = -EINVAL,
2030 }, 2033 },
2031 { 2034 {
2032 "check: div_k_0", 2035 "check: div_k_0",
@@ -2036,7 +2039,9 @@ static struct bpf_test tests[] = {
2036 }, 2039 },
2037 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, 2040 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
2038 { }, 2041 { },
2039 { } 2042 { },
2043 .fill_helper = NULL,
2044 .expected_errcode = -EINVAL,
2040 }, 2045 },
2041 { 2046 {
2042 "check: unknown insn", 2047 "check: unknown insn",
@@ -2047,7 +2052,9 @@ static struct bpf_test tests[] = {
2047 }, 2052 },
2048 CLASSIC | FLAG_EXPECTED_FAIL, 2053 CLASSIC | FLAG_EXPECTED_FAIL,
2049 { }, 2054 { },
2050 { } 2055 { },
2056 .fill_helper = NULL,
2057 .expected_errcode = -EINVAL,
2051 }, 2058 },
2052 { 2059 {
2053 "check: out of range spill/fill", 2060 "check: out of range spill/fill",
@@ -2057,7 +2064,9 @@ static struct bpf_test tests[] = {
2057 }, 2064 },
2058 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, 2065 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
2059 { }, 2066 { },
2060 { } 2067 { },
2068 .fill_helper = NULL,
2069 .expected_errcode = -EINVAL,
2061 }, 2070 },
2062 { 2071 {
2063 "JUMPS + HOLES", 2072 "JUMPS + HOLES",
@@ -2149,6 +2158,8 @@ static struct bpf_test tests[] = {
2149 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, 2158 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
2150 { }, 2159 { },
2151 { }, 2160 { },
2161 .fill_helper = NULL,
2162 .expected_errcode = -EINVAL,
2152 }, 2163 },
2153 { 2164 {
2154 "check: LDX + RET X", 2165 "check: LDX + RET X",
@@ -2159,6 +2170,8 @@ static struct bpf_test tests[] = {
2159 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, 2170 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
2160 { }, 2171 { },
2161 { }, 2172 { },
2173 .fill_helper = NULL,
2174 .expected_errcode = -EINVAL,
2162 }, 2175 },
2163 { /* Mainly checking JIT here. */ 2176 { /* Mainly checking JIT here. */
2164 "M[]: alt STX + LDX", 2177 "M[]: alt STX + LDX",
@@ -2333,6 +2346,8 @@ static struct bpf_test tests[] = {
2333 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, 2346 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
2334 { }, 2347 { },
2335 { }, 2348 { },
2349 .fill_helper = NULL,
2350 .expected_errcode = -EINVAL,
2336 }, 2351 },
2337 { /* Passes checker but fails during runtime. */ 2352 { /* Passes checker but fails during runtime. */
2338 "LD [SKF_AD_OFF-1]", 2353 "LD [SKF_AD_OFF-1]",
@@ -5395,6 +5410,7 @@ static struct bpf_test tests[] = {
5395 { }, 5410 { },
5396 { }, 5411 { },
5397 .fill_helper = bpf_fill_maxinsns4, 5412 .fill_helper = bpf_fill_maxinsns4,
5413 .expected_errcode = -EINVAL,
5398 }, 5414 },
5399 { /* Mainly checking JIT here. */ 5415 { /* Mainly checking JIT here. */
5400 "BPF_MAXINSNS: Very long jump", 5416 "BPF_MAXINSNS: Very long jump",
@@ -5450,10 +5466,15 @@ static struct bpf_test tests[] = {
5450 { 5466 {
5451 "BPF_MAXINSNS: Jump, gap, jump, ...", 5467 "BPF_MAXINSNS: Jump, gap, jump, ...",
5452 { }, 5468 { },
5469#ifdef CONFIG_BPF_JIT_ALWAYS_ON
5470 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
5471#else
5453 CLASSIC | FLAG_NO_DATA, 5472 CLASSIC | FLAG_NO_DATA,
5473#endif
5454 { }, 5474 { },
5455 { { 0, 0xababcbac } }, 5475 { { 0, 0xababcbac } },
5456 .fill_helper = bpf_fill_maxinsns11, 5476 .fill_helper = bpf_fill_maxinsns11,
5477 .expected_errcode = -ENOTSUPP,
5457 }, 5478 },
5458 { 5479 {
5459 "BPF_MAXINSNS: ld_abs+get_processor_id", 5480 "BPF_MAXINSNS: ld_abs+get_processor_id",
@@ -6344,7 +6365,7 @@ static struct bpf_prog *generate_filter(int which, int *err)
6344 6365
6345 *err = bpf_prog_create(&fp, &fprog); 6366 *err = bpf_prog_create(&fp, &fprog);
6346 if (tests[which].aux & FLAG_EXPECTED_FAIL) { 6367 if (tests[which].aux & FLAG_EXPECTED_FAIL) {
6347 if (*err == -EINVAL) { 6368 if (*err == tests[which].expected_errcode) {
6348 pr_cont("PASS\n"); 6369 pr_cont("PASS\n");
6349 /* Verifier rejected filter as expected. */ 6370 /* Verifier rejected filter as expected. */
6350 *err = 0; 6371 *err = 0;
diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
index 6bb9e14c710a..622caa4039e0 100644
--- a/net/ipv4/tcp_ulp.c
+++ b/net/ipv4/tcp_ulp.c
@@ -29,6 +29,18 @@ static struct tcp_ulp_ops *tcp_ulp_find(const char *name)
29 return NULL; 29 return NULL;
30} 30}
31 31
32static struct tcp_ulp_ops *tcp_ulp_find_id(const int ulp)
33{
34 struct tcp_ulp_ops *e;
35
36 list_for_each_entry_rcu(e, &tcp_ulp_list, list) {
37 if (e->uid == ulp)
38 return e;
39 }
40
41 return NULL;
42}
43
32static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name) 44static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name)
33{ 45{
34 const struct tcp_ulp_ops *ulp = NULL; 46 const struct tcp_ulp_ops *ulp = NULL;
@@ -51,6 +63,18 @@ static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name)
51 return ulp; 63 return ulp;
52} 64}
53 65
66static const struct tcp_ulp_ops *__tcp_ulp_lookup(const int uid)
67{
68 const struct tcp_ulp_ops *ulp;
69
70 rcu_read_lock();
71 ulp = tcp_ulp_find_id(uid);
72 if (!ulp || !try_module_get(ulp->owner))
73 ulp = NULL;
74 rcu_read_unlock();
75 return ulp;
76}
77
54/* Attach new upper layer protocol to the list 78/* Attach new upper layer protocol to the list
55 * of available protocols. 79 * of available protocols.
56 */ 80 */
@@ -59,13 +83,10 @@ int tcp_register_ulp(struct tcp_ulp_ops *ulp)
59 int ret = 0; 83 int ret = 0;
60 84
61 spin_lock(&tcp_ulp_list_lock); 85 spin_lock(&tcp_ulp_list_lock);
62 if (tcp_ulp_find(ulp->name)) { 86 if (tcp_ulp_find(ulp->name))
63 pr_notice("%s already registered or non-unique name\n",
64 ulp->name);
65 ret = -EEXIST; 87 ret = -EEXIST;
66 } else { 88 else
67 list_add_tail_rcu(&ulp->list, &tcp_ulp_list); 89 list_add_tail_rcu(&ulp->list, &tcp_ulp_list);
68 }
69 spin_unlock(&tcp_ulp_list_lock); 90 spin_unlock(&tcp_ulp_list_lock);
70 91
71 return ret; 92 return ret;
@@ -124,6 +145,34 @@ int tcp_set_ulp(struct sock *sk, const char *name)
124 if (!ulp_ops) 145 if (!ulp_ops)
125 return -ENOENT; 146 return -ENOENT;
126 147
148 if (!ulp_ops->user_visible) {
149 module_put(ulp_ops->owner);
150 return -ENOENT;
151 }
152
153 err = ulp_ops->init(sk);
154 if (err) {
155 module_put(ulp_ops->owner);
156 return err;
157 }
158
159 icsk->icsk_ulp_ops = ulp_ops;
160 return 0;
161}
162
163int tcp_set_ulp_id(struct sock *sk, int ulp)
164{
165 struct inet_connection_sock *icsk = inet_csk(sk);
166 const struct tcp_ulp_ops *ulp_ops;
167 int err;
168
169 if (icsk->icsk_ulp_ops)
170 return -EEXIST;
171
172 ulp_ops = __tcp_ulp_lookup(ulp);
173 if (!ulp_ops)
174 return -ENOENT;
175
127 err = ulp_ops->init(sk); 176 err = ulp_ops->init(sk);
128 if (err) { 177 if (err) {
129 module_put(ulp_ops->owner); 178 module_put(ulp_ops->owner);
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 736719c8314e..b0d5fcea47e7 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -484,6 +484,8 @@ out:
484 484
485static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = { 485static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
486 .name = "tls", 486 .name = "tls",
487 .uid = TCP_ULP_TLS,
488 .user_visible = true,
487 .owner = THIS_MODULE, 489 .owner = THIS_MODULE,
488 .init = tls_init, 490 .init = tls_init,
489}; 491};
diff --git a/tools/bpf/bpftool/Documentation/Makefile b/tools/bpf/bpftool/Documentation/Makefile
index c462a928e03d..a9d47c1558bb 100644
--- a/tools/bpf/bpftool/Documentation/Makefile
+++ b/tools/bpf/bpftool/Documentation/Makefile
@@ -23,7 +23,12 @@ DOC_MAN8 = $(addprefix $(OUTPUT),$(_DOC_MAN8))
23man: man8 23man: man8
24man8: $(DOC_MAN8) 24man8: $(DOC_MAN8)
25 25
26RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null)
27
26$(OUTPUT)%.8: %.rst 28$(OUTPUT)%.8: %.rst
29ifndef RST2MAN_DEP
30 $(error "rst2man not found, but required to generate man pages")
31endif
27 $(QUIET_GEN)rst2man $< > $@ 32 $(QUIET_GEN)rst2man $< > $@
28 33
29clean: 34clean:
diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
index 2fe2a1bdbe3e..0e4e923235b6 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
@@ -26,8 +26,8 @@ MAP COMMANDS
26| **bpftool** **cgroup help** 26| **bpftool** **cgroup help**
27| 27|
28| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } 28| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
29| *ATTACH_TYPE* := { *ingress* | *egress* | *sock_create* | *sock_ops* | *device* } 29| *ATTACH_TYPE* := { **ingress** | **egress** | **sock_create** | **sock_ops** | **device** }
30| *ATTACH_FLAGS* := { *multi* | *override* } 30| *ATTACH_FLAGS* := { **multi** | **override** }
31 31
32DESCRIPTION 32DESCRIPTION
33=========== 33===========
diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst
index 0ab32b312aec..457e868bd32f 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-map.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst
@@ -31,7 +31,8 @@ MAP COMMANDS
31| **bpftool** **map help** 31| **bpftool** **map help**
32| 32|
33| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } 33| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
34| *VALUE* := { *BYTES* | *MAP* | *PROGRAM* } 34| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
35| *VALUE* := { *BYTES* | *MAP* | *PROG* }
35| *UPDATE_FLAGS* := { **any** | **exist** | **noexist** } 36| *UPDATE_FLAGS* := { **any** | **exist** | **noexist** }
36 37
37DESCRIPTION 38DESCRIPTION
diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool
index 0137866bb8f6..08719c54a614 100644
--- a/tools/bpf/bpftool/bash-completion/bpftool
+++ b/tools/bpf/bpftool/bash-completion/bpftool
@@ -52,16 +52,24 @@ _bpftool_once_attr()
52 done 52 done
53} 53}
54 54
55# Takes a list of words in argument; adds them all to COMPREPLY if none of them 55# Takes a list of words as argument; if any of those words is present on the
56# is already present on the command line. Returns no value. 56# command line, return 0. Otherwise, return 1.
57_bpftool_one_of_list() 57_bpftool_search_list()
58{ 58{
59 local w idx 59 local w idx
60 for w in $*; do 60 for w in $*; do
61 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do 61 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
62 [[ $w == ${words[idx]} ]] && return 1 62 [[ $w == ${words[idx]} ]] && return 0
63 done 63 done
64 done 64 done
65 return 1
66}
67
68# Takes a list of words in argument; adds them all to COMPREPLY if none of them
69# is already present on the command line. Returns no value.
70_bpftool_one_of_list()
71{
72 _bpftool_search_list $* && return 1
65 COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) ) 73 COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) )
66} 74}
67 75
@@ -230,10 +238,14 @@ _bpftool()
230 fi 238 fi
231 return 0 239 return 0
232 ;; 240 ;;
241 load)
242 _filedir
243 return 0
244 ;;
233 *) 245 *)
234 [[ $prev == $object ]] && \ 246 [[ $prev == $object ]] && \
235 COMPREPLY=( $( compgen -W 'dump help pin show list' -- \ 247 COMPREPLY=( $( compgen -W 'dump help pin load \
236 "$cur" ) ) 248 show list' -- "$cur" ) )
237 ;; 249 ;;
238 esac 250 esac
239 ;; 251 ;;
@@ -347,6 +359,54 @@ _bpftool()
347 ;; 359 ;;
348 esac 360 esac
349 ;; 361 ;;
362 cgroup)
363 case $command in
364 show|list)
365 _filedir
366 return 0
367 ;;
368 attach|detach)
369 local ATTACH_TYPES='ingress egress sock_create sock_ops \
370 device'
371 local ATTACH_FLAGS='multi override'
372 local PROG_TYPE='id pinned tag'
373 case $prev in
374 $command)
375 _filedir
376 return 0
377 ;;
378 ingress|egress|sock_create|sock_ops|device)
379 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
380 "$cur" ) )
381 return 0
382 ;;
383 id)
384 _bpftool_get_prog_ids
385 return 0
386 ;;
387 *)
388 if ! _bpftool_search_list "$ATTACH_TYPES"; then
389 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- \
390 "$cur" ) )
391 elif [[ "$command" == "attach" ]]; then
392 # We have an attach type on the command line,
393 # but it is not the previous word, or
394 # "id|pinned|tag" (we already checked for
395 # that). This should only leave the case when
396 # we need attach flags for "attach" commamnd.
397 _bpftool_one_of_list "$ATTACH_FLAGS"
398 fi
399 return 0
400 ;;
401 esac
402 ;;
403 *)
404 [[ $prev == $object ]] && \
405 COMPREPLY=( $( compgen -W 'help attach detach \
406 show list' -- "$cur" ) )
407 ;;
408 esac
409 ;;
350 esac 410 esac
351} && 411} &&
352complete -F _bpftool bpftool 412complete -F _bpftool bpftool
diff --git a/tools/include/uapi/linux/bpf_common.h b/tools/include/uapi/linux/bpf_common.h
index 18be90725ab0..ee97668bdadb 100644
--- a/tools/include/uapi/linux/bpf_common.h
+++ b/tools/include/uapi/linux/bpf_common.h
@@ -15,9 +15,10 @@
15 15
16/* ld/ldx fields */ 16/* ld/ldx fields */
17#define BPF_SIZE(code) ((code) & 0x18) 17#define BPF_SIZE(code) ((code) & 0x18)
18#define BPF_W 0x00 18#define BPF_W 0x00 /* 32-bit */
19#define BPF_H 0x08 19#define BPF_H 0x08 /* 16-bit */
20#define BPF_B 0x10 20#define BPF_B 0x10 /* 8-bit */
21/* eBPF BPF_DW 0x18 64-bit */
21#define BPF_MODE(code) ((code) & 0xe0) 22#define BPF_MODE(code) ((code) & 0xe0)
22#define BPF_IMM 0x00 23#define BPF_IMM 0x00
23#define BPF_ABS 0x20 24#define BPF_ABS 0x20
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 71ddc481f349..97073d649c1a 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -319,8 +319,8 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx,
319 319
320 prog->section_name = strdup(section_name); 320 prog->section_name = strdup(section_name);
321 if (!prog->section_name) { 321 if (!prog->section_name) {
322 pr_warning("failed to alloc name for prog under section %s\n", 322 pr_warning("failed to alloc name for prog under section(%d) %s\n",
323 section_name); 323 idx, section_name);
324 goto errout; 324 goto errout;
325 } 325 }
326 326
@@ -742,6 +742,24 @@ bpf_object__init_maps(struct bpf_object *obj)
742 return 0; 742 return 0;
743} 743}
744 744
745static bool section_have_execinstr(struct bpf_object *obj, int idx)
746{
747 Elf_Scn *scn;
748 GElf_Shdr sh;
749
750 scn = elf_getscn(obj->efile.elf, idx);
751 if (!scn)
752 return false;
753
754 if (gelf_getshdr(scn, &sh) != &sh)
755 return false;
756
757 if (sh.sh_flags & SHF_EXECINSTR)
758 return true;
759
760 return false;
761}
762
745static int bpf_object__elf_collect(struct bpf_object *obj) 763static int bpf_object__elf_collect(struct bpf_object *obj)
746{ 764{
747 Elf *elf = obj->efile.elf; 765 Elf *elf = obj->efile.elf;
@@ -763,29 +781,29 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
763 781
764 idx++; 782 idx++;
765 if (gelf_getshdr(scn, &sh) != &sh) { 783 if (gelf_getshdr(scn, &sh) != &sh) {
766 pr_warning("failed to get section header from %s\n", 784 pr_warning("failed to get section(%d) header from %s\n",
767 obj->path); 785 idx, obj->path);
768 err = -LIBBPF_ERRNO__FORMAT; 786 err = -LIBBPF_ERRNO__FORMAT;
769 goto out; 787 goto out;
770 } 788 }
771 789
772 name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name); 790 name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name);
773 if (!name) { 791 if (!name) {
774 pr_warning("failed to get section name from %s\n", 792 pr_warning("failed to get section(%d) name from %s\n",
775 obj->path); 793 idx, obj->path);
776 err = -LIBBPF_ERRNO__FORMAT; 794 err = -LIBBPF_ERRNO__FORMAT;
777 goto out; 795 goto out;
778 } 796 }
779 797
780 data = elf_getdata(scn, 0); 798 data = elf_getdata(scn, 0);
781 if (!data) { 799 if (!data) {
782 pr_warning("failed to get section data from %s(%s)\n", 800 pr_warning("failed to get section(%d) data from %s(%s)\n",
783 name, obj->path); 801 idx, name, obj->path);
784 err = -LIBBPF_ERRNO__FORMAT; 802 err = -LIBBPF_ERRNO__FORMAT;
785 goto out; 803 goto out;
786 } 804 }
787 pr_debug("section %s, size %ld, link %d, flags %lx, type=%d\n", 805 pr_debug("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
788 name, (unsigned long)data->d_size, 806 idx, name, (unsigned long)data->d_size,
789 (int)sh.sh_link, (unsigned long)sh.sh_flags, 807 (int)sh.sh_link, (unsigned long)sh.sh_flags,
790 (int)sh.sh_type); 808 (int)sh.sh_type);
791 809
@@ -825,6 +843,14 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
825 } else if (sh.sh_type == SHT_REL) { 843 } else if (sh.sh_type == SHT_REL) {
826 void *reloc = obj->efile.reloc; 844 void *reloc = obj->efile.reloc;
827 int nr_reloc = obj->efile.nr_reloc + 1; 845 int nr_reloc = obj->efile.nr_reloc + 1;
846 int sec = sh.sh_info; /* points to other section */
847
848 /* Only do relo for section with exec instructions */
849 if (!section_have_execinstr(obj, sec)) {
850 pr_debug("skip relo %s(%d) for section(%d)\n",
851 name, idx, sec);
852 continue;
853 }
828 854
829 reloc = realloc(reloc, 855 reloc = realloc(reloc,
830 sizeof(*obj->efile.reloc) * nr_reloc); 856 sizeof(*obj->efile.reloc) * nr_reloc);
@@ -840,6 +866,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
840 obj->efile.reloc[n].shdr = sh; 866 obj->efile.reloc[n].shdr = sh;
841 obj->efile.reloc[n].data = data; 867 obj->efile.reloc[n].data = data;
842 } 868 }
869 } else {
870 pr_debug("skip section(%d) %s\n", idx, name);
843 } 871 }
844 if (err) 872 if (err)
845 goto out; 873 goto out;
@@ -1119,8 +1147,7 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
1119 1147
1120 prog = bpf_object__find_prog_by_idx(obj, idx); 1148 prog = bpf_object__find_prog_by_idx(obj, idx);
1121 if (!prog) { 1149 if (!prog) {
1122 pr_warning("relocation failed: no %d section\n", 1150 pr_warning("relocation failed: no section(%d)\n", idx);
1123 idx);
1124 return -LIBBPF_ERRNO__RELOC; 1151 return -LIBBPF_ERRNO__RELOC;
1125 } 1152 }
1126 1153
@@ -1816,12 +1843,17 @@ static const struct {
1816 BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER), 1843 BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER),
1817 BPF_PROG_SEC("kprobe/", BPF_PROG_TYPE_KPROBE), 1844 BPF_PROG_SEC("kprobe/", BPF_PROG_TYPE_KPROBE),
1818 BPF_PROG_SEC("kretprobe/", BPF_PROG_TYPE_KPROBE), 1845 BPF_PROG_SEC("kretprobe/", BPF_PROG_TYPE_KPROBE),
1846 BPF_PROG_SEC("classifier", BPF_PROG_TYPE_SCHED_CLS),
1847 BPF_PROG_SEC("action", BPF_PROG_TYPE_SCHED_ACT),
1819 BPF_PROG_SEC("tracepoint/", BPF_PROG_TYPE_TRACEPOINT), 1848 BPF_PROG_SEC("tracepoint/", BPF_PROG_TYPE_TRACEPOINT),
1820 BPF_PROG_SEC("xdp", BPF_PROG_TYPE_XDP), 1849 BPF_PROG_SEC("xdp", BPF_PROG_TYPE_XDP),
1821 BPF_PROG_SEC("perf_event", BPF_PROG_TYPE_PERF_EVENT), 1850 BPF_PROG_SEC("perf_event", BPF_PROG_TYPE_PERF_EVENT),
1822 BPF_PROG_SEC("cgroup/skb", BPF_PROG_TYPE_CGROUP_SKB), 1851 BPF_PROG_SEC("cgroup/skb", BPF_PROG_TYPE_CGROUP_SKB),
1823 BPF_PROG_SEC("cgroup/sock", BPF_PROG_TYPE_CGROUP_SOCK), 1852 BPF_PROG_SEC("cgroup/sock", BPF_PROG_TYPE_CGROUP_SOCK),
1824 BPF_PROG_SEC("cgroup/dev", BPF_PROG_TYPE_CGROUP_DEVICE), 1853 BPF_PROG_SEC("cgroup/dev", BPF_PROG_TYPE_CGROUP_DEVICE),
1854 BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN),
1855 BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT),
1856 BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT),
1825 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS), 1857 BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS),
1826 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB), 1858 BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB),
1827}; 1859};
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 566d6adc172a..5c43c187f27c 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -13,6 +13,7 @@ endif
13CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include 13CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
14LDLIBS += -lcap -lelf -lrt -lpthread 14LDLIBS += -lcap -lelf -lrt -lpthread
15 15
16# Order correspond to 'make run_tests' order
16TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ 17TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
17 test_align test_verifier_log test_dev_cgroup test_tcpbpf_user 18 test_align test_verifier_log test_dev_cgroup test_tcpbpf_user
18 19
@@ -22,15 +23,24 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
22 test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \ 23 test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
23 sample_map_ret0.o test_tcpbpf_kern.o 24 sample_map_ret0.o test_tcpbpf_kern.o
24 25
25TEST_PROGS := test_kmod.sh test_xdp_redirect.sh test_xdp_meta.sh \ 26# Order correspond to 'make run_tests' order
27TEST_PROGS := test_kmod.sh \
28 test_libbpf.sh \
29 test_xdp_redirect.sh \
30 test_xdp_meta.sh \
26 test_offload.py 31 test_offload.py
27 32
33# Compile but not part of 'make run_tests'
34TEST_GEN_PROGS_EXTENDED = test_libbpf_open
35
28include ../lib.mk 36include ../lib.mk
29 37
30BPFOBJ := $(OUTPUT)/libbpf.a cgroup_helpers.c 38BPFOBJ := $(OUTPUT)/libbpf.a cgroup_helpers.c
31 39
32$(TEST_GEN_PROGS): $(BPFOBJ) 40$(TEST_GEN_PROGS): $(BPFOBJ)
33 41
42$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
43
34.PHONY: force 44.PHONY: force
35 45
36# force a rebuild of BPFOBJ when its dependencies are updated 46# force a rebuild of BPFOBJ when its dependencies are updated
diff --git a/tools/testing/selftests/bpf/test_kmod.sh b/tools/testing/selftests/bpf/test_kmod.sh
index ed4774d8d6ed..35669ccd4d23 100755
--- a/tools/testing/selftests/bpf/test_kmod.sh
+++ b/tools/testing/selftests/bpf/test_kmod.sh
@@ -10,9 +10,21 @@ test_run()
10 10
11 echo "[ JIT enabled:$1 hardened:$2 ]" 11 echo "[ JIT enabled:$1 hardened:$2 ]"
12 dmesg -C 12 dmesg -C
13 insmod $SRC_TREE/lib/test_bpf.ko 2> /dev/null 13 if [ -f ${SRC_TREE}/lib/test_bpf.ko ]; then
14 if [ $? -ne 0 ]; then 14 insmod ${SRC_TREE}/lib/test_bpf.ko 2> /dev/null
15 rc=1 15 if [ $? -ne 0 ]; then
16 rc=1
17 fi
18 else
19 # Use modprobe dry run to check for missing test_bpf module
20 if ! /sbin/modprobe -q -n test_bpf; then
21 echo "test_bpf: [SKIP]"
22 elif /sbin/modprobe -q test_bpf; then
23 echo "test_bpf: ok"
24 else
25 echo "test_bpf: [FAIL]"
26 rc=1
27 fi
16 fi 28 fi
17 rmmod test_bpf 2> /dev/null 29 rmmod test_bpf 2> /dev/null
18 dmesg | grep FAIL 30 dmesg | grep FAIL
diff --git a/tools/testing/selftests/bpf/test_libbpf.sh b/tools/testing/selftests/bpf/test_libbpf.sh
new file mode 100755
index 000000000000..d97dc914cd49
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_libbpf.sh
@@ -0,0 +1,49 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0
3
4export TESTNAME=test_libbpf
5
6# Determine selftest success via shell exit code
7exit_handler()
8{
9 if (( $? == 0 )); then
10 echo "selftests: $TESTNAME [PASS]";
11 else
12 echo "$TESTNAME: failed at file $LAST_LOADED" 1>&2
13 echo "selftests: $TESTNAME [FAILED]";
14 fi
15}
16
17libbpf_open_file()
18{
19 LAST_LOADED=$1
20 if [ -n "$VERBOSE" ]; then
21 ./test_libbpf_open $1
22 else
23 ./test_libbpf_open --quiet $1
24 fi
25}
26
27# Exit script immediately (well catched by trap handler) if any
28# program/thing exits with a non-zero status.
29set -e
30
31# (Use 'trap -l' to list meaning of numbers)
32trap exit_handler 0 2 3 6 9
33
34libbpf_open_file test_l4lb.o
35
36# TODO: fix libbpf to load noinline functions
37# [warning] libbpf: incorrect bpf_call opcode
38#libbpf_open_file test_l4lb_noinline.o
39
40# TODO: fix test_xdp_meta.c to load with libbpf
41# [warning] libbpf: test_xdp_meta.o doesn't provide kernel version
42#libbpf_open_file test_xdp_meta.o
43
44# TODO: fix libbpf to handle .eh_frame
45# [warning] libbpf: relocation failed: no section(10)
46#libbpf_open_file ../../../../samples/bpf/tracex3_kern.o
47
48# Success
49exit 0
diff --git a/tools/testing/selftests/bpf/test_libbpf_open.c b/tools/testing/selftests/bpf/test_libbpf_open.c
new file mode 100644
index 000000000000..8fcd1c076add
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_libbpf_open.c
@@ -0,0 +1,150 @@
1/* SPDX-License-Identifier: GPL-2.0
2 * Copyright (c) 2018 Jesper Dangaard Brouer, Red Hat Inc.
3 */
4static const char *__doc__ =
5 "Libbpf test program for loading BPF ELF object files";
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <string.h>
10#include <stdarg.h>
11#include <bpf/libbpf.h>
12#include <getopt.h>
13
14static const struct option long_options[] = {
15 {"help", no_argument, NULL, 'h' },
16 {"debug", no_argument, NULL, 'D' },
17 {"quiet", no_argument, NULL, 'q' },
18 {0, 0, NULL, 0 }
19};
20
21static void usage(char *argv[])
22{
23 int i;
24
25 printf("\nDOCUMENTATION:\n%s\n\n", __doc__);
26 printf(" Usage: %s (options-see-below) BPF_FILE\n", argv[0]);
27 printf(" Listing options:\n");
28 for (i = 0; long_options[i].name != 0; i++) {
29 printf(" --%-12s", long_options[i].name);
30 printf(" short-option: -%c",
31 long_options[i].val);
32 printf("\n");
33 }
34 printf("\n");
35}
36
37#define DEFINE_PRINT_FN(name, enabled) \
38static int libbpf_##name(const char *fmt, ...) \
39{ \
40 va_list args; \
41 int ret; \
42 \
43 va_start(args, fmt); \
44 if (enabled) { \
45 fprintf(stderr, "[" #name "] "); \
46 ret = vfprintf(stderr, fmt, args); \
47 } \
48 va_end(args); \
49 return ret; \
50}
51DEFINE_PRINT_FN(warning, 1)
52DEFINE_PRINT_FN(info, 1)
53DEFINE_PRINT_FN(debug, 1)
54
55#define EXIT_FAIL_LIBBPF EXIT_FAILURE
56#define EXIT_FAIL_OPTION 2
57
58int test_walk_progs(struct bpf_object *obj, bool verbose)
59{
60 struct bpf_program *prog;
61 int cnt = 0;
62
63 bpf_object__for_each_program(prog, obj) {
64 cnt++;
65 if (verbose)
66 printf("Prog (count:%d) section_name: %s\n", cnt,
67 bpf_program__title(prog, false));
68 }
69 return 0;
70}
71
72int test_walk_maps(struct bpf_object *obj, bool verbose)
73{
74 struct bpf_map *map;
75 int cnt = 0;
76
77 bpf_map__for_each(map, obj) {
78 cnt++;
79 if (verbose)
80 printf("Map (count:%d) name: %s\n", cnt,
81 bpf_map__name(map));
82 }
83 return 0;
84}
85
86int test_open_file(char *filename, bool verbose)
87{
88 struct bpf_object *bpfobj = NULL;
89 long err;
90
91 if (verbose)
92 printf("Open BPF ELF-file with libbpf: %s\n", filename);
93
94 /* Load BPF ELF object file and check for errors */
95 bpfobj = bpf_object__open(filename);
96 err = libbpf_get_error(bpfobj);
97 if (err) {
98 char err_buf[128];
99 libbpf_strerror(err, err_buf, sizeof(err_buf));
100 if (verbose)
101 printf("Unable to load eBPF objects in file '%s': %s\n",
102 filename, err_buf);
103 return EXIT_FAIL_LIBBPF;
104 }
105 test_walk_progs(bpfobj, verbose);
106 test_walk_maps(bpfobj, verbose);
107
108 if (verbose)
109 printf("Close BPF ELF-file with libbpf: %s\n",
110 bpf_object__name(bpfobj));
111 bpf_object__close(bpfobj);
112
113 return 0;
114}
115
116int main(int argc, char **argv)
117{
118 char filename[1024] = { 0 };
119 bool verbose = 1;
120 int longindex = 0;
121 int opt;
122
123 libbpf_set_print(libbpf_warning, libbpf_info, NULL);
124
125 /* Parse commands line args */
126 while ((opt = getopt_long(argc, argv, "hDq",
127 long_options, &longindex)) != -1) {
128 switch (opt) {
129 case 'D':
130 libbpf_set_print(libbpf_warning, libbpf_info,
131 libbpf_debug);
132 break;
133 case 'q': /* Use in scripting mode */
134 verbose = 0;
135 break;
136 case 'h':
137 default:
138 usage(argv);
139 return EXIT_FAIL_OPTION;
140 }
141 }
142 if (optind >= argc) {
143 usage(argv);
144 printf("ERROR: Expected BPF_FILE argument after options\n");
145 return EXIT_FAIL_OPTION;
146 }
147 snprintf(filename, sizeof(filename), "%s", argv[optind]);
148
149 return test_open_file(filename, verbose);
150}
diff --git a/tools/testing/selftests/bpf/test_xdp_meta.sh b/tools/testing/selftests/bpf/test_xdp_meta.sh
index 307aa856cee3..637fcf4fe4e3 100755
--- a/tools/testing/selftests/bpf/test_xdp_meta.sh
+++ b/tools/testing/selftests/bpf/test_xdp_meta.sh
@@ -9,6 +9,7 @@ cleanup()
9 fi 9 fi
10 10
11 set +e 11 set +e
12 ip link del veth1 2> /dev/null
12 ip netns del ns1 2> /dev/null 13 ip netns del ns1 2> /dev/null
13 ip netns del ns2 2> /dev/null 14 ip netns del ns2 2> /dev/null
14} 15}
diff --git a/tools/testing/selftests/bpf/test_xdp_redirect.sh b/tools/testing/selftests/bpf/test_xdp_redirect.sh
index 344a3656dea6..c4b17e08d431 100755
--- a/tools/testing/selftests/bpf/test_xdp_redirect.sh
+++ b/tools/testing/selftests/bpf/test_xdp_redirect.sh
@@ -19,6 +19,8 @@ cleanup()
19 fi 19 fi
20 20
21 set +e 21 set +e
22 ip link del veth1 2> /dev/null
23 ip link del veth2 2> /dev/null
22 ip netns del ns1 2> /dev/null 24 ip netns del ns1 2> /dev/null
23 ip netns del ns2 2> /dev/null 25 ip netns del ns2 2> /dev/null
24} 26}