]>
git.proxmox.com Git - mirror_frr.git/blob - lib/frrlua.c
2 * This file defines the lua interface into
5 * Copyright (C) 2016-2019 Cumulus Networks, Inc.
6 * Donald Sharp, Quentin Young
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 DEFINE_MTYPE(LIB
, SCRIPT_RES
, "Scripting results");
37 * FRR convenience functions.
39 * This section has convenience functions used to make interacting with the Lua
43 int frrlua_table_get_integer(lua_State
*L
, const char *key
)
47 lua_pushstring(L
, key
);
50 result
= lua_tointeger(L
, -1);
57 * This section has functions that convert internal FRR datatypes into Lua
58 * datatypes: one encoder function and two decoder functions for each type.
62 void lua_pushprefix(lua_State
*L
, const struct prefix
*prefix
)
64 char buffer
[PREFIX_STRLEN
];
67 lua_pushstring(L
, prefix2str(prefix
, buffer
, PREFIX_STRLEN
));
68 lua_setfield(L
, -2, "network");
69 lua_pushinteger(L
, prefix
->prefixlen
);
70 lua_setfield(L
, -2, "length");
71 lua_pushinteger(L
, prefix
->family
);
72 lua_setfield(L
, -2, "family");
75 void lua_decode_prefix(lua_State
*L
, int idx
, struct prefix
*prefix
)
77 lua_getfield(L
, idx
, "network");
78 (void)str2prefix(lua_tostring(L
, -1), prefix
);
84 void *lua_toprefix(lua_State
*L
, int idx
)
86 struct prefix
*p
= XCALLOC(MTYPE_SCRIPT_RES
, sizeof(struct prefix
));
87 lua_decode_prefix(L
, idx
, p
);
91 void lua_pushinterface(lua_State
*L
, const struct interface
*ifp
)
94 lua_pushstring(L
, ifp
->name
);
95 lua_setfield(L
, -2, "name");
96 lua_pushinteger(L
, ifp
->ifindex
);
97 lua_setfield(L
, -2, "ifindex");
98 lua_pushinteger(L
, ifp
->status
);
99 lua_setfield(L
, -2, "status");
100 lua_pushinteger(L
, ifp
->flags
);
101 lua_setfield(L
, -2, "flags");
102 lua_pushinteger(L
, ifp
->metric
);
103 lua_setfield(L
, -2, "metric");
104 lua_pushinteger(L
, ifp
->speed
);
105 lua_setfield(L
, -2, "speed");
106 lua_pushinteger(L
, ifp
->mtu
);
107 lua_setfield(L
, -2, "mtu");
108 lua_pushinteger(L
, ifp
->mtu6
);
109 lua_setfield(L
, -2, "mtu6");
110 lua_pushinteger(L
, ifp
->bandwidth
);
111 lua_setfield(L
, -2, "bandwidth");
112 lua_pushinteger(L
, ifp
->link_ifindex
);
113 lua_setfield(L
, -2, "link_ifindex");
114 lua_pushinteger(L
, ifp
->ll_type
);
115 lua_setfield(L
, -2, "linklayer_type");
118 void lua_decode_interface(lua_State
*L
, int idx
, struct interface
*ifp
)
120 lua_getfield(L
, idx
, "name");
121 strlcpy(ifp
->name
, lua_tostring(L
, -1), sizeof(ifp
->name
));
123 lua_getfield(L
, idx
, "ifindex");
124 ifp
->ifindex
= lua_tointeger(L
, -1);
126 lua_getfield(L
, idx
, "status");
127 ifp
->status
= lua_tointeger(L
, -1);
129 lua_getfield(L
, idx
, "flags");
130 ifp
->flags
= lua_tointeger(L
, -1);
132 lua_getfield(L
, idx
, "metric");
133 ifp
->metric
= lua_tointeger(L
, -1);
135 lua_getfield(L
, idx
, "speed");
136 ifp
->speed
= lua_tointeger(L
, -1);
138 lua_getfield(L
, idx
, "mtu");
139 ifp
->mtu
= lua_tointeger(L
, -1);
141 lua_getfield(L
, idx
, "mtu6");
142 ifp
->mtu6
= lua_tointeger(L
, -1);
144 lua_getfield(L
, idx
, "bandwidth");
145 ifp
->bandwidth
= lua_tointeger(L
, -1);
147 lua_getfield(L
, idx
, "link_ifindex");
148 ifp
->link_ifindex
= lua_tointeger(L
, -1);
150 lua_getfield(L
, idx
, "linklayer_type");
151 ifp
->ll_type
= lua_tointeger(L
, -1);
156 void *lua_tointerface(lua_State
*L
, int idx
)
158 struct interface
*ifp
=
159 XCALLOC(MTYPE_SCRIPT_RES
, sizeof(struct interface
));
161 lua_decode_interface(L
, idx
, ifp
);
165 void lua_pushinaddr(lua_State
*L
, const struct in_addr
*addr
)
167 char buf
[INET_ADDRSTRLEN
];
169 inet_ntop(AF_INET
, addr
, buf
, sizeof(buf
));
172 lua_pushinteger(L
, addr
->s_addr
);
173 lua_setfield(L
, -2, "value");
174 lua_pushstring(L
, buf
);
175 lua_setfield(L
, -2, "string");
178 void lua_decode_inaddr(lua_State
*L
, int idx
, struct in_addr
*inaddr
)
180 lua_getfield(L
, idx
, "value");
181 inaddr
->s_addr
= lua_tointeger(L
, -1);
187 void *lua_toinaddr(lua_State
*L
, int idx
)
189 struct in_addr
*inaddr
=
190 XCALLOC(MTYPE_SCRIPT_RES
, sizeof(struct in_addr
));
191 lua_decode_inaddr(L
, idx
, inaddr
);
196 void lua_pushin6addr(lua_State
*L
, const struct in6_addr
*addr
)
198 char buf
[INET6_ADDRSTRLEN
];
200 inet_ntop(AF_INET6
, addr
, buf
, sizeof(buf
));
203 lua_pushlstring(L
, (const char *)addr
->s6_addr
, 16);
204 lua_setfield(L
, -2, "value");
205 lua_pushstring(L
, buf
);
206 lua_setfield(L
, -2, "string");
209 void lua_decode_in6addr(lua_State
*L
, int idx
, struct in6_addr
*in6addr
)
211 lua_getfield(L
, idx
, "string");
212 inet_pton(AF_INET6
, lua_tostring(L
, -1), in6addr
);
218 void *lua_toin6addr(lua_State
*L
, int idx
)
220 struct in6_addr
*in6addr
=
221 XCALLOC(MTYPE_SCRIPT_RES
, sizeof(struct in6_addr
));
222 lua_decode_in6addr(L
, idx
, in6addr
);
226 void lua_pushsockunion(lua_State
*L
, const union sockunion
*su
)
228 char buf
[SU_ADDRSTRLEN
];
230 sockunion2str(su
, buf
, sizeof(buf
));
233 lua_pushlstring(L
, (const char *)sockunion_get_addr(su
),
234 sockunion_get_addrlen(su
));
235 lua_setfield(L
, -2, "value");
236 lua_pushstring(L
, buf
);
237 lua_setfield(L
, -2, "string");
240 void lua_decode_sockunion(lua_State
*L
, int idx
, union sockunion
*su
)
242 lua_getfield(L
, idx
, "string");
243 (void)str2sockunion(lua_tostring(L
, -1), su
);
249 void *lua_tosockunion(lua_State
*L
, int idx
)
251 union sockunion
*su
=
252 XCALLOC(MTYPE_SCRIPT_RES
, sizeof(union sockunion
));
254 lua_decode_sockunion(L
, idx
, su
);
258 void lua_pushtimet(lua_State
*L
, const time_t *time
)
260 lua_pushinteger(L
, *time
);
263 void lua_decode_timet(lua_State
*L
, int idx
, time_t *t
)
265 *t
= lua_tointeger(L
, idx
);
269 void *lua_totimet(lua_State
*L
, int idx
)
271 time_t *t
= XCALLOC(MTYPE_SCRIPT_RES
, sizeof(time_t));
273 lua_decode_timet(L
, idx
, t
);
277 void lua_pushintegerp(lua_State
*L
, const long long *num
)
279 lua_pushinteger(L
, *num
);
282 void lua_decode_integerp(lua_State
*L
, int idx
, long long *num
)
285 *num
= lua_tonumberx(L
, idx
, &isnum
);
290 void *lua_tointegerp(lua_State
*L
, int idx
)
292 long long *num
= XCALLOC(MTYPE_SCRIPT_RES
, sizeof(long long));
294 lua_decode_integerp(L
, idx
, num
);
298 void lua_decode_stringp(lua_State
*L
, int idx
, char *str
)
300 strlcpy(str
, lua_tostring(L
, idx
), strlen(str
) + 1);
304 void *lua_tostringp(lua_State
*L
, int idx
)
306 char *string
= XSTRDUP(MTYPE_SCRIPT_RES
, lua_tostring(L
, idx
));
312 * Decoder for const values, since we cannot modify them.
314 void lua_decode_noop(lua_State
*L
, int idx
, const void *ptr
)
320 * Noop decoder for int.
322 void lua_decode_integer_noop(lua_State
*L
, int idx
, int i
)
329 * Lua-compatible wrappers for FRR logging functions.
331 static const char *frrlua_log_thunk(lua_State
*L
)
335 nargs
= lua_gettop(L
);
338 return lua_tostring(L
, 1);
341 static int frrlua_log_debug(lua_State
*L
)
343 zlog_debug("%s", frrlua_log_thunk(L
));
347 static int frrlua_log_info(lua_State
*L
)
349 zlog_info("%s", frrlua_log_thunk(L
));
353 static int frrlua_log_notice(lua_State
*L
)
355 zlog_notice("%s", frrlua_log_thunk(L
));
359 static int frrlua_log_warn(lua_State
*L
)
361 zlog_warn("%s", frrlua_log_thunk(L
));
365 static int frrlua_log_error(lua_State
*L
)
367 zlog_err("%s", frrlua_log_thunk(L
));
371 static const luaL_Reg log_funcs
[] = {
372 {"debug", frrlua_log_debug
},
373 {"info", frrlua_log_info
},
374 {"notice", frrlua_log_notice
},
375 {"warn", frrlua_log_warn
},
376 {"error", frrlua_log_error
},
380 void frrlua_export_logging(lua_State
*L
)
383 luaL_setfuncs(L
, log_funcs
, 0);
384 lua_setglobal(L
, "log");
391 char *frrlua_stackdump(lua_State
*L
)
393 int top
= lua_gettop(L
);
396 struct buffer
*buf
= buffer_new(4098);
398 for (int i
= 1; i
<= top
; i
++) {
399 int t
= lua_type(L
, i
);
402 case LUA_TSTRING
: /* strings */
403 snprintf(tmpbuf
, sizeof(tmpbuf
), "\"%s\"\n",
405 buffer_putstr(buf
, tmpbuf
);
407 case LUA_TBOOLEAN
: /* booleans */
408 snprintf(tmpbuf
, sizeof(tmpbuf
), "%s\n",
409 lua_toboolean(L
, i
) ? "true" : "false");
410 buffer_putstr(buf
, tmpbuf
);
412 case LUA_TNUMBER
: /* numbers */
413 snprintf(tmpbuf
, sizeof(tmpbuf
), "%g\n",
415 buffer_putstr(buf
, tmpbuf
);
417 default: /* other values */
418 snprintf(tmpbuf
, sizeof(tmpbuf
), "%s\n",
420 buffer_putstr(buf
, tmpbuf
);
425 char *result
= XSTRDUP(MTYPE_TMP
, buffer_getstr(buf
));
432 #endif /* HAVE_SCRIPTING */