Line data Source code
1 : /*
2 : *------------------------------------------------------------------
3 : * bfd_api.c - bfd api
4 : *
5 : * Copyright (c) 2016 Cisco and/or its affiliates.
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at:
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : *------------------------------------------------------------------
18 : */
19 : /**
20 : * @file
21 : * @brief BFD binary API implementation
22 : */
23 :
24 : #include <vnet/vnet.h>
25 : #include <vlibmemory/api.h>
26 :
27 : #include <vnet/interface.h>
28 : #include <vnet/api_errno.h>
29 : #include <vnet/bfd/bfd_main.h>
30 : #include <vnet/bfd/bfd_api.h>
31 : #include <vnet/ip/ip_types_api.h>
32 :
33 : #include <vnet/format_fns.h>
34 : #include <vnet/bfd/bfd.api_enum.h>
35 : #include <vnet/bfd/bfd.api_types.h>
36 :
37 : #define REPLY_MSG_ID_BASE bfd_main.msg_id_base
38 : #include <vlibapi/api_helper_macros.h>
39 :
40 :
41 1921 : pub_sub_handler (bfd_events, BFD_EVENTS);
42 :
43 : #define BFD_UDP_API_PARAM_COMMON_CODE \
44 : ip46_address_t local_addr; \
45 : ip46_address_t peer_addr; \
46 : ip_address_decode(&mp->local_addr, &local_addr); \
47 : ip_address_decode(&mp->peer_addr, &peer_addr);
48 :
49 : #define BFD_UDP_API_PARAM_FROM_MP(mp) \
50 : clib_net_to_host_u32 (mp->sw_if_index), &local_addr, &peer_addr
51 :
52 : static void
53 102 : vl_api_bfd_udp_add_t_handler (vl_api_bfd_udp_add_t * mp)
54 : {
55 : vl_api_bfd_udp_add_reply_t *rmp;
56 : int rv;
57 :
58 102 : VALIDATE_SW_IF_INDEX (mp);
59 :
60 102 : BFD_UDP_API_PARAM_COMMON_CODE;
61 :
62 102 : rv = bfd_udp_add_session (BFD_UDP_API_PARAM_FROM_MP (mp),
63 : clib_net_to_host_u32 (mp->desired_min_tx),
64 : clib_net_to_host_u32 (mp->required_min_rx),
65 102 : mp->detect_mult, mp->is_authenticated,
66 : clib_net_to_host_u32 (mp->conf_key_id),
67 102 : mp->bfd_key_id);
68 :
69 102 : BAD_SW_IF_INDEX_LABEL;
70 102 : REPLY_MACRO (VL_API_BFD_UDP_ADD_REPLY);
71 : }
72 :
73 : static void
74 2 : vl_api_bfd_udp_upd_t_handler (vl_api_bfd_udp_add_t *mp)
75 : {
76 : vl_api_bfd_udp_upd_reply_t *rmp;
77 : int rv;
78 :
79 2 : VALIDATE_SW_IF_INDEX (mp);
80 :
81 2 : BFD_UDP_API_PARAM_COMMON_CODE;
82 :
83 2 : rv = bfd_udp_upd_session (
84 : BFD_UDP_API_PARAM_FROM_MP (mp), clib_net_to_host_u32 (mp->desired_min_tx),
85 2 : clib_net_to_host_u32 (mp->required_min_rx), mp->detect_mult,
86 2 : mp->is_authenticated, clib_net_to_host_u32 (mp->conf_key_id),
87 2 : mp->bfd_key_id);
88 :
89 2 : BAD_SW_IF_INDEX_LABEL;
90 2 : REPLY_MACRO2 (VL_API_BFD_UDP_UPD_REPLY,
91 : ({ rmp->stats_index = clib_host_to_net_u32 (0); }));
92 : }
93 :
94 : static void
95 17 : vl_api_bfd_udp_mod_t_handler (vl_api_bfd_udp_mod_t * mp)
96 : {
97 : vl_api_bfd_udp_mod_reply_t *rmp;
98 : int rv;
99 :
100 17 : VALIDATE_SW_IF_INDEX (mp);
101 :
102 17 : BFD_UDP_API_PARAM_COMMON_CODE;
103 :
104 17 : rv = bfd_udp_mod_session (BFD_UDP_API_PARAM_FROM_MP (mp),
105 : clib_net_to_host_u32 (mp->desired_min_tx),
106 : clib_net_to_host_u32 (mp->required_min_rx),
107 17 : mp->detect_mult);
108 :
109 17 : BAD_SW_IF_INDEX_LABEL;
110 17 : REPLY_MACRO (VL_API_BFD_UDP_MOD_REPLY);
111 : }
112 :
113 : static void
114 97 : vl_api_bfd_udp_del_t_handler (vl_api_bfd_udp_del_t * mp)
115 : {
116 : vl_api_bfd_udp_del_reply_t *rmp;
117 : int rv;
118 :
119 97 : VALIDATE_SW_IF_INDEX (mp);
120 :
121 97 : BFD_UDP_API_PARAM_COMMON_CODE;
122 :
123 97 : rv = bfd_udp_del_session (BFD_UDP_API_PARAM_FROM_MP (mp));
124 :
125 97 : BAD_SW_IF_INDEX_LABEL;
126 97 : REPLY_MACRO (VL_API_BFD_UDP_DEL_REPLY);
127 : }
128 :
129 : void
130 216 : send_bfd_udp_session_details (vl_api_registration_t * reg, u32 context,
131 : bfd_session_t * bs)
132 : {
133 216 : if (bs->transport != BFD_TRANSPORT_UDP4 &&
134 32 : bs->transport != BFD_TRANSPORT_UDP6)
135 : {
136 0 : return;
137 : }
138 :
139 216 : vl_api_bfd_udp_session_details_t *mp = vl_msg_api_alloc (sizeof (*mp));
140 216 : clib_memset (mp, 0, sizeof (*mp));
141 216 : mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_BFD_UDP_SESSION_DETAILS);
142 216 : mp->context = context;
143 216 : mp->state = clib_host_to_net_u32 (bs->local_state);
144 216 : bfd_udp_session_t *bus = &bs->udp;
145 216 : bfd_udp_key_t *key = &bus->key;
146 216 : mp->sw_if_index = clib_host_to_net_u32 (key->sw_if_index);
147 216 : if ((!bs->auth.is_delayed && bs->auth.curr_key) ||
148 158 : (bs->auth.is_delayed && bs->auth.next_key))
149 : {
150 60 : mp->is_authenticated = true;
151 : }
152 216 : if (bs->auth.is_delayed && bs->auth.next_key)
153 : {
154 2 : mp->bfd_key_id = bs->auth.next_bfd_key_id;
155 2 : mp->conf_key_id = clib_host_to_net_u32 (bs->auth.next_key->conf_key_id);
156 : }
157 214 : else if (!bs->auth.is_delayed && bs->auth.curr_key)
158 : {
159 58 : mp->bfd_key_id = bs->auth.curr_bfd_key_id;
160 58 : mp->conf_key_id = clib_host_to_net_u32 (bs->auth.curr_key->conf_key_id);
161 : }
162 216 : ip_address_encode (&key->local_addr, IP46_TYPE_ANY, &mp->local_addr);
163 216 : ip_address_encode (&key->peer_addr, IP46_TYPE_ANY, &mp->peer_addr);
164 :
165 216 : mp->required_min_rx =
166 216 : clib_host_to_net_u32 (bs->config_required_min_rx_usec);
167 216 : mp->desired_min_tx = clib_host_to_net_u32 (bs->config_desired_min_tx_usec);
168 216 : mp->detect_mult = bs->local_detect_mult;
169 216 : vl_api_send_msg (reg, (u8 *) mp);
170 : }
171 :
172 : void
173 111 : send_bfd_udp_session_event (vl_api_registration_t *reg, u32 pid,
174 : bfd_session_t *bs)
175 : {
176 111 : if (bs->transport != BFD_TRANSPORT_UDP4 &&
177 14 : bs->transport != BFD_TRANSPORT_UDP6)
178 : {
179 0 : return;
180 : }
181 :
182 111 : vl_api_bfd_udp_session_event_t *mp = vl_msg_api_alloc (sizeof (*mp));
183 111 : clib_memset (mp, 0, sizeof (*mp));
184 111 : mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_BFD_UDP_SESSION_EVENT);
185 111 : mp->pid = pid;
186 111 : mp->state = clib_host_to_net_u32 (bs->local_state);
187 111 : bfd_udp_session_t *bus = &bs->udp;
188 111 : bfd_udp_key_t *key = &bus->key;
189 111 : mp->sw_if_index = clib_host_to_net_u32 (key->sw_if_index);
190 111 : if ((!bs->auth.is_delayed && bs->auth.curr_key) ||
191 88 : (bs->auth.is_delayed && bs->auth.next_key))
192 : {
193 23 : mp->is_authenticated = true;
194 : }
195 111 : if (bs->auth.is_delayed && bs->auth.next_key)
196 : {
197 0 : mp->bfd_key_id = bs->auth.next_bfd_key_id;
198 0 : mp->conf_key_id = clib_host_to_net_u32 (bs->auth.next_key->conf_key_id);
199 : }
200 111 : else if (!bs->auth.is_delayed && bs->auth.curr_key)
201 : {
202 23 : mp->bfd_key_id = bs->auth.curr_bfd_key_id;
203 23 : mp->conf_key_id = clib_host_to_net_u32 (bs->auth.curr_key->conf_key_id);
204 : }
205 111 : ip_address_encode (&key->local_addr, IP46_TYPE_ANY, &mp->local_addr);
206 111 : ip_address_encode (&key->peer_addr, IP46_TYPE_ANY, &mp->peer_addr);
207 :
208 111 : mp->required_min_rx = clib_host_to_net_u32 (bs->config_required_min_rx_usec);
209 111 : mp->desired_min_tx = clib_host_to_net_u32 (bs->config_desired_min_tx_usec);
210 111 : mp->detect_mult = bs->local_detect_mult;
211 111 : vl_api_send_msg (reg, (u8 *) mp);
212 : }
213 :
214 : void
215 127 : bfd_event (bfd_main_t * bm, bfd_session_t * bs)
216 : {
217 127 : vpe_api_main_t *vam = &vpe_api_main;
218 : vpe_client_registration_t *reg;
219 : vl_api_registration_t *vl_reg;
220 : /* *INDENT-OFF* */
221 238 : pool_foreach (reg, vam->bfd_events_registrations) {
222 111 : vl_reg = vl_api_client_index_to_registration (reg->client_index);
223 111 : if (vl_reg)
224 : {
225 111 : switch (bs->transport)
226 : {
227 111 : case BFD_TRANSPORT_UDP4:
228 : /* fallthrough */
229 : case BFD_TRANSPORT_UDP6:
230 111 : send_bfd_udp_session_event (vl_reg, 0, bs);
231 : }
232 : }
233 : }
234 : /* *INDENT-ON* */
235 127 : }
236 :
237 : static void
238 314 : vl_api_bfd_udp_session_dump_t_handler (vl_api_bfd_udp_session_dump_t * mp)
239 : {
240 : vl_api_registration_t *reg;
241 :
242 314 : reg = vl_api_client_index_to_registration (mp->client_index);
243 314 : if (!reg)
244 0 : return;
245 :
246 314 : bfd_session_t *bs = NULL;
247 : /* *INDENT-OFF* */
248 530 : pool_foreach (bs, bfd_main.sessions) {
249 216 : if (bs->transport == BFD_TRANSPORT_UDP4 ||
250 32 : bs->transport == BFD_TRANSPORT_UDP6)
251 216 : send_bfd_udp_session_details (reg, mp->context, bs);
252 : }
253 : /* *INDENT-ON* */
254 : }
255 :
256 : static void
257 69 : vl_api_bfd_udp_session_set_flags_t_handler (vl_api_bfd_udp_session_set_flags_t
258 : * mp)
259 : {
260 : vl_api_bfd_udp_session_set_flags_reply_t *rmp;
261 : int rv;
262 :
263 69 : BFD_UDP_API_PARAM_COMMON_CODE;
264 :
265 69 : rv = bfd_udp_session_set_flags (vlib_get_main (),
266 : BFD_UDP_API_PARAM_FROM_MP (mp),
267 69 : clib_net_to_host_u32 (mp->flags) &
268 : IF_STATUS_API_FLAG_ADMIN_UP);
269 :
270 69 : REPLY_MACRO (VL_API_BFD_UDP_SESSION_SET_FLAGS_REPLY);
271 : }
272 :
273 : static void
274 49 : vl_api_bfd_auth_set_key_t_handler (vl_api_bfd_auth_set_key_t * mp)
275 : {
276 : vl_api_bfd_auth_set_key_reply_t *rmp;
277 49 : int rv = bfd_auth_set_key (clib_net_to_host_u32 (mp->conf_key_id),
278 49 : mp->auth_type, mp->key_len, mp->key);
279 :
280 49 : REPLY_MACRO (VL_API_BFD_AUTH_SET_KEY_REPLY);
281 : }
282 :
283 : static void
284 49 : vl_api_bfd_auth_del_key_t_handler (vl_api_bfd_auth_del_key_t * mp)
285 : {
286 : vl_api_bfd_auth_del_key_reply_t *rmp;
287 49 : int rv = bfd_auth_del_key (clib_net_to_host_u32 (mp->conf_key_id));
288 :
289 49 : REPLY_MACRO (VL_API_BFD_AUTH_DEL_KEY_REPLY);
290 : }
291 :
292 : static void
293 229 : vl_api_bfd_auth_keys_dump_t_handler (vl_api_bfd_auth_keys_dump_t * mp)
294 : {
295 : vl_api_registration_t *reg;
296 :
297 229 : reg = vl_api_client_index_to_registration (mp->client_index);
298 229 : if (!reg)
299 0 : return;
300 :
301 229 : bfd_auth_key_t *key = NULL;
302 229 : vl_api_bfd_auth_keys_details_t *rmp = NULL;
303 :
304 : /* *INDENT-OFF* */
305 923 : pool_foreach (key, bfd_main.auth_keys) {
306 694 : rmp = vl_msg_api_alloc (sizeof (*rmp));
307 694 : clib_memset (rmp, 0, sizeof (*rmp));
308 694 : rmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_BFD_AUTH_KEYS_DETAILS);
309 694 : rmp->context = mp->context;
310 694 : rmp->conf_key_id = clib_host_to_net_u32 (key->conf_key_id);
311 694 : rmp->auth_type = key->auth_type;
312 694 : rmp->use_count = clib_host_to_net_u32 (key->use_count);
313 694 : vl_api_send_msg (reg, (u8 *)rmp);
314 : }
315 : /* *INDENT-ON* */
316 : }
317 :
318 : static void
319 7 : vl_api_bfd_udp_auth_activate_t_handler (vl_api_bfd_udp_auth_activate_t * mp)
320 : {
321 : vl_api_bfd_udp_auth_activate_reply_t *rmp;
322 : int rv;
323 :
324 7 : VALIDATE_SW_IF_INDEX (mp);
325 :
326 7 : BFD_UDP_API_PARAM_COMMON_CODE;
327 :
328 7 : rv = bfd_udp_auth_activate (BFD_UDP_API_PARAM_FROM_MP (mp),
329 : clib_net_to_host_u32 (mp->conf_key_id),
330 7 : mp->bfd_key_id, mp->is_delayed);
331 :
332 7 : BAD_SW_IF_INDEX_LABEL;
333 7 : REPLY_MACRO (VL_API_BFD_UDP_AUTH_ACTIVATE_REPLY);
334 : }
335 :
336 : static void
337 3 : vl_api_bfd_udp_auth_deactivate_t_handler (vl_api_bfd_udp_auth_deactivate_t *
338 : mp)
339 : {
340 : vl_api_bfd_udp_auth_deactivate_reply_t *rmp;
341 : int rv;
342 :
343 3 : VALIDATE_SW_IF_INDEX (mp);
344 :
345 3 : BFD_UDP_API_PARAM_COMMON_CODE;
346 :
347 : rv =
348 3 : bfd_udp_auth_deactivate (BFD_UDP_API_PARAM_FROM_MP (mp), mp->is_delayed);
349 :
350 3 : BAD_SW_IF_INDEX_LABEL;
351 3 : REPLY_MACRO (VL_API_BFD_UDP_AUTH_DEACTIVATE_REPLY);
352 : }
353 :
354 : static void
355 14 : vl_api_bfd_udp_set_echo_source_t_handler (vl_api_bfd_udp_set_echo_source_t *
356 : mp)
357 : {
358 : vl_api_bfd_udp_set_echo_source_reply_t *rmp;
359 : int rv;
360 :
361 14 : VALIDATE_SW_IF_INDEX (mp);
362 :
363 14 : rv = bfd_udp_set_echo_source (clib_net_to_host_u32 (mp->sw_if_index));
364 :
365 14 : BAD_SW_IF_INDEX_LABEL;
366 14 : REPLY_MACRO (VL_API_BFD_UDP_SET_ECHO_SOURCE_REPLY);
367 : }
368 :
369 : static void
370 3 : vl_api_bfd_udp_del_echo_source_t_handler (vl_api_bfd_udp_del_echo_source_t *
371 : mp)
372 : {
373 : vl_api_bfd_udp_del_echo_source_reply_t *rmp;
374 : int rv;
375 :
376 3 : rv = bfd_udp_del_echo_source ();
377 :
378 3 : REPLY_MACRO (VL_API_BFD_UDP_DEL_ECHO_SOURCE_REPLY);
379 : }
380 :
381 : static void
382 5 : vl_api_bfd_udp_get_echo_source_t_handler (vl_api_bfd_udp_get_echo_source_t *
383 : mp)
384 : {
385 : vl_api_bfd_udp_get_echo_source_reply_t *rmp;
386 5 : int rv = 0;
387 : int is_set;
388 : u32 sw_if_index;
389 : int have_usable_ip4;
390 : ip4_address_t ip4;
391 : int have_usable_ip6;
392 : ip6_address_t ip6;
393 :
394 5 : bfd_udp_get_echo_source (&is_set, &sw_if_index, &have_usable_ip4, &ip4,
395 : &have_usable_ip6, &ip6);
396 :
397 : /* *INDENT-OFF* */
398 5 : REPLY_MACRO2 (VL_API_BFD_UDP_GET_ECHO_SOURCE_REPLY,
399 : ({
400 : rmp->sw_if_index = ntohl (sw_if_index);
401 : if (is_set)
402 : {
403 : rmp->is_set = true;
404 : rmp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
405 : if (have_usable_ip4)
406 : {
407 : rmp->have_usable_ip4 = true;
408 : ip4_address_encode(&ip4, rmp->ip4_addr);
409 : }
410 : else
411 : {
412 : rmp->have_usable_ip4 = false;
413 : }
414 : if (have_usable_ip6)
415 : {
416 : rmp->have_usable_ip6 = true;
417 : ip6_address_encode(&ip6, rmp->ip6_addr);
418 : }
419 : else
420 : {
421 : rmp->have_usable_ip6 = false;
422 : }
423 : }
424 : else
425 : {
426 : rmp->is_set = false;
427 : rmp->have_usable_ip4 = false;
428 : rmp->have_usable_ip6 = false;
429 : }
430 : }))
431 : /* *INDENT-ON* */
432 : }
433 :
434 : #include <vnet/bfd/bfd.api.c>
435 : static clib_error_t *
436 559 : bfd_api_hookup (vlib_main_t * vm)
437 : {
438 : /*
439 : * Set up the (msg_name, crc, message-id) table
440 : */
441 559 : REPLY_MSG_ID_BASE = setup_message_id_table ();
442 :
443 559 : return 0;
444 : }
445 :
446 6719 : VLIB_API_INIT_FUNCTION (bfd_api_hookup);
447 :
448 : /*
449 : * fd.io coding-style-patch-verification: ON
450 : *
451 : * Local Variables:
452 : * eval: (c-set-style "gnu")
453 : * End:
454 : */
|