+vnet_api_error_t
+bfd_auth_set_key (u32 conf_key_id, u8 auth_type, u8 key_len,
+ const u8 * key_data)
+{
+ bfd_main_t *bm = &bfd_main;
+#if WITH_LIBSSL > 0
+ bfd_auth_key_t *auth_key = NULL;
+ if (!key_len || key_len > bfd_max_key_len_for_auth_type (auth_type))
+ {
+ vlib_log_err (bm->log_class,
+ "invalid authentication key length for auth_type=%d:%s "
+ "(key_len=%u, must be non-zero, expected max=%u)",
+ auth_type, bfd_auth_type_str (auth_type), key_len,
+ (u32) bfd_max_key_len_for_auth_type (auth_type));
+ return VNET_API_ERROR_INVALID_VALUE;
+ }
+ if (!bfd_auth_type_supported (auth_type))
+ {
+ vlib_log_err (bm->log_class, "unsupported auth type=%d:%s", auth_type,
+ bfd_auth_type_str (auth_type));
+ return VNET_API_ERROR_BFD_NOTSUPP;
+ }
+ uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
+ if (key_idx_p)
+ {
+ /* modifying existing key - must not be used */
+ const uword key_idx = *key_idx_p;
+ auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
+ if (auth_key->use_count > 0)
+ {
+ vlib_log_err (bm->log_class,
+ "authentication key with conf ID %u in use by %u BFD "
+ "session(s) - cannot modify", conf_key_id,
+ auth_key->use_count);
+ return VNET_API_ERROR_BFD_EINUSE;
+ }
+ }
+ else
+ {
+ /* adding new key */
+ pool_get (bm->auth_keys, auth_key);
+ auth_key->conf_key_id = conf_key_id;
+ hash_set (bm->auth_key_by_conf_key_id, conf_key_id,
+ auth_key - bm->auth_keys);
+ }
+ auth_key->auth_type = auth_type;
+ clib_memset (auth_key->key, 0, sizeof (auth_key->key));
+ clib_memcpy (auth_key->key, key_data, key_len);
+ return 0;
+#else
+ vlib_log_err (bm->log_class,
+ "SSL missing, cannot manipulate authentication keys");
+ return VNET_API_ERROR_BFD_NOTSUPP;
+#endif
+}
+
+vnet_api_error_t
+bfd_auth_del_key (u32 conf_key_id)
+{
+#if WITH_LIBSSL > 0
+ bfd_auth_key_t *auth_key = NULL;
+ bfd_main_t *bm = &bfd_main;
+ uword *key_idx_p = hash_get (bm->auth_key_by_conf_key_id, conf_key_id);
+ if (key_idx_p)
+ {
+ /* deleting existing key - must not be used */
+ const uword key_idx = *key_idx_p;
+ auth_key = pool_elt_at_index (bm->auth_keys, key_idx);
+ if (auth_key->use_count > 0)
+ {
+ vlib_log_err (bm->log_class,
+ "authentication key with conf ID %u in use by %u BFD "
+ "session(s) - cannot delete", conf_key_id,
+ auth_key->use_count);
+ return VNET_API_ERROR_BFD_EINUSE;
+ }
+ hash_unset (bm->auth_key_by_conf_key_id, conf_key_id);
+ clib_memset (auth_key, 0, sizeof (*auth_key));
+ pool_put (bm->auth_keys, auth_key);
+ }
+ else
+ {
+ /* no such key */
+ vlib_log_err (bm->log_class,
+ "authentication key with conf ID %u does not exist",
+ conf_key_id);
+ return VNET_API_ERROR_BFD_ENOENT;
+ }
+ return 0;
+#else
+ vlib_log_err (bm->log_class,
+ "SSL missing, cannot manipulate authentication keys");
+ return VNET_API_ERROR_BFD_NOTSUPP;
+#endif
+}
+