]> git.proxmox.com Git - mirror_frr.git/blob - zebra/sample_plugin.c
Merge pull request #5706 from mjstapp/fix_nh_debug_show
[mirror_frr.git] / zebra / sample_plugin.c
1 /*
2 * Sample plugin for the FRR zebra dataplane.
3 *
4 * Copyright (c) 2019 Volta Networks, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /*
22 * Should be possible to build this plugin using this sort of command:
23 *
24 * gcc -I ~/work/frr/ -I ~/work/frr/lib -I ~/work/frr/zebra \
25 * -g -O0 -o sample_plugin.so -shared -fPIC sample_plugin.c
26 *
27 * where 'frr' is a configured and built frr sandbox.
28 *
29 * Run zebra with '-M /path/to/sample_plugin.so' to load the module.
30 */
31
32 #include "config.h" /* Include this explicitly */
33 #include "lib/zebra.h"
34 #include "lib/libfrr.h"
35 #include "zebra/zebra_dplane.h"
36 #include "zebra/debug.h"
37
38 static const char *plugin_name = "SAMPLE";
39
40 static struct zebra_dplane_provider *prov_p;
41
42 /*
43 * Startup/init callback, called from the dataplane.
44 */
45 static int sample_start(struct zebra_dplane_provider *prov)
46 {
47 /* Nothing special to do - we don't allocate anything. */
48 return 0;
49 }
50
51
52 /*
53 * Shutdown/cleanup callback, called from the dataplane pthread.
54 */
55 static int sample_fini(struct zebra_dplane_provider *prov, bool early)
56 {
57 /* Nothing special to do. */
58 return 0;
59 }
60
61 /*
62 * Callback from the dataplane to process incoming work; this runs in the
63 * dplane pthread.
64 */
65 static int sample_process(struct zebra_dplane_provider *prov)
66 {
67 int counter, limit;
68 struct zebra_dplane_ctx *ctx;
69
70 limit = dplane_provider_get_work_limit(prov_p);
71
72 /* Respect the configured limit on the amount of work to do in
73 * any one call.
74 */
75 for (counter = 0; counter < limit; counter++) {
76 ctx = dplane_provider_dequeue_in_ctx(prov_p);
77 if (!ctx)
78 break;
79
80 /* Just set 'success' status and return to the dataplane */
81 dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_SUCCESS);
82 dplane_provider_enqueue_out_ctx(prov_p, ctx);
83 }
84
85 return 0;
86 }
87
88 /*
89 * Init entry point called during zebra startup. This is registered during
90 * module init.
91 */
92 static int init_sample_plugin(struct thread_master *tm)
93 {
94 int ret;
95 struct zebra_dplane_provider *prov = NULL;
96
97 /* Note that we don't use or store the thread_master 'tm'. We
98 * don't use the zebra main pthread: our plugin code will run in
99 * the zebra dataplane pthread context.
100 */
101
102 /* Register the plugin with the dataplane infrastructure. We
103 * register to be called before the kernel, and we register
104 * our init, process work, and shutdown callbacks.
105 */
106 ret = dplane_provider_register(plugin_name, DPLANE_PRIO_PRE_KERNEL,
107 DPLANE_PROV_FLAGS_DEFAULT,
108 sample_start,
109 sample_process,
110 sample_fini,
111 NULL,
112 &prov_p);
113
114 if (IS_ZEBRA_DEBUG_DPLANE)
115 zlog_debug("sample plugin register => %d", ret);
116
117 return 0;
118 }
119
120 /*
121 * Base FRR loadable module info: basic info including module entry-point.
122 */
123 static int module_init(void)
124 {
125 hook_register(frr_late_init, init_sample_plugin);
126 return 0;
127 }
128
129 FRR_MODULE_SETUP(
130 .name = "dplane_sample",
131 .version = "0.0.1",
132 .description = "Dataplane Sample Plugin",
133 .init = module_init,
134 )