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

TOMOYO Linux Cross Reference
Linux/kernel/bpf/tcx.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/tcx.c (Version linux-6.12-rc7) and /kernel/bpf/tcx.c (Version policy-sample)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /* Copyright (c) 2023 Isovalent */                
  3                                                   
  4 #include <linux/bpf.h>                            
  5 #include <linux/bpf_mprog.h>                      
  6 #include <linux/netdevice.h>                      
  7                                                   
  8 #include <net/tcx.h>                              
  9                                                   
 10 int tcx_prog_attach(const union bpf_attr *attr    
 11 {                                                 
 12         bool created, ingress = attr->attach_t    
 13         struct net *net = current->nsproxy->ne    
 14         struct bpf_mprog_entry *entry, *entry_    
 15         struct bpf_prog *replace_prog = NULL;     
 16         struct net_device *dev;                   
 17         int ret;                                  
 18                                                   
 19         rtnl_lock();                              
 20         dev = __dev_get_by_index(net, attr->ta    
 21         if (!dev) {                               
 22                 ret = -ENODEV;                    
 23                 goto out;                         
 24         }                                         
 25         if (attr->attach_flags & BPF_F_REPLACE    
 26                 replace_prog = bpf_prog_get_ty    
 27                                                   
 28                 if (IS_ERR(replace_prog)) {       
 29                         ret = PTR_ERR(replace_    
 30                         replace_prog = NULL;      
 31                         goto out;                 
 32                 }                                 
 33         }                                         
 34         entry = tcx_entry_fetch_or_create(dev,    
 35         if (!entry) {                             
 36                 ret = -ENOMEM;                    
 37                 goto out;                         
 38         }                                         
 39         ret = bpf_mprog_attach(entry, &entry_n    
 40                                attr->attach_fl    
 41                                attr->expected_    
 42         if (!ret) {                               
 43                 if (entry != entry_new) {         
 44                         tcx_entry_update(dev,     
 45                         tcx_entry_sync();         
 46                         tcx_skeys_inc(ingress)    
 47                 }                                 
 48                 bpf_mprog_commit(entry);          
 49         } else if (created) {                     
 50                 tcx_entry_free(entry);            
 51         }                                         
 52 out:                                              
 53         if (replace_prog)                         
 54                 bpf_prog_put(replace_prog);       
 55         rtnl_unlock();                            
 56         return ret;                               
 57 }                                                 
 58                                                   
 59 int tcx_prog_detach(const union bpf_attr *attr    
 60 {                                                 
 61         bool ingress = attr->attach_type == BP    
 62         struct net *net = current->nsproxy->ne    
 63         struct bpf_mprog_entry *entry, *entry_    
 64         struct net_device *dev;                   
 65         int ret;                                  
 66                                                   
 67         rtnl_lock();                              
 68         dev = __dev_get_by_index(net, attr->ta    
 69         if (!dev) {                               
 70                 ret = -ENODEV;                    
 71                 goto out;                         
 72         }                                         
 73         entry = tcx_entry_fetch(dev, ingress);    
 74         if (!entry) {                             
 75                 ret = -ENOENT;                    
 76                 goto out;                         
 77         }                                         
 78         ret = bpf_mprog_detach(entry, &entry_n    
 79                                attr->relative_    
 80         if (!ret) {                               
 81                 if (!tcx_entry_is_active(entry    
 82                         entry_new = NULL;         
 83                 tcx_entry_update(dev, entry_ne    
 84                 tcx_entry_sync();                 
 85                 tcx_skeys_dec(ingress);           
 86                 bpf_mprog_commit(entry);          
 87                 if (!entry_new)                   
 88                         tcx_entry_free(entry);    
 89         }                                         
 90 out:                                              
 91         rtnl_unlock();                            
 92         return ret;                               
 93 }                                                 
 94                                                   
 95 void tcx_uninstall(struct net_device *dev, boo    
 96 {                                                 
 97         struct bpf_mprog_entry *entry, *entry_    
 98         struct bpf_tuple tuple = {};              
 99         struct bpf_mprog_fp *fp;                  
100         struct bpf_mprog_cp *cp;                  
101         bool active;                              
102                                                   
103         entry = tcx_entry_fetch(dev, ingress);    
104         if (!entry)                               
105                 return;                           
106         active = tcx_entry(entry)->miniq_activ    
107         if (active)                               
108                 bpf_mprog_clear_all(entry, &en    
109         tcx_entry_update(dev, entry_new, ingre    
110         tcx_entry_sync();                         
111         bpf_mprog_foreach_tuple(entry, fp, cp,    
112                 if (tuple.link)                   
113                         tcx_link(tuple.link)->    
114                 else                              
115                         bpf_prog_put(tuple.pro    
116                 tcx_skeys_dec(ingress);           
117         }                                         
118         if (!active)                              
119                 tcx_entry_free(entry);            
120 }                                                 
121                                                   
122 int tcx_prog_query(const union bpf_attr *attr,    
123 {                                                 
124         bool ingress = attr->query.attach_type    
125         struct net *net = current->nsproxy->ne    
126         struct net_device *dev;                   
127         int ret;                                  
128                                                   
129         rtnl_lock();                              
130         dev = __dev_get_by_index(net, attr->qu    
131         if (!dev) {                               
132                 ret = -ENODEV;                    
133                 goto out;                         
134         }                                         
135         ret = bpf_mprog_query(attr, uattr, tcx    
136 out:                                              
137         rtnl_unlock();                            
138         return ret;                               
139 }                                                 
140                                                   
141 static int tcx_link_prog_attach(struct bpf_lin    
142                                 u64 revision)     
143 {                                                 
144         struct tcx_link *tcx = tcx_link(link);    
145         bool created, ingress = tcx->location     
146         struct bpf_mprog_entry *entry, *entry_    
147         struct net_device *dev = tcx->dev;        
148         int ret;                                  
149                                                   
150         ASSERT_RTNL();                            
151         entry = tcx_entry_fetch_or_create(dev,    
152         if (!entry)                               
153                 return -ENOMEM;                   
154         ret = bpf_mprog_attach(entry, &entry_n    
155                                id_or_fd, revis    
156         if (!ret) {                               
157                 if (entry != entry_new) {         
158                         tcx_entry_update(dev,     
159                         tcx_entry_sync();         
160                         tcx_skeys_inc(ingress)    
161                 }                                 
162                 bpf_mprog_commit(entry);          
163         } else if (created) {                     
164                 tcx_entry_free(entry);            
165         }                                         
166         return ret;                               
167 }                                                 
168                                                   
169 static void tcx_link_release(struct bpf_link *    
170 {                                                 
171         struct tcx_link *tcx = tcx_link(link);    
172         bool ingress = tcx->location == BPF_TC    
173         struct bpf_mprog_entry *entry, *entry_    
174         struct net_device *dev;                   
175         int ret = 0;                              
176                                                   
177         rtnl_lock();                              
178         dev = tcx->dev;                           
179         if (!dev)                                 
180                 goto out;                         
181         entry = tcx_entry_fetch(dev, ingress);    
182         if (!entry) {                             
183                 ret = -ENOENT;                    
184                 goto out;                         
185         }                                         
186         ret = bpf_mprog_detach(entry, &entry_n    
187         if (!ret) {                               
188                 if (!tcx_entry_is_active(entry    
189                         entry_new = NULL;         
190                 tcx_entry_update(dev, entry_ne    
191                 tcx_entry_sync();                 
192                 tcx_skeys_dec(ingress);           
193                 bpf_mprog_commit(entry);          
194                 if (!entry_new)                   
195                         tcx_entry_free(entry);    
196                 tcx->dev = NULL;                  
197         }                                         
198 out:                                              
199         WARN_ON_ONCE(ret);                        
200         rtnl_unlock();                            
201 }                                                 
202                                                   
203 static int tcx_link_update(struct bpf_link *li    
204                            struct bpf_prog *op    
205 {                                                 
206         struct tcx_link *tcx = tcx_link(link);    
207         bool ingress = tcx->location == BPF_TC    
208         struct bpf_mprog_entry *entry, *entry_    
209         struct net_device *dev;                   
210         int ret = 0;                              
211                                                   
212         rtnl_lock();                              
213         dev = tcx->dev;                           
214         if (!dev) {                               
215                 ret = -ENOLINK;                   
216                 goto out;                         
217         }                                         
218         if (oprog && link->prog != oprog) {       
219                 ret = -EPERM;                     
220                 goto out;                         
221         }                                         
222         oprog = link->prog;                       
223         if (oprog == nprog) {                     
224                 bpf_prog_put(nprog);              
225                 goto out;                         
226         }                                         
227         entry = tcx_entry_fetch(dev, ingress);    
228         if (!entry) {                             
229                 ret = -ENOENT;                    
230                 goto out;                         
231         }                                         
232         ret = bpf_mprog_attach(entry, &entry_n    
233                                BPF_F_REPLACE |    
234                                link->prog->aux    
235         if (!ret) {                               
236                 WARN_ON_ONCE(entry != entry_ne    
237                 oprog = xchg(&link->prog, npro    
238                 bpf_prog_put(oprog);              
239                 bpf_mprog_commit(entry);          
240         }                                         
241 out:                                              
242         rtnl_unlock();                            
243         return ret;                               
244 }                                                 
245                                                   
246 static void tcx_link_dealloc(struct bpf_link *    
247 {                                                 
248         kfree(tcx_link(link));                    
249 }                                                 
250                                                   
251 static void tcx_link_fdinfo(const struct bpf_l    
252 {                                                 
253         const struct tcx_link *tcx = tcx_link(    
254         u32 ifindex = 0;                          
255                                                   
256         rtnl_lock();                              
257         if (tcx->dev)                             
258                 ifindex = tcx->dev->ifindex;      
259         rtnl_unlock();                            
260                                                   
261         seq_printf(seq, "ifindex:\t%u\n", ifin    
262         seq_printf(seq, "attach_type:\t%u (%s)    
263                    tcx->location,                 
264                    tcx->location == BPF_TCX_IN    
265 }                                                 
266                                                   
267 static int tcx_link_fill_info(const struct bpf    
268                               struct bpf_link_    
269 {                                                 
270         const struct tcx_link *tcx = tcx_link(    
271         u32 ifindex = 0;                          
272                                                   
273         rtnl_lock();                              
274         if (tcx->dev)                             
275                 ifindex = tcx->dev->ifindex;      
276         rtnl_unlock();                            
277                                                   
278         info->tcx.ifindex = ifindex;              
279         info->tcx.attach_type = tcx->location;    
280         return 0;                                 
281 }                                                 
282                                                   
283 static int tcx_link_detach(struct bpf_link *li    
284 {                                                 
285         tcx_link_release(link);                   
286         return 0;                                 
287 }                                                 
288                                                   
289 static const struct bpf_link_ops tcx_link_lops    
290         .release        = tcx_link_release,       
291         .detach         = tcx_link_detach,        
292         .dealloc        = tcx_link_dealloc,       
293         .update_prog    = tcx_link_update,        
294         .show_fdinfo    = tcx_link_fdinfo,        
295         .fill_link_info = tcx_link_fill_info,     
296 };                                                
297                                                   
298 static int tcx_link_init(struct tcx_link *tcx,    
299                          struct bpf_link_prime    
300                          const union bpf_attr     
301                          struct net_device *de    
302                          struct bpf_prog *prog    
303 {                                                 
304         bpf_link_init(&tcx->link, BPF_LINK_TYP    
305         tcx->location = attr->link_create.atta    
306         tcx->dev = dev;                           
307         return bpf_link_prime(&tcx->link, link    
308 }                                                 
309                                                   
310 int tcx_link_attach(const union bpf_attr *attr    
311 {                                                 
312         struct net *net = current->nsproxy->ne    
313         struct bpf_link_primer link_primer;       
314         struct net_device *dev;                   
315         struct tcx_link *tcx;                     
316         int ret;                                  
317                                                   
318         rtnl_lock();                              
319         dev = __dev_get_by_index(net, attr->li    
320         if (!dev) {                               
321                 ret = -ENODEV;                    
322                 goto out;                         
323         }                                         
324         tcx = kzalloc(sizeof(*tcx), GFP_USER);    
325         if (!tcx) {                               
326                 ret = -ENOMEM;                    
327                 goto out;                         
328         }                                         
329         ret = tcx_link_init(tcx, &link_primer,    
330         if (ret) {                                
331                 kfree(tcx);                       
332                 goto out;                         
333         }                                         
334         ret = tcx_link_prog_attach(&tcx->link,    
335                                    attr->link_    
336                                    attr->link_    
337         if (ret) {                                
338                 tcx->dev = NULL;                  
339                 bpf_link_cleanup(&link_primer)    
340                 goto out;                         
341         }                                         
342         ret = bpf_link_settle(&link_primer);      
343 out:                                              
344         rtnl_unlock();                            
345         return ret;                               
346 }                                                 
347                                                   

~ [ 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