Line data Source code
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 *
35 0 : bfdd_bfd_sessions_single_hop_get_next(struct nb_cb_get_next_args *args)
36 : {
37 0 : return bfd_session_next(args->list_entry, false);
38 : }
39 :
40 0 : int bfdd_bfd_sessions_single_hop_get_keys(struct nb_cb_get_keys_args *args)
41 : {
42 0 : const struct bfd_session *bs = args->list_entry;
43 0 : char dstbuf[INET6_ADDRSTRLEN];
44 :
45 0 : inet_ntop(bs->key.family, &bs->key.peer, dstbuf, sizeof(dstbuf));
46 :
47 0 : args->keys->num = 3;
48 0 : strlcpy(args->keys->key[0], dstbuf, sizeof(args->keys->key[0]));
49 0 : strlcpy(args->keys->key[1], bs->key.ifname, sizeof(args->keys->key[1]));
50 0 : strlcpy(args->keys->key[2], bs->key.vrfname,
51 : sizeof(args->keys->key[2]));
52 :
53 0 : return NB_OK;
54 : }
55 :
56 : const void *
57 0 : bfdd_bfd_sessions_single_hop_lookup_entry(struct nb_cb_lookup_entry_args *args)
58 : {
59 0 : const char *dest_addr = args->keys->key[0];
60 0 : const char *ifname = args->keys->key[1];
61 0 : const char *vrf = args->keys->key[2];
62 0 : struct sockaddr_any psa, lsa;
63 0 : struct bfd_key bk;
64 :
65 0 : strtosa(dest_addr, &psa);
66 0 : memset(&lsa, 0, sizeof(lsa));
67 0 : gen_bfd_key(&bk, &psa, &lsa, false, ifname, vrf);
68 :
69 0 : return bfd_key_lookup(bk);
70 : }
71 :
72 : /*
73 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-discriminator
74 : */
75 : struct yang_data *
76 0 : bfdd_bfd_sessions_single_hop_stats_local_discriminator_get_elem(
77 : struct nb_cb_get_elem_args *args)
78 : {
79 0 : const struct bfd_session *bs = args->list_entry;
80 :
81 0 : return yang_data_new_uint32(args->xpath, bs->discrs.my_discr);
82 : }
83 :
84 : /*
85 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-state
86 : */
87 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_state_get_elem(
88 : struct nb_cb_get_elem_args *args)
89 : {
90 0 : const struct bfd_session *bs = args->list_entry;
91 :
92 0 : return yang_data_new_enum(args->xpath, bs->ses_state);
93 : }
94 :
95 : /*
96 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-diagnostic
97 : */
98 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_diagnostic_get_elem(
99 : struct nb_cb_get_elem_args *args)
100 : {
101 0 : const struct bfd_session *bs = args->list_entry;
102 :
103 0 : return yang_data_new_enum(args->xpath, bs->local_diag);
104 : }
105 :
106 : /*
107 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-multiplier
108 : */
109 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_multiplier_get_elem(
110 : struct nb_cb_get_elem_args *args)
111 : {
112 0 : const struct bfd_session *bs = args->list_entry;
113 :
114 0 : return yang_data_new_int8(args->xpath, bs->detect_mult);
115 : }
116 :
117 : /*
118 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-discriminator
119 : */
120 : struct yang_data *
121 0 : bfdd_bfd_sessions_single_hop_stats_remote_discriminator_get_elem(
122 : struct nb_cb_get_elem_args *args)
123 : {
124 0 : const struct bfd_session *bs = args->list_entry;
125 :
126 0 : if (bs->discrs.remote_discr == 0)
127 : return NULL;
128 :
129 0 : return yang_data_new_uint32(args->xpath, bs->discrs.remote_discr);
130 : }
131 :
132 : /*
133 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-state
134 : */
135 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_state_get_elem(
136 : struct nb_cb_get_elem_args *args)
137 : {
138 0 : const struct bfd_session *bs = args->list_entry;
139 :
140 0 : return yang_data_new_enum(args->xpath, bs->ses_state);
141 : }
142 :
143 : /*
144 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-diagnostic
145 : */
146 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_diagnostic_get_elem(
147 : struct nb_cb_get_elem_args *args)
148 : {
149 0 : const struct bfd_session *bs = args->list_entry;
150 :
151 0 : return yang_data_new_enum(args->xpath, bs->remote_diag);
152 : }
153 :
154 : /*
155 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-multiplier
156 : */
157 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_multiplier_get_elem(
158 : struct nb_cb_get_elem_args *args)
159 : {
160 0 : const struct bfd_session *bs = args->list_entry;
161 :
162 0 : return yang_data_new_int8(args->xpath, bs->remote_detect_mult);
163 : }
164 :
165 : /*
166 : * XPath:
167 : * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/negotiated-transmission-interval
168 : */
169 : struct yang_data *
170 0 : bfdd_bfd_sessions_single_hop_stats_negotiated_transmission_interval_get_elem(
171 : struct nb_cb_get_elem_args *args)
172 : {
173 0 : const struct bfd_session *bs = args->list_entry;
174 :
175 0 : return yang_data_new_uint32(args->xpath,
176 0 : bs->remote_timers.desired_min_tx);
177 : }
178 :
179 : /*
180 : * XPath:
181 : * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/negotiated-receive-interval
182 : */
183 : struct yang_data *
184 0 : bfdd_bfd_sessions_single_hop_stats_negotiated_receive_interval_get_elem(
185 : struct nb_cb_get_elem_args *args)
186 : {
187 0 : const struct bfd_session *bs = args->list_entry;
188 :
189 0 : return yang_data_new_uint32(args->xpath,
190 0 : bs->remote_timers.required_min_rx);
191 : }
192 :
193 : /*
194 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/detection-mode
195 : */
196 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_detection_mode_get_elem(
197 : struct nb_cb_get_elem_args *args)
198 : {
199 0 : const struct bfd_session *bs = args->list_entry;
200 0 : int detection_mode;
201 :
202 : /*
203 : * Detection mode:
204 : * 1. Async with echo
205 : * 2. Async without echo
206 : * 3. Demand with echo
207 : * 4. Demand without echo
208 : *
209 : * TODO: support demand mode.
210 : */
211 0 : if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO))
212 : detection_mode = 1;
213 : else
214 0 : detection_mode = 2;
215 :
216 0 : return yang_data_new_enum(args->xpath, detection_mode);
217 : }
218 :
219 : /*
220 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/last-down-time
221 : */
222 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_down_time_get_elem(
223 : struct nb_cb_get_elem_args *args)
224 : {
225 : /*
226 : * TODO: implement me.
227 : *
228 : * No yang support for time elements yet.
229 : */
230 0 : return NULL;
231 : }
232 :
233 : /*
234 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/last-up-time
235 : */
236 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_up_time_get_elem(
237 : struct nb_cb_get_elem_args *args)
238 : {
239 : /*
240 : * TODO: implement me.
241 : *
242 : * No yang support for time elements yet.
243 : */
244 0 : return NULL;
245 : }
246 :
247 : /*
248 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/session-down-count
249 : */
250 : struct yang_data *
251 0 : bfdd_bfd_sessions_single_hop_stats_session_down_count_get_elem(
252 : struct nb_cb_get_elem_args *args)
253 : {
254 0 : const struct bfd_session *bs = args->list_entry;
255 :
256 0 : return yang_data_new_uint64(args->xpath, bs->stats.session_down);
257 : }
258 :
259 : /*
260 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/session-up-count
261 : */
262 0 : struct yang_data *bfdd_bfd_sessions_single_hop_stats_session_up_count_get_elem(
263 : struct nb_cb_get_elem_args *args)
264 : {
265 0 : const struct bfd_session *bs = args->list_entry;
266 :
267 0 : return yang_data_new_uint64(args->xpath, bs->stats.session_up);
268 : }
269 :
270 : /*
271 : * XPath:
272 : * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/control-packet-input-count
273 : */
274 : struct yang_data *
275 0 : bfdd_bfd_sessions_single_hop_stats_control_packet_input_count_get_elem(
276 : struct nb_cb_get_elem_args *args)
277 : {
278 0 : const struct bfd_session *bs = args->list_entry;
279 :
280 0 : return yang_data_new_uint64(args->xpath, bs->stats.rx_ctrl_pkt);
281 : }
282 :
283 : /*
284 : * XPath:
285 : * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/control-packet-output-count
286 : */
287 : struct yang_data *
288 0 : bfdd_bfd_sessions_single_hop_stats_control_packet_output_count_get_elem(
289 : struct nb_cb_get_elem_args *args)
290 : {
291 0 : const struct bfd_session *bs = args->list_entry;
292 :
293 0 : return yang_data_new_uint64(args->xpath, bs->stats.tx_ctrl_pkt);
294 : }
295 :
296 : /*
297 : * XPath:
298 : * /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/negotiated-echo-transmission-interval
299 : */
300 : struct yang_data *
301 0 : bfdd_bfd_sessions_single_hop_stats_negotiated_echo_transmission_interval_get_elem(
302 : struct nb_cb_get_elem_args *args)
303 : {
304 0 : const struct bfd_session *bs = args->list_entry;
305 :
306 0 : return yang_data_new_uint32(args->xpath,
307 0 : bs->remote_timers.required_min_echo);
308 : }
309 :
310 : /*
311 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/echo-packet-input-count
312 : */
313 : struct yang_data *
314 0 : bfdd_bfd_sessions_single_hop_stats_echo_packet_input_count_get_elem(
315 : struct nb_cb_get_elem_args *args)
316 : {
317 0 : const struct bfd_session *bs = args->list_entry;
318 :
319 0 : return yang_data_new_uint64(args->xpath, bs->stats.rx_echo_pkt);
320 : }
321 :
322 : /*
323 : * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/echo-packet-output-count
324 : */
325 : struct yang_data *
326 0 : bfdd_bfd_sessions_single_hop_stats_echo_packet_output_count_get_elem(
327 : struct nb_cb_get_elem_args *args)
328 : {
329 0 : const struct bfd_session *bs = args->list_entry;
330 :
331 0 : return yang_data_new_uint64(args->xpath, bs->stats.tx_echo_pkt);
332 : }
333 :
334 : /*
335 : * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop
336 : */
337 : const void *
338 0 : bfdd_bfd_sessions_multi_hop_get_next(struct nb_cb_get_next_args *args)
339 : {
340 0 : return bfd_session_next(args->list_entry, true);
341 : }
342 :
343 0 : int bfdd_bfd_sessions_multi_hop_get_keys(struct nb_cb_get_keys_args *args)
344 : {
345 0 : const struct bfd_session *bs = args->list_entry;
346 0 : char dstbuf[INET6_ADDRSTRLEN], srcbuf[INET6_ADDRSTRLEN];
347 :
348 0 : inet_ntop(bs->key.family, &bs->key.peer, dstbuf, sizeof(dstbuf));
349 0 : inet_ntop(bs->key.family, &bs->key.local, srcbuf, sizeof(srcbuf));
350 :
351 0 : args->keys->num = 4;
352 0 : strlcpy(args->keys->key[0], srcbuf, sizeof(args->keys->key[0]));
353 0 : strlcpy(args->keys->key[1], dstbuf, sizeof(args->keys->key[1]));
354 0 : strlcpy(args->keys->key[2], bs->key.vrfname,
355 : sizeof(args->keys->key[2]));
356 :
357 0 : return NB_OK;
358 : }
359 :
360 : const void *
361 0 : bfdd_bfd_sessions_multi_hop_lookup_entry(struct nb_cb_lookup_entry_args *args)
362 : {
363 0 : const char *source_addr = args->keys->key[0];
364 0 : const char *dest_addr = args->keys->key[1];
365 0 : const char *vrf = args->keys->key[2];
366 0 : struct sockaddr_any psa, lsa;
367 0 : struct bfd_key bk;
368 :
369 0 : strtosa(dest_addr, &psa);
370 0 : strtosa(source_addr, &lsa);
371 0 : gen_bfd_key(&bk, &psa, &lsa, true, NULL, vrf);
372 :
373 0 : return bfd_key_lookup(bk);
374 : }
|