]> git.proxmox.com Git - mirror_frr.git/blob - lib/frrscript.c
9b27ca745943b3a4f2b526a861153c56a5799cb3
[mirror_frr.git] / lib / frrscript.c
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
20 #include <zebra.h>
21
22 #include "frrscript.h"
23 #include "memory.h"
24 #include "hash.h"
25 #include "log.h"
26
27 #include "frrlua.h"
28
29 /* Type encoders */
30
31 struct encoder {
32 char *typename;
33 int (*encoder)(struct lua_State *, const void *);
34 };
35
36 struct hash *encoder_hash;
37
38 static unsigned int encoder_hash_key(const void *data)
39 {
40 const struct encoder *e = data;
41
42 return string_hash_make(e->typename);
43 }
44
45 static bool encoder_hash_cmp(const void *d1, const void *d2)
46 {
47 return !strcmp(d1, d2);
48 }
49
50 static void *encoder_alloc(void *arg)
51 {
52 struct encoder *tmp = arg;
53
54 struct encoder *e = XCALLOC(MTYPE_TMP, sizeof(struct encoder));
55 e->typename = XSTRDUP(MTYPE_TMP, tmp->typename);
56
57 return e;
58 }
59
60 #if 0
61 static void encoder_free(struct encoder *e)
62 {
63 XFREE(MTYPE_TMP, e->typename);
64 XFREE(MTYPE_TMP, e);
65 }
66 #endif
67
68 /* Generic script APIs */
69
70 int frrscript_lua_call(struct frrscript *fs, ...)
71 {
72 /* Process arguments according to argspec in fs */
73 /* ... */
74
75 int ret = lua_pcall(fs->L, 0, 0, 0);
76
77 /* Process stack result according to argspec in fs */
78 /* ... */
79
80 /* LUA_OK is 0, so we can just return lua_pcall's result directly */
81 return ret;
82 }
83
84 void frrscript_register_type_encoder(const char *typename,
85 int (*encoder)(lua_State *L, void *))
86 {
87 struct encoder e = {
88 .typename = (char *) typename,
89 .encoder = NULL
90 };
91
92 if (hash_lookup(encoder_hash, &e)) {
93 zlog_backtrace(LOG_ERR);
94 assert(!"Type encoder double-registered.");
95 }
96
97 hash_get(encoder_hash, &e, encoder_alloc);
98 }
99
100
101 struct frrscript *frrscript_load(const char *name,
102 int (*load_cb)(struct frrscript *))
103 {
104 struct frrscript *fs = XCALLOC(MTYPE_TMP, sizeof(struct frrscript));
105
106 fs->name = XSTRDUP(MTYPE_TMP, name);
107 fs->L = luaL_newstate();
108
109 char fname[MAXPATHLEN];
110 snprintf(fname, sizeof(fname), FRRSCRIPT_PATH "/%s.lua", fs->name);
111
112 if (luaL_loadfile(fs->L, fname) != LUA_OK)
113 goto fail;
114
115 if (load_cb && (*load_cb)(fs) != 0)
116 goto fail;
117
118 return fs;
119 fail:
120 frrscript_unload(fs);
121 return NULL;
122 }
123
124 void frrscript_unload(struct frrscript *fs)
125 {
126 XFREE(MTYPE_TMP, fs->name);
127 XFREE(MTYPE_TMP, fs);
128 }
129
130 void frrscript_init()
131 {
132 encoder_hash = hash_create(encoder_hash_key, encoder_hash_cmp, "Lua type encoders");
133 }