Skip to content

Commit a6b8881

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Alexei Starovoitov says: ==================== pull-request: bpf 2018-02-02 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) support XDP attach in libbpf, from Eric. 2) minor fixes, from Daniel, Jakub, Yonghong, Alexei. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 3527799 + 09c0656 commit a6b8881

File tree

28 files changed

+1716
-141
lines changed

28 files changed

+1716
-141
lines changed

Documentation/bpf/bpf_devel_QA.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,4 +516,35 @@ A: LLVM has a -mcpu selector for the BPF back end in order to allow the
516516
By the way, the BPF kernel selftests run with -mcpu=probe for better
517517
test coverage.
518518

519+
Q: In some cases clang flag "-target bpf" is used but in other cases the
520+
default clang target, which matches the underlying architecture, is used.
521+
What is the difference and when I should use which?
522+
523+
A: Although LLVM IR generation and optimization try to stay architecture
524+
independent, "-target <arch>" still has some impact on generated code:
525+
526+
- BPF program may recursively include header file(s) with file scope
527+
inline assembly codes. The default target can handle this well,
528+
while bpf target may fail if bpf backend assembler does not
529+
understand these assembly codes, which is true in most cases.
530+
531+
- When compiled without -g, additional elf sections, e.g.,
532+
.eh_frame and .rela.eh_frame, may be present in the object file
533+
with default target, but not with bpf target.
534+
535+
- The default target may turn a C switch statement into a switch table
536+
lookup and jump operation. Since the switch table is placed
537+
in the global readonly section, the bpf program will fail to load.
538+
The bpf target does not support switch table optimization.
539+
The clang option "-fno-jump-tables" can be used to disable
540+
switch table generation.
541+
542+
You should use default target when:
543+
544+
- Your program includes a header file, e.g., ptrace.h, which eventually
545+
pulls in some header files containing file scope host assembly codes.
546+
- You can add "-fno-jump-tables" to work around the switch table issue.
547+
548+
Otherwise, you can use bpf target.
549+
519550
Happy BPF hacking!

