summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_script.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_script.c')
-rw-r--r--bgpd/bgp_script.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c
new file mode 100644
index 0000000..b373858
--- /dev/null
+++ b/bgpd/bgp_script.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* BGP scripting foo
+ * Copyright (C) 2020 NVIDIA Corporation
+ * Quentin Young
+ */
+
+#include <zebra.h>
+
+#ifdef HAVE_SCRIPTING
+
+#include "bgpd.h"
+#include "bgp_script.h"
+#include "bgp_debug.h"
+#include "bgp_aspath.h"
+#include "frratomic.h"
+#include "frrscript.h"
+
+void lua_pushpeer(lua_State *L, const struct peer *peer)
+{
+ lua_newtable(L);
+ lua_pushinteger(L, peer->as);
+ lua_setfield(L, -2, "remote_as");
+ lua_pushinteger(L, peer->local_as);
+ lua_setfield(L, -2, "local_as");
+ lua_pushinaddr(L, &peer->remote_id);
+ lua_setfield(L, -2, "remote_id");
+ lua_pushinaddr(L, &peer->local_id);
+ lua_setfield(L, -2, "local_id");
+ lua_pushstring(L, lookup_msg(bgp_status_msg, peer->connection->status,
+ NULL));
+ lua_setfield(L, -2, "state");
+ lua_pushstring(L, peer->desc ? peer->desc : "");
+ lua_setfield(L, -2, "description");
+ lua_pushinteger(L, peer->uptime);
+ lua_setfield(L, -2, "uptime");
+ lua_pushinteger(L, peer->readtime);
+ lua_setfield(L, -2, "last_readtime");
+ lua_pushinteger(L, peer->resettime);
+ lua_setfield(L, -2, "last_resettime");
+ lua_pushsockunion(L, peer->su_local);
+ lua_setfield(L, -2, "local_address");
+ lua_pushsockunion(L, peer->su_remote);
+ lua_setfield(L, -2, "remote_address");
+ lua_pushinteger(L, peer->cap);
+ lua_setfield(L, -2, "capabilities");
+ lua_pushinteger(L, peer->flags);
+ lua_setfield(L, -2, "flags");
+ lua_pushstring(L, peer->password ? peer->password : "");
+ lua_setfield(L, -2, "password");
+
+ /* Nested tables here */
+ lua_newtable(L);
+ {
+ lua_newtable(L);
+ {
+ lua_pushinteger(L, peer->holdtime);
+ lua_setfield(L, -2, "hold");
+ lua_pushinteger(L, peer->keepalive);
+ lua_setfield(L, -2, "keepalive");
+ lua_pushinteger(L, peer->connect);
+ lua_setfield(L, -2, "connect");
+ lua_pushinteger(L, peer->routeadv);
+ lua_setfield(L, -2, "route_advertisement");
+ }
+ lua_setfield(L, -2, "configured");
+
+ lua_newtable(L);
+ {
+ lua_pushinteger(L, peer->v_holdtime);
+ lua_setfield(L, -2, "hold");
+ lua_pushinteger(L, peer->v_keepalive);
+ lua_setfield(L, -2, "keepalive");
+ lua_pushinteger(L, peer->v_connect);
+ lua_setfield(L, -2, "connect");
+ lua_pushinteger(L, peer->v_routeadv);
+ lua_setfield(L, -2, "route_advertisement");
+ }
+ lua_setfield(L, -2, "negotiated");
+ }
+ lua_setfield(L, -2, "timers");
+
+ lua_newtable(L);
+ {
+ lua_pushinteger(L, atomic_load_explicit(&peer->open_in,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "open_in");
+ lua_pushinteger(L, atomic_load_explicit(&peer->open_out,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "open_out");
+ lua_pushinteger(L, atomic_load_explicit(&peer->update_in,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "update_in");
+ lua_pushinteger(L, atomic_load_explicit(&peer->update_out,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "update_out");
+ lua_pushinteger(L, atomic_load_explicit(&peer->update_time,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "update_time");
+ lua_pushinteger(L, atomic_load_explicit(&peer->keepalive_in,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "keepalive_in");
+ lua_pushinteger(L, atomic_load_explicit(&peer->keepalive_out,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "keepalive_out");
+ lua_pushinteger(L, atomic_load_explicit(&peer->notify_in,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "notify_in");
+ lua_pushinteger(L, atomic_load_explicit(&peer->notify_out,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "notify_out");
+ lua_pushinteger(L, atomic_load_explicit(&peer->refresh_in,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "refresh_in");
+ lua_pushinteger(L, atomic_load_explicit(&peer->refresh_out,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "refresh_out");
+ lua_pushinteger(L, atomic_load_explicit(&peer->dynamic_cap_in,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "dynamic_cap_in");
+ lua_pushinteger(L, atomic_load_explicit(&peer->dynamic_cap_out,
+ memory_order_relaxed));
+ lua_setfield(L, -2, "dynamic_cap_out");
+ lua_pushinteger(L, peer->established);
+ lua_setfield(L, -2, "times_established");
+ lua_pushinteger(L, peer->dropped);
+ lua_setfield(L, -2, "times_dropped");
+ }
+ lua_setfield(L, -2, "stats");
+}
+
+void lua_pushattr(lua_State *L, const struct attr *attr)
+{
+ lua_newtable(L);
+ lua_pushinteger(L, attr->med);
+ lua_setfield(L, -2, "metric");
+ lua_pushinteger(L, attr->nh_ifindex);
+ lua_setfield(L, -2, "ifindex");
+ lua_pushstring(L, attr->aspath->str);
+ lua_setfield(L, -2, "aspath");
+ lua_pushinteger(L, attr->local_pref);
+ lua_setfield(L, -2, "localpref");
+}
+
+void lua_decode_attr(lua_State *L, int idx, struct attr *attr)
+{
+ lua_getfield(L, idx, "metric");
+ attr->med = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, idx, "ifindex");
+ attr->nh_ifindex = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, idx, "aspath");
+ attr->aspath = aspath_str2aspath(lua_tostring(L, -1),
+ bgp_get_asnotation(NULL));
+ lua_pop(L, 1);
+ lua_getfield(L, idx, "localpref");
+ attr->local_pref = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+ lua_pop(L, 1);
+}
+
+void *lua_toattr(lua_State *L, int idx)
+{
+ struct attr *attr = XCALLOC(MTYPE_TMP, sizeof(struct attr));
+
+ lua_decode_attr(L, idx, attr);
+ return attr;
+}
+
+struct frrscript_codec frrscript_codecs_bgpd[] = {
+ {.typename = "peer",
+ .encoder = (encoder_func)lua_pushpeer,
+ .decoder = NULL},
+ {.typename = "attr",
+ .encoder = (encoder_func)lua_pushattr,
+ .decoder = lua_toattr},
+ {}};
+
+void bgp_script_init(void)
+{
+ frrscript_register_type_codecs(frrscript_codecs_bgpd);
+}
+
+#endif /* HAVE_SCRIPTING */