]>
Commit | Line | Data |
---|---|---|
6c574029 RW |
1 | /* |
2 | * BFD daemon northbound implementation. | |
3 | * | |
4 | * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF") | |
5 | * Rafael Zalamena | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
20 | * 02110-1301 USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "lib/log.h" | |
26 | #include "lib/northbound.h" | |
27 | ||
28 | #include "bfd.h" | |
29 | #include "bfdd_nb.h" | |
30 | ||
31 | /* | |
32 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop | |
33 | */ | |
34 | const void *bfdd_bfd_sessions_single_hop_get_next(const void *parent_list_entry | |
35 | __attribute__((__unused__)), | |
36 | const void *list_entry) | |
37 | { | |
38 | return bfd_session_next(list_entry, false); | |
39 | } | |
40 | ||
41 | int bfdd_bfd_sessions_single_hop_get_keys(const void *list_entry, | |
42 | struct yang_list_keys *keys) | |
43 | { | |
44 | const struct bfd_session *bs = list_entry; | |
45 | char dstbuf[INET6_ADDRSTRLEN]; | |
46 | ||
47 | inet_ntop(bs->key.family, &bs->key.peer, dstbuf, sizeof(dstbuf)); | |
48 | ||
49 | keys->num = 3; | |
50 | strlcpy(keys->key[0], dstbuf, sizeof(keys->key[0])); | |
51 | strlcpy(keys->key[1], bs->key.ifname, sizeof(keys->key[1])); | |
52 | strlcpy(keys->key[2], bs->key.vrfname, sizeof(keys->key[2])); | |
53 | ||
54 | return NB_OK; | |
55 | } | |
56 | ||
57 | const void * | |
58 | bfdd_bfd_sessions_single_hop_lookup_entry(const void *parent_list_entry | |
59 | __attribute__((__unused__)), | |
60 | const struct yang_list_keys *keys) | |
61 | { | |
62 | const char *dest_addr = keys->key[0]; | |
63 | const char *ifname = keys->key[1]; | |
64 | const char *vrf = keys->key[2]; | |
65 | struct sockaddr_any psa, lsa; | |
66 | struct bfd_key bk; | |
67 | ||
68 | strtosa(dest_addr, &psa); | |
69 | memset(&lsa, 0, sizeof(lsa)); | |
70 | gen_bfd_key(&bk, &psa, &lsa, false, ifname, vrf); | |
71 | ||
72 | return bfd_key_lookup(bk); | |
73 | } | |
74 | ||
75 | /* | |
76 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-discriminator | |
77 | */ | |
78 | struct yang_data * | |
79 | bfdd_bfd_sessions_single_hop_stats_local_discriminator_get_elem( | |
80 | const char *xpath, const void *list_entry) | |
81 | { | |
82 | const struct bfd_session *bs = list_entry; | |
83 | ||
84 | return yang_data_new_uint32(xpath, bs->discrs.my_discr); | |
85 | } | |
86 | ||
87 | /* | |
88 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-state | |
89 | */ | |
90 | struct yang_data * | |
91 | bfdd_bfd_sessions_single_hop_stats_local_state_get_elem(const char *xpath, | |
92 | const void *list_entry) | |
93 | { | |
94 | const struct bfd_session *bs = list_entry; | |
95 | ||
96 | return yang_data_new_enum(xpath, bs->ses_state); | |
97 | } | |
98 | ||
99 | /* | |
100 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-diagnostic | |
101 | */ | |
102 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_diagnostic_get_elem( | |
103 | const char *xpath, const void *list_entry) | |
104 | { | |
105 | const struct bfd_session *bs = list_entry; | |
106 | ||
107 | return yang_data_new_enum(xpath, bs->local_diag); | |
108 | } | |
109 | ||
110 | /* | |
111 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-multiplier | |
112 | */ | |
113 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_multiplier_get_elem( | |
114 | const char *xpath, const void *list_entry) | |
115 | { | |
116 | const struct bfd_session *bs = list_entry; | |
117 | ||
118 | return yang_data_new_int8(xpath, bs->detect_mult); | |
119 | } | |
120 | ||
121 | /* | |
122 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-discriminator | |
123 | */ | |
124 | struct yang_data * | |
125 | bfdd_bfd_sessions_single_hop_stats_remote_discriminator_get_elem( | |
126 | const char *xpath, const void *list_entry) | |
127 | { | |
128 | const struct bfd_session *bs = list_entry; | |
129 | ||
130 | if (bs->discrs.remote_discr == 0) | |
131 | return NULL; | |
132 | ||
133 | return yang_data_new_uint32(xpath, bs->discrs.remote_discr); | |
134 | } | |
135 | ||
136 | /* | |
137 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-state | |
138 | */ | |
139 | struct yang_data * | |
140 | bfdd_bfd_sessions_single_hop_stats_remote_state_get_elem(const char *xpath, | |
141 | const void *list_entry) | |
142 | { | |
143 | const struct bfd_session *bs = list_entry; | |
144 | ||
145 | return yang_data_new_enum(xpath, bs->ses_state); | |
146 | } | |
147 | ||
148 | /* | |
149 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-diagnostic | |
150 | */ | |
151 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_diagnostic_get_elem( | |
152 | const char *xpath, const void *list_entry) | |
153 | { | |
154 | const struct bfd_session *bs = list_entry; | |
155 | ||
156 | return yang_data_new_enum(xpath, bs->remote_diag); | |
157 | } | |
158 | ||
159 | /* | |
160 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-multiplier | |
161 | */ | |
162 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_multiplier_get_elem( | |
163 | const char *xpath, const void *list_entry) | |
164 | { | |
165 | const struct bfd_session *bs = list_entry; | |
166 | ||
167 | return yang_data_new_int8(xpath, bs->remote_detect_mult); | |
168 | } | |
169 | ||
170 | /* | |
171 | * XPath: | |
172 | * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/negotiated-transmission-interval | |
173 | */ | |
174 | struct yang_data * | |
175 | bfdd_bfd_sessions_single_hop_stats_negotiated_transmission_interval_get_elem( | |
176 | const char *xpath, const void *list_entry) | |
177 | { | |
178 | const struct bfd_session *bs = list_entry; | |
179 | ||
180 | return yang_data_new_uint32(xpath, bs->remote_timers.desired_min_tx); | |
181 | } | |
182 | ||
183 | /* | |
184 | * XPath: | |
185 | * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/negotiated-receive-interval | |
186 | */ | |
187 | struct yang_data * | |
188 | bfdd_bfd_sessions_single_hop_stats_negotiated_receive_interval_get_elem( | |
189 | const char *xpath, const void *list_entry) | |
190 | { | |
191 | const struct bfd_session *bs = list_entry; | |
192 | ||
193 | return yang_data_new_uint32(xpath, bs->remote_timers.required_min_rx); | |
194 | } | |
195 | ||
196 | /* | |
197 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/detection-mode | |
198 | */ | |
199 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_detection_mode_get_elem( | |
200 | const char *xpath, const void *list_entry) | |
201 | { | |
202 | const struct bfd_session *bs = list_entry; | |
203 | int detection_mode; | |
204 | ||
205 | /* | |
206 | * Detection mode: | |
207 | * 1. Async with echo | |
208 | * 2. Async without echo | |
209 | * 3. Demand with echo | |
210 | * 4. Demand without echo | |
211 | * | |
212 | * TODO: support demand mode. | |
213 | */ | |
214 | if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO)) | |
215 | detection_mode = 1; | |
216 | else | |
217 | detection_mode = 2; | |
218 | ||
219 | return yang_data_new_enum(xpath, detection_mode); | |
220 | } | |
221 | ||
222 | /* | |
223 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/last-down-time | |
224 | */ | |
225 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_down_time_get_elem( | |
226 | const char *xpath __attribute__((__unused__)), | |
227 | const void *list_entry __attribute__((__unused__))) | |
228 | { | |
229 | /* | |
230 | * TODO: implement me. | |
231 | * | |
232 | * No yang support for time elements yet. | |
233 | */ | |
234 | return NULL; | |
235 | } | |
236 | ||
237 | /* | |
238 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/last-up-time | |
239 | */ | |
240 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_up_time_get_elem( | |
241 | const char *xpath __attribute__((__unused__)), | |
242 | const void *list_entry __attribute__((__unused__))) | |
243 | { | |
244 | /* | |
245 | * TODO: implement me. | |
246 | * | |
247 | * No yang support for time elements yet. | |
248 | */ | |
249 | return NULL; | |
250 | } | |
251 | ||
252 | /* | |
253 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/session-down-count | |
254 | */ | |
255 | struct yang_data * | |
256 | bfdd_bfd_sessions_single_hop_stats_session_down_count_get_elem( | |
257 | const char *xpath, const void *list_entry) | |
258 | { | |
259 | const struct bfd_session *bs = list_entry; | |
260 | ||
261 | return yang_data_new_uint64(xpath, bs->stats.session_down); | |
262 | } | |
263 | ||
264 | /* | |
265 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/session-up-count | |
266 | */ | |
267 | struct yang_data *bfdd_bfd_sessions_single_hop_stats_session_up_count_get_elem( | |
268 | const char *xpath, const void *list_entry) | |
269 | { | |
270 | const struct bfd_session *bs = list_entry; | |
271 | ||
272 | return yang_data_new_uint64(xpath, bs->stats.session_up); | |
273 | } | |
274 | ||
275 | /* | |
276 | * XPath: | |
277 | * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/control-packet-input-count | |
278 | */ | |
279 | struct yang_data * | |
280 | bfdd_bfd_sessions_single_hop_stats_control_packet_input_count_get_elem( | |
281 | const char *xpath, const void *list_entry) | |
282 | { | |
283 | const struct bfd_session *bs = list_entry; | |
284 | ||
285 | return yang_data_new_uint64(xpath, bs->stats.rx_ctrl_pkt); | |
286 | } | |
287 | ||
288 | /* | |
289 | * XPath: | |
290 | * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/control-packet-output-count | |
291 | */ | |
292 | struct yang_data * | |
293 | bfdd_bfd_sessions_single_hop_stats_control_packet_output_count_get_elem( | |
294 | const char *xpath, const void *list_entry) | |
295 | { | |
296 | const struct bfd_session *bs = list_entry; | |
297 | ||
298 | return yang_data_new_uint64(xpath, bs->stats.tx_ctrl_pkt); | |
299 | } | |
300 | ||
301 | /* | |
302 | * XPath: | |
303 | * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/negotiated-echo-transmission-interval | |
304 | */ | |
305 | struct yang_data * | |
306 | bfdd_bfd_sessions_single_hop_stats_negotiated_echo_transmission_interval_get_elem( | |
307 | const char *xpath, const void *list_entry) | |
308 | { | |
309 | const struct bfd_session *bs = list_entry; | |
310 | ||
311 | return yang_data_new_uint32(xpath, bs->remote_timers.required_min_echo); | |
312 | } | |
313 | ||
314 | /* | |
315 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/echo-packet-input-count | |
316 | */ | |
317 | struct yang_data * | |
318 | bfdd_bfd_sessions_single_hop_stats_echo_packet_input_count_get_elem( | |
319 | const char *xpath, const void *list_entry) | |
320 | { | |
321 | const struct bfd_session *bs = list_entry; | |
322 | ||
323 | return yang_data_new_uint64(xpath, bs->stats.rx_echo_pkt); | |
324 | } | |
325 | ||
326 | /* | |
327 | * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/echo-packet-output-count | |
328 | */ | |
329 | struct yang_data * | |
330 | bfdd_bfd_sessions_single_hop_stats_echo_packet_output_count_get_elem( | |
331 | const char *xpath, const void *list_entry) | |
332 | { | |
333 | const struct bfd_session *bs = list_entry; | |
334 | ||
335 | return yang_data_new_uint64(xpath, bs->stats.tx_echo_pkt); | |
336 | } | |
337 | ||
338 | /* | |
339 | * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop | |
340 | */ | |
341 | const void *bfdd_bfd_sessions_multi_hop_get_next(const void *parent_list_entry | |
342 | __attribute__((__unused__)), | |
343 | const void *list_entry) | |
344 | { | |
345 | return bfd_session_next(list_entry, true); | |
346 | } | |
347 | ||
348 | int bfdd_bfd_sessions_multi_hop_get_keys(const void *list_entry, | |
349 | struct yang_list_keys *keys) | |
350 | { | |
351 | const struct bfd_session *bs = list_entry; | |
352 | char dstbuf[INET6_ADDRSTRLEN], srcbuf[INET6_ADDRSTRLEN]; | |
353 | ||
354 | inet_ntop(bs->key.family, &bs->key.peer, dstbuf, sizeof(dstbuf)); | |
355 | inet_ntop(bs->key.family, &bs->key.local, srcbuf, sizeof(srcbuf)); | |
356 | ||
357 | keys->num = 4; | |
358 | strlcpy(keys->key[0], srcbuf, sizeof(keys->key[0])); | |
359 | strlcpy(keys->key[1], dstbuf, sizeof(keys->key[1])); | |
360 | strlcpy(keys->key[2], bs->key.ifname, sizeof(keys->key[2])); | |
361 | strlcpy(keys->key[3], bs->key.vrfname, sizeof(keys->key[3])); | |
362 | ||
363 | return NB_OK; | |
364 | } | |
365 | ||
366 | const void * | |
367 | bfdd_bfd_sessions_multi_hop_lookup_entry(const void *parent_list_entry | |
368 | __attribute__((__unused__)), | |
369 | const struct yang_list_keys *keys) | |
370 | { | |
371 | const char *source_addr = keys->key[0]; | |
372 | const char *dest_addr = keys->key[1]; | |
373 | const char *ifname = keys->key[2]; | |
374 | const char *vrf = keys->key[3]; | |
375 | struct sockaddr_any psa, lsa; | |
376 | struct bfd_key bk; | |
377 | ||
378 | strtosa(dest_addr, &psa); | |
379 | strtosa(source_addr, &lsa); | |
380 | gen_bfd_key(&bk, &psa, &lsa, true, ifname, vrf); | |
381 | ||
382 | return bfd_key_lookup(bk); | |
383 | } |