drivers/net/netdevsim/bpf.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,7 @@ static int
480480
nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
481481
{
482482
struct nsim_bpf_bound_map *nmap;
483-
unsigned int i;
484-
int err;
483+
int i, err;
485484

486485
if (WARN_ON(offmap->map.map_type != BPF_MAP_TYPE_ARRAY &&
487486
offmap->map.map_type != BPF_MAP_TYPE_HASH))
@@ -518,7 +517,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
518517
return 0;
519518

520519
err_free:
521-
while (--i) {
520+
while (--i >= 0) {
522521
kfree(nmap->entry[i].key);
523522
kfree(nmap->entry[i].value);
524523
}

include/linux/netdevice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3228,6 +3228,12 @@ static inline int netif_set_real_num_rx_queues(struct net_device *dev,
32283228
}
32293229
#endif
32303230

3231+
static inline struct netdev_rx_queue *
3232+
__netif_get_rx_queue(struct net_device *dev, unsigned int rxq)
3233+
{
3234+
return dev->_rx + rxq;
3235+
}
3236+
32313237
#ifdef CONFIG_SYSFS
32323238
static inline unsigned int get_netdev_rx_queue_index(
32333239
struct netdev_rx_queue *queue)

kernel/bpf/core.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,25 +1576,41 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
15761576
__u32 __user *prog_ids, u32 cnt)
15771577
{
15781578
struct bpf_prog **prog;
1579-
u32 i = 0, id;
1580-
1579+
unsigned long err = 0;
1580+
u32 i = 0, *ids;
1581+
bool nospc;
1582+
1583+
/* users of this function are doing:
1584+
* cnt = bpf_prog_array_length();
1585+
* if (cnt > 0)
1586+
* bpf_prog_array_copy_to_user(..., cnt);
1587+
* so below kcalloc doesn't need extra cnt > 0 check, but
1588+
* bpf_prog_array_length() releases rcu lock and
1589+
* prog array could have been swapped with empty or larger array,
1590+
* so always copy 'cnt' prog_ids to the user.
1591+
* In a rare race the user will see zero prog_ids
1592+
*/
1593+
ids = kcalloc(cnt, sizeof(u32), GFP_USER);
1594+
if (!ids)
1595+
return -ENOMEM;
15811596
rcu_read_lock();
15821597
prog = rcu_dereference(progs)->progs;
15831598
for (; *prog; prog++) {
15841599
if (*prog == &dummy_bpf_prog.prog)
15851600
continue;
1586-
id = (*prog)->aux->id;
1587-
if (copy_to_user(prog_ids + i, &id, sizeof(id))) {
1588-
rcu_read_unlock();
1589-
return -EFAULT;
1590-
}
1601+
ids[i] = (*prog)->aux->id;
15911602
if (++i == cnt) {
15921603
prog++;
15931604
break;
15941605
}
15951606
}
1607+
nospc = !!(*prog);
15961608
rcu_read_unlock();
1597-
if (*prog)
1609+
err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
1610+
kfree(ids);
1611+
if (err)
1612+
return -EFAULT;
1613+
if (nospc)
15981614
return -ENOSPC;
15991615
return 0;
16001616
}

net/bpf/test_run.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
151151
{
152152
u32 size = kattr->test.data_size_in;
153153
u32 repeat = kattr->test.repeat;
154+
struct netdev_rx_queue *rxqueue;
154155
struct xdp_buff xdp = {};
155156
u32 retval, duration;
156157
void *data;
@@ -165,6 +166,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
165166
xdp.data_meta = xdp.data;
166167
xdp.data_end = xdp.data + size;
167168

169+
rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
170+
xdp.rxq = &rxqueue->xdp_rxq;
171+
168172
retval = bpf_test_run(prog, &xdp, repeat, &duration);
169173
if (xdp.data != data + XDP_PACKET_HEADROOM + NET_IP_ALIGN)
170174
size = xdp.data_end - xdp.data;

samples/bpf/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ hostprogs-y += xdp_rxq_info
4545
hostprogs-y += syscall_tp
4646

4747
# Libbpf dependencies
48-
LIBBPF := ../../tools/lib/bpf/bpf.o
48+
LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o
4949
CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o
5050

5151
test_lru_dist-objs := test_lru_dist.o $(LIBBPF)

samples/bpf/bpf_load.c

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -695,105 +695,3 @@ struct ksym *ksym_search(long key)
695695
return &syms[0];
696696
}
697697

698-
int set_link_xdp_fd(int ifindex, int fd, __u32 flags)
699-
{
700-
struct sockaddr_nl sa;
701-
int sock, seq = 0, len, ret = -1;
702-
char buf[4096];
703-
struct nlattr *nla, *nla_xdp;
704-
struct {
705-
struct nlmsghdr nh;
706-
struct ifinfomsg ifinfo;
707-
char attrbuf[64];
708-
} req;
709-
struct nlmsghdr *nh;
710-
struct nlmsgerr *err;
711-
712-
memset(&sa, 0, sizeof(sa));
713-
sa.nl_family = AF_NETLINK;
714-
715-
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
716-
if (sock < 0) {
717-
printf("open netlink socket: %s\n", strerror(errno));
718-
return -1;
719-
}
720-
721-
if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
722-
printf("bind to netlink: %s\n", strerror(errno));
723-
goto cleanup;
724-
}
725-
726-
memset(&req, 0, sizeof(req));
727-
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
728-
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
729-
req.nh.nlmsg_type = RTM_SETLINK;
730-
req.nh.nlmsg_pid = 0;
731-
req.nh.nlmsg_seq = ++seq;
732-
req.ifinfo.ifi_family = AF_UNSPEC;
733-
req.ifinfo.ifi_index = ifindex;
734-
735-
/* started nested attribute for XDP */
736-
nla = (struct nlattr *)(((char *)&req)
737-
+ NLMSG_ALIGN(req.nh.nlmsg_len));
738-
nla->nla_type = NLA_F_NESTED | 43/*IFLA_XDP*/;
739-
nla->nla_len = NLA_HDRLEN;
740-
741-
/* add XDP fd */
742-
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
743-
nla_xdp->nla_type = 1/*IFLA_XDP_FD*/;
744-
nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
745-
memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
746-
nla->nla_len += nla_xdp->nla_len;
747-
748-
/* if user passed in any flags, add those too */
749-
if (flags) {
750-
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
751-
nla_xdp->nla_type = 3/*IFLA_XDP_FLAGS*/;
752-
nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
753-
memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
754-
nla->nla_len += nla_xdp->nla_len;
755-
}
756-
757-
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
758-
759-
if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
760-
printf("send to netlink: %s\n", strerror(errno));
761-
goto cleanup;
762-
}
763-
764-
len = recv(sock, buf, sizeof(buf), 0);
765-
if (len < 0) {
766-
printf("recv from netlink: %s\n", strerror(errno));
767-
goto cleanup;
768-
}
769-
770-
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
771-
nh = NLMSG_NEXT(nh, len)) {
772-
if (nh->nlmsg_pid != getpid()) {
773-
printf("Wrong pid %d, expected %d\n",
774-
nh->nlmsg_pid, getpid());
775-
goto cleanup;
776-
}
777-
if (nh->nlmsg_seq != seq) {
778-
printf("Wrong seq %d, expected %d\n",
779-
nh->nlmsg_seq, seq);
780-
goto cleanup;
781-
}
782-
switch (nh->nlmsg_type) {
783-
case NLMSG_ERROR:
784-
err = (struct nlmsgerr *)NLMSG_DATA(nh);
785-
if (!err->error)
786-
continue;
787-
printf("nlmsg error %s\n", strerror(-err->error));
788-
goto cleanup;
789-
case NLMSG_DONE:
790-
break;
791-
}
792-
}
793-
794-
ret = 0;
795-
796-
cleanup:
797-
close(sock);
798-
return ret;
799-
}

