2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2020-11-29 22:01:59 +01:00
|
|
|
/* BGP scripting foo
|
|
|
|
* Copyright (C) 2020 NVIDIA Corporation
|
|
|
|
* Quentin Young
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
2020-11-30 23:01:03 +01:00
|
|
|
|
|
|
|
#ifdef HAVE_SCRIPTING
|
2020-11-29 22:01:59 +01:00
|
|
|
|
|
|
|
#include "bgpd.h"
|
|
|
|
#include "bgp_script.h"
|
|
|
|
#include "bgp_debug.h"
|
|
|
|
#include "bgp_aspath.h"
|
|
|
|
#include "frratomic.h"
|
|
|
|
#include "frrscript.h"
|
|
|
|
|
2021-06-21 23:03:07 +02:00
|
|
|
void lua_pushpeer(lua_State *L, const struct peer *peer)
|
2020-11-29 22:01:59 +01:00
|
|
|
{
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2021-06-21 23:03:07 +02:00
|
|
|
void lua_pushattr(lua_State *L, const struct attr *attr)
|
2020-11-29 22:01:59 +01:00
|
|
|
{
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2021-06-21 23:03:07 +02:00
|
|
|
void lua_decode_attr(lua_State *L, int idx, struct attr *attr)
|
2020-11-29 22:01:59 +01:00
|
|
|
{
|
2022-03-29 16:47:28 +02:00
|
|
|
lua_getfield(L, idx, "metric");
|
2020-11-29 22:01:59 +01:00
|
|
|
attr->med = lua_tointeger(L, -1);
|
|
|
|
lua_pop(L, 1);
|
2022-03-29 16:47:28 +02:00
|
|
|
lua_getfield(L, idx, "ifindex");
|
2020-11-29 22:01:59 +01:00
|
|
|
attr->nh_ifindex = lua_tointeger(L, -1);
|
|
|
|
lua_pop(L, 1);
|
2022-03-29 16:47:28 +02:00
|
|
|
lua_getfield(L, idx, "aspath");
|
bgpd: aspath list format binds on as-notation format
Each BGP prefix may have an as-path list attached. A forged
string is stored in the BGP attribute and shows the as-path
list output.
Before this commit, the as-path list output was expressed as
a list of AS values in plain format. Now, if a given BGP instance
uses a specific asnotation, then the output is changed:
new output:
router bgp 1.1 asnotation dot
!
address-family ipv4 unicast
network 10.200.0.0/24 route-map rmap
network 10.201.0.0/24 route-map rmap
redistribute connected route-map rmap
exit-address-family
exit
!
route-map rmap permit 1
set as-path prepend 1.1 5433.55 264564564
exit
ubuntu2004# do show bgp ipv4
BGP table version is 2, local router ID is 10.0.2.15, vrf id 0
Default local pref 100, local AS 1.1
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 4.4.4.4/32 0.0.0.0 0 32768 1.1 5433.55 4036.61268 ?
*> 10.0.2.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 ?
10.200.0.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 i
10.201.0.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 i
The changes include:
- the aspath structure has a new field: asnotation type
The ashash list will differentiate 2 aspaths using a different
asnotation.
- 3 new printf extensions display the as number in the wished
format: pASP, pASD, pASE for plain, dot, or dot+ format (extended).
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2022-11-14 15:56:40 +01:00
|
|
|
attr->aspath = aspath_str2aspath(lua_tostring(L, -1),
|
|
|
|
bgp_get_asnotation(NULL));
|
2020-11-29 22:01:59 +01:00
|
|
|
lua_pop(L, 1);
|
2022-03-29 16:47:28 +02:00
|
|
|
lua_getfield(L, idx, "localpref");
|
2020-11-29 22:01:59 +01:00
|
|
|
attr->local_pref = lua_tointeger(L, -1);
|
|
|
|
lua_pop(L, 1);
|
2022-03-29 16:47:28 +02:00
|
|
|
lua_pop(L, 1);
|
2021-06-21 23:03:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void *lua_toattr(lua_State *L, int idx)
|
|
|
|
{
|
|
|
|
struct attr *attr = XCALLOC(MTYPE_TMP, sizeof(struct attr));
|
2020-11-29 22:01:59 +01:00
|
|
|
|
2021-06-21 23:03:07 +02:00
|
|
|
lua_decode_attr(L, idx, attr);
|
2020-11-29 22:01:59 +01:00
|
|
|
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);
|
|
|
|
}
|
2020-11-30 23:01:03 +01:00
|
|
|
|
|
|
|
#endif /* HAVE_SCRIPTING */
|