]>
Commit | Line | Data |
---|---|---|
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 | |
31 | extern "C" { | |
32 | #endif | |
33 | ||
47dd8736 | 34 | typedef void (*encoder_func)(lua_State *, const void *); |
f869ab17 QY |
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 | }; | |
f944ec67 | 42 | |
105ba9af DL |
43 | struct lua_function_state { |
44 | const char *name; | |
45 | lua_State *L; | |
46 | }; | |
47 | ||
48 | ||
5f98c815 QY |
49 | struct 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 | ||
62 | void *lua_function_alloc(void *arg); | |
63 | ||
64 | unsigned int lua_function_hash_key(const void *data); | |
65 | ||
66 | bool lua_function_hash_cmp(const void *d1, const void *d2); | |
67 | ||
f869ab17 QY |
68 | struct 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 | */ | |
82 | struct frrscript *frrscript_load(const char *name, | |
83 | int (*load_cb)(struct frrscript *)); | |
84 | ||
85 | /* | |
86 | * Destroy FRR script. | |
87 | */ | |
88 | void 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 |
106 | void frrscript_register_type_codec(struct frrscript_codec *codec); |
107 | void 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 | 115 | void 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), \ | |
140 | long long * : lua_pushintegerp, \ | |
141 | struct prefix * : lua_pushprefix, \ | |
142 | struct interface * : lua_pushinterface, \ | |
143 | struct in_addr * : lua_pushinaddr, \ | |
144 | struct in6_addr * : lua_pushin6addr, \ | |
145 | union sockunion * : lua_pushsockunion, \ | |
146 | time_t * : lua_pushtimet, \ | |
b7da61c1 DL |
147 | char * : lua_pushstring_wrapper, \ |
148 | struct attr * : lua_pushattr, \ | |
81fde499 DL |
149 | struct peer * : lua_pushpeer, \ |
150 | const struct prefix * : lua_pushprefix \ | |
c2642aab | 151 | )(L, value) |
43a5106d | 152 | |
3a3cfe47 DL |
153 | #define DECODE_ARGS_WITH_STATE(L, value) \ |
154 | _Generic((value), \ | |
155 | long long * : lua_decode_integerp, \ | |
156 | struct prefix * : lua_decode_prefix, \ | |
157 | struct interface * : lua_decode_interface, \ | |
158 | struct in_addr * : lua_decode_inaddr, \ | |
159 | struct in6_addr * : lua_decode_in6addr, \ | |
160 | union sockunion * : lua_decode_sockunion, \ | |
161 | time_t * : lua_decode_timet, \ | |
b7da61c1 | 162 | char * : lua_decode_stringp, \ |
81fde499 DL |
163 | struct attr * : lua_decode_attr, \ |
164 | struct peer * : lua_decode_noop, \ | |
165 | const 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 |
177 | int _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 |
214 | void *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__ */ |