2 * Copyright (C) 2017 Netronome Systems, Inc.
4 * This software is licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
8 * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
9 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
10 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
12 * OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
13 * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16 #include <linux/bpf.h>
17 #include <linux/bpf_verifier.h>
18 #include <linux/bug.h>
19 #include <linux/list.h>
20 #include <linux/netdevice.h>
21 #include <linux/printk.h>
22 #include <linux/rtnetlink.h>
24 /* protected by RTNL */
25 static LIST_HEAD(bpf_prog_offload_devs
);
27 int bpf_prog_offload_init(struct bpf_prog
*prog
, union bpf_attr
*attr
)
29 struct net
*net
= current
->nsproxy
->net_ns
;
30 struct bpf_dev_offload
*offload
;
32 if (attr
->prog_type
!= BPF_PROG_TYPE_SCHED_CLS
&&
33 attr
->prog_type
!= BPF_PROG_TYPE_XDP
)
39 offload
= kzalloc(sizeof(*offload
), GFP_USER
);
44 init_waitqueue_head(&offload
->verifier_done
);
47 offload
->netdev
= __dev_get_by_index(net
, attr
->prog_ifindex
);
48 if (!offload
->netdev
) {
54 prog
->aux
->offload
= offload
;
55 list_add_tail(&offload
->offloads
, &bpf_prog_offload_devs
);
61 static int __bpf_offload_ndo(struct bpf_prog
*prog
, enum bpf_netdev_command cmd
,
62 struct netdev_bpf
*data
)
64 struct net_device
*netdev
= prog
->aux
->offload
->netdev
;
70 if (!netdev
->netdev_ops
->ndo_bpf
)
75 return netdev
->netdev_ops
->ndo_bpf(netdev
, data
);
78 int bpf_prog_offload_verifier_prep(struct bpf_verifier_env
*env
)
80 struct netdev_bpf data
= {};
83 data
.verifier
.prog
= env
->prog
;
86 err
= __bpf_offload_ndo(env
->prog
, BPF_OFFLOAD_VERIFIER_PREP
, &data
);
90 env
->dev_ops
= data
.verifier
.ops
;
92 env
->prog
->aux
->offload
->dev_state
= true;
93 env
->prog
->aux
->offload
->verifier_running
= true;
99 static void __bpf_prog_offload_destroy(struct bpf_prog
*prog
)
101 struct bpf_dev_offload
*offload
= prog
->aux
->offload
;
102 struct netdev_bpf data
= {};
104 /* Caution - if netdev is destroyed before the program, this function
105 * will be called twice.
108 data
.offload
.prog
= prog
;
110 if (offload
->verifier_running
)
111 wait_event(offload
->verifier_done
, !offload
->verifier_running
);
113 if (offload
->dev_state
)
114 WARN_ON(__bpf_offload_ndo(prog
, BPF_OFFLOAD_DESTROY
, &data
));
116 offload
->dev_state
= false;
117 list_del_init(&offload
->offloads
);
118 offload
->netdev
= NULL
;
121 void bpf_prog_offload_destroy(struct bpf_prog
*prog
)
123 struct bpf_dev_offload
*offload
= prog
->aux
->offload
;
125 offload
->verifier_running
= false;
126 wake_up(&offload
->verifier_done
);
129 __bpf_prog_offload_destroy(prog
);
135 static int bpf_prog_offload_translate(struct bpf_prog
*prog
)
137 struct bpf_dev_offload
*offload
= prog
->aux
->offload
;
138 struct netdev_bpf data
= {};
141 data
.offload
.prog
= prog
;
143 offload
->verifier_running
= false;
144 wake_up(&offload
->verifier_done
);
147 ret
= __bpf_offload_ndo(prog
, BPF_OFFLOAD_TRANSLATE
, &data
);
153 static unsigned int bpf_prog_warn_on_exec(const void *ctx
,
154 const struct bpf_insn
*insn
)
156 WARN(1, "attempt to execute device eBPF program on the host!");
160 int bpf_prog_offload_compile(struct bpf_prog
*prog
)
162 prog
->bpf_func
= bpf_prog_warn_on_exec
;
164 return bpf_prog_offload_translate(prog
);
167 const struct bpf_prog_ops bpf_offload_prog_ops
= {
170 static int bpf_offload_notification(struct notifier_block
*notifier
,
171 ulong event
, void *ptr
)
173 struct net_device
*netdev
= netdev_notifier_info_to_dev(ptr
);
174 struct bpf_dev_offload
*offload
, *tmp
;
179 case NETDEV_UNREGISTER
:
180 /* ignore namespace changes */
181 if (netdev
->reg_state
!= NETREG_UNREGISTERING
)
184 list_for_each_entry_safe(offload
, tmp
, &bpf_prog_offload_devs
,
186 if (offload
->netdev
== netdev
)
187 __bpf_prog_offload_destroy(offload
->prog
);
196 static struct notifier_block bpf_offload_notifier
= {
197 .notifier_call
= bpf_offload_notification
,
200 static int __init
bpf_offload_init(void)
202 register_netdevice_notifier(&bpf_offload_notifier
);
206 subsys_initcall(bpf_offload_init
);