samples/bpf/bpf_load.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,5 @@ struct ksym {
6161

6262
int load_kallsyms(void);
6363
struct ksym *ksym_search(long key);
64-
int set_link_xdp_fd(int ifindex, int fd, __u32 flags);
64+
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
6565
#endif

samples/bpf/xdp1_user.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static __u32 xdp_flags;
2525

2626
static void int_exit(int sig)
2727
{
28-
set_link_xdp_fd(ifindex, -1, xdp_flags);
28+
bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
2929
exit(0);
3030
}
3131

@@ -116,7 +116,7 @@ int main(int argc, char **argv)
116116
signal(SIGINT, int_exit);
117117
signal(SIGTERM, int_exit);
118118

119-
if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
119+
if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
120120
printf("link set xdp fd failed\n");
121121
return 1;
122122
}

samples/bpf/xdp_redirect_cpu_user.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static const char *__doc__ =
2626

2727
/* Wanted to get rid of bpf_load.h and fake-"libbpf.h" (and instead
2828
* use bpf/libbpf.h), but cannot as (currently) needed for XDP
29-
* attaching to a device via set_link_xdp_fd()
29+
* attaching to a device via bpf_set_link_xdp_fd()
3030
*/
3131
#include "libbpf.h"
3232
#include "bpf_load.h"
@@ -67,7 +67,7 @@ static void int_exit(int sig)
6767
"Interrupted: Removing XDP program on ifindex:%d device:%s\n",
6868
ifindex, ifname);
6969
if (ifindex > -1)
70-
set_link_xdp_fd(ifindex, -1, xdp_flags);
70+
bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
7171
exit(EXIT_OK);
7272
}
7373

@@ -682,7 +682,7 @@ int main(int argc, char **argv)
682682
/* Remove XDP program when program is interrupted */
683683
signal(SIGINT, int_exit);
684684

685-
if (set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) {
685+
if (bpf_set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) {
686686
fprintf(stderr, "link set xdp fd failed\n");
687687
return EXIT_FAIL_XDP;
688688
}

samples/bpf/xdp_redirect_map_user.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ static __u32 xdp_flags;
3434

3535
static void int_exit(int sig)
3636
{
37-
set_link_xdp_fd(ifindex_in, -1, xdp_flags);
37+
bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
3838
if (ifindex_out_xdp_dummy_attached)
39-
set_link_xdp_fd(ifindex_out, -1, xdp_flags);
39+
bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
4040
exit(0);
4141
}
4242

@@ -120,13 +120,13 @@ int main(int argc, char **argv)
120120
return 1;
121121
}
122122

123-
if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
123+
if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
124124
printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
125125
return 1;
126126
}
127127

128128
/* Loading dummy XDP prog on out-device */
129-
if (set_link_xdp_fd(ifindex_out, prog_fd[1],
129+
if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
130130
(xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
131131
printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
132132
ifindex_out_xdp_dummy_attached = false;

samples/bpf/xdp_redirect_user.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ static __u32 xdp_flags;
3333

3434
static void int_exit(int sig)
3535
{
36-
set_link_xdp_fd(ifindex_in, -1, xdp_flags);
36+
bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
3737
if (ifindex_out_xdp_dummy_attached)
38-
set_link_xdp_fd(ifindex_out, -1, xdp_flags);
38+
bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
3939
exit(0);
4040
}
4141

@@ -114,13 +114,13 @@ int main(int argc, char **argv)
114114
return 1;
115115
}
116116

117-
if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
117+
if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
118118
printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
119119
return 1;
120120
}
121121

122122
/* Loading dummy XDP prog on out-device */
123-
if (set_link_xdp_fd(ifindex_out, prog_fd[1],
123+
if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
124124
(xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
125125
printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
126126
ifindex_out_xdp_dummy_attached = false;

0 commit comments

Comments
 (0)