22#include <stdio.h>
33#include <errno.h>
44#include <string.h>
5+ #include <unistd.h>
6+ #include <errno.h>
57
68#include <bpf/libbpf.h>
79#include <xdp/libxdp.h>
@@ -140,7 +142,10 @@ static int do_load(const void *cfg, __unused const char *pin_root_path)
140142{
141143 struct xdp_program * xdp_prog = NULL , * init_prog = NULL ;
142144 DECLARE_LIBBPF_OPTS (xdp_program_opts , opts );
145+ struct bpf_program * return_prog = NULL ;
143146 const struct load_opts * opt = cfg ;
147+ struct bpf_link * link = NULL ;
148+ char pin_link_path [PATH_MAX ];
144149 struct xdp_forward * skel ;
145150 int ret = EXIT_FAILURE ;
146151 struct iface * iface ;
@@ -217,6 +222,34 @@ static int do_load(const void *cfg, __unused const char *pin_root_path)
217222 pr_info ("Loaded on interface %s\n" , iface -> ifname );
218223 }
219224
225+ /* Attach xdp_check_return to xdp_frame_return tracepoint and
226+ * pin the link to pin_root_path/xdp_check_return.
227+ */
228+
229+ return_prog = bpf_object__find_program_by_name (skel -> obj ,"xdp_check_return" );
230+ if (!return_prog ) {
231+ pr_warn ("Failed to find xdp_check_return program\n" );
232+ goto end_detach ;
233+ }
234+
235+ link = bpf_program__attach_raw_tracepoint (return_prog , "xdp_frame_return" );
236+ if (libbpf_get_error ((const void * ) link )) {
237+ pr_warn ("Couldn't attach to xdp_frame_return: %s\n" ,
238+ strerror (libbpf_get_error ((const void * ) link )));
239+ goto end_detach ;
240+ }
241+ skel -> links .xdp_check_return = link ;
242+
243+ snprintf (pin_link_path , sizeof (pin_link_path ), "%s/%s" , pin_root_path ,
244+ "xdp_check_return" );
245+ ret = bpf_link__pin (link , pin_link_path );
246+ if (ret ) {
247+ pr_warn ("Failed to pin link: %s\n" ,
248+ strerror (errno ));
249+ goto end_detach ;
250+ }
251+ pr_info ("Pinned xdp_check_return to %s\n" , pin_link_path );
252+
220253end_destroy :
221254 xdp_forward__destroy (skel );
222255end :
@@ -225,6 +258,10 @@ static int do_load(const void *cfg, __unused const char *pin_root_path)
225258end_detach :
226259 for (iface = opt -> ifaces ; iface ; iface = iface -> next )
227260 xdp_program__detach (xdp_prog , iface -> ifindex , opt -> xdp_mode , 0 );
261+
262+ bpf_link__unpin (link );
263+ bpf_link__destroy (link );
264+
228265 goto end_destroy ;
229266}
230267
@@ -246,6 +283,8 @@ struct prog_option unload_options[] = {
246283static int do_unload (const void * cfg , __unused const char * pin_root_path )
247284{
248285 const struct unload_opts * opt = cfg ;
286+ struct bpf_link * link = NULL ;
287+ char pin_link_path [PATH_MAX ];
249288 int ret = EXIT_SUCCESS ;
250289 struct iface * iface ;
251290
@@ -258,6 +297,24 @@ static int do_unload(const void *cfg, __unused const char *pin_root_path)
258297 pr_info ("Unloaded from interface %s\n" , iface -> ifname );
259298 }
260299
300+ snprintf (pin_link_path , sizeof (pin_link_path ), "%s/%s" , pin_root_path ,
301+ "xdp_check_return" );
302+
303+ link = bpf_link__open (pin_link_path );
304+ ret = bpf_link__unpin (link );
305+ if (ret ){
306+ pr_warn ("Couldn't unpin link\n" );
307+ } else {
308+ pr_info ("Unpinned link from %s\n" , pin_link_path );
309+ }
310+
311+ ret = bpf_link__destroy (link );
312+ if (ret ){
313+ pr_warn ("Couldn't destroy link\n" );
314+ } else {
315+ pr_info ("Destroyed link\n" );
316+ }
317+
261318 return ret ;
262319}
263320
0 commit comments