]>
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_pushipaddr(lua_State
*L
, const struct ipaddr
*addr
)
228 if (IS_IPADDR_V4(addr
))
229 lua_pushinaddr(L
, &addr
->ipaddr_v4
);
231 lua_pushin6addr(L
, &addr
->ipaddr_v6
);
234 void lua_pushethaddr(lua_State
*L
, const struct ethaddr
*addr
)
237 lua_pushinteger(L
, *(addr
->octet
));
238 lua_setfield(L
, -2, "octet");
241 void lua_pushsockunion(lua_State
*L
, const union sockunion
*su
)
243 char buf
[SU_ADDRSTRLEN
];
245 sockunion2str(su
, buf
, sizeof(buf
));
248 lua_pushlstring(L
, (const char *)sockunion_get_addr(su
),
249 sockunion_get_addrlen(su
));
250 lua_setfield(L
, -2, "value");
251 lua_pushstring(L
, buf
);
252 lua_setfield(L
, -2, "string");
255 void lua_decode_sockunion(lua_State
*L
, int idx
, union sockunion
*su
)
257 lua_getfield(L
, idx
, "string");
258 if (str2sockunion(lua_tostring(L
, -1), su
) < 0)
259 zlog_err("Lua hook call: Failed to decode sockunion");
266 void *lua_tosockunion(lua_State
*L
, int idx
)
268 union sockunion
*su
=
269 XCALLOC(MTYPE_SCRIPT_RES
, sizeof(union sockunion
));
271 lua_decode_sockunion(L
, idx
, su
);
275 void lua_pushtimet(lua_State
*L
, const time_t *time
)
277 lua_pushinteger(L
, *time
);
280 void lua_decode_timet(lua_State
*L
, int idx
, time_t *t
)
282 *t
= lua_tointeger(L
, idx
);
286 void *lua_totimet(lua_State
*L
, int idx
)
288 time_t *t
= XCALLOC(MTYPE_SCRIPT_RES
, sizeof(time_t));
290 lua_decode_timet(L
, idx
, t
);
294 void lua_pushintegerp(lua_State
*L
, const long long *num
)
296 lua_pushinteger(L
, *num
);
299 void lua_decode_integerp(lua_State
*L
, int idx
, long long *num
)
302 *num
= lua_tonumberx(L
, idx
, &isnum
);
307 void *lua_tointegerp(lua_State
*L
, int idx
)
309 long long *num
= XCALLOC(MTYPE_SCRIPT_RES
, sizeof(long long));
311 lua_decode_integerp(L
, idx
, num
);
315 void lua_pushnexthop(lua_State
*L
, const struct nexthop
*nexthop
)
318 lua_pushinteger(L
, nexthop
->vrf_id
);
319 lua_setfield(L
, -2, "vrf_id");
320 lua_pushinteger(L
, nexthop
->ifindex
);
321 lua_setfield(L
, -2, "ifindex");
322 lua_pushinteger(L
, nexthop
->type
);
323 lua_setfield(L
, -2, "type");
324 lua_pushinteger(L
, nexthop
->flags
);
325 lua_setfield(L
, -2, "flags");
326 if (nexthop
->type
== NEXTHOP_TYPE_BLACKHOLE
) {
327 lua_pushinteger(L
, nexthop
->bh_type
);
328 lua_setfield(L
, -2, "bh_type");
329 } else if (nexthop
->type
== NEXTHOP_TYPE_IPV4
) {
330 lua_pushinaddr(L
, &nexthop
->gate
.ipv4
);
331 lua_setfield(L
, -2, "gate");
332 } else if (nexthop
->type
== NEXTHOP_TYPE_IPV6
) {
333 lua_pushin6addr(L
, &nexthop
->gate
.ipv6
);
334 lua_setfield(L
, -2, "gate");
336 lua_pushinteger(L
, nexthop
->nh_label_type
);
337 lua_setfield(L
, -2, "nh_label_type");
338 lua_pushinteger(L
, nexthop
->weight
);
339 lua_setfield(L
, -2, "weight");
340 lua_pushinteger(L
, nexthop
->backup_num
);
341 lua_setfield(L
, -2, "backup_num");
342 lua_pushinteger(L
, *(nexthop
->backup_idx
));
343 lua_setfield(L
, -2, "backup_idx");
344 if (nexthop
->nh_encap_type
== NET_VXLAN
) {
345 lua_pushinteger(L
, nexthop
->nh_encap
.vni
);
346 lua_setfield(L
, -2, "vni");
348 lua_pushinteger(L
, nexthop
->nh_encap_type
);
349 lua_setfield(L
, -2, "nh_encap_type");
350 lua_pushinteger(L
, nexthop
->srte_color
);
351 lua_setfield(L
, -2, "srte_color");
354 void lua_pushnexthop_group(lua_State
*L
, const struct nexthop_group
*ng
)
357 struct nexthop
*nexthop
;
360 for (ALL_NEXTHOPS_PTR(ng
, nexthop
)) {
361 lua_pushnexthop(L
, nexthop
);
367 void lua_decode_stringp(lua_State
*L
, int idx
, char *str
)
369 strlcpy(str
, lua_tostring(L
, idx
), strlen(str
) + 1);
373 void *lua_tostringp(lua_State
*L
, int idx
)
375 char *string
= XSTRDUP(MTYPE_SCRIPT_RES
, lua_tostring(L
, idx
));
381 * Decoder for const values, since we cannot modify them.
383 void lua_decode_noop(lua_State
*L
, int idx
, const void *ptr
)
389 * Noop decoder for int.
391 void lua_decode_integer_noop(lua_State
*L
, int idx
, int i
)
398 * Lua-compatible wrappers for FRR logging functions.
400 static const char *frrlua_log_thunk(lua_State
*L
)
404 nargs
= lua_gettop(L
);
407 return lua_tostring(L
, 1);
410 static int frrlua_log_debug(lua_State
*L
)
412 zlog_debug("%s", frrlua_log_thunk(L
));
416 static int frrlua_log_info(lua_State
*L
)
418 zlog_info("%s", frrlua_log_thunk(L
));
422 static int frrlua_log_notice(lua_State
*L
)
424 zlog_notice("%s", frrlua_log_thunk(L
));
428 static int frrlua_log_warn(lua_State
*L
)
430 zlog_warn("%s", frrlua_log_thunk(L
));
434 static int frrlua_log_error(lua_State
*L
)
436 zlog_err("%s", frrlua_log_thunk(L
));
440 static const luaL_Reg log_funcs
[] = {
441 {"debug", frrlua_log_debug
},
442 {"info", frrlua_log_info
},
443 {"notice", frrlua_log_notice
},
444 {"warn", frrlua_log_warn
},
445 {"error", frrlua_log_error
},
449 void frrlua_export_logging(lua_State
*L
)
452 luaL_setfuncs(L
, log_funcs
, 0);
453 lua_setglobal(L
, "log");
460 char *frrlua_stackdump(lua_State
*L
)
462 int top
= lua_gettop(L
);
465 struct buffer
*buf
= buffer_new(4098);
467 for (int i
= 1; i
<= top
; i
++) {
468 int t
= lua_type(L
, i
);
471 case LUA_TSTRING
: /* strings */
472 snprintf(tmpbuf
, sizeof(tmpbuf
), "\"%s\"\n",
474 buffer_putstr(buf
, tmpbuf
);
476 case LUA_TBOOLEAN
: /* booleans */
477 snprintf(tmpbuf
, sizeof(tmpbuf
), "%s\n",
478 lua_toboolean(L
, i
) ? "true" : "false");
479 buffer_putstr(buf
, tmpbuf
);
481 case LUA_TNUMBER
: /* numbers */
482 snprintf(tmpbuf
, sizeof(tmpbuf
), "%g\n",
484 buffer_putstr(buf
, tmpbuf
);
486 default: /* other values */
487 snprintf(tmpbuf
, sizeof(tmpbuf
), "%s\n",
489 buffer_putstr(buf
, tmpbuf
);
494 char *result
= XSTRDUP(MTYPE_TMP
, buffer_getstr(buf
));
501 #endif /* HAVE_SCRIPTING */