Commit 121fd33b authored by Vishal Chourasia's avatar Vishal Chourasia Committed by Daniel Borkmann

bpf, docs: Fix invalid escape sequence warnings in bpf_doc.py

The script bpf_doc.py generates multiple SyntaxWarnings related to invalid
escape sequences when executed with Python 3.12. These warnings do not appear
in Python 3.10 and 3.11 and do not affect the kernel build, which completes
successfully.

This patch resolves these SyntaxWarnings by converting the relevant string
literals to raw strings or by escaping backslashes. This ensures that
backslashes are interpreted as literal characters, eliminating the warnings.
Reported-by: default avatarSrikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: default avatarVishal Chourasia <vishalc@linux.ibm.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Tested-by: default avatarQuentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/20230829074931.2511204-1-vishalc@linux.ibm.com
parent 3e019d8a
...@@ -59,9 +59,9 @@ class Helper(APIElement): ...@@ -59,9 +59,9 @@ class Helper(APIElement):
Break down helper function protocol into smaller chunks: return type, Break down helper function protocol into smaller chunks: return type,
name, distincts arguments. name, distincts arguments.
""" """
arg_re = re.compile('((\w+ )*?(\w+|...))( (\**)(\w+))?$') arg_re = re.compile(r'((\w+ )*?(\w+|...))( (\**)(\w+))?$')
res = {} res = {}
proto_re = re.compile('(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$') proto_re = re.compile(r'(.+) (\**)(\w+)\(((([^,]+)(, )?){1,5})\)$')
capture = proto_re.match(self.proto) capture = proto_re.match(self.proto)
res['ret_type'] = capture.group(1) res['ret_type'] = capture.group(1)
...@@ -114,11 +114,11 @@ class HeaderParser(object): ...@@ -114,11 +114,11 @@ class HeaderParser(object):
return Helper(proto=proto, desc=desc, ret=ret) return Helper(proto=proto, desc=desc, ret=ret)
def parse_symbol(self): def parse_symbol(self):
p = re.compile(' \* ?(BPF\w+)$') p = re.compile(r' \* ?(BPF\w+)$')
capture = p.match(self.line) capture = p.match(self.line)
if not capture: if not capture:
raise NoSyscallCommandFound raise NoSyscallCommandFound
end_re = re.compile(' \* ?NOTES$') end_re = re.compile(r' \* ?NOTES$')
end = end_re.match(self.line) end = end_re.match(self.line)
if end: if end:
raise NoSyscallCommandFound raise NoSyscallCommandFound
...@@ -133,7 +133,7 @@ class HeaderParser(object): ...@@ -133,7 +133,7 @@ class HeaderParser(object):
# - Same as above, with "const" and/or "struct" in front of type # - Same as above, with "const" and/or "struct" in front of type
# - "..." (undefined number of arguments, for bpf_trace_printk()) # - "..." (undefined number of arguments, for bpf_trace_printk())
# There is at least one term ("void"), and at most five arguments. # There is at least one term ("void"), and at most five arguments.
p = re.compile(' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$') p = re.compile(r' \* ?((.+) \**\w+\((((const )?(struct )?(\w+|\.\.\.)( \**\w+)?)(, )?){1,5}\))$')
capture = p.match(self.line) capture = p.match(self.line)
if not capture: if not capture:
raise NoHelperFound raise NoHelperFound
...@@ -141,7 +141,7 @@ class HeaderParser(object): ...@@ -141,7 +141,7 @@ class HeaderParser(object):
return capture.group(1) return capture.group(1)
def parse_desc(self, proto): def parse_desc(self, proto):
p = re.compile(' \* ?(?:\t| {5,8})Description$') p = re.compile(r' \* ?(?:\t| {5,8})Description$')
capture = p.match(self.line) capture = p.match(self.line)
if not capture: if not capture:
raise Exception("No description section found for " + proto) raise Exception("No description section found for " + proto)
...@@ -154,7 +154,7 @@ class HeaderParser(object): ...@@ -154,7 +154,7 @@ class HeaderParser(object):
if self.line == ' *\n': if self.line == ' *\n':
desc += '\n' desc += '\n'
else: else:
p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') p = re.compile(r' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
capture = p.match(self.line) capture = p.match(self.line)
if capture: if capture:
desc_present = True desc_present = True
...@@ -167,7 +167,7 @@ class HeaderParser(object): ...@@ -167,7 +167,7 @@ class HeaderParser(object):
return desc return desc
def parse_ret(self, proto): def parse_ret(self, proto):
p = re.compile(' \* ?(?:\t| {5,8})Return$') p = re.compile(r' \* ?(?:\t| {5,8})Return$')
capture = p.match(self.line) capture = p.match(self.line)
if not capture: if not capture:
raise Exception("No return section found for " + proto) raise Exception("No return section found for " + proto)
...@@ -180,7 +180,7 @@ class HeaderParser(object): ...@@ -180,7 +180,7 @@ class HeaderParser(object):
if self.line == ' *\n': if self.line == ' *\n':
ret += '\n' ret += '\n'
else: else:
p = re.compile(' \* ?(?:\t| {5,8})(?:\t| {8})(.*)') p = re.compile(r' \* ?(?:\t| {5,8})(?:\t| {8})(.*)')
capture = p.match(self.line) capture = p.match(self.line)
if capture: if capture:
ret_present = True ret_present = True
...@@ -219,12 +219,12 @@ class HeaderParser(object): ...@@ -219,12 +219,12 @@ class HeaderParser(object):
self.seek_to('enum bpf_cmd {', self.seek_to('enum bpf_cmd {',
'Could not find start of bpf_cmd enum', 0) 'Could not find start of bpf_cmd enum', 0)
# Searches for either one or more BPF\w+ enums # Searches for either one or more BPF\w+ enums
bpf_p = re.compile('\s*(BPF\w+)+') bpf_p = re.compile(r'\s*(BPF\w+)+')
# Searches for an enum entry assigned to another entry, # Searches for an enum entry assigned to another entry,
# for e.g. BPF_PROG_RUN = BPF_PROG_TEST_RUN, which is # for e.g. BPF_PROG_RUN = BPF_PROG_TEST_RUN, which is
# not documented hence should be skipped in check to # not documented hence should be skipped in check to
# determine if the right number of syscalls are documented # determine if the right number of syscalls are documented
assign_p = re.compile('\s*(BPF\w+)\s*=\s*(BPF\w+)') assign_p = re.compile(r'\s*(BPF\w+)\s*=\s*(BPF\w+)')
bpf_cmd_str = '' bpf_cmd_str = ''
while True: while True:
capture = assign_p.match(self.line) capture = assign_p.match(self.line)
...@@ -239,7 +239,7 @@ class HeaderParser(object): ...@@ -239,7 +239,7 @@ class HeaderParser(object):
break break
self.line = self.reader.readline() self.line = self.reader.readline()
# Find the number of occurences of BPF\w+ # Find the number of occurences of BPF\w+
self.enum_syscalls = re.findall('(BPF\w+)+', bpf_cmd_str) self.enum_syscalls = re.findall(r'(BPF\w+)+', bpf_cmd_str)
def parse_desc_helpers(self): def parse_desc_helpers(self):
self.seek_to(helpersDocStart, self.seek_to(helpersDocStart,
...@@ -263,7 +263,7 @@ class HeaderParser(object): ...@@ -263,7 +263,7 @@ class HeaderParser(object):
self.seek_to('#define ___BPF_FUNC_MAPPER(FN, ctx...)', self.seek_to('#define ___BPF_FUNC_MAPPER(FN, ctx...)',
'Could not find start of eBPF helper definition list') 'Could not find start of eBPF helper definition list')
# Searches for one FN(\w+) define or a backslash for newline # Searches for one FN(\w+) define or a backslash for newline
p = re.compile('\s*FN\((\w+), (\d+), ##ctx\)|\\\\') p = re.compile(r'\s*FN\((\w+), (\d+), ##ctx\)|\\\\')
fn_defines_str = '' fn_defines_str = ''
i = 0 i = 0
while True: while True:
...@@ -278,7 +278,7 @@ class HeaderParser(object): ...@@ -278,7 +278,7 @@ class HeaderParser(object):
break break
self.line = self.reader.readline() self.line = self.reader.readline()
# Find the number of occurences of FN(\w+) # Find the number of occurences of FN(\w+)
self.define_unique_helpers = re.findall('FN\(\w+, \d+, ##ctx\)', fn_defines_str) self.define_unique_helpers = re.findall(r'FN\(\w+, \d+, ##ctx\)', fn_defines_str)
def validate_helpers(self): def validate_helpers(self):
last_helper = '' last_helper = ''
...@@ -425,7 +425,7 @@ class PrinterRST(Printer): ...@@ -425,7 +425,7 @@ class PrinterRST(Printer):
try: try:
cmd = ['git', 'log', '-1', '--pretty=format:%cs', '--no-patch', cmd = ['git', 'log', '-1', '--pretty=format:%cs', '--no-patch',
'-L', '-L',
'/{}/,/\*\//:include/uapi/linux/bpf.h'.format(delimiter)] '/{}/,/\\*\\//:include/uapi/linux/bpf.h'.format(delimiter)]
date = subprocess.run(cmd, cwd=linuxRoot, date = subprocess.run(cmd, cwd=linuxRoot,
capture_output=True, check=True) capture_output=True, check=True)
return date.stdout.decode().rstrip() return date.stdout.decode().rstrip()
...@@ -516,7 +516,7 @@ as "Dual BSD/GPL", may be used). Some helper functions are only accessible to ...@@ -516,7 +516,7 @@ as "Dual BSD/GPL", may be used). Some helper functions are only accessible to
programs that are compatible with the GNU Privacy License (GPL). programs that are compatible with the GNU Privacy License (GPL).
In order to use such helpers, the eBPF program must be loaded with the correct In order to use such helpers, the eBPF program must be loaded with the correct
license string passed (via **attr**) to the **bpf**\ () system call, and this license string passed (via **attr**) to the **bpf**\\ () system call, and this
generally translates into the C source code of the program containing a line generally translates into the C source code of the program containing a line
similar to the following: similar to the following:
...@@ -550,7 +550,7 @@ may be interested in: ...@@ -550,7 +550,7 @@ may be interested in:
* The bpftool utility can be used to probe the availability of helper functions * The bpftool utility can be used to probe the availability of helper functions
on the system (as well as supported program and map types, and a number of on the system (as well as supported program and map types, and a number of
other parameters). To do so, run **bpftool feature probe** (see other parameters). To do so, run **bpftool feature probe** (see
**bpftool-feature**\ (8) for details). Add the **unprivileged** keyword to **bpftool-feature**\\ (8) for details). Add the **unprivileged** keyword to
list features available to unprivileged users. list features available to unprivileged users.
Compatibility between helper functions and program types can generally be found Compatibility between helper functions and program types can generally be found
...@@ -562,23 +562,23 @@ other functions, themselves allowing access to additional helpers. The ...@@ -562,23 +562,23 @@ other functions, themselves allowing access to additional helpers. The
requirement for GPL license is also in those **struct bpf_func_proto**. requirement for GPL license is also in those **struct bpf_func_proto**.
Compatibility between helper functions and map types can be found in the Compatibility between helper functions and map types can be found in the
**check_map_func_compatibility**\ () function in file *kernel/bpf/verifier.c*. **check_map_func_compatibility**\\ () function in file *kernel/bpf/verifier.c*.
Helper functions that invalidate the checks on **data** and **data_end** Helper functions that invalidate the checks on **data** and **data_end**
pointers for network processing are listed in function pointers for network processing are listed in function
**bpf_helper_changes_pkt_data**\ () in file *net/core/filter.c*. **bpf_helper_changes_pkt_data**\\ () in file *net/core/filter.c*.
SEE ALSO SEE ALSO
======== ========
**bpf**\ (2), **bpf**\\ (2),
**bpftool**\ (8), **bpftool**\\ (8),
**cgroups**\ (7), **cgroups**\\ (7),
**ip**\ (8), **ip**\\ (8),
**perf_event_open**\ (2), **perf_event_open**\\ (2),
**sendmsg**\ (2), **sendmsg**\\ (2),
**socket**\ (7), **socket**\\ (7),
**tc-bpf**\ (8)''' **tc-bpf**\\ (8)'''
print(footer) print(footer)
def print_proto(self, helper): def print_proto(self, helper):
...@@ -598,7 +598,7 @@ SEE ALSO ...@@ -598,7 +598,7 @@ SEE ALSO
one_arg = '{}{}'.format(comma, a['type']) one_arg = '{}{}'.format(comma, a['type'])
if a['name']: if a['name']:
if a['star']: if a['star']:
one_arg += ' {}**\ '.format(a['star'].replace('*', '\\*')) one_arg += ' {}**\\ '.format(a['star'].replace('*', '\\*'))
else: else:
one_arg += '** ' one_arg += '** '
one_arg += '*{}*\\ **'.format(a['name']) one_arg += '*{}*\\ **'.format(a['name'])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment