]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
b4becb06 QY |
2 | /* BGP scripting foo |
3 | * Copyright (C) 2020 NVIDIA Corporation | |
4 | * Quentin Young | |
b4becb06 QY |
5 | */ |
6 | ||
7 | #include <zebra.h> | |
fa22080d QY |
8 | |
9 | #ifdef HAVE_SCRIPTING | |
b4becb06 QY |
10 | |
11 | #include "bgpd.h" | |
12 | #include "bgp_script.h" | |
13 | #include "bgp_debug.h" | |
14 | #include "bgp_aspath.h" | |
15 | #include "frratomic.h" | |
16 | #include "frrscript.h" | |
17 | ||
b7da61c1 | 18 | void lua_pushpeer(lua_State *L, const struct peer *peer) |
b4becb06 QY |
19 | { |
20 | lua_newtable(L); | |
21 | lua_pushinteger(L, peer->as); | |
22 | lua_setfield(L, -2, "remote_as"); | |
23 | lua_pushinteger(L, peer->local_as); | |
24 | lua_setfield(L, -2, "local_as"); | |
25 | lua_pushinaddr(L, &peer->remote_id); | |
26 | lua_setfield(L, -2, "remote_id"); | |
27 | lua_pushinaddr(L, &peer->local_id); | |
28 | lua_setfield(L, -2, "local_id"); | |
29 | lua_pushstring(L, lookup_msg(bgp_status_msg, peer->status, NULL)); | |
30 | lua_setfield(L, -2, "state"); | |
31 | lua_pushstring(L, peer->desc ? peer->desc : ""); | |
32 | lua_setfield(L, -2, "description"); | |
33 | lua_pushtimet(L, &peer->uptime); | |
34 | lua_setfield(L, -2, "uptime"); | |
35 | lua_pushtimet(L, &peer->readtime); | |
36 | lua_setfield(L, -2, "last_readtime"); | |
37 | lua_pushtimet(L, &peer->resettime); | |
38 | lua_setfield(L, -2, "last_resettime"); | |
39 | lua_pushsockunion(L, peer->su_local); | |
40 | lua_setfield(L, -2, "local_address"); | |
41 | lua_pushsockunion(L, peer->su_remote); | |
42 | lua_setfield(L, -2, "remote_address"); | |
43 | lua_pushinteger(L, peer->cap); | |
44 | lua_setfield(L, -2, "capabilities"); | |
45 | lua_pushinteger(L, peer->flags); | |
46 | lua_setfield(L, -2, "flags"); | |
47 | lua_pushstring(L, peer->password ? peer->password : ""); | |
48 | lua_setfield(L, -2, "password"); | |
49 | ||
50 | /* Nested tables here */ | |
51 | lua_newtable(L); | |
52 | { | |
53 | lua_newtable(L); | |
54 | { | |
55 | lua_pushinteger(L, peer->holdtime); | |
56 | lua_setfield(L, -2, "hold"); | |
57 | lua_pushinteger(L, peer->keepalive); | |
58 | lua_setfield(L, -2, "keepalive"); | |
59 | lua_pushinteger(L, peer->connect); | |
60 | lua_setfield(L, -2, "connect"); | |
61 | lua_pushinteger(L, peer->routeadv); | |
62 | lua_setfield(L, -2, "route_advertisement"); | |
63 | } | |
64 | lua_setfield(L, -2, "configured"); | |
65 | ||
66 | lua_newtable(L); | |
67 | { | |
68 | lua_pushinteger(L, peer->v_holdtime); | |
69 | lua_setfield(L, -2, "hold"); | |
70 | lua_pushinteger(L, peer->v_keepalive); | |
71 | lua_setfield(L, -2, "keepalive"); | |
72 | lua_pushinteger(L, peer->v_connect); | |
73 | lua_setfield(L, -2, "connect"); | |
74 | lua_pushinteger(L, peer->v_routeadv); | |
75 | lua_setfield(L, -2, "route_advertisement"); | |
76 | } | |
77 | lua_setfield(L, -2, "negotiated"); | |
78 | } | |
79 | lua_setfield(L, -2, "timers"); | |
80 | ||
81 | lua_newtable(L); | |
82 | { | |
83 | lua_pushinteger(L, atomic_load_explicit(&peer->open_in, | |
84 | memory_order_relaxed)); | |
85 | lua_setfield(L, -2, "open_in"); | |
86 | lua_pushinteger(L, atomic_load_explicit(&peer->open_out, | |
87 | memory_order_relaxed)); | |
88 | lua_setfield(L, -2, "open_out"); | |
89 | lua_pushinteger(L, atomic_load_explicit(&peer->update_in, | |
90 | memory_order_relaxed)); | |
91 | lua_setfield(L, -2, "update_in"); | |
92 | lua_pushinteger(L, atomic_load_explicit(&peer->update_out, | |
93 | memory_order_relaxed)); | |
94 | lua_setfield(L, -2, "update_out"); | |
95 | lua_pushinteger(L, atomic_load_explicit(&peer->update_time, | |
96 | memory_order_relaxed)); | |
97 | lua_setfield(L, -2, "update_time"); | |
98 | lua_pushinteger(L, atomic_load_explicit(&peer->keepalive_in, | |
99 | memory_order_relaxed)); | |
100 | lua_setfield(L, -2, "keepalive_in"); | |
101 | lua_pushinteger(L, atomic_load_explicit(&peer->keepalive_out, | |
102 | memory_order_relaxed)); | |
103 | lua_setfield(L, -2, "keepalive_out"); | |
104 | lua_pushinteger(L, atomic_load_explicit(&peer->notify_in, | |
105 | memory_order_relaxed)); | |
106 | lua_setfield(L, -2, "notify_in"); | |
107 | lua_pushinteger(L, atomic_load_explicit(&peer->notify_out, | |
108 | memory_order_relaxed)); | |
109 | lua_setfield(L, -2, "notify_out"); | |
110 | lua_pushinteger(L, atomic_load_explicit(&peer->refresh_in, | |
111 | memory_order_relaxed)); | |
112 | lua_setfield(L, -2, "refresh_in"); | |
113 | lua_pushinteger(L, atomic_load_explicit(&peer->refresh_out, | |
114 | memory_order_relaxed)); | |
115 | lua_setfield(L, -2, "refresh_out"); | |
116 | lua_pushinteger(L, atomic_load_explicit(&peer->dynamic_cap_in, | |
117 | memory_order_relaxed)); | |
118 | lua_setfield(L, -2, "dynamic_cap_in"); | |
119 | lua_pushinteger(L, atomic_load_explicit(&peer->dynamic_cap_out, | |
120 | memory_order_relaxed)); | |
121 | lua_setfield(L, -2, "dynamic_cap_out"); | |
122 | lua_pushinteger(L, peer->established); | |
123 | lua_setfield(L, -2, "times_established"); | |
124 | lua_pushinteger(L, peer->dropped); | |
125 | lua_setfield(L, -2, "times_dropped"); | |
126 | } | |
127 | lua_setfield(L, -2, "stats"); | |
128 | } | |
129 | ||
b7da61c1 | 130 | void lua_pushattr(lua_State *L, const struct attr *attr) |
b4becb06 QY |
131 | { |
132 | lua_newtable(L); | |
133 | lua_pushinteger(L, attr->med); | |
134 | lua_setfield(L, -2, "metric"); | |
135 | lua_pushinteger(L, attr->nh_ifindex); | |
136 | lua_setfield(L, -2, "ifindex"); | |
137 | lua_pushstring(L, attr->aspath->str); | |
138 | lua_setfield(L, -2, "aspath"); | |
139 | lua_pushinteger(L, attr->local_pref); | |
140 | lua_setfield(L, -2, "localpref"); | |
141 | } | |
142 | ||
b7da61c1 | 143 | void lua_decode_attr(lua_State *L, int idx, struct attr *attr) |
b4becb06 | 144 | { |
9aa2174c | 145 | lua_getfield(L, idx, "metric"); |
b4becb06 QY |
146 | attr->med = lua_tointeger(L, -1); |
147 | lua_pop(L, 1); | |
9aa2174c | 148 | lua_getfield(L, idx, "ifindex"); |
b4becb06 QY |
149 | attr->nh_ifindex = lua_tointeger(L, -1); |
150 | lua_pop(L, 1); | |
9aa2174c | 151 | lua_getfield(L, idx, "aspath"); |
17571c4a PG |
152 | attr->aspath = aspath_str2aspath(lua_tostring(L, -1), |
153 | bgp_get_asnotation(NULL)); | |
b4becb06 | 154 | lua_pop(L, 1); |
9aa2174c | 155 | lua_getfield(L, idx, "localpref"); |
b4becb06 QY |
156 | attr->local_pref = lua_tointeger(L, -1); |
157 | lua_pop(L, 1); | |
9aa2174c | 158 | lua_pop(L, 1); |
b7da61c1 DL |
159 | } |
160 | ||
161 | void *lua_toattr(lua_State *L, int idx) | |
162 | { | |
163 | struct attr *attr = XCALLOC(MTYPE_TMP, sizeof(struct attr)); | |
b4becb06 | 164 | |
b7da61c1 | 165 | lua_decode_attr(L, idx, attr); |
b4becb06 QY |
166 | return attr; |
167 | } | |
168 | ||
169 | struct frrscript_codec frrscript_codecs_bgpd[] = { | |
170 | {.typename = "peer", | |
171 | .encoder = (encoder_func)lua_pushpeer, | |
172 | .decoder = NULL}, | |
173 | {.typename = "attr", | |
174 | .encoder = (encoder_func)lua_pushattr, | |
175 | .decoder = lua_toattr}, | |
176 | {}}; | |
177 | ||
178 | void bgp_script_init(void) | |
179 | { | |
180 | frrscript_register_type_codecs(frrscript_codecs_bgpd); | |
181 | } | |
fa22080d QY |
182 | |
183 | #endif /* HAVE_SCRIPTING */ |