~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/bpf/offload.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /kernel/bpf/offload.c (Version linux-6.12-rc7) and /kernel/bpf/offload.c (Version policy-sample)


  1 /*                                                  1 
  2  * Copyright (C) 2017-2018 Netronome Systems,     
  3  *                                                
  4  * This software is licensed under the GNU Gen    
  5  * June 1991 as shown in the file COPYING in t    
  6  * source tree.                                   
  7  *                                                
  8  * THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES     
  9  * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRES    
 10  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES     
 11  * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK A    
 12  * OF THE PROGRAM IS WITH YOU. SHOULD THE PROG    
 13  * THE COST OF ALL NECESSARY SERVICING, REPAIR    
 14  */                                               
 15                                                   
 16 #include <linux/bpf.h>                            
 17 #include <linux/bpf_verifier.h>                   
 18 #include <linux/bug.h>                            
 19 #include <linux/kdev_t.h>                         
 20 #include <linux/list.h>                           
 21 #include <linux/lockdep.h>                        
 22 #include <linux/netdevice.h>                      
 23 #include <linux/printk.h>                         
 24 #include <linux/proc_ns.h>                        
 25 #include <linux/rhashtable.h>                     
 26 #include <linux/rtnetlink.h>                      
 27 #include <linux/rwsem.h>                          
 28 #include <net/xdp.h>                              
 29                                                   
 30 /* Protects offdevs, members of bpf_offload_ne    
 31  * of all progs.                                  
 32  * RTNL lock cannot be taken when holding this    
 33  */                                               
 34 static DECLARE_RWSEM(bpf_devs_lock);              
 35                                                   
 36 struct bpf_offload_dev {                          
 37         const struct bpf_prog_offload_ops *ops    
 38         struct list_head netdevs;                 
 39         void *priv;                               
 40 };                                                
 41                                                   
 42 struct bpf_offload_netdev {                       
 43         struct rhash_head l;                      
 44         struct net_device *netdev;                
 45         struct bpf_offload_dev *offdev; /* NUL    
 46         struct list_head progs;                   
 47         struct list_head maps;                    
 48         struct list_head offdev_netdevs;          
 49 };                                                
 50                                                   
 51 static const struct rhashtable_params offdevs_    
 52         .nelem_hint             = 4,              
 53         .key_len                = sizeof(struc    
 54         .key_offset             = offsetof(str    
 55         .head_offset            = offsetof(str    
 56         .automatic_shrinking    = true,           
 57 };                                                
 58                                                   
 59 static struct rhashtable offdevs;                 
 60                                                   
 61 static int bpf_dev_offload_check(struct net_de    
 62 {                                                 
 63         if (!netdev)                              
 64                 return -EINVAL;                   
 65         if (!netdev->netdev_ops->ndo_bpf)         
 66                 return -EOPNOTSUPP;               
 67         return 0;                                 
 68 }                                                 
 69                                                   
 70 static struct bpf_offload_netdev *                
 71 bpf_offload_find_netdev(struct net_device *net    
 72 {                                                 
 73         lockdep_assert_held(&bpf_devs_lock);      
 74                                                   
 75         return rhashtable_lookup_fast(&offdevs    
 76 }                                                 
 77                                                   
 78 static int __bpf_offload_dev_netdev_register(s    
 79                                              s    
 80 {                                                 
 81         struct bpf_offload_netdev *ondev;         
 82         int err;                                  
 83                                                   
 84         ondev = kzalloc(sizeof(*ondev), GFP_KE    
 85         if (!ondev)                               
 86                 return -ENOMEM;                   
 87                                                   
 88         ondev->netdev = netdev;                   
 89         ondev->offdev = offdev;                   
 90         INIT_LIST_HEAD(&ondev->progs);            
 91         INIT_LIST_HEAD(&ondev->maps);             
 92                                                   
 93         err = rhashtable_insert_fast(&offdevs,    
 94         if (err) {                                
 95                 netdev_warn(netdev, "failed to    
 96                 goto err_free;                    
 97         }                                         
 98                                                   
 99         if (offdev)                               
100                 list_add(&ondev->offdev_netdev    
101         return 0;                                 
102                                                   
103 err_free:                                         
104         kfree(ondev);                             
105         return err;                               
106 }                                                 
107                                                   
108 static void __bpf_prog_offload_destroy(struct     
109 {                                                 
110         struct bpf_prog_offload *offload = pro    
111                                                   
112         if (offload->dev_state)                   
113                 offload->offdev->ops->destroy(    
114                                                   
115         list_del_init(&offload->offloads);        
116         kfree(offload);                           
117         prog->aux->offload = NULL;                
118 }                                                 
119                                                   
120 static int bpf_map_offload_ndo(struct bpf_offl    
121                                enum bpf_netdev    
122 {                                                 
123         struct netdev_bpf data = {};              
124         struct net_device *netdev;                
125                                                   
126         ASSERT_RTNL();                            
127                                                   
128         data.command = cmd;                       
129         data.offmap = offmap;                     
130         /* Caller must make sure netdev is val    
131         netdev = offmap->netdev;                  
132                                                   
133         return netdev->netdev_ops->ndo_bpf(net    
134 }                                                 
135                                                   
136 static void __bpf_map_offload_destroy(struct b    
137 {                                                 
138         WARN_ON(bpf_map_offload_ndo(offmap, BP    
139         /* Make sure BPF_MAP_GET_NEXT_ID can't    
140         bpf_map_free_id(&offmap->map);            
141         list_del_init(&offmap->offloads);         
142         offmap->netdev = NULL;                    
143 }                                                 
144                                                   
145 static void __bpf_offload_dev_netdev_unregiste    
146                                                   
147 {                                                 
148         struct bpf_offload_netdev *ondev, *alt    
149         struct bpf_offloaded_map *offmap, *mtm    
150         struct bpf_prog_offload *offload, *ptm    
151                                                   
152         ASSERT_RTNL();                            
153                                                   
154         ondev = rhashtable_lookup_fast(&offdev    
155         if (WARN_ON(!ondev))                      
156                 return;                           
157                                                   
158         WARN_ON(rhashtable_remove_fast(&offdev    
159                                                   
160         /* Try to move the objects to another     
161         if (offdev) {                             
162                 list_del(&ondev->offdev_netdev    
163                 altdev = list_first_entry_or_n    
164                                                   
165                                                   
166         }                                         
167                                                   
168         if (altdev) {                             
169                 list_for_each_entry(offload, &    
170                         offload->netdev = altd    
171                 list_splice_init(&ondev->progs    
172                                                   
173                 list_for_each_entry(offmap, &o    
174                         offmap->netdev = altde    
175                 list_splice_init(&ondev->maps,    
176         } else {                                  
177                 list_for_each_entry_safe(offlo    
178                         __bpf_prog_offload_des    
179                 list_for_each_entry_safe(offma    
180                         __bpf_map_offload_dest    
181         }                                         
182                                                   
183         WARN_ON(!list_empty(&ondev->progs));      
184         WARN_ON(!list_empty(&ondev->maps));       
185         kfree(ondev);                             
186 }                                                 
187                                                   
188 static int __bpf_prog_dev_bound_init(struct bp    
189 {                                                 
190         struct bpf_offload_netdev *ondev;         
191         struct bpf_prog_offload *offload;         
192         int err;                                  
193                                                   
194         offload = kzalloc(sizeof(*offload), GF    
195         if (!offload)                             
196                 return -ENOMEM;                   
197                                                   
198         offload->prog = prog;                     
199         offload->netdev = netdev;                 
200                                                   
201         ondev = bpf_offload_find_netdev(offloa    
202         /* When program is offloaded require p    
203          * bpf_offload_netdev, avoid the one c    
204          */                                       
205         if (bpf_prog_is_offloaded(prog->aux) &    
206                 err = -EINVAL;                    
207                 goto err_free;                    
208         }                                         
209         if (!ondev) {                             
210                 /* When only binding to the de    
211                  * create an entry in the hash    
212                  */                               
213                 err = __bpf_offload_dev_netdev    
214                 if (err)                          
215                         goto err_free;            
216                 ondev = bpf_offload_find_netde    
217         }                                         
218         offload->offdev = ondev->offdev;          
219         prog->aux->offload = offload;             
220         list_add_tail(&offload->offloads, &ond    
221                                                   
222         return 0;                                 
223 err_free:                                         
224         kfree(offload);                           
225         return err;                               
226 }                                                 
227                                                   
228 int bpf_prog_dev_bound_init(struct bpf_prog *p    
229 {                                                 
230         struct net_device *netdev;                
231         int err;                                  
232                                                   
233         if (attr->prog_type != BPF_PROG_TYPE_S    
234             attr->prog_type != BPF_PROG_TYPE_X    
235                 return -EINVAL;                   
236                                                   
237         if (attr->prog_flags & ~(BPF_F_XDP_DEV    
238                 return -EINVAL;                   
239                                                   
240         /* Frags are allowed only if program i    
241          * if it is requesting bpf offload.       
242          */                                       
243         if (attr->prog_flags & BPF_F_XDP_HAS_F    
244             !(attr->prog_flags & BPF_F_XDP_DEV    
245                 return -EINVAL;                   
246                                                   
247         if (attr->prog_type == BPF_PROG_TYPE_S    
248             attr->prog_flags & BPF_F_XDP_DEV_B    
249                 return -EINVAL;                   
250                                                   
251         netdev = dev_get_by_index(current->nsp    
252         if (!netdev)                              
253                 return -EINVAL;                   
254                                                   
255         err = bpf_dev_offload_check(netdev);      
256         if (err)                                  
257                 goto out;                         
258                                                   
259         prog->aux->offload_requested = !(attr-    
260                                                   
261         down_write(&bpf_devs_lock);               
262         err = __bpf_prog_dev_bound_init(prog,     
263         up_write(&bpf_devs_lock);                 
264                                                   
265 out:                                              
266         dev_put(netdev);                          
267         return err;                               
268 }                                                 
269                                                   
270 int bpf_prog_dev_bound_inherit(struct bpf_prog    
271 {                                                 
272         int err;                                  
273                                                   
274         if (!bpf_prog_is_dev_bound(old_prog->a    
275                 return 0;                         
276                                                   
277         if (bpf_prog_is_offloaded(old_prog->au    
278                 return -EINVAL;                   
279                                                   
280         new_prog->aux->dev_bound = old_prog->a    
281         new_prog->aux->offload_requested = old    
282                                                   
283         down_write(&bpf_devs_lock);               
284         if (!old_prog->aux->offload) {            
285                 err = -EINVAL;                    
286                 goto out;                         
287         }                                         
288                                                   
289         err = __bpf_prog_dev_bound_init(new_pr    
290                                                   
291 out:                                              
292         up_write(&bpf_devs_lock);                 
293         return err;                               
294 }                                                 
295                                                   
296 int bpf_prog_offload_verifier_prep(struct bpf_    
297 {                                                 
298         struct bpf_prog_offload *offload;         
299         int ret = -ENODEV;                        
300                                                   
301         down_read(&bpf_devs_lock);                
302         offload = prog->aux->offload;             
303         if (offload) {                            
304                 ret = offload->offdev->ops->pr    
305                 offload->dev_state = !ret;        
306         }                                         
307         up_read(&bpf_devs_lock);                  
308                                                   
309         return ret;                               
310 }                                                 
311                                                   
312 int bpf_prog_offload_verify_insn(struct bpf_ve    
313                                  int insn_idx,    
314 {                                                 
315         struct bpf_prog_offload *offload;         
316         int ret = -ENODEV;                        
317                                                   
318         down_read(&bpf_devs_lock);                
319         offload = env->prog->aux->offload;        
320         if (offload)                              
321                 ret = offload->offdev->ops->in    
322                                                   
323         up_read(&bpf_devs_lock);                  
324                                                   
325         return ret;                               
326 }                                                 
327                                                   
328 int bpf_prog_offload_finalize(struct bpf_verif    
329 {                                                 
330         struct bpf_prog_offload *offload;         
331         int ret = -ENODEV;                        
332                                                   
333         down_read(&bpf_devs_lock);                
334         offload = env->prog->aux->offload;        
335         if (offload) {                            
336                 if (offload->offdev->ops->fina    
337                         ret = offload->offdev-    
338                 else                              
339                         ret = 0;                  
340         }                                         
341         up_read(&bpf_devs_lock);                  
342                                                   
343         return ret;                               
344 }                                                 
345                                                   
346 void                                              
347 bpf_prog_offload_replace_insn(struct bpf_verif    
348                               struct bpf_insn     
349 {                                                 
350         const struct bpf_prog_offload_ops *ops    
351         struct bpf_prog_offload *offload;         
352         int ret = -EOPNOTSUPP;                    
353                                                   
354         down_read(&bpf_devs_lock);                
355         offload = env->prog->aux->offload;        
356         if (offload) {                            
357                 ops = offload->offdev->ops;       
358                 if (!offload->opt_failed && op    
359                         ret = ops->replace_ins    
360                 offload->opt_failed |= ret;       
361         }                                         
362         up_read(&bpf_devs_lock);                  
363 }                                                 
364                                                   
365 void                                              
366 bpf_prog_offload_remove_insns(struct bpf_verif    
367 {                                                 
368         struct bpf_prog_offload *offload;         
369         int ret = -EOPNOTSUPP;                    
370                                                   
371         down_read(&bpf_devs_lock);                
372         offload = env->prog->aux->offload;        
373         if (offload) {                            
374                 if (!offload->opt_failed && of    
375                         ret = offload->offdev-    
376                 offload->opt_failed |= ret;       
377         }                                         
378         up_read(&bpf_devs_lock);                  
379 }                                                 
380                                                   
381 void bpf_prog_dev_bound_destroy(struct bpf_pro    
382 {                                                 
383         struct bpf_offload_netdev *ondev;         
384         struct net_device *netdev;                
385                                                   
386         rtnl_lock();                              
387         down_write(&bpf_devs_lock);               
388         if (prog->aux->offload) {                 
389                 list_del_init(&prog->aux->offl    
390                                                   
391                 netdev = prog->aux->offload->n    
392                 __bpf_prog_offload_destroy(pro    
393                                                   
394                 ondev = bpf_offload_find_netde    
395                 if (!ondev->offdev && list_emp    
396                         __bpf_offload_dev_netd    
397         }                                         
398         up_write(&bpf_devs_lock);                 
399         rtnl_unlock();                            
400 }                                                 
401                                                   
402 static int bpf_prog_offload_translate(struct b    
403 {                                                 
404         struct bpf_prog_offload *offload;         
405         int ret = -ENODEV;                        
406                                                   
407         down_read(&bpf_devs_lock);                
408         offload = prog->aux->offload;             
409         if (offload)                              
410                 ret = offload->offdev->ops->tr    
411         up_read(&bpf_devs_lock);                  
412                                                   
413         return ret;                               
414 }                                                 
415                                                   
416 static unsigned int bpf_prog_warn_on_exec(cons    
417                                           cons    
418 {                                                 
419         WARN(1, "attempt to execute device eBP    
420         return 0;                                 
421 }                                                 
422                                                   
423 int bpf_prog_offload_compile(struct bpf_prog *    
424 {                                                 
425         prog->bpf_func = bpf_prog_warn_on_exec    
426                                                   
427         return bpf_prog_offload_translate(prog    
428 }                                                 
429                                                   
430 struct ns_get_path_bpf_prog_args {                
431         struct bpf_prog *prog;                    
432         struct bpf_prog_info *info;               
433 };                                                
434                                                   
435 static struct ns_common *bpf_prog_offload_info    
436 {                                                 
437         struct ns_get_path_bpf_prog_args *args    
438         struct bpf_prog_aux *aux = args->prog-    
439         struct ns_common *ns;                     
440         struct net *net;                          
441                                                   
442         rtnl_lock();                              
443         down_read(&bpf_devs_lock);                
444                                                   
445         if (aux->offload) {                       
446                 args->info->ifindex = aux->off    
447                 net = dev_net(aux->offload->ne    
448                 get_net(net);                     
449                 ns = &net->ns;                    
450         } else {                                  
451                 args->info->ifindex = 0;          
452                 ns = NULL;                        
453         }                                         
454                                                   
455         up_read(&bpf_devs_lock);                  
456         rtnl_unlock();                            
457                                                   
458         return ns;                                
459 }                                                 
460                                                   
461 int bpf_prog_offload_info_fill(struct bpf_prog    
462                                struct bpf_prog    
463 {                                                 
464         struct ns_get_path_bpf_prog_args args     
465                 .prog   = prog,                   
466                 .info   = info,                   
467         };                                        
468         struct bpf_prog_aux *aux = prog->aux;     
469         struct inode *ns_inode;                   
470         struct path ns_path;                      
471         char __user *uinsns;                      
472         int res;                                  
473         u32 ulen;                                 
474                                                   
475         res = ns_get_path_cb(&ns_path, bpf_pro    
476         if (res) {                                
477                 if (!info->ifindex)               
478                         return -ENODEV;           
479                 return res;                       
480         }                                         
481                                                   
482         down_read(&bpf_devs_lock);                
483                                                   
484         if (!aux->offload) {                      
485                 up_read(&bpf_devs_lock);          
486                 return -ENODEV;                   
487         }                                         
488                                                   
489         ulen = info->jited_prog_len;              
490         info->jited_prog_len = aux->offload->j    
491         if (info->jited_prog_len && ulen) {       
492                 uinsns = u64_to_user_ptr(info-    
493                 ulen = min_t(u32, info->jited_    
494                 if (copy_to_user(uinsns, aux->    
495                         up_read(&bpf_devs_lock    
496                         return -EFAULT;           
497                 }                                 
498         }                                         
499                                                   
500         up_read(&bpf_devs_lock);                  
501                                                   
502         ns_inode = ns_path.dentry->d_inode;       
503         info->netns_dev = new_encode_dev(ns_in    
504         info->netns_ino = ns_inode->i_ino;        
505         path_put(&ns_path);                       
506                                                   
507         return 0;                                 
508 }                                                 
509                                                   
510 const struct bpf_prog_ops bpf_offload_prog_ops    
511 };                                                
512                                                   
513 struct bpf_map *bpf_map_offload_map_alloc(unio    
514 {                                                 
515         struct net *net = current->nsproxy->ne    
516         struct bpf_offload_netdev *ondev;         
517         struct bpf_offloaded_map *offmap;         
518         int err;                                  
519                                                   
520         if (!capable(CAP_SYS_ADMIN))              
521                 return ERR_PTR(-EPERM);           
522         if (attr->map_type != BPF_MAP_TYPE_ARR    
523             attr->map_type != BPF_MAP_TYPE_HAS    
524                 return ERR_PTR(-EINVAL);          
525                                                   
526         offmap = bpf_map_area_alloc(sizeof(*of    
527         if (!offmap)                              
528                 return ERR_PTR(-ENOMEM);          
529                                                   
530         bpf_map_init_from_attr(&offmap->map, a    
531                                                   
532         rtnl_lock();                              
533         down_write(&bpf_devs_lock);               
534         offmap->netdev = __dev_get_by_index(ne    
535         err = bpf_dev_offload_check(offmap->ne    
536         if (err)                                  
537                 goto err_unlock;                  
538                                                   
539         ondev = bpf_offload_find_netdev(offmap    
540         if (!ondev) {                             
541                 err = -EINVAL;                    
542                 goto err_unlock;                  
543         }                                         
544                                                   
545         err = bpf_map_offload_ndo(offmap, BPF_    
546         if (err)                                  
547                 goto err_unlock;                  
548                                                   
549         list_add_tail(&offmap->offloads, &onde    
550         up_write(&bpf_devs_lock);                 
551         rtnl_unlock();                            
552                                                   
553         return &offmap->map;                      
554                                                   
555 err_unlock:                                       
556         up_write(&bpf_devs_lock);                 
557         rtnl_unlock();                            
558         bpf_map_area_free(offmap);                
559         return ERR_PTR(err);                      
560 }                                                 
561                                                   
562 void bpf_map_offload_map_free(struct bpf_map *    
563 {                                                 
564         struct bpf_offloaded_map *offmap = map    
565                                                   
566         rtnl_lock();                              
567         down_write(&bpf_devs_lock);               
568         if (offmap->netdev)                       
569                 __bpf_map_offload_destroy(offm    
570         up_write(&bpf_devs_lock);                 
571         rtnl_unlock();                            
572                                                   
573         bpf_map_area_free(offmap);                
574 }                                                 
575                                                   
576 u64 bpf_map_offload_map_mem_usage(const struct    
577 {                                                 
578         /* The memory dynamically allocated in    
579         return sizeof(struct bpf_offloaded_map    
580 }                                                 
581                                                   
582 int bpf_map_offload_lookup_elem(struct bpf_map    
583 {                                                 
584         struct bpf_offloaded_map *offmap = map    
585         int ret = -ENODEV;                        
586                                                   
587         down_read(&bpf_devs_lock);                
588         if (offmap->netdev)                       
589                 ret = offmap->dev_ops->map_loo    
590         up_read(&bpf_devs_lock);                  
591                                                   
592         return ret;                               
593 }                                                 
594                                                   
595 int bpf_map_offload_update_elem(struct bpf_map    
596                                 void *key, voi    
597 {                                                 
598         struct bpf_offloaded_map *offmap = map    
599         int ret = -ENODEV;                        
600                                                   
601         if (unlikely(flags > BPF_EXIST))          
602                 return -EINVAL;                   
603                                                   
604         down_read(&bpf_devs_lock);                
605         if (offmap->netdev)                       
606                 ret = offmap->dev_ops->map_upd    
607                                                   
608         up_read(&bpf_devs_lock);                  
609                                                   
610         return ret;                               
611 }                                                 
612                                                   
613 int bpf_map_offload_delete_elem(struct bpf_map    
614 {                                                 
615         struct bpf_offloaded_map *offmap = map    
616         int ret = -ENODEV;                        
617                                                   
618         down_read(&bpf_devs_lock);                
619         if (offmap->netdev)                       
620                 ret = offmap->dev_ops->map_del    
621         up_read(&bpf_devs_lock);                  
622                                                   
623         return ret;                               
624 }                                                 
625                                                   
626 int bpf_map_offload_get_next_key(struct bpf_ma    
627 {                                                 
628         struct bpf_offloaded_map *offmap = map    
629         int ret = -ENODEV;                        
630                                                   
631         down_read(&bpf_devs_lock);                
632         if (offmap->netdev)                       
633                 ret = offmap->dev_ops->map_get    
634         up_read(&bpf_devs_lock);                  
635                                                   
636         return ret;                               
637 }                                                 
638                                                   
639 struct ns_get_path_bpf_map_args {                 
640         struct bpf_offloaded_map *offmap;         
641         struct bpf_map_info *info;                
642 };                                                
643                                                   
644 static struct ns_common *bpf_map_offload_info_    
645 {                                                 
646         struct ns_get_path_bpf_map_args *args     
647         struct ns_common *ns;                     
648         struct net *net;                          
649                                                   
650         rtnl_lock();                              
651         down_read(&bpf_devs_lock);                
652                                                   
653         if (args->offmap->netdev) {               
654                 args->info->ifindex = args->of    
655                 net = dev_net(args->offmap->ne    
656                 get_net(net);                     
657                 ns = &net->ns;                    
658         } else {                                  
659                 args->info->ifindex = 0;          
660                 ns = NULL;                        
661         }                                         
662                                                   
663         up_read(&bpf_devs_lock);                  
664         rtnl_unlock();                            
665                                                   
666         return ns;                                
667 }                                                 
668                                                   
669 int bpf_map_offload_info_fill(struct bpf_map_i    
670 {                                                 
671         struct ns_get_path_bpf_map_args args =    
672                 .offmap = map_to_offmap(map),     
673                 .info   = info,                   
674         };                                        
675         struct inode *ns_inode;                   
676         struct path ns_path;                      
677         int res;                                  
678                                                   
679         res = ns_get_path_cb(&ns_path, bpf_map    
680         if (res) {                                
681                 if (!info->ifindex)               
682                         return -ENODEV;           
683                 return res;                       
684         }                                         
685                                                   
686         ns_inode = ns_path.dentry->d_inode;       
687         info->netns_dev = new_encode_dev(ns_in    
688         info->netns_ino = ns_inode->i_ino;        
689         path_put(&ns_path);                       
690                                                   
691         return 0;                                 
692 }                                                 
693                                                   
694 static bool __bpf_offload_dev_match(struct bpf    
695                                     struct net    
696 {                                                 
697         struct bpf_offload_netdev *ondev1, *on    
698         struct bpf_prog_offload *offload;         
699                                                   
700         if (!bpf_prog_is_dev_bound(prog->aux))    
701                 return false;                     
702                                                   
703         offload = prog->aux->offload;             
704         if (!offload)                             
705                 return false;                     
706         if (offload->netdev == netdev)            
707                 return true;                      
708                                                   
709         ondev1 = bpf_offload_find_netdev(offlo    
710         ondev2 = bpf_offload_find_netdev(netde    
711                                                   
712         return ondev1 && ondev2 && ondev1->off    
713 }                                                 
714                                                   
715 bool bpf_offload_dev_match(struct bpf_prog *pr    
716 {                                                 
717         bool ret;                                 
718                                                   
719         down_read(&bpf_devs_lock);                
720         ret = __bpf_offload_dev_match(prog, ne    
721         up_read(&bpf_devs_lock);                  
722                                                   
723         return ret;                               
724 }                                                 
725 EXPORT_SYMBOL_GPL(bpf_offload_dev_match);         
726                                                   
727 bool bpf_prog_dev_bound_match(const struct bpf    
728 {                                                 
729         bool ret;                                 
730                                                   
731         if (bpf_prog_is_offloaded(lhs->aux) !=    
732                 return false;                     
733                                                   
734         down_read(&bpf_devs_lock);                
735         ret = lhs->aux->offload && rhs->aux->o    
736               lhs->aux->offload->netdev &&        
737               lhs->aux->offload->netdev == rhs    
738         up_read(&bpf_devs_lock);                  
739                                                   
740         return ret;                               
741 }                                                 
742                                                   
743 bool bpf_offload_prog_map_match(struct bpf_pro    
744 {                                                 
745         struct bpf_offloaded_map *offmap;         
746         bool ret;                                 
747                                                   
748         if (!bpf_map_is_offloaded(map))           
749                 return bpf_map_offload_neutral    
750         offmap = map_to_offmap(map);              
751                                                   
752         down_read(&bpf_devs_lock);                
753         ret = __bpf_offload_dev_match(prog, of    
754         up_read(&bpf_devs_lock);                  
755                                                   
756         return ret;                               
757 }                                                 
758                                                   
759 int bpf_offload_dev_netdev_register(struct bpf    
760                                     struct net    
761 {                                                 
762         int err;                                  
763                                                   
764         down_write(&bpf_devs_lock);               
765         err = __bpf_offload_dev_netdev_registe    
766         up_write(&bpf_devs_lock);                 
767         return err;                               
768 }                                                 
769 EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_regis    
770                                                   
771 void bpf_offload_dev_netdev_unregister(struct     
772                                        struct     
773 {                                                 
774         down_write(&bpf_devs_lock);               
775         __bpf_offload_dev_netdev_unregister(of    
776         up_write(&bpf_devs_lock);                 
777 }                                                 
778 EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_unreg    
779                                                   
780 struct bpf_offload_dev *                          
781 bpf_offload_dev_create(const struct bpf_prog_o    
782 {                                                 
783         struct bpf_offload_dev *offdev;           
784                                                   
785         offdev = kzalloc(sizeof(*offdev), GFP_    
786         if (!offdev)                              
787                 return ERR_PTR(-ENOMEM);          
788                                                   
789         offdev->ops = ops;                        
790         offdev->priv = priv;                      
791         INIT_LIST_HEAD(&offdev->netdevs);         
792                                                   
793         return offdev;                            
794 }                                                 
795 EXPORT_SYMBOL_GPL(bpf_offload_dev_create);        
796                                                   
797 void bpf_offload_dev_destroy(struct bpf_offloa    
798 {                                                 
799         WARN_ON(!list_empty(&offdev->netdevs))    
800         kfree(offdev);                            
801 }                                                 
802 EXPORT_SYMBOL_GPL(bpf_offload_dev_destroy);       
803                                                   
804 void *bpf_offload_dev_priv(struct bpf_offload_    
805 {                                                 
806         return offdev->priv;                      
807 }                                                 
808 EXPORT_SYMBOL_GPL(bpf_offload_dev_priv);          
809                                                   
810 void bpf_dev_bound_netdev_unregister(struct ne    
811 {                                                 
812         struct bpf_offload_netdev *ondev;         
813                                                   
814         ASSERT_RTNL();                            
815                                                   
816         down_write(&bpf_devs_lock);               
817         ondev = bpf_offload_find_netdev(dev);     
818         if (ondev && !ondev->offdev)              
819                 __bpf_offload_dev_netdev_unreg    
820         up_write(&bpf_devs_lock);                 
821 }                                                 
822                                                   
823 int bpf_dev_bound_kfunc_check(struct bpf_verif    
824                               struct bpf_prog_    
825 {                                                 
826         if (!bpf_prog_is_dev_bound(prog_aux))     
827                 bpf_log(log, "metadata kfuncs     
828                 return -EINVAL;                   
829         }                                         
830                                                   
831         if (bpf_prog_is_offloaded(prog_aux)) {    
832                 bpf_log(log, "metadata kfuncs     
833                 return -EINVAL;                   
834         }                                         
835                                                   
836         return 0;                                 
837 }                                                 
838                                                   
839 void *bpf_dev_bound_resolve_kfunc(struct bpf_p    
840 {                                                 
841         const struct xdp_metadata_ops *ops;       
842         void *p = NULL;                           
843                                                   
844         /* We don't hold bpf_devs_lock while r    
845          * kfuncs and can race with the unregi    
846          * We rely on bpf_dev_bound_match() ch    
847          * to render this program unusable.       
848          */                                       
849         down_read(&bpf_devs_lock);                
850         if (!prog->aux->offload)                  
851                 goto out;                         
852                                                   
853         ops = prog->aux->offload->netdev->xdp_    
854         if (!ops)                                 
855                 goto out;                         
856                                                   
857 #define XDP_METADATA_KFUNC(name, _, __, xmo) \    
858         if (func_id == bpf_xdp_metadata_kfunc_    
859         XDP_METADATA_KFUNC_xxx                    
860 #undef XDP_METADATA_KFUNC                         
861                                                   
862 out:                                              
863         up_read(&bpf_devs_lock);                  
864                                                   
865         return p;                                 
866 }                                                 
867                                                   
868 static int __init bpf_offload_init(void)          
869 {                                                 
870         return rhashtable_init(&offdevs, &offd    
871 }                                                 
872                                                   
873 core_initcall(bpf_offload_init);                  
874                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php