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

TOMOYO Linux Cross Reference
Linux/scripts/bpf_doc.py

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/bpf_doc.py (Version linux-6.11.5) and /scripts/bpf_doc.py (Version linux-4.16.18)


  1 #!/usr/bin/env python3                            
  2 # SPDX-License-Identifier: GPL-2.0-only           
  3 #                                                 
  4 # Copyright (C) 2018-2019 Netronome Systems, I    
  5 # Copyright (C) 2021 Isovalent, Inc.              
  6                                                   
  7 # In case user attempts to run with Python 2.     
  8 from __future__ import print_function             
  9                                                   
 10 import argparse                                   
 11 import re                                         
 12 import sys, os                                    
 13 import subprocess                                 
 14                                                   
 15 helpersDocStart = 'Start of BPF helper functio    
 16                                                   
 17 class NoHelperFound(BaseException):               
 18     pass                                          
 19                                                   
 20 class NoSyscallCommandFound(BaseException):       
 21     pass                                          
 22                                                   
 23 class ParsingError(BaseException):                
 24     def __init__(self, line='<line not provide    
 25         if reader:                                
 26             BaseException.__init__(self,          
 27                                    'Error at f    
 28                                    (reader.tel    
 29         else:                                     
 30             BaseException.__init__(self, 'Erro    
 31                                                   
 32                                                   
 33 class APIElement(object):                         
 34     """                                           
 35     An object representing the description of     
 36     @proto: prototype of the API symbol           
 37     @desc: textual description of the symbol      
 38     @ret: (optional) description of any associ    
 39     """                                           
 40     def __init__(self, proto='', desc='', ret=    
 41         self.proto = proto                        
 42         self.desc = desc                          
 43         self.ret = ret                            
 44                                                   
 45                                                   
 46 class Helper(APIElement):                         
 47     """                                           
 48     An object representing the description of     
 49     @proto: function prototype of the helper f    
 50     @desc: textual description of the helper f    
 51     @ret: description of the return value of t    
 52     """                                           
 53     def __init__(self, *args, **kwargs):          
 54         super().__init__(*args, **kwargs)         
 55         self.enum_val = None                      
 56                                                   
 57     def proto_break_down(self):                   
 58         """                                       
 59         Break down helper function protocol in    
 60         name, distincts arguments.                
 61         """                                       
 62         arg_re = re.compile(r'((\w+ )*?(\w+|..    
 63         res = {}                                  
 64         proto_re = re.compile(r'(.+) (\**)(\w+    
 65                                                   
 66         capture = proto_re.match(self.proto)      
 67         res['ret_type'] = capture.group(1)        
 68         res['ret_star'] = capture.group(2)        
 69         res['name']     = capture.group(3)        
 70         res['args'] = []                          
 71                                                   
 72         args    = capture.group(4).split(', ')    
 73         for a in args:                            
 74             capture = arg_re.match(a)             
 75             res['args'].append({                  
 76                 'type' : capture.group(1),        
 77                 'star' : capture.group(5),        
 78                 'name' : capture.group(6)         
 79             })                                    
 80                                                   
 81         return res                                
 82                                                   
 83                                                   
 84 class HeaderParser(object):                       
 85     """                                           
 86     An object used to parse a file in order to    
 87     list of eBPF helper functions. All the hel    
 88     stored as Helper object, in the self.helpe    
 89     @filename: name of file to parse, usually     
 90                kernel tree                        
 91     """                                           
 92     def __init__(self, filename):                 
 93         self.reader = open(filename, 'r')         
 94         self.line = ''                            
 95         self.helpers = []                         
 96         self.commands = []                        
 97         self.desc_unique_helpers = set()          
 98         self.define_unique_helpers = []           
 99         self.helper_enum_vals = {}                
100         self.helper_enum_pos = {}                 
101         self.desc_syscalls = []                   
102         self.enum_syscalls = []                   
103                                                   
104     def parse_element(self):                      
105         proto    = self.parse_symbol()            
106         desc     = self.parse_desc(proto)         
107         ret      = self.parse_ret(proto)          
108         return APIElement(proto=proto, desc=de    
109                                                   
110     def parse_helper(self):                       
111         proto    = self.parse_proto()             
112         desc     = self.parse_desc(proto)         
113         ret      = self.parse_ret(proto)          
114         return Helper(proto=proto, desc=desc,     
115                                                   
116     def parse_symbol(self):                       
117         p = re.compile(r' \* ?(BPF\w+)$')         
118         capture = p.match(self.line)              
119         if not capture:                           
120             raise NoSyscallCommandFound           
121         end_re = re.compile(r' \* ?NOTES$')       
122         end = end_re.match(self.line)             
123         if end:                                   
124             raise NoSyscallCommandFound           
125         self.line = self.reader.readline()        
126         return capture.group(1)                   
127                                                   
128     def parse_proto(self):                        
129         # Argument can be of shape:               
130         #   - "void"                              
131         #   - "type  name"                        
132         #   - "type *name"                        
133         #   - Same as above, with "const" and/    
134         #   - "..." (undefined number of argum    
135         # There is at least one term ("void"),    
136         p = re.compile(r' \* ?((.+) \**\w+\(((    
137         capture = p.match(self.line)              
138         if not capture:                           
139             raise NoHelperFound                   
140         self.line = self.reader.readline()        
141         return capture.group(1)                   
142                                                   
143     def parse_desc(self, proto):                  
144         p = re.compile(r' \* ?(?:\t| {5,8})Des    
145         capture = p.match(self.line)              
146         if not capture:                           
147             raise Exception("No description se    
148         # Description can be several lines, so    
149         # stops when another subsection title     
150         desc = ''                                 
151         desc_present = False                      
152         while True:                               
153             self.line = self.reader.readline()    
154             if self.line == ' *\n':               
155                 desc += '\n'                      
156             else:                                 
157                 p = re.compile(r' \* ?(?:\t| {    
158                 capture = p.match(self.line)      
159                 if capture:                       
160                     desc_present = True           
161                     desc += capture.group(1) +    
162                 else:                             
163                     break                         
164                                                   
165         if not desc_present:                      
166             raise Exception("No description fo    
167         return desc                               
168                                                   
169     def parse_ret(self, proto):                   
170         p = re.compile(r' \* ?(?:\t| {5,8})Ret    
171         capture = p.match(self.line)              
172         if not capture:                           
173             raise Exception("No return section    
174         # Return value description can be seve    
175         # empty, and it stops when another sub    
176         ret = ''                                  
177         ret_present = False                       
178         while True:                               
179             self.line = self.reader.readline()    
180             if self.line == ' *\n':               
181                 ret += '\n'                       
182             else:                                 
183                 p = re.compile(r' \* ?(?:\t| {    
184                 capture = p.match(self.line)      
185                 if capture:                       
186                     ret_present = True            
187                     ret += capture.group(1) +     
188                 else:                             
189                     break                         
190                                                   
191         if not ret_present:                       
192             raise Exception("No return found f    
193         return ret                                
194                                                   
195     def seek_to(self, target, help_message, di    
196         self.reader.seek(0)                       
197         offset = self.reader.read().find(targe    
198         if offset == -1:                          
199             raise Exception(help_message)         
200         self.reader.seek(offset)                  
201         self.reader.readline()                    
202         for _ in range(discard_lines):            
203             self.reader.readline()                
204         self.line = self.reader.readline()        
205                                                   
206     def parse_desc_syscall(self):                 
207         self.seek_to('* DOC: eBPF Syscall Comm    
208                      'Could not find start of     
209         while True:                               
210             try:                                  
211                 command = self.parse_element()    
212                 self.commands.append(command)     
213                 self.desc_syscalls.append(comm    
214                                                   
215             except NoSyscallCommandFound:         
216                 break                             
217                                                   
218     def parse_enum_syscall(self):                 
219         self.seek_to('enum bpf_cmd {',            
220                      'Could not find start of     
221         # Searches for either one or more BPF\    
222         bpf_p = re.compile(r'\s*(BPF\w+)+')       
223         # Searches for an enum entry assigned     
224         # for e.g. BPF_PROG_RUN = BPF_PROG_TES    
225         # not documented hence should be skipp    
226         # determine if the right number of sys    
227         assign_p = re.compile(r'\s*(BPF\w+)\s*    
228         bpf_cmd_str = ''                          
229         while True:                               
230             capture = assign_p.match(self.line    
231             if capture:                           
232                 # Skip line if an enum entry i    
233                 self.line = self.reader.readli    
234                 continue                          
235             capture = bpf_p.match(self.line)      
236             if capture:                           
237                 bpf_cmd_str += self.line          
238             else:                                 
239                 break                             
240             self.line = self.reader.readline()    
241         # Find the number of occurences of BPF    
242         self.enum_syscalls = re.findall(r'(BPF    
243                                                   
244     def parse_desc_helpers(self):                 
245         self.seek_to(helpersDocStart,             
246                      'Could not find start of     
247         while True:                               
248             try:                                  
249                 helper = self.parse_helper()      
250                 self.helpers.append(helper)       
251                 proto = helper.proto_break_dow    
252                 self.desc_unique_helpers.add(p    
253             except NoHelperFound:                 
254                 break                             
255                                                   
256     def parse_define_helpers(self):               
257         # Parse FN(...) in #define ___BPF_FUNC    
258         # number of unique function names pres    
259         # correct enumeration value.              
260         # Note: seek_to(..) discards the first    
261         # resulting in FN(unspec, 0, ##ctx) be    
262         # self.define_unique_helpers.             
263         self.seek_to('#define ___BPF_FUNC_MAPP    
264                      'Could not find start of     
265         # Searches for one FN(\w+) define or a    
266         p = re.compile(r'\s*FN\((\w+), (\d+),     
267         fn_defines_str = ''                       
268         i = 0                                     
269         while True:                               
270             capture = p.match(self.line)          
271             if capture:                           
272                 fn_defines_str += self.line       
273                 helper_name = capture.expand(r    
274                 self.helper_enum_vals[helper_n    
275                 self.helper_enum_pos[helper_na    
276                 i += 1                            
277             else:                                 
278                 break                             
279             self.line = self.reader.readline()    
280         # Find the number of occurences of FN(    
281         self.define_unique_helpers = re.findal    
282                                                   
283     def validate_helpers(self):                   
284         last_helper = ''                          
285         seen_helpers = set()                      
286         seen_enum_vals = set()                    
287         i = 0                                     
288         for helper in self.helpers:               
289             proto = helper.proto_break_down()     
290             name = proto['name']                  
291             try:                                  
292                 enum_val = self.helper_enum_va    
293                 enum_pos = self.helper_enum_po    
294             except KeyError:                      
295                 raise Exception("Helper %s is     
296                                                   
297             if name in seen_helpers:              
298                 if last_helper != name:           
299                     raise Exception("Helper %s    
300                 continue                          
301                                                   
302             # Enforce current practice of havi    
303             # by enum value.                      
304             if enum_pos != i:                     
305                 raise Exception("Helper %s (ID    
306             if enum_val in seen_enum_vals:        
307                 raise Exception("Helper %s has    
308                                                   
309             seen_helpers.add(name)                
310             last_helper = name                    
311             seen_enum_vals.add(enum_val)          
312                                                   
313             helper.enum_val = enum_val            
314             i += 1                                
315                                                   
316     def run(self):                                
317         self.parse_desc_syscall()                 
318         self.parse_enum_syscall()                 
319         self.parse_desc_helpers()                 
320         self.parse_define_helpers()               
321         self.validate_helpers()                   
322         self.reader.close()                       
323                                                   
324 ##############################################    
325                                                   
326 class Printer(object):                            
327     """                                           
328     A generic class for printers. Printers sho    
329     Helper objects, and implement a way to pri    
330     @parser: A HeaderParser with objects to pr    
331     """                                           
332     def __init__(self, parser):                   
333         self.parser = parser                      
334         self.elements = []                        
335                                                   
336     def print_header(self):                       
337         pass                                      
338                                                   
339     def print_footer(self):                       
340         pass                                      
341                                                   
342     def print_one(self, helper):                  
343         pass                                      
344                                                   
345     def print_all(self):                          
346         self.print_header()                       
347         for elem in self.elements:                
348             self.print_one(elem)                  
349         self.print_footer()                       
350                                                   
351     def elem_number_check(self, desc_unique_el    
352         """                                       
353         Checks the number of helpers/syscalls     
354         description with those defined as part    
355         Exception if they don't match.            
356         """                                       
357         nr_desc_unique_elem = len(desc_unique_    
358         nr_define_unique_elem = len(define_uni    
359         if nr_desc_unique_elem != nr_define_un    
360             exception_msg = '''                   
361 The number of unique %s in description (%d) do    
362 ''' % (type, nr_desc_unique_elem, type, instan    
363             if nr_desc_unique_elem < nr_define    
364                 # Function description is pars    
365                 # misformatting). Hence, only     
366                 exception_msg += '''              
367 The description for %s is not present or forma    
368 ''' % (define_unique_elem[nr_desc_unique_elem]    
369             raise Exception(exception_msg)        
370                                                   
371 class PrinterRST(Printer):                        
372     """                                           
373     A generic class for printers that print Re    
374     be created with a HeaderParser object, and    
375     elements in the desired fashion.              
376     @parser: A HeaderParser with objects to pr    
377     """                                           
378     def __init__(self, parser):                   
379         self.parser = parser                      
380                                                   
381     def print_license(self):                      
382         license = '''\                            
383 .. Copyright (C) All BPF authors and contribut    
384 .. See git log include/uapi/linux/bpf.h in ker    
385 ..                                                
386 .. SPDX-License-Identifier: Linux-man-pages-co    
387 ..                                                
388 .. Please do not edit this file. It was genera    
389 .. located in file include/uapi/linux/bpf.h of    
390 .. (helpers description), and from scripts/bpf    
391 .. repository (header and footer).                
392 '''                                               
393         print(license)                            
394                                                   
395     def print_elem(self, elem):                   
396         if (elem.desc):                           
397             print('\tDescription')                
398             # Do not strip all newline charact    
399             # a section must be followed by a     
400             for line in re.sub('\n$', '', elem    
401                 print('{}{}'.format('\t\t' if     
402                                                   
403         if (elem.ret):                            
404             print('\tReturn')                     
405             for line in elem.ret.rstrip().spli    
406                 print('{}{}'.format('\t\t' if     
407                                                   
408         print('')                                 
409                                                   
410     def get_kernel_version(self):                 
411         try:                                      
412             version = subprocess.run(['git', '    
413                                      capture_o    
414             version = version.stdout.decode().    
415         except:                                   
416             try:                                  
417                 version = subprocess.run(['mak    
418                                          cwd=l    
419                 version = version.stdout.decod    
420             except:                               
421                 return 'Linux'                    
422         return 'Linux {version}'.format(versio    
423                                                   
424     def get_last_doc_update(self, delimiter):     
425         try:                                      
426             cmd = ['git', 'log', '-1', '--pret    
427                    '-L',                          
428                    '/{}/,/\\*\\//:include/uapi    
429             date = subprocess.run(cmd, cwd=lin    
430                                   capture_outp    
431             return date.stdout.decode().rstrip    
432         except:                                   
433             return ''                             
434                                                   
435 class PrinterHelpersRST(PrinterRST):              
436     """                                           
437     A printer for dumping collected informatio    
438     Text page compatible with the rst2man prog    
439     generate a manual page for the helpers.       
440     @parser: A HeaderParser with Helper object    
441     """                                           
442     def __init__(self, parser):                   
443         self.elements = parser.helpers            
444         self.elem_number_check(parser.desc_uni    
445                                                   
446     def print_header(self):                       
447         header = '''\                             
448 ===========                                       
449 BPF-HELPERS                                       
450 ===========                                       
451 ----------------------------------------------    
452 list of eBPF helper functions                     
453 ----------------------------------------------    
454                                                   
455 :Manual section: 7                                
456 :Version: {version}                               
457 {date_field}{date}                                
458                                                   
459 DESCRIPTION                                       
460 ===========                                       
461                                                   
462 The extended Berkeley Packet Filter (eBPF) sub    
463 written in a pseudo-assembly language, then at    
464 kernel hooks and run in reaction of specific e    
465 from the older, "classic" BPF (or "cBPF") in s    
466 the ability to call special functions (or "hel    
467 These functions are restricted to a white-list    
468 kernel.                                           
469                                                   
470 These helpers are used by eBPF programs to int    
471 the context in which they work. For instance,     
472 debugging messages, to get the time since the     
473 with eBPF maps, or to manipulate network packe    
474 program types, and that they do not run in the    
475 can only call a subset of those helpers.          
476                                                   
477 Due to eBPF conventions, a helper can not have    
478                                                   
479 Internally, eBPF programs call directly into t    
480 without requiring any foreign-function interfa    
481 introduces no overhead, thus offering excellen    
482                                                   
483 This document is an attempt to list and docume    
484 developers. They are sorted by chronological o    
485 kernel at the top).                               
486                                                   
487 HELPERS                                           
488 =======                                           
489 '''                                               
490         kernelVersion = self.get_kernel_versio    
491         lastUpdate = self.get_last_doc_update(    
492                                                   
493         PrinterRST.print_license(self)            
494         print(header.format(version=kernelVers    
495                             date_field = ':Dat    
496                             date=lastUpdate))     
497                                                   
498     def print_footer(self):                       
499         footer = '''                              
500 EXAMPLES                                          
501 ========                                          
502                                                   
503 Example usage for most of the eBPF helpers lis    
504 available within the Linux kernel sources, at     
505                                                   
506 * *samples/bpf/*                                  
507 * *tools/testing/selftests/bpf/*                  
508                                                   
509 LICENSE                                           
510 =======                                           
511                                                   
512 eBPF programs can have an associated license,     
513 instructions to the kernel when the programs a    
514 string is identical to the one in use for kern    
515 as "Dual BSD/GPL", may be used). Some helper f    
516 programs that are compatible with the GNU Gene    
517                                                   
518 In order to use such helpers, the eBPF program    
519 license string passed (via **attr**) to the **    
520 generally translates into the C source code of    
521 similar to the following:                         
522                                                   
523 ::                                                
524                                                   
525         char ____license[] __attribute__((sect    
526                                                   
527 IMPLEMENTATION                                    
528 ==============                                    
529                                                   
530 This manual page is an effort to document the     
531 But as of this writing, the BPF sub-system is     
532 program or map types are added, along with new    
533 are occasionally made available for additional    
534 the efforts of the community, this page might     
535 check by yourself what helper functions exist     
536 programs they can support, here are some files    
537 may be interested in:                             
538                                                   
539 * *include/uapi/linux/bpf.h* is the main BPF h    
540   of all helper functions, as well as many oth    
541   of the flags, structs or constants used by t    
542 * *net/core/filter.c* contains the definition     
543   functions, and the list of program types fro    
544 * *kernel/trace/bpf_trace.c* is the equivalent    
545   helpers.                                        
546 * *kernel/bpf/verifier.c* contains the functio    
547   of eBPF maps are used with a given helper fu    
548 * *kernel/bpf/* directory contains other files    
549   defined (for cgroups, sockmaps, etc.).          
550 * The bpftool utility can be used to probe the    
551   on the system (as well as supported program     
552   other parameters). To do so, run **bpftool f    
553   **bpftool-feature**\\ (8) for details). Add     
554   list features available to unprivileged user    
555                                                   
556 Compatibility between helper functions and pro    
557 in the files where helper functions are define    
558 bpf_func_proto** objects and for functions ret    
559 contain a list of helpers that a given program    
560 **default:** label of the **switch ... case**     
561 other functions, themselves allowing access to    
562 requirement for GPL license is also in those *    
563                                                   
564 Compatibility between helper functions and map    
565 **check_map_func_compatibility**\\ () function    
566                                                   
567 Helper functions that invalidate the checks on    
568 pointers for network processing are listed in     
569 **bpf_helper_changes_pkt_data**\\ () in file *    
570                                                   
571 SEE ALSO                                          
572 ========                                          
573                                                   
574 **bpf**\\ (2),                                    
575 **bpftool**\\ (8),                                
576 **cgroups**\\ (7),                                
577 **ip**\\ (8),                                     
578 **perf_event_open**\\ (2),                        
579 **sendmsg**\\ (2),                                
580 **socket**\\ (7),                                 
581 **tc-bpf**\\ (8)'''                               
582         print(footer)                             
583                                                   
584     def print_proto(self, helper):                
585         """                                       
586         Format function protocol with bold and    
587         file less readable, but gives nice res    
588         """                                       
589         proto = helper.proto_break_down()         
590                                                   
591         print('**%s %s%s(' % (proto['ret_type'    
592                               proto['ret_star'    
593                               proto['name']),     
594               end='')                             
595                                                   
596         comma = ''                                
597         for a in proto['args']:                   
598             one_arg = '{}{}'.format(comma, a['    
599             if a['name']:                         
600                 if a['star']:                     
601                     one_arg += ' {}**\\ '.form    
602                 else:                             
603                     one_arg += '** '              
604                 one_arg += '*{}*\\ **'.format(    
605             comma = ', '                          
606             print(one_arg, end='')                
607                                                   
608         print(')**')                              
609                                                   
610     def print_one(self, helper):                  
611         self.print_proto(helper)                  
612         self.print_elem(helper)                   
613                                                   
614                                                   
615 class PrinterSyscallRST(PrinterRST):              
616     """                                           
617     A printer for dumping collected informatio    
618     ReStructured Text page compatible with the    
619     used to generate a manual page for the sys    
620     @parser: A HeaderParser with APIElement ob    
621              output                               
622     """                                           
623     def __init__(self, parser):                   
624         self.elements = parser.commands           
625         self.elem_number_check(parser.desc_sys    
626                                                   
627     def print_header(self):                       
628         header = '''\                             
629 ===                                               
630 bpf                                               
631 ===                                               
632 ----------------------------------------------    
633 Perform a command on an extended BPF object       
634 ----------------------------------------------    
635                                                   
636 :Manual section: 2                                
637                                                   
638 COMMANDS                                          
639 ========                                          
640 '''                                               
641         PrinterRST.print_license(self)            
642         print(header)                             
643                                                   
644     def print_one(self, command):                 
645         print('**%s**' % (command.proto))         
646         self.print_elem(command)                  
647                                                   
648                                                   
649 class PrinterHelpers(Printer):                    
650     """                                           
651     A printer for dumping collected informatio    
652     be included from BPF program.                 
653     @parser: A HeaderParser with Helper object    
654     """                                           
655     def __init__(self, parser):                   
656         self.elements = parser.helpers            
657         self.elem_number_check(parser.desc_uni    
658                                                   
659     type_fwds = [                                 
660             'struct bpf_fib_lookup',              
661             'struct bpf_sk_lookup',               
662             'struct bpf_perf_event_data',         
663             'struct bpf_perf_event_value',        
664             'struct bpf_pidns_info',              
665             'struct bpf_redir_neigh',             
666             'struct bpf_sock',                    
667             'struct bpf_sock_addr',               
668             'struct bpf_sock_ops',                
669             'struct bpf_sock_tuple',              
670             'struct bpf_spin_lock',               
671             'struct bpf_sysctl',                  
672             'struct bpf_tcp_sock',                
673             'struct bpf_tunnel_key',              
674             'struct bpf_xfrm_state',              
675             'struct linux_binprm',                
676             'struct pt_regs',                     
677             'struct sk_reuseport_md',             
678             'struct sockaddr',                    
679             'struct tcphdr',                      
680             'struct seq_file',                    
681             'struct tcp6_sock',                   
682             'struct tcp_sock',                    
683             'struct tcp_timewait_sock',           
684             'struct tcp_request_sock',            
685             'struct udp6_sock',                   
686             'struct unix_sock',                   
687             'struct task_struct',                 
688             'struct cgroup',                      
689                                                   
690             'struct __sk_buff',                   
691             'struct sk_msg_md',                   
692             'struct xdp_md',                      
693             'struct path',                        
694             'struct btf_ptr',                     
695             'struct inode',                       
696             'struct socket',                      
697             'struct file',                        
698             'struct bpf_timer',                   
699             'struct mptcp_sock',                  
700             'struct bpf_dynptr',                  
701             'struct iphdr',                       
702             'struct ipv6hdr',                     
703     ]                                             
704     known_types = {                               
705             '...',                                
706             'void',                               
707             'const void',                         
708             'char',                               
709             'const char',                         
710             'int',                                
711             'long',                               
712             'unsigned long',                      
713                                                   
714             '__be16',                             
715             '__be32',                             
716             '__wsum',                             
717                                                   
718             'struct bpf_fib_lookup',              
719             'struct bpf_perf_event_data',         
720             'struct bpf_perf_event_value',        
721             'struct bpf_pidns_info',              
722             'struct bpf_redir_neigh',             
723             'struct bpf_sk_lookup',               
724             'struct bpf_sock',                    
725             'struct bpf_sock_addr',               
726             'struct bpf_sock_ops',                
727             'struct bpf_sock_tuple',              
728             'struct bpf_spin_lock',               
729             'struct bpf_sysctl',                  
730             'struct bpf_tcp_sock',                
731             'struct bpf_tunnel_key',              
732             'struct bpf_xfrm_state',              
733             'struct linux_binprm',                
734             'struct pt_regs',                     
735             'struct sk_reuseport_md',             
736             'struct sockaddr',                    
737             'struct tcphdr',                      
738             'struct seq_file',                    
739             'struct tcp6_sock',                   
740             'struct tcp_sock',                    
741             'struct tcp_timewait_sock',           
742             'struct tcp_request_sock',            
743             'struct udp6_sock',                   
744             'struct unix_sock',                   
745             'struct task_struct',                 
746             'struct cgroup',                      
747             'struct path',                        
748             'struct btf_ptr',                     
749             'struct inode',                       
750             'struct socket',                      
751             'struct file',                        
752             'struct bpf_timer',                   
753             'struct mptcp_sock',                  
754             'struct bpf_dynptr',                  
755             'const struct bpf_dynptr',            
756             'struct iphdr',                       
757             'struct ipv6hdr',                     
758     }                                             
759     mapped_types = {                              
760             'u8': '__u8',                         
761             'u16': '__u16',                       
762             'u32': '__u32',                       
763             'u64': '__u64',                       
764             's8': '__s8',                         
765             's16': '__s16',                       
766             's32': '__s32',                       
767             's64': '__s64',                       
768             'size_t': 'unsigned long',            
769             'struct bpf_map': 'void',             
770             'struct sk_buff': 'struct __sk_buf    
771             'const struct sk_buff': 'const str    
772             'struct sk_msg_buff': 'struct sk_m    
773             'struct xdp_buff': 'struct xdp_md'    
774     }                                             
775     # Helpers overloaded for different context    
776     overloaded_helpers = [                        
777         'bpf_get_socket_cookie',                  
778         'bpf_sk_assign',                          
779     ]                                             
780                                                   
781     def print_header(self):                       
782         header = '''\                             
783 /* This is auto-generated file. See bpf_doc.py    
784                                                   
785 /* Forward declarations of BPF structs */'''      
786                                                   
787         print(header)                             
788         for fwd in self.type_fwds:                
789             print('%s;' % fwd)                    
790         print('')                                 
791                                                   
792     def print_footer(self):                       
793         footer = ''                               
794         print(footer)                             
795                                                   
796     def map_type(self, t):                        
797         if t in self.known_types:                 
798             return t                              
799         if t in self.mapped_types:                
800             return self.mapped_types[t]           
801         print("Unrecognized type '%s', please     
802               file=sys.stderr)                    
803         sys.exit(1)                               
804                                                   
805     seen_helpers = set()                          
806                                                   
807     def print_one(self, helper):                  
808         proto = helper.proto_break_down()         
809                                                   
810         if proto['name'] in self.seen_helpers:    
811             return                                
812         self.seen_helpers.add(proto['name'])      
813                                                   
814         print('/*')                               
815         print(" * %s" % proto['name'])            
816         print(" *")                               
817         if (helper.desc):                         
818             # Do not strip all newline charact    
819             # a section must be followed by a     
820             for line in re.sub('\n$', '', help    
821                 print(' *{}{}'.format(' \t' if    
822                                                   
823         if (helper.ret):                          
824             print(' *')                           
825             print(' * Returns')                   
826             for line in helper.ret.rstrip().sp    
827                 print(' *{}{}'.format(' \t' if    
828                                                   
829         print(' */')                              
830         print('static %s %s(* const %s)(' % (s    
831                                       proto['r    
832         comma = ''                                
833         for i, a in enumerate(proto['args']):     
834             t = a['type']                         
835             n = a['name']                         
836             if proto['name'] in self.overloade    
837                     t = 'void'                    
838                     n = 'ctx'                     
839             one_arg = '{}{}'.format(comma, sel    
840             if n:                                 
841                 if a['star']:                     
842                     one_arg += ' {}'.format(a[    
843                 else:                             
844                     one_arg += ' '                
845                 one_arg += '{}'.format(n)         
846             comma = ', '                          
847             print(one_arg, end='')                
848                                                   
849         print(') = (void *) %d;' % helper.enum    
850         print('')                                 
851                                                   
852 ##############################################    
853                                                   
854 # If script is launched from scripts/ from ker    
855 # ../include/uapi/linux/bpf.h, use it as a def    
856 # otherwise the --filename argument will be re    
857 script = os.path.abspath(sys.argv[0])             
858 linuxRoot = os.path.dirname(os.path.dirname(sc    
859 bpfh = os.path.join(linuxRoot, 'include/uapi/l    
860                                                   
861 printers = {                                      
862         'helpers': PrinterHelpersRST,             
863         'syscall': PrinterSyscallRST,             
864 }                                                 
865                                                   
866 argParser = argparse.ArgumentParser(descriptio    
867 Parse eBPF header file and generate documentat    
868 The RST-formatted output produced can be turne    
869 rst2man utility.                                  
870 """)                                              
871 argParser.add_argument('--header', action='sto    
872                        help='generate C header    
873 if (os.path.isfile(bpfh)):                        
874     argParser.add_argument('--filename', help=    
875                            default=bpfh)          
876 else:                                             
877     argParser.add_argument('--filename', help=    
878 argParser.add_argument('target', nargs='?', de    
879                        choices=printers.keys()    
880 args = argParser.parse_args()                     
881                                                   
882 # Parse file.                                     
883 headerParser = HeaderParser(args.filename)        
884 headerParser.run()                                
885                                                   
886 # Print formatted output to standard output.      
887 if args.header:                                   
888     if args.target != 'helpers':                  
889         raise NotImplementedError('Only helper    
890     printer = PrinterHelpers(headerParser)        
891 else:                                             
892     printer = printers[args.target](headerPars    
893 printer.print_all()                               
                                                      

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