]> git.proxmox.com Git - mirror_frr.git/blob - lib/frrscript.h
5410f53e1167d1c0c87e69d8bff7aa36abbd61a0
[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
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 typedef void (*encoder_func)(lua_State *, const void *);
34 typedef void *(*decoder_func)(lua_State *, int);
35
36 struct frrscript_codec {
37 const char *typename;
38 encoder_func encoder;
39 decoder_func decoder;
40 };
41
42 struct frrscript {
43 /* Script name */
44 char *name;
45
46 /* Lua state */
47 struct lua_State *L;
48 };
49
50 struct frrscript_env {
51 /* Value type */
52 const char *typename;
53
54 /* Binding name */
55 const char *name;
56
57 /* Value */
58 const void *val;
59 };
60
61 /*
62 * Create new FRR script.
63 */
64 struct frrscript *frrscript_load(const char *name,
65 int (*load_cb)(struct frrscript *));
66
67 /*
68 * Destroy FRR script.
69 */
70 void frrscript_unload(struct frrscript *fs);
71
72 /*
73 * Register a Lua codec for a type.
74 *
75 * tname
76 * Name of type; e.g., "peer", "ospf_interface", etc. Chosen at will.
77 *
78 * codec(s)
79 * Function pointer to codec struct. Encoder function should push a Lua
80 * table representing the passed argument - which will have the C type
81 * associated with the chosen 'tname' to the provided stack. The decoder
82 * function should pop a value from the top of the stack and return a heap
83 * chunk containing that value. Allocations should be made with MTYPE_TMP.
84 *
85 * If using the plural function variant, pass a NULL-terminated array.
86 *
87 */
88 void frrscript_register_type_codec(struct frrscript_codec *codec);
89 void frrscript_register_type_codecs(struct frrscript_codec *codecs);
90
91 /*
92 * Initialize scripting subsystem. Call this before anything else.
93 *
94 * scriptdir
95 * Directory in which to look for scripts
96 */
97 void frrscript_init(const char *scriptdir);
98
99 #define ENCODE_ARGS(name, value) \
100 do { \
101 ENCODE_ARGS_WITH_STATE(L, value); \
102 lua_setglobal(L, name); \
103 } while (0)
104
105 #define DECODE_ARGS(name, value) \
106 do { \
107 lua_getglobal(L, name); \
108 DECODE_ARGS_WITH_STATE(L, value) \
109 } while (0)
110
111 #define ENCODE_ARGS_WITH_STATE(L, value) \
112 _Generic((value), \
113 long long * : lua_pushintegerp, \
114 struct prefix * : lua_pushprefix, \
115 struct interface * : lua_pushinterface, \
116 struct in_addr * : lua_pushinaddr, \
117 struct in6_addr * : lua_pushin6addr, \
118 union sockunion * : lua_pushsockunion, \
119 time_t * : lua_pushtimet, \
120 char * : lua_pushstring_wrapper \
121 )(L, value)
122
123 #define DECODE_ARGS_WITH_STATE(L, value) _Generic((value), )(L, value);
124
125 /*
126 * Call script.
127 *
128 * fs
129 * The script to call; this is obtained from frrscript_load().
130 *
131 * env
132 * The script's environment. Specify this as an array of frrscript_env.
133 *
134 * Returns:
135 * 0 if the script ran successfully, nonzero otherwise.
136 */
137 int _frrscript_call(struct frrscript *fs);
138
139 #define frrscript_call(fs, ...) \
140 ({ \
141 lua_State *L = fs->L; \
142 MAP_LISTS(ENCODE_ARGS, ##__VA_ARGS__); \
143 int ret = _frrscript_call(fs); \
144 if (ret == 0) { \
145 MAP_LISTS(DECODE_ARGS, ##__VA_ARGS__); \
146 } \
147 ret; \
148 })
149
150 /*
151 * Get result from finished script.
152 *
153 * fs
154 * The script. This script must have been run already.
155 *
156 * result
157 * The result to extract from the script.
158 * This reuses the frrscript_env type, but only the typename and name fields
159 * need to be set. The value is returned directly.
160 *
161 * Returns:
162 * The script result of the specified name and type, or NULL.
163 */
164 void *frrscript_get_result(struct frrscript *fs,
165 const struct frrscript_env *result);
166
167 #ifdef __cplusplus
168 }
169 #endif /* __cplusplus */
170
171 #endif /* HAVE_SCRIPTING */
172
173 #endif /* __FRRSCRIPT_H__ */