Skip to content

Commit 170257b

Browse files
committed
basic02: Text nits
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
1 parent a07e8de commit 170257b

1 file changed

Lines changed: 89 additions & 65 deletions

File tree

basic02-prog-by-name/README.org

Lines changed: 89 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,80 @@
11
# -*- fill-column: 76; -*-
2-
#+TITLE: Tutorial: Basic02
2+
#+TITLE: Tutorial: Basic02 - loading a program by name
33
#+OPTIONS: ^:nil
44

5-
In this assignment you will see that an BPF-ELF file produced by LLVM can
6-
contain more than one XDP program, and how you can select between them using
7-
the *libbpf API*.
5+
In this lesson you will see that a BPF ELF file produced by LLVM can contain
6+
more than one XDP program, and how you can select which one to load using
7+
the *libbpf API*. Complete each of the assignments below to complete the
8+
lesson.
89

910
* Table of Contents :TOC:
10-
- [[#lessons-using-libbpf][Lessons using libbpf]]
11-
- [[#lesson1-bpf_object][Lesson#1: bpf_object]]
12-
- [[#lesson2-bpf_object-to-bpf_program][Lesson#2: bpf_object to bpf_program]]
13-
- [[#lesson3-hardware-offloading][Lesson#3: Hardware offloading]]
11+
- [[#using-libbpf][Using libbpf]]
12+
- [[#basic-bpf_object-usage][Basic bpf_object usage]]
13+
- [[#converting-a-bpf_object-to-bpf_program][Converting a bpf_object to bpf_program]]
14+
- [[#hardware-offloading][Hardware offloading]]
1415
- [[#assignments][Assignments]]
15-
- [[#assignment1-setup-testlab][Assignment#1: Setup testlab]]
16-
- [[#assignment2-add-xdp_abort-program][Assignment#2: Add xdp_abort program]]
16+
- [[#assignment-1-setting-up-your-test-lab][Assignment 1: Setting up your test lab]]
17+
- [[#assignment-2-add-xdp_abort-program][Assignment 2: Add xdp_abort program]]
1718

18-
* Lessons using libbpf
19+
* Using libbpf
1920

20-
The libbpf API provides more than the basic system call wrappers (which are
21-
defined in libbpf [[https://github.com/libbpf/libbpf/blob/master/src/bpf.h][bpf.h]]). The libbpf API provides "[[https://github.com/libbpf/libbpf/blob/master/src/README.rst#objects][objects]]" and functions to
21+
The libbpf API not only provides the basic system call wrappers (which are
22+
defined in libbpf [[https://github.com/libbpf/libbpf/blob/master/src/bpf.h][bpf.h]]). The API also provides "[[https://github.com/libbpf/libbpf/blob/master/src/README.rst#objects][objects]]" and functions to
2223
work with them (defined in include [[https://github.com/libbpf/libbpf/blob/master/src/libbpf.h][libbpf.h]]).
2324

24-
The corresponding object struct's are:
25+
The C structs corresponding to the libbpf objects are:
2526
- struct =bpf_object=
2627
- struct =bpf_program=
2728
- struct =bpf_map=
2829

2930
These structs are for libbpf internal use, and you must use the API
3031
functions to interact with the objects. Functions that work with an object
31-
have the struct name plus double underscore, and then part that describes
32-
function purpose.
32+
have are named after the struct, followed by a double underscore, and a
33+
descriptive name.
3334

3435
Lets look at a practical usage of =bpf_object= and =bpf_program=.
3536

36-
** Lesson#1: bpf_object
37+
** Basic bpf_object usage
3738

3839
In [[file:xdp_loader.c]] the function =__load_bpf_object_file()= now returns a
39-
libbpf struct =bpf_object= pointer (while basic01 assignment returned the
40-
file-descriptor to the first BPF-prog).
40+
libbpf struct =bpf_object= pointer (while in the basic01 lesson we just
41+
returned the file descriptor to the first BPF prog).
4142

42-
The struct =bpf_object= represents ELF object itself.
43+
The struct =bpf_object= represents an ELF object, which can be of various
44+
types.
4345

44-
** Lesson#2: bpf_object to bpf_program
46+
** Converting a bpf_object to bpf_program
4547

46-
In [[file:xdp_loader.c]] the function =__load_bpf_and_xdp_attach()= use
47-
=bpf_object__find_program_by_title()= on the bpf_object, which is the "SEC"
48-
name, not the C-function name. This returns an struct =bpf_program= object,
49-
and we use the function =bpf_program__fd()= is used for getting the
50-
file-descriptor that we want to attach to the XDP hook.
48+
In [[file:xdp_loader.c]] the function =__load_bpf_and_xdp_attach()= uses
49+
=bpf_object__find_program_by_title()= on the bpf_object, which finds a
50+
program by the "SEC" name (not the C-function name). The return type is a
51+
struct =bpf_program= object, and we can use the function =bpf_program__fd()=
52+
for getting the file descriptor that we want to attach to the XDP hook.
5153

52-
** Lesson#3: Hardware offloading
54+
** Hardware offloading
5355

54-
XDP can also be hardware offloaded to capable NICs.
56+
XDP can also be offloaded to run in the NIC hardware (on some
57+
offload-capable NICs).
5558

56-
The XDP-flag XDP_FLAGS_HW_MODE enables/request hardware offloading, and is
57-
set with long-option =--offload-mode=. The [[file:xdp_loader.c][loader-code]] also need to use a
58-
more advanced libbpf API call =bpf_prog_load_xattr()=, which allows us to
59-
set the ifindex, as this is also needed for HW offloading.
59+
The XDP flag XDP_FLAGS_HW_MODE enables (requests) hardware offloading, and
60+
is set with the long-option =--offload-mode=. The [[file:xdp_loader.c][loader code]] also needs to
61+
use a more advanced libbpf API call =bpf_prog_load_xattr()=, which allows us
62+
to set the ifindex, as this is needed at load time to enable HW offloading.
6063

6164
There are some details on how to get hardware offloading working on
62-
Netronome's Agilio SmartNICs in [[file:xdp_offload_nfp.org]], like updating the
63-
firmware to support eBPF.
65+
Netronome's Agilio SmartNICs in [[file:xdp_offload_nfp.org]]; for instance, the
66+
firmware needs updating to support eBPF.
6467

6568
* Assignments
6669

67-
** Assignment#1: Setup testlab
70+
** Assignment 1: Setting up your test lab
6871

6972
As this lesson involves loading and selecting an XDP program that simply
70-
drops all packets (via action =XDP_DROP=), you need to establish a testlab
71-
environment. In the directory [[file:../testenv/][testenv/]] there is a script =testenv.sh= that
72-
helps you setup a testlab based on =veth= and network namespaces.
73+
drops all packets (via action =XDP_DROP=), you will need to load it on a
74+
real interface to observe what is happening. To do this, we establish a test
75+
lab environment. In the [[file:../testenv/][testenv/]] directory you will find a script
76+
=testenv.sh= that helps you setup a test lab based on =veth= devices and
77+
network namespaces.
7378

7479
E.g. run the script like:
7580
#+begin_example sh
@@ -78,15 +83,15 @@ Setting up new environment 'veth-basic02'
7883
Setup environment 'veth-basic02' with peer ip fc00:dead:cafe:1::2.
7984
#+end_example
8085

81-
This result in the creation of an (outer) interface named: =veth-basic02=.
82-
You can test that the environment network is operational by pinging the IPv6
83-
address =fc00:dead:cafe:1::2=.
86+
This results in the creation of an (outer) interface named: =veth-basic02=.
87+
You can test that the environment network is operational by pinging the peer
88+
IPv6 address =fc00:dead:cafe:1::2= (as seen in the script output).
8489

85-
The *assignment* is to manually load the compiled xdp program in ELF-OBJ file
86-
=xdp_prog_kern.o=, using the =xdp_loader= program in this directory. Observe
87-
the available options you can give the xdp_loader via =--help=. Try to
88-
select the program section named =xdp_drop= via =--progsec=, and observe via
89-
ping that packets gets dropped.
90+
The *assignment* is to manually load the compiled xdp program in the ELF OBJ
91+
file =xdp_prog_kern.o=, using the =xdp_loader= program in this directory.
92+
Observe the available options you can give the xdp_loader via =--help=. Try
93+
to select the program section named =xdp_drop= via =--progsec=, and observe
94+
via ping that packets gets dropped.
9095

9196
Here are some example commands:
9297
#+begin_example sh
@@ -96,20 +101,23 @@ sudo ./xdp_loader --dev veth-basic02 --force --progsec xdp_drop
96101
sudo ./xdp_loader --dev veth-basic02 --force --progsec xdp_pass
97102
#+end_example
98103

99-
The testenv script also have a helper command for "load":
104+
The testenv script also has a helper command for "load" which will use the
105+
=xdp_loader= program in the current directory:
100106
#+begin_example
101107
sudo ../testenv/testenv.sh load --name veth-basic02
102108
sudo ../testenv/testenv.sh load --name veth-basic02 -- --force
103109
sudo ../testenv/testenv.sh load --name veth-basic02 -- --force --progsec xdp_drop
104110
sudo ../testenv/testenv.sh load --name veth-basic02 -- --force --progsec xdp_pass
105111
#+end_example
106112

107-
*** A note about: Testlab and veth packets directions
108-
109-
You should do the ping from *within* the network namespace (netns) that were
110-
created by the script. This is because XDP program only operates on
111-
RX-packets. XDP was loaded on "outer" veth device "veth-basic02", which RX
112-
packets from from the "inner" veth0 device.
113+
*** A note about: The test environment and veth packets directions
114+
When you load an XDP program on the interface visible on your host machine,
115+
it will operate on all packets arriving *to* that interface. And since
116+
packets that are sent from one interface in a veth pair will arrive at the
117+
other end, the packets that your XDP program will see are the ones sent from
118+
*within* the network namespace (netns). This means that when you are
119+
testing, you should do the ping from *within* the network namespace that
120+
were created by the script.
113121

114122
You can "enter" the namespace manually (via =sudo ip netns exec veth-basic02
115123
/bin/bash=) or via the script like:
@@ -118,19 +126,19 @@ $ sudo ../testenv/testenv.sh enter --name veth-basic02
118126
# ping fc00:dead:cafe:1::1
119127
#+end_example
120128

121-
To make this ping connectivity test easier, the script have a ping command
122-
that pings from within the the netns, like:
129+
To make this ping connectivity test easier, the script also has a =ping=
130+
command that pings from within the netns:
123131
#+begin_example
124132
$ sudo ../testenv/testenv.sh ping --name veth-basic02
125133
#+end_example
126134

127135
You should note that, the *cool thing* about using netns as a testlab is
128136
that we can still "enter" the netns even-when XDP is dropping all packets.
129137

130-
*** Recommend: Create alias for testenv.sh
138+
*** Recommended: Create an alias for testenv.sh
131139

132140
To have faster access to the testenv.sh script, we recommend that you create
133-
a shell alias (called =t=). The testenv script even have a command helper
141+
a shell alias (called =t=). The testenv script even has a command helper
134142
for this purpose:
135143

136144
#+begin_example
@@ -141,26 +149,42 @@ WARNING: Creating sudo alias; be careful, this script WILL execute arbitrary pro
141149
alias t='sudo /home/fedora/git/xdp-tutorial/testenv/testenv.sh'
142150
#+end_example
143151

144-
As pointed out run:
152+
As pointed out, run:
145153
#+begin_example
146154
eval $(../testenv/testenv.sh alias)
147155
#+end_example
148156

149-
** Assignment#2: Add xdp_abort program
157+
You should now be able to run testenv commands as =t <command>= (e.g., =t
158+
ping=). All subsequent examples will use this syntax.
159+
160+
*** Convenience: Skipping the environment name
161+
162+
The testenv script will save the last used testenv name, so in most cases
163+
you can skip the =--name= parameter when running the script. If you don't
164+
specify a name when you run =t setup=, a random name will be generated for
165+
you.
166+
167+
You can have several active test environments at the same time, and you can
168+
always select a specific one using the =--name= parameter. Run =t status= to
169+
see the currently selected environment (i.e., the one that will be used if
170+
you don't specify one with =--name=), as well as the list of all currently
171+
active environments.
172+
173+
** Assignment 2: Add xdp_abort program
150174

151-
Add a new program section "xdp_abort" in [[file:xdp_prog_kern.c]] that
152-
use/return the XDP action =XDP_ABORTED= (and compile via =make=).
153-
Load this new program, e.g. similar to above:
175+
Add a new program section "xdp_abort" in [[file:xdp_prog_kern.c]] that uses
176+
(returns) the XDP action =XDP_ABORTED= (and compile via =make=). Load this
177+
new program, e.g. similar to above:
154178

155179
#+begin_example sh
156180
sudo ./xdp_loader --dev veth-basic02 --force --progsec xdp_abort
157181
#+end_example
158182

159-
*Lesson*: XDP_ABORTED is different from XDP_DROP, because it trigger the
183+
*Lesson*: XDP_ABORTED is different from XDP_DROP, because it triggers the
160184
tracepoint named =xdp:xdp_exception=.
161185

162-
*Exercise*: while e.g. ping the namespace, record this tracepoint and
163-
observe these records. E.g with perf like this:
186+
While pinging from inside the namespace, record this tracepoint and observe
187+
these records. E.g with perf like this:
164188

165189
#+begin_example sh
166190
sudo perf record -a -e xdp:xdp_exception sleep 4

0 commit comments

Comments
 (0)