Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #!/usr/bin/env python3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) # SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) # Copyright (C) 2018-2019 Netronome Systems, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) # In case user attempts to run with Python 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) from __future__ import print_function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) import argparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) import re
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) import sys, os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) class NoHelperFound(BaseException):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)     pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) class ParsingError(BaseException):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)     def __init__(self, line='<line not provided>', reader=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)         if reader:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)             BaseException.__init__(self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)                                    'Error at file offset %d, parsing line: %s' %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)                                    (reader.tell(), line))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)         else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)             BaseException.__init__(self, 'Error parsing line: %s' % line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) class Helper(object):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)     An object representing the description of an eBPF helper function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)     @proto: function prototype of the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)     @desc: textual description of the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)     @ret: description of the return value of the helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)     def __init__(self, proto='', desc='', ret=''):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)         self.proto = proto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)         self.desc = desc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)         self.ret = ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)     def proto_break_down(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)         """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)         Break down helper function protocol into smaller chunks: return type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)         name, distincts arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)         """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)         arg_re = re.compile('((\w+ )*?(\w+|...))( (\**)(\w+))?$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)         res = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)         proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)         capture = proto_re.match(self.proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)         res['ret_type'] = capture.group(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)         res['ret_star'] = capture.group(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)         res['name']     = capture.group(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)         res['args'] = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)         args    = capture.group(4).split(', ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)         for a in args:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)             capture = arg_re.match(a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)             res['args'].append({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)                 'type' : capture.group(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)                 'star' : capture.group(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)                 'name' : capture.group(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)             })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)         return res
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) class HeaderParser(object):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)     An object used to parse a file in order to extract the documentation of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)     list of eBPF helper functions. All the helpers that can be retrieved are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)     stored as Helper object, in the self.helpers() array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)     @filename: name of file to parse, usually include/uapi/linux/bpf.h in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)                kernel tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)     def __init__(self, filename):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)         self.reader = open(filename, 'r')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)         self.line = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)         self.helpers = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)     def parse_helper(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)         proto    = self.parse_proto()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)         desc     = self.parse_desc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)         ret      = self.parse_ret()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)         return Helper(proto=proto, desc=desc, ret=ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)     def parse_proto(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)         # Argument can be of shape:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)         #   - "void"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)         #   - "type  name"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)         #   - "type *name"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)         #   - Same as above, with "const" and/or "struct" in front of type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)         #   - "..." (undefined number of arguments, for bpf_trace_printk())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)         # There is at least one term ("void"), and at most five arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)         p = re.compile(' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)         capture = p.match(self.line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)         if not capture:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)             raise NoHelperFound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)         self.line = self.reader.readline()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)         return capture.group(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)     def parse_desc(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)         p = re.compile(' \* ?(?:\t| {5,8})Description$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)         capture = p.match(self.line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)         if not capture:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)             # Helper can have empty description and we might be parsing another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)             # attribute: return but do not consume.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)             return ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)         # Description can be several lines, some of them possibly empty, and it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)         # stops when another subsection title is met.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)         desc = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)         while True:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)             self.line = self.reader.readline()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)             if self.line == ' *\n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)                 desc += '\n'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)             else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)                 p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)                 capture = p.match(self.line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)                 if capture:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)                     desc += capture.group(1) + '\n'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)                 else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)                     break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)         return desc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)     def parse_ret(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)         p = re.compile(' \* ?(?:\t| {5,8})Return$')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)         capture = p.match(self.line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)         if not capture:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)             # Helper can have empty retval and we might be parsing another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)             # attribute: return but do not consume.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)             return ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)         # Return value description can be several lines, some of them possibly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)         # empty, and it stops when another subsection title is met.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)         ret = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)         while True:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)             self.line = self.reader.readline()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)             if self.line == ' *\n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)                 ret += '\n'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)             else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)                 p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)                 capture = p.match(self.line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)                 if capture:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)                     ret += capture.group(1) + '\n'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)                 else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)                     break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)         return ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)     def run(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)         # Advance to start of helper function descriptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)         offset = self.reader.read().find('* Start of BPF helper function descriptions:')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)         if offset == -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)             raise Exception('Could not find start of eBPF helper descriptions list')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)         self.reader.seek(offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)         self.reader.readline()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)         self.reader.readline()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)         self.line = self.reader.readline()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)         while True:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)             try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)                 helper = self.parse_helper()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)                 self.helpers.append(helper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)             except NoHelperFound:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)                 break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)         self.reader.close()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ###############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) class Printer(object):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)     A generic class for printers. Printers should be created with an array of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)     Helper objects, and implement a way to print them in the desired fashion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)     @helpers: array of Helper objects to print to standard output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)     def __init__(self, helpers):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)         self.helpers = helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)     def print_header(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)         pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)     def print_footer(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)         pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)     def print_one(self, helper):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)         pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)     def print_all(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)         self.print_header()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)         for helper in self.helpers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)             self.print_one(helper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)         self.print_footer()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) class PrinterRST(Printer):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)     A printer for dumping collected information about helpers as a ReStructured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)     Text page compatible with the rst2man program, which can be used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)     generate a manual page for the helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)     @helpers: array of Helper objects to print to standard output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)     def print_header(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)         header = '''\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .. Copyright (C) All BPF authors and contributors from 2014 to present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .. See git log include/uapi/linux/bpf.h in kernel tree for details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) .. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .. %%%LICENSE_START(VERBATIM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .. Permission is granted to make and distribute verbatim copies of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .. manual provided the copyright notice and this permission notice are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .. preserved on all copies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .. Permission is granted to copy and distribute modified versions of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .. manual under the conditions for verbatim copying, provided that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) .. entire resulting derived work is distributed under the terms of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .. permission notice identical to this one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .. Since the Linux kernel and libraries are constantly changing, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .. manual page may be incorrect or out-of-date.  The author(s) assume no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) .. responsibility for errors or omissions, or for damages resulting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .. the use of the information contained herein.  The author(s) may not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .. have taken the same level of care in the production of this manual,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .. which is licensed free of charge, as they might when working
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .. professionally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .. Formatted or processed versions of this manual, if unaccompanied by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .. the source, must acknowledge the copyright and authors of this work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .. %%%LICENSE_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .. Please do not edit this file. It was generated from the documentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .. located in file include/uapi/linux/bpf.h of the Linux kernel sources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .. (helpers description), and from scripts/bpf_helpers_doc.py in the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .. repository (header and footer).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) BPF-HELPERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) list of eBPF helper functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) :Manual section: 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) DESCRIPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) The extended Berkeley Packet Filter (eBPF) subsystem consists in programs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) written in a pseudo-assembly language, then attached to one of the several
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) kernel hooks and run in reaction of specific events. This framework differs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) from the older, "classic" BPF (or "cBPF") in several aspects, one of them being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) the ability to call special functions (or "helpers") from within a program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) These functions are restricted to a white-list of helpers defined in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) kernel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) These helpers are used by eBPF programs to interact with the system, or with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) the context in which they work. For instance, they can be used to print
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) debugging messages, to get the time since the system was booted, to interact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) with eBPF maps, or to manipulate network packets. Since there are several eBPF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) program types, and that they do not run in the same context, each program type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) can only call a subset of those helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) Due to eBPF conventions, a helper can not have more than five arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) Internally, eBPF programs call directly into the compiled helper functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) without requiring any foreign-function interface. As a result, calling helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) introduces no overhead, thus offering excellent performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) This document is an attempt to list and document the helpers available to eBPF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) developers. They are sorted by chronological order (the oldest helpers in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) kernel at the top).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) HELPERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) =======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) '''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)         print(header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)     def print_footer(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)         footer = '''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) EXAMPLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) Example usage for most of the eBPF helpers listed in this manual page are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) available within the Linux kernel sources, at the following locations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * *samples/bpf/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * *tools/testing/selftests/bpf/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) LICENSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) =======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) eBPF programs can have an associated license, passed along with the bytecode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) instructions to the kernel when the programs are loaded. The format for that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) string is identical to the one in use for kernel modules (Dual licenses, such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) as "Dual BSD/GPL", may be used). Some helper functions are only accessible to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) programs that are compatible with the GNU Privacy License (GPL).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) In order to use such helpers, the eBPF program must be loaded with the correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) license string passed (via **attr**) to the **bpf**\ () system call, and this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) generally translates into the C source code of the program containing a line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) similar to the following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	char ____license[] __attribute__((section("license"), used)) = "GPL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) IMPLEMENTATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ==============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) This manual page is an effort to document the existing eBPF helper functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) But as of this writing, the BPF sub-system is under heavy development. New eBPF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) program or map types are added, along with new helper functions. Some helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) are occasionally made available for additional program types. So in spite of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) the efforts of the community, this page might not be up-to-date. If you want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) check by yourself what helper functions exist in your kernel, or what types of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) programs they can support, here are some files among the kernel tree that you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) may be interested in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * *include/uapi/linux/bpf.h* is the main BPF header. It contains the full list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)   of all helper functions, as well as many other BPF definitions including most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)   of the flags, structs or constants used by the helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * *net/core/filter.c* contains the definition of most network-related helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)   functions, and the list of program types from which they can be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * *kernel/trace/bpf_trace.c* is the equivalent for most tracing program-related
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)   helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * *kernel/bpf/verifier.c* contains the functions used to check that valid types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)   of eBPF maps are used with a given helper function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * *kernel/bpf/* directory contains other files in which additional helpers are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)   defined (for cgroups, sockmaps, etc.).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * The bpftool utility can be used to probe the availability of helper functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)   on the system (as well as supported program and map types, and a number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)   other parameters). To do so, run **bpftool feature probe** (see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)   **bpftool-feature**\ (8) for details). Add the **unprivileged** keyword to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)   list features available to unprivileged users.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) Compatibility between helper functions and program types can generally be found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) in the files where helper functions are defined. Look for the **struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) bpf_func_proto** objects and for functions returning them: these functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) contain a list of helpers that a given program type can call. Note that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) **default:** label of the **switch ... case** used to filter helpers can call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) other functions, themselves allowing access to additional helpers. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) requirement for GPL license is also in those **struct bpf_func_proto**.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) Compatibility between helper functions and map types can be found in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) **check_map_func_compatibility**\ () function in file *kernel/bpf/verifier.c*.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) Helper functions that invalidate the checks on **data** and **data_end**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) pointers for network processing are listed in function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) **bpf_helper_changes_pkt_data**\ () in file *net/core/filter.c*.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) SEE ALSO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) **bpf**\ (2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) **bpftool**\ (8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) **cgroups**\ (7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) **ip**\ (8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) **perf_event_open**\ (2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) **sendmsg**\ (2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) **socket**\ (7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) **tc-bpf**\ (8)'''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)         print(footer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)     def print_proto(self, helper):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)         """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)         Format function protocol with bold and italics markers. This makes RST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)         file less readable, but gives nice results in the manual page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)         """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)         proto = helper.proto_break_down()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)         print('**%s %s%s(' % (proto['ret_type'],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)                               proto['ret_star'].replace('*', '\\*'),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)                               proto['name']),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)               end='')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)         comma = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)         for a in proto['args']:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)             one_arg = '{}{}'.format(comma, a['type'])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)             if a['name']:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)                 if a['star']:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)                     one_arg += ' {}**\ '.format(a['star'].replace('*', '\\*'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)                 else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)                     one_arg += '** '
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)                 one_arg += '*{}*\\ **'.format(a['name'])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)             comma = ', '
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)             print(one_arg, end='')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)         print(')**')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)     def print_one(self, helper):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)         self.print_proto(helper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)         if (helper.desc):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)             print('\tDescription')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)             # Do not strip all newline characters: formatted code at the end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)             # a section must be followed by a blank line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)             for line in re.sub('\n$', '', helper.desc, count=1).split('\n'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)                 print('{}{}'.format('\t\t' if line else '', line))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)         if (helper.ret):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)             print('\tReturn')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)             for line in helper.ret.rstrip().split('\n'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)                 print('{}{}'.format('\t\t' if line else '', line))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)         print('')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) class PrinterHelpers(Printer):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)     A printer for dumping collected information about helpers as C header to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)     be included from BPF program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)     @helpers: array of Helper objects to print to standard output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)     """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)     type_fwds = [
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)             'struct bpf_fib_lookup',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)             'struct bpf_sk_lookup',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)             'struct bpf_perf_event_data',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)             'struct bpf_perf_event_value',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)             'struct bpf_pidns_info',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)             'struct bpf_redir_neigh',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)             'struct bpf_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)             'struct bpf_sock_addr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)             'struct bpf_sock_ops',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)             'struct bpf_sock_tuple',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)             'struct bpf_spin_lock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)             'struct bpf_sysctl',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)             'struct bpf_tcp_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)             'struct bpf_tunnel_key',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)             'struct bpf_xfrm_state',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)             'struct pt_regs',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)             'struct sk_reuseport_md',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)             'struct sockaddr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)             'struct tcphdr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)             'struct seq_file',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)             'struct tcp6_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)             'struct tcp_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)             'struct tcp_timewait_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)             'struct tcp_request_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)             'struct udp6_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)             'struct task_struct',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)             'struct __sk_buff',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)             'struct sk_msg_md',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)             'struct xdp_md',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)             'struct path',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)             'struct btf_ptr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)     ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)     known_types = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)             '...',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)             'void',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)             'const void',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)             'char',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)             'const char',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)             'int',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)             'long',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)             'unsigned long',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)             '__be16',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)             '__be32',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)             '__wsum',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)             'struct bpf_fib_lookup',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)             'struct bpf_perf_event_data',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)             'struct bpf_perf_event_value',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)             'struct bpf_pidns_info',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)             'struct bpf_redir_neigh',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)             'struct bpf_sk_lookup',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)             'struct bpf_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)             'struct bpf_sock_addr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)             'struct bpf_sock_ops',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)             'struct bpf_sock_tuple',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)             'struct bpf_spin_lock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)             'struct bpf_sysctl',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)             'struct bpf_tcp_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)             'struct bpf_tunnel_key',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)             'struct bpf_xfrm_state',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)             'struct pt_regs',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)             'struct sk_reuseport_md',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)             'struct sockaddr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)             'struct tcphdr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)             'struct seq_file',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)             'struct tcp6_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)             'struct tcp_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)             'struct tcp_timewait_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)             'struct tcp_request_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)             'struct udp6_sock',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)             'struct task_struct',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)             'struct path',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)             'struct btf_ptr',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)     mapped_types = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)             'u8': '__u8',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)             'u16': '__u16',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)             'u32': '__u32',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)             'u64': '__u64',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)             's8': '__s8',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)             's16': '__s16',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)             's32': '__s32',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)             's64': '__s64',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)             'size_t': 'unsigned long',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)             'struct bpf_map': 'void',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)             'struct sk_buff': 'struct __sk_buff',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)             'const struct sk_buff': 'const struct __sk_buff',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)             'struct sk_msg_buff': 'struct sk_msg_md',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)             'struct xdp_buff': 'struct xdp_md',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)     # Helpers overloaded for different context types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)     overloaded_helpers = [
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)         'bpf_get_socket_cookie',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)         'bpf_sk_assign',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)     ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)     def print_header(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)         header = '''\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* This is auto-generated file. See bpf_helpers_doc.py for details. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* Forward declarations of BPF structs */'''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)         print(header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)         for fwd in self.type_fwds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)             print('%s;' % fwd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)         print('')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)     def print_footer(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)         footer = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)         print(footer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)     def map_type(self, t):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)         if t in self.known_types:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)             return t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)         if t in self.mapped_types:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)             return self.mapped_types[t]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)         print("Unrecognized type '%s', please add it to known types!" % t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)               file=sys.stderr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)         sys.exit(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)     seen_helpers = set()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)     def print_one(self, helper):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)         proto = helper.proto_break_down()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)         if proto['name'] in self.seen_helpers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)             return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)         self.seen_helpers.add(proto['name'])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)         print('/*')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)         print(" * %s" % proto['name'])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)         print(" *")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)         if (helper.desc):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)             # Do not strip all newline characters: formatted code at the end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)             # a section must be followed by a blank line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)             for line in re.sub('\n$', '', helper.desc, count=1).split('\n'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)                 print(' *{}{}'.format(' \t' if line else '', line))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)         if (helper.ret):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)             print(' *')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)             print(' * Returns')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)             for line in helper.ret.rstrip().split('\n'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)                 print(' *{}{}'.format(' \t' if line else '', line))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)         print(' */')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)         print('static %s %s(*%s)(' % (self.map_type(proto['ret_type']),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)                                       proto['ret_star'], proto['name']), end='')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)         comma = ''
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)         for i, a in enumerate(proto['args']):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)             t = a['type']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)             n = a['name']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)             if proto['name'] in self.overloaded_helpers and i == 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)                     t = 'void'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)                     n = 'ctx'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)             one_arg = '{}{}'.format(comma, self.map_type(t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)             if n:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)                 if a['star']:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)                     one_arg += ' {}'.format(a['star'])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)                 else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)                     one_arg += ' '
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)                 one_arg += '{}'.format(n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)             comma = ', '
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)             print(one_arg, end='')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)         print(') = (void *) %d;' % len(self.seen_helpers))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)         print('')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ###############################################################################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) # If script is launched from scripts/ from kernel tree and can access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) # ../include/uapi/linux/bpf.h, use it as a default name for the file to parse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) # otherwise the --filename argument will be required from the command line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) script = os.path.abspath(sys.argv[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) linuxRoot = os.path.dirname(os.path.dirname(script))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) bpfh = os.path.join(linuxRoot, 'include/uapi/linux/bpf.h')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) argParser = argparse.ArgumentParser(description="""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) Parse eBPF header file and generate documentation for eBPF helper functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) The RST-formatted output produced can be turned into a manual page with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) rst2man utility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) """)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) argParser.add_argument('--header', action='store_true',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)                        help='generate C header file')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (os.path.isfile(bpfh)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)     argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)                            default=bpfh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)     argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) args = argParser.parse_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) # Parse file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) headerParser = HeaderParser(args.filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) headerParser.run()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) # Print formatted output to standard output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if args.header:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)     printer = PrinterHelpers(headerParser.helpers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)     printer = PrinterRST(headerParser.helpers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) printer.print_all()