]> git.proxmox.com Git - mirror_frr.git/blob - lib/frrscript.h
lib: add comments for functions
[mirror_frr.git] / lib / frrscript.h
1 /* Scripting foo
2 * Copyright (C) 2020 NVIDIA Corporation
3 * Quentin Young
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 #ifndef __FRRSCRIPT_H__
20 #define __FRRSCRIPT_H__
21
22 #include <zebra.h>
23
24 #ifdef HAVE_SCRIPTING
25
26 #include <lua.h>
27 #include "frrlua.h"
28 #include "../bgpd/bgp_script.h"
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 typedef void (*encoder_func)(lua_State *, const void *);
35 typedef void *(*decoder_func)(lua_State *, int);
36
37 struct frrscript_codec {
38 const char *typename;
39 encoder_func encoder;
40 decoder_func decoder;
41 };
42
43 struct frrscript {
44 /* Script name */
45 char *name;
46
47 /* Lua state */
48 struct lua_State *L;
49 };
50
51 struct frrscript_env {
52 /* Value type */
53 const char *typename;
54
55 /* Binding name */
56 const char *name;
57
58 /* Value */
59 const void *val;
60 };
61
62 /*
63 * Create new FRR script.
64 */
65 struct frrscript *frrscript_load(const char *name,
66 int (*load_cb)(struct frrscript *));
67
68 /*
69 * Destroy FRR script.
70 */
71 void frrscript_unload(struct frrscript *fs);
72
73 /*
74 * Register a Lua codec for a type.
75 *
76 * tname
77 * Name of type; e.g., "peer", "ospf_interface", etc. Chosen at will.
78 *
79 * codec(s)
80 * Function pointer to codec struct. Encoder function should push a Lua
81 * table representing the passed argument - which will have the C type
82 * associated with the chosen 'tname' to the provided stack. The decoder
83 * function should pop a value from the top of the stack and return a heap
84 * chunk containing that value. Allocations should be made with MTYPE_TMP.
85 *
86 * If using the plural function variant, pass a NULL-terminated array.
87 *
88 */
89 void frrscript_register_type_codec(struct frrscript_codec *codec);
90 void frrscript_register_type_codecs(struct frrscript_codec *codecs);
91
92 /*
93 * Initialize scripting subsystem. Call this before anything else.
94 *
95 * scriptdir
96 * Directory in which to look for scripts
97 */
98 void frrscript_init(const char *scriptdir);
99
100 #define ENCODE_ARGS(name, value) \
101 do { \
102 ENCODE_ARGS_WITH_STATE(L, value); \
103 lua_setglobal(L, name); \
104 } while (0)
105
106 #define DECODE_ARGS(name, value) \
107 do { \
108 lua_getglobal(L, name); \
109 DECODE_ARGS_WITH_STATE(L, value); \
110 } while (0)
111
112 /*
113 * Maps the type of value to its encoder/decoder.
114 * Add new mappings here.
115 *
116 * L
117 * Lua state
118 * scriptdir
119 * Directory in which to look for scripts
120 */
121 #define ENCODE_ARGS_WITH_STATE(L, value) \
122 _Generic((value), \
123 long long * : lua_pushintegerp, \
124 struct prefix * : lua_pushprefix, \
125 struct interface * : lua_pushinterface, \
126 struct in_addr * : lua_pushinaddr, \
127 struct in6_addr * : lua_pushin6addr, \
128 union sockunion * : lua_pushsockunion, \
129 time_t * : lua_pushtimet, \
130 char * : lua_pushstring_wrapper, \
131 struct attr * : lua_pushattr, \
132 struct peer * : lua_pushpeer, \
133 const struct prefix * : lua_pushprefix \
134 )(L, value)
135
136 #define DECODE_ARGS_WITH_STATE(L, value) \
137 _Generic((value), \
138 long long * : lua_decode_integerp, \
139 struct prefix * : lua_decode_prefix, \
140 struct interface * : lua_decode_interface, \
141 struct in_addr * : lua_decode_inaddr, \
142 struct in6_addr * : lua_decode_in6addr, \
143 union sockunion * : lua_decode_sockunion, \
144 time_t * : lua_decode_timet, \
145 char * : lua_decode_stringp, \
146 struct attr * : lua_decode_attr, \
147 struct peer * : lua_decode_noop, \
148 const struct prefix * : lua_decode_noop \
149 )(L, -1, value)
150
151 /*
152 * Call script.
153 *
154 * fs
155 * The script to call; this is obtained from frrscript_load().
156 *
157 * Returns:
158 * 0 if the script ran successfully, nonzero otherwise.
159 */
160 int _frrscript_call(struct frrscript *fs);
161
162 /*
163 * Wrapper for call script. Maps values passed in to their encoder
164 * and decoder types.
165 *
166 * fs
167 * The script to call; this is obtained from frrscript_load().
168 *
169 * Returns:
170 * 0 if the script ran successfully, nonzero otherwise.
171 */
172 #define frrscript_call(fs, ...) \
173 ({ \
174 lua_State *L = fs->L; \
175 MAP_LISTS(ENCODE_ARGS, ##__VA_ARGS__); \
176 int ret = _frrscript_call(fs); \
177 if (ret == 0) { \
178 MAP_LISTS(DECODE_ARGS, ##__VA_ARGS__); \
179 } \
180 ret; \
181 })
182
183 /*
184 * Get result from finished script.
185 *
186 * fs
187 * The script. This script must have been run already.
188 *
189 * result
190 * The result to extract from the script.
191 * This reuses the frrscript_env type, but only the typename and name fields
192 * need to be set. The value is returned directly.
193 *
194 * Returns:
195 * The script result of the specified name and type, or NULL.
196 */
197 void *frrscript_get_result(struct frrscript *fs,
198 const struct frrscript_env *result);
199
200 #ifdef __cplusplus
201 }
202 #endif /* __cplusplus */
203
204 #endif /* HAVE_SCRIPTING */
205
206 #endif /* __FRRSCRIPT_H__ */