diff options
| author | Quentin Young <qlyoung@nvidia.com> | 2020-11-29 16:01:59 -0500 | 
|---|---|---|
| committer | Quentin Young <qlyoung@nvidia.com> | 2020-12-01 18:37:14 -0500 | 
| commit | b4becb063f0ec06c4ecfe2ca832383d49d375441 (patch) | |
| tree | 737b41984d65acb66b9acd594b8d554e04790c7c /bgpd/bgp_script.c | |
| parent | 1a3a91e211f60d62376c78e81f11e9db452f3c33 (diff) | |
bgpd: update routemap scripting example
- Change from "match command <foo>" to "match script <script>"
- Use new scripting API
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
Diffstat (limited to 'bgpd/bgp_script.c')
| -rw-r--r-- | bgpd/bgp_script.c | 188 | 
1 files changed, 188 insertions, 0 deletions
diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c new file mode 100644 index 0000000000..c665f2e7c5 --- /dev/null +++ b/bgpd/bgp_script.c @@ -0,0 +1,188 @@ +/* BGP scripting foo + * Copyright (C) 2020  NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <zebra.h> +#include <lua.h> + +#include "bgpd.h" +#include "bgp_script.h" +#include "bgp_debug.h" +#include "bgp_aspath.h" +#include "frratomic.h" +#include "frrscript.h" + +static 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->status, NULL)); +	lua_setfield(L, -2, "state"); +	lua_pushstring(L, peer->desc ? peer->desc : ""); +	lua_setfield(L, -2, "description"); +	lua_pushtimet(L, &peer->uptime); +	lua_setfield(L, -2, "uptime"); +	lua_pushtimet(L, &peer->readtime); +	lua_setfield(L, -2, "last_readtime"); +	lua_pushtimet(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"); +} + +static 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"); +} + +static void *lua_toattr(lua_State *L, int idx) +{ +	struct attr *attr = XCALLOC(MTYPE_TMP, sizeof(struct attr)); + +	lua_getfield(L, -1, "metric"); +	attr->med = lua_tointeger(L, -1); +	lua_pop(L, 1); +	lua_getfield(L, -1, "ifindex"); +	attr->nh_ifindex = lua_tointeger(L, -1); +	lua_pop(L, 1); +	lua_getfield(L, -1, "aspath"); +	attr->aspath = aspath_str2aspath(lua_tostring(L, -1)); +	lua_pop(L, 1); +	lua_getfield(L, -1, "localpref"); +	attr->local_pref = lua_tointeger(L, -1); +	lua_pop(L, 1); + +	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); +}  | 
