]> git.proxmox.com Git - mirror_frr.git/blame - lib/frrscript.h
lib: Change frrscript to hold many Lua states
[mirror_frr.git] / lib / frrscript.h
CommitLineData
5f98c815
QY
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
fa22080d
QY
22#include <zebra.h>
23
24#ifdef HAVE_SCRIPTING
25
9e47ee98 26#include <lua.h>
5f98c815 27#include "frrlua.h"
b7da61c1 28#include "../bgpd/bgp_script.h"
5f98c815
QY
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
47dd8736 34typedef void (*encoder_func)(lua_State *, const void *);
f869ab17
QY
35typedef void *(*decoder_func)(lua_State *, int);
36
37struct frrscript_codec {
38 const char *typename;
39 encoder_func encoder;
40 decoder_func decoder;
41};
f944ec67 42
105ba9af
DL
43struct lua_function_state {
44 const char *name;
45 lua_State *L;
46};
47
48
5f98c815
QY
49struct frrscript {
50 /* Script name */
51 char *name;
52
105ba9af
DL
53 /* Hash of Lua function name to Lua function state */
54 struct hash *lua_function_hash;
5f98c815
QY
55};
56
105ba9af
DL
57
58/*
59 * Hash related functions for lua_function_hash
60 */
61
62void *lua_function_alloc(void *arg);
63
64unsigned int lua_function_hash_key(const void *data);
65
66bool lua_function_hash_cmp(const void *d1, const void *d2);
67
f869ab17
QY
68struct frrscript_env {
69 /* Value type */
70 const char *typename;
71
72 /* Binding name */
73 const char *name;
74
75 /* Value */
76 const void *val;
77};
5f98c815
QY
78
79/*
80 * Create new FRR script.
81 */
82struct frrscript *frrscript_load(const char *name,
83 int (*load_cb)(struct frrscript *));
84
85/*
86 * Destroy FRR script.
87 */
88void frrscript_unload(struct frrscript *fs);
89
90/*
f869ab17 91 * Register a Lua codec for a type.
5f98c815
QY
92 *
93 * tname
94 * Name of type; e.g., "peer", "ospf_interface", etc. Chosen at will.
95 *
f869ab17
QY
96 * codec(s)
97 * Function pointer to codec struct. Encoder function should push a Lua
5f98c815 98 * table representing the passed argument - which will have the C type
f869ab17
QY
99 * associated with the chosen 'tname' to the provided stack. The decoder
100 * function should pop a value from the top of the stack and return a heap
101 * chunk containing that value. Allocations should be made with MTYPE_TMP.
102 *
103 * If using the plural function variant, pass a NULL-terminated array.
5f98c815
QY
104 *
105 */
f869ab17
QY
106void frrscript_register_type_codec(struct frrscript_codec *codec);
107void frrscript_register_type_codecs(struct frrscript_codec *codecs);
5f98c815
QY
108
109/*
110 * Initialize scripting subsystem. Call this before anything else.
e4e0229a
QY
111 *
112 * scriptdir
113 * Directory in which to look for scripts
5f98c815 114 */
e4e0229a 115void frrscript_init(const char *scriptdir);
5f98c815 116
43a5106d
DL
117#define ENCODE_ARGS(name, value) \
118 do { \
c2642aab 119 ENCODE_ARGS_WITH_STATE(L, value); \
43a5106d
DL
120 lua_setglobal(L, name); \
121 } while (0)
122
123#define DECODE_ARGS(name, value) \
124 do { \
125 lua_getglobal(L, name); \
3a3cfe47 126 DECODE_ARGS_WITH_STATE(L, value); \
43a5106d
DL
127 } while (0)
128
19eee398
DL
129/*
130 * Maps the type of value to its encoder/decoder.
131 * Add new mappings here.
132 *
133 * L
134 * Lua state
135 * scriptdir
136 * Directory in which to look for scripts
137 */
c2642aab
DL
138#define ENCODE_ARGS_WITH_STATE(L, value) \
139 _Generic((value), \
140long long * : lua_pushintegerp, \
141struct prefix * : lua_pushprefix, \
142struct interface * : lua_pushinterface, \
143struct in_addr * : lua_pushinaddr, \
144struct in6_addr * : lua_pushin6addr, \
145union sockunion * : lua_pushsockunion, \
146time_t * : lua_pushtimet, \
b7da61c1
DL
147char * : lua_pushstring_wrapper, \
148struct attr * : lua_pushattr, \
81fde499
DL
149struct peer * : lua_pushpeer, \
150const struct prefix * : lua_pushprefix \
c2642aab 151)(L, value)
43a5106d 152
3a3cfe47
DL
153#define DECODE_ARGS_WITH_STATE(L, value) \
154 _Generic((value), \
155long long * : lua_decode_integerp, \
156struct prefix * : lua_decode_prefix, \
157struct interface * : lua_decode_interface, \
158struct in_addr * : lua_decode_inaddr, \
159struct in6_addr * : lua_decode_in6addr, \
160union sockunion * : lua_decode_sockunion, \
161time_t * : lua_decode_timet, \
b7da61c1 162char * : lua_decode_stringp, \
81fde499
DL
163struct attr * : lua_decode_attr, \
164struct peer * : lua_decode_noop, \
165const struct prefix * : lua_decode_noop \
3a3cfe47 166)(L, -1, value)
5f98c815
QY
167
168/*
f869ab17 169 * Call script.
3b002f19 170 *
f869ab17
QY
171 * fs
172 * The script to call; this is obtained from frrscript_load().
3b002f19 173 *
f869ab17
QY
174 * Returns:
175 * 0 if the script ran successfully, nonzero otherwise.
3b002f19 176 */
43a5106d
DL
177int _frrscript_call(struct frrscript *fs);
178
19eee398
DL
179/*
180 * Wrapper for call script. Maps values passed in to their encoder
181 * and decoder types.
182 *
183 * fs
184 * The script to call; this is obtained from frrscript_load().
185 *
186 * Returns:
187 * 0 if the script ran successfully, nonzero otherwise.
188 */
43a5106d
DL
189#define frrscript_call(fs, ...) \
190 ({ \
191 lua_State *L = fs->L; \
192 MAP_LISTS(ENCODE_ARGS, ##__VA_ARGS__); \
193 int ret = _frrscript_call(fs); \
194 if (ret == 0) { \
195 MAP_LISTS(DECODE_ARGS, ##__VA_ARGS__); \
196 } \
197 ret; \
198 })
3b002f19
QY
199
200/*
f869ab17 201 * Get result from finished script.
3b002f19 202 *
f869ab17
QY
203 * fs
204 * The script. This script must have been run already.
3b002f19 205 *
f869ab17
QY
206 * result
207 * The result to extract from the script.
208 * This reuses the frrscript_env type, but only the typename and name fields
209 * need to be set. The value is returned directly.
3b002f19 210 *
f869ab17
QY
211 * Returns:
212 * The script result of the specified name and type, or NULL.
3b002f19 213 */
f869ab17
QY
214void *frrscript_get_result(struct frrscript *fs,
215 const struct frrscript_env *result);
3b002f19 216
5f98c815
QY
217#ifdef __cplusplus
218}
219#endif /* __cplusplus */
220
fa22080d
QY
221#endif /* HAVE_SCRIPTING */
222
5f98c815 223#endif /* __FRRSCRIPT_H__ */