]> git.proxmox.com Git - mirror_frr.git/blame - lib/frrscript.h
lib: create new frrscript_new
[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 */
f0cddf95
DL
82struct frrscript *frrscript_new(const char *name);
83
84/*
85 * Load a function into frrscript, run callback if any
86 */
87int frrscript_load(struct frrscript *fs, const char *function_name,
88 int (*load_cb)(struct frrscript *));
5f98c815
QY
89
90/*
91 * Destroy FRR script.
92 */
93void frrscript_unload(struct frrscript *fs);
94
95/*
f869ab17 96 * Register a Lua codec for a type.
5f98c815
QY
97 *
98 * tname
99 * Name of type; e.g., "peer", "ospf_interface", etc. Chosen at will.
100 *
f869ab17
QY
101 * codec(s)
102 * Function pointer to codec struct. Encoder function should push a Lua
5f98c815 103 * table representing the passed argument - which will have the C type
f869ab17
QY
104 * associated with the chosen 'tname' to the provided stack. The decoder
105 * function should pop a value from the top of the stack and return a heap
106 * chunk containing that value. Allocations should be made with MTYPE_TMP.
107 *
108 * If using the plural function variant, pass a NULL-terminated array.
5f98c815
QY
109 *
110 */
f869ab17
QY
111void frrscript_register_type_codec(struct frrscript_codec *codec);
112void frrscript_register_type_codecs(struct frrscript_codec *codecs);
5f98c815
QY
113
114/*
115 * Initialize scripting subsystem. Call this before anything else.
e4e0229a
QY
116 *
117 * scriptdir
118 * Directory in which to look for scripts
5f98c815 119 */
e4e0229a 120void frrscript_init(const char *scriptdir);
5f98c815 121
43a5106d
DL
122#define ENCODE_ARGS(name, value) \
123 do { \
c2642aab 124 ENCODE_ARGS_WITH_STATE(L, value); \
43a5106d
DL
125 lua_setglobal(L, name); \
126 } while (0)
127
128#define DECODE_ARGS(name, value) \
129 do { \
130 lua_getglobal(L, name); \
3a3cfe47 131 DECODE_ARGS_WITH_STATE(L, value); \
43a5106d
DL
132 } while (0)
133
19eee398
DL
134/*
135 * Maps the type of value to its encoder/decoder.
136 * Add new mappings here.
137 *
138 * L
139 * Lua state
140 * scriptdir
141 * Directory in which to look for scripts
142 */
c2642aab
DL
143#define ENCODE_ARGS_WITH_STATE(L, value) \
144 _Generic((value), \
145long long * : lua_pushintegerp, \
146struct prefix * : lua_pushprefix, \
147struct interface * : lua_pushinterface, \
148struct in_addr * : lua_pushinaddr, \
149struct in6_addr * : lua_pushin6addr, \
150union sockunion * : lua_pushsockunion, \
151time_t * : lua_pushtimet, \
b7da61c1
DL
152char * : lua_pushstring_wrapper, \
153struct attr * : lua_pushattr, \
81fde499
DL
154struct peer * : lua_pushpeer, \
155const struct prefix * : lua_pushprefix \
c2642aab 156)(L, value)
43a5106d 157
3a3cfe47
DL
158#define DECODE_ARGS_WITH_STATE(L, value) \
159 _Generic((value), \
160long long * : lua_decode_integerp, \
161struct prefix * : lua_decode_prefix, \
162struct interface * : lua_decode_interface, \
163struct in_addr * : lua_decode_inaddr, \
164struct in6_addr * : lua_decode_in6addr, \
165union sockunion * : lua_decode_sockunion, \
166time_t * : lua_decode_timet, \
b7da61c1 167char * : lua_decode_stringp, \
81fde499
DL
168struct attr * : lua_decode_attr, \
169struct peer * : lua_decode_noop, \
170const struct prefix * : lua_decode_noop \
3a3cfe47 171)(L, -1, value)
5f98c815
QY
172
173/*
f869ab17 174 * Call script.
3b002f19 175 *
f869ab17
QY
176 * fs
177 * The script to call; this is obtained from frrscript_load().
3b002f19 178 *
f869ab17
QY
179 * Returns:
180 * 0 if the script ran successfully, nonzero otherwise.
3b002f19 181 */
43a5106d
DL
182int _frrscript_call(struct frrscript *fs);
183
19eee398
DL
184/*
185 * Wrapper for call script. Maps values passed in to their encoder
186 * and decoder types.
187 *
188 * fs
189 * The script to call; this is obtained from frrscript_load().
190 *
191 * Returns:
192 * 0 if the script ran successfully, nonzero otherwise.
193 */
43a5106d
DL
194#define frrscript_call(fs, ...) \
195 ({ \
196 lua_State *L = fs->L; \
197 MAP_LISTS(ENCODE_ARGS, ##__VA_ARGS__); \
198 int ret = _frrscript_call(fs); \
199 if (ret == 0) { \
200 MAP_LISTS(DECODE_ARGS, ##__VA_ARGS__); \
201 } \
202 ret; \
203 })
3b002f19
QY
204
205/*
f869ab17 206 * Get result from finished script.
3b002f19 207 *
f869ab17
QY
208 * fs
209 * The script. This script must have been run already.
3b002f19 210 *
f869ab17
QY
211 * result
212 * The result to extract from the script.
213 * This reuses the frrscript_env type, but only the typename and name fields
214 * need to be set. The value is returned directly.
3b002f19 215 *
f869ab17
QY
216 * Returns:
217 * The script result of the specified name and type, or NULL.
3b002f19 218 */
f869ab17
QY
219void *frrscript_get_result(struct frrscript *fs,
220 const struct frrscript_env *result);
3b002f19 221
5f98c815
QY
222#ifdef __cplusplus
223}
224#endif /* __cplusplus */
225
fa22080d
QY
226#endif /* HAVE_SCRIPTING */
227
5f98c815 228#endif /* __FRRSCRIPT_H__ */