diff options
| author | Christian Hopps <chopps@labn.net> | 2024-02-24 05:48:40 -0500 |
|---|---|---|
| committer | Christian Hopps <chopps@labn.net> | 2024-03-04 20:00:15 -0500 |
| commit | 4caffbda8e6c690dc185b3740b203c2fa54e465e (patch) | |
| tree | 860987d6b4ef824ebc626f412dfcb3b20c72789d /lib/keychain_nb.c | |
| parent | 29dba445b4e6d762e80e1bd015a70cb362a7906e (diff) | |
lib: add keychain northbound support
Signed-off-by: Christian Hopps <chopps@labn.net>
Diffstat (limited to 'lib/keychain_nb.c')
| -rw-r--r-- | lib/keychain_nb.c | 1153 |
1 files changed, 489 insertions, 664 deletions
diff --git a/lib/keychain_nb.c b/lib/keychain_nb.c index 1a2853a905..6838268a93 100644 --- a/lib/keychain_nb.c +++ b/lib/keychain_nb.c @@ -1,92 +1,165 @@ // SPDX-License-Identifier: GPL-2.0-or-later +/* + * February 22 2024, Christian Hopps <chopps@labn.net> + * + * Copyright (C) 2024 LabN Consulting, L.L.C. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> +#include "lib_errors.h" +#include "northbound.h" +#include "keychain.h" + +static void keychain_touch(struct keychain *keychain) +{ + keychain->last_touch = time(NULL); +} /* * XPath: /ietf-key-chain:key-chains/key-chain */ static int key_chains_key_chain_create(struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + const char *name; + struct keychain *keychain; - return NB_OK; -} + if (args->event != NB_EV_APPLY) + return NB_OK; -static void key_chains_key_chain_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + name = yang_dnode_get_string(args->dnode, "name"); + keychain = keychain_get(name); + keychain_touch(keychain); + return NB_OK; } static int key_chains_key_chain_destroy(struct nb_cb_destroy_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + const char *name; + + if (args->event != NB_EV_APPLY) + return NB_OK; + name = yang_dnode_get_string(args->dnode, "name"); + keychain_delete(keychain_lookup(name)); return NB_OK; } static const void *key_chains_key_chain_get_next(struct nb_cb_get_next_args *args) { - /* TODO: implement me. */ - return NULL; + const struct listnode *prev = args->list_entry; + + return prev ? prev->next : keychain_list->head; } static int key_chains_key_chain_get_keys(struct nb_cb_get_keys_args *args) { - /* TODO: implement me. */ + const struct listnode *node = args->list_entry; + const struct keychain *keychain = node->data; + + args->keys->num = 1; + strlcpy(args->keys->key[0], keychain->name, sizeof(args->keys->key[0])); return NB_OK; } static const void *key_chains_key_chain_lookup_entry(struct nb_cb_lookup_entry_args *args) { - /* TODO: implement me. */ + const char *name = args->keys->key[0]; + struct keychain *keychain; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(keychain_list, node, keychain)) { + if (strcmp(keychain->name, name) == 0) + return node; + } return NULL; } + +static int __destroy_nop(struct nb_cb_destroy_args *args) +{ + /* modified by sibling or cleaned up by container destroy */ + return NB_OK; +} + +static struct key *__dnode_get_key2(const struct lyd_node *dnode, bool touch) +{ + struct keychain *keychain; + const char *name; + struct key *key; + uint32_t index; + + name = yang_dnode_get_string(dnode, "../../../name"); + keychain = keychain_lookup(name); + index = (uint32_t)yang_dnode_get_uint64(dnode, "../../key-id"); + key = key_lookup(keychain, index); + if (touch) + keychain_touch(keychain); + return key; +} + +static struct key *__dnode_get_key3(const struct lyd_node *dnode, bool touch) +{ + struct keychain *keychain; + const char *name; + struct key *key; + uint32_t index; + + name = yang_dnode_get_string(dnode, "../../../../name"); + keychain = keychain_lookup(name); + index = (uint32_t)yang_dnode_get_uint64(dnode, "../../../key-id"); + key = key_lookup(keychain, index); + if (touch) + keychain_touch(keychain); + return key; +} + /* * XPath: /ietf-key-chain:key-chains/key-chain/description */ static int key_chains_key_chain_description_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + struct keychain *keychain; + const char *name; - return NB_OK; -} + if (args->event != NB_EV_APPLY) + return NB_OK; -static void key_chains_key_chain_description_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + name = yang_dnode_get_string(args->dnode, "../name"); + keychain = keychain_lookup(name); + XFREE(MTYPE_KEYCHAIN_DESC, keychain->desc); + keychain->desc = XSTRDUP(MTYPE_KEYCHAIN_DESC, + yang_dnode_get_string(args->dnode, NULL)); + + keychain_touch(keychain); + return NB_OK; } static int key_chains_key_chain_description_destroy(struct nb_cb_destroy_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + struct keychain *keychain; + const char *name; + + if (args->event != NB_EV_APPLY) + return NB_OK; + name = yang_dnode_get_string(args->dnode, "../name"); + keychain = keychain_lookup(name); + XFREE(MTYPE_KEYCHAIN_DESC, keychain->desc); + + keychain_touch(keychain); return NB_OK; } @@ -95,8 +168,11 @@ static int key_chains_key_chain_description_destroy(struct nb_cb_destroy_args *a */ static struct yang_data *key_chains_key_chain_last_modified_timestamp_get_elem(struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + const struct listnode *kcnode = args->list_entry; + const struct keychain *keychain = kcnode->data; + + return yang_data_new_date_and_time(args->xpath, keychain->last_touch, + false); } /* @@ -104,269 +180,271 @@ static struct yang_data *key_chains_key_chain_last_modified_timestamp_get_elem(s */ static int key_chains_key_chain_key_create(struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; + struct keychain *keychain; + struct key *key; + const char *name; + uint64_t keyid; + + if (args->event != NB_EV_VALIDATE && args->event != NB_EV_APPLY) + return NB_OK; + + keyid = yang_dnode_get_uint64(args->dnode, "key-id"); + if (args->event == NB_EV_VALIDATE) { + if (keyid > UINT32_MAX) { + /* Warn most protocols can't use this value */ + flog_err(EC_LIB_NB_CB_CONFIG_VALIDATE, + "Protocols do not accept > 32-bit key-id values"); + return NB_EV_VALIDATE; + } + return NB_OK; } + if (args->event != NB_EV_APPLY) + return NB_OK; - return NB_OK; -} + name = yang_dnode_get_string(args->dnode, "../name"); + keychain = keychain_lookup(name); + assert(keyid <= UINT32_MAX); + key = key_get(keychain, (uint32_t)keyid); + assert(key); -static void key_chains_key_chain_key_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + keychain_touch(keychain); + return NB_OK; } static int key_chains_key_chain_key_destroy(struct nb_cb_destroy_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + struct keychain *keychain; + struct key *key; + const char *name; + uint64_t keyid; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + keyid = yang_dnode_get_uint64(args->dnode, "key-id"); + if (keyid > UINT32_MAX) + return NB_ERR_NOT_FOUND; + name = yang_dnode_get_string(args->dnode, "../name"); + keychain = keychain_lookup(name); + key = key_lookup(keychain, (uint32_t)keyid); + key_delete(keychain, key); + keychain_touch(keychain); return NB_OK; } static const void *key_chains_key_chain_key_get_next(struct nb_cb_get_next_args *args) { - /* TODO: implement me. */ - return NULL; + const struct listnode *kcnode = args->parent_list_entry; + const struct keychain *keychain = kcnode->data; + const struct listnode *prev = args->list_entry; + + return prev ? prev->next : keychain->key->head; } static int key_chains_key_chain_key_get_keys(struct nb_cb_get_keys_args *args) { - /* TODO: implement me. */ + const struct listnode *node = args->list_entry; + const struct key *key = node->data; + + args->keys->num = 1; + snprintf(args->keys->key[0], sizeof(args->keys->key[0]), "%" PRIu32, + key->index); + return NB_OK; } static const void *key_chains_key_chain_key_lookup_entry(struct nb_cb_lookup_entry_args *args) { - /* TODO: implement me. */ + const struct listnode *kcnode = args->parent_list_entry; + const struct keychain *keychain = kcnode->data; + struct listnode *node; + struct key *key; + uint32_t index; + + index = strtoul(args->keys->key[0], NULL, 0); + for (ALL_LIST_ELEMENTS_RO(keychain->key, node, key)) + if (key->index == index) + return node; return NULL; } -/* - * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/always - */ -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_always_create(struct nb_cb_create_args *args) +static int __lifetime_create(struct nb_cb_create_args *args, bool send, + bool accept, bool always) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + struct key *key; + + if (args->event != NB_EV_APPLY) + return NB_OK; + if (always) + key = __dnode_get_key3(args->dnode, true); + else + key = __dnode_get_key2(args->dnode, true); + if (send) { + key->send.start = 0; + key->send.end = -1; + key->send.duration = 0; + } + if (accept) { + key->accept.start = 0; + key->accept.end = -1; + key->accept.duration = 0; + } return NB_OK; } -static void key_chains_key_chain_key_lifetime_send_accept_lifetime_always_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +static int __lifetime_start_date_time_modify(struct nb_cb_modify_args *args, + bool send, bool accept) { - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} + struct key *key; + time_t time; -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_always_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + if (args->event != NB_EV_APPLY) + return NB_OK; - return NB_OK; -} + key = __dnode_get_key3(args->dnode, true); + time = yang_dnode_get_date_and_time(args->dnode, NULL); -/* - * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/start-date-time - */ -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_modify(struct nb_cb_modify_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + if (send) + key->send.start = time; + if (accept) + key->accept.start = time; return NB_OK; } -static void key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +static int __lifetime_no_end_time_create(struct nb_cb_create_args *args, + bool send, bool accept) { - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} + struct key *key; -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + key = __dnode_get_key3(args->dnode, true); + if (send) + key->send.end = -1; + if (accept) + key->accept.end = -1; return NB_OK; } -/* - * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/no-end-time - */ -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_create(struct nb_cb_create_args *args) +static int __lifetime_duration_modify(struct nb_cb_modify_args *args, bool send, + bool accept) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + struct key *key; + uint32_t duration; + time_t time; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + key = __dnode_get_key3(args->dnode, true); + time = yang_dnode_get_date_and_time(args->dnode, "../start-date-time"); + duration = yang_dnode_get_uint32(args->dnode, NULL); + if (send) + key->send.end = time + duration; + if (accept) + key->accept.end = time + duration; return NB_OK; } -static void key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +static int __lifetime_end_date_time_modify(struct nb_cb_modify_args *args, + bool send, bool accept) { - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} + struct key *key; + time_t time; -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + if (args->event != NB_EV_APPLY) + return NB_OK; + key = __dnode_get_key3(args->dnode, true); + time = yang_dnode_get_date_and_time(args->dnode, NULL); + + if (send) + key->send.end = time; + if (accept) + key->accept.end = time; return NB_OK; } /* - * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/duration + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime */ -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_modify(struct nb_cb_modify_args *args) +static int key_chains_key_chain_key_lifetime_send_accept_lifetime_create( + struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - return NB_OK; + return __lifetime_create(args, true, true, false); } -static void key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +/* + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/always + */ +static int key_chains_key_chain_key_lifetime_send_accept_lifetime_always_create( + struct nb_cb_create_args *args) { - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + return __lifetime_create(args, true, true, true); } -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_destroy(struct nb_cb_destroy_args *args) +/* + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/start-date-time + */ +static int +key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_modify( + struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_start_date_time_modify(args, true, true); } /* - * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/end-date-time + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/no-end-time */ -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_modify(struct nb_cb_modify_args *args) +static int +key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_create( + struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_no_end_time_create(args, true, true); } -static void key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +/* + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/duration + */ +static int key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_modify( + struct nb_cb_modify_args *args) { - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + return __lifetime_duration_modify(args, true, true); } -static int key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_destroy(struct nb_cb_destroy_args *args) +/* + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/end-date-time + */ +static int +key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_modify( + struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_end_date_time_modify(args, true, true); } /* - * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/always + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime */ -static int key_chains_key_chain_key_lifetime_send_lifetime_always_create(struct nb_cb_create_args *args) +static int key_chains_key_chain_key_lifetime_send_lifetime_create( + struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} -static void key_chains_key_chain_key_lifetime_send_lifetime_always_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + return __lifetime_create(args, true, false, false); } -static int key_chains_key_chain_key_lifetime_send_lifetime_always_destroy(struct nb_cb_destroy_args *args) +/* + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/always + */ +static int key_chains_key_chain_key_lifetime_send_lifetime_always_create( + struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_create(args, true, false, true); } /* @@ -374,35 +452,7 @@ static int key_chains_key_chain_key_lifetime_send_lifetime_always_destroy(struct */ static int key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_start_date_time_modify(args, true, false); } /* @@ -410,35 +460,7 @@ static int key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_destr */ static int key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_create(struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_no_end_time_create(args, true, false); } /* @@ -446,35 +468,7 @@ static int key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_destroy(s */ static int key_chains_key_chain_key_lifetime_send_lifetime_duration_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_send_lifetime_duration_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_send_lifetime_duration_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_duration_modify(args, true, false); } /* @@ -482,35 +476,17 @@ static int key_chains_key_chain_key_lifetime_send_lifetime_duration_destroy(stru */ static int key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_end_date_time_modify(args, true, false); } -static void key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_destroy(struct nb_cb_destroy_args *args) +/* + * XPath: /ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime + */ +static int key_chains_key_chain_key_lifetime_accept_lifetime_create( + struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - return NB_OK; + return __lifetime_create(args, false, true, false); } /* @@ -518,35 +494,7 @@ static int key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_destroy */ static int key_chains_key_chain_key_lifetime_accept_lifetime_always_create(struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_accept_lifetime_always_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_accept_lifetime_always_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_create(args, false, true, true); } /* @@ -554,35 +502,7 @@ static int key_chains_key_chain_key_lifetime_accept_lifetime_always_destroy(stru */ static int key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_start_date_time_modify(args, false, true); } /* @@ -590,35 +510,7 @@ static int key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_des */ static int key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_create(struct nb_cb_create_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_no_end_time_create(args, false, true); } /* @@ -626,35 +518,7 @@ static int key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_destroy */ static int key_chains_key_chain_key_lifetime_accept_lifetime_duration_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_accept_lifetime_duration_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_accept_lifetime_duration_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_duration_modify(args, false, true); } /* @@ -662,35 +526,7 @@ static int key_chains_key_chain_key_lifetime_accept_lifetime_duration_destroy(st */ static int key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; -} - -static void key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ -} - -static int key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_destroy(struct nb_cb_destroy_args *args) -{ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_OK; + return __lifetime_end_date_time_modify(args, false, true); } /* @@ -698,21 +534,67 @@ static int key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_destr */ static int key_chains_key_chain_key_crypto_algorithm_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; + static const char prefix[] = "ietf-key-chain:"; + static const int prefix_len = sizeof(prefix) - 1; + struct keychain *keychain; + const char *name; + struct key *key; + uint32_t index; + uint8_t hash_algo; + + if (args->event != NB_EV_VALIDATE && args->event != NB_EV_APPLY) + return NB_OK; + + name = yang_dnode_get_string(args->dnode, "../../name"); + keychain = keychain_lookup(name); + index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../key-id"); + key = key_lookup(keychain, index); + name = yang_dnode_get_string(args->dnode, NULL); + if (!strncmp(name, prefix, prefix_len)) + name += prefix_len; + hash_algo = keychain_get_algo_id_by_name(name); + + if (args->event == NB_EV_VALIDATE) { + if (!hash_algo) { + zlog_err("\"%s\" hash algo not supported", name); + return NB_ERR_VALIDATION; + } +#ifndef CRYPTO_OPENSSL + if (hash_algo == KEYCHAIN_ALGO_NULL) { + zlog_err("\"%s\" algo not supported, compile with --with-crypto=openssl", + name); + return NB_ERR_VALIDATION; + } +#endif /* CRYPTO_OPENSSL */ + return NB_OK; } + assert(args->event == NB_EV_APPLY); + key->hash_algo = hash_algo; + + keychain_touch(keychain); return NB_OK; } -static void key_chains_key_chain_key_crypto_algorithm_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) +static int key_chains_key_chain_key_crypto_algorithm_destroy( + struct nb_cb_destroy_args *args) { - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + struct keychain *keychain; + const char *name; + struct key *key; + uint32_t index; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + name = yang_dnode_get_string(args->dnode, "../../../name"); + keychain = keychain_lookup(name); + index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../../key-id"); + key = key_lookup(keychain, index); + key->hash_algo = KEYCHAIN_ALGO_NULL; + keychain_touch(keychain); + + return NB_OK; } /* @@ -720,33 +602,48 @@ static void key_chains_key_chain_key_crypto_algorithm_cli_write(struct vty *vty, */ static int key_chains_key_chain_key_key_string_keystring_modify(struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + struct keychain *keychain; + const char *name; + struct key *key; + uint32_t index; - return NB_OK; -} + if (args->event != NB_EV_APPLY) + return NB_OK; -static void key_chains_key_chain_key_key_string_keystring_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults) -{ - /* TODO: this cli callback is optional; the cli output may not need to be done at each node. */ + name = yang_dnode_get_string(args->dnode, "../../../name"); + keychain = keychain_lookup(name); + index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../../key-id"); + key = key_lookup(keychain, index); + assert(key); + + + if (key->string) + XFREE(MTYPE_KEY, key->string); + key->string = XSTRDUP(MTYPE_KEY, + yang_dnode_get_string(args->dnode, NULL)); + + keychain_touch(keychain); + return NB_OK; } static int key_chains_key_chain_key_key_string_keystring_destroy(struct nb_cb_destroy_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } + struct keychain *keychain; + const char *name; + struct key *key; + uint32_t index; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + name = yang_dnode_get_string(args->dnode, "../../../name"); + keychain = keychain_lookup(name); + index = (uint32_t)yang_dnode_get_uint64(args->dnode, "../../key-id"); + key = key_lookup(keychain, index); + assert(key); + + XFREE(MTYPE_KEY, key->string); + keychain_touch(keychain); return NB_OK; } @@ -756,8 +653,18 @@ static int key_chains_key_chain_key_key_string_keystring_destroy(struct nb_cb_de */ static struct yang_data *key_chains_key_chain_key_send_lifetime_active_get_elem(struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + const struct listnode *node = args->list_entry; + const struct key *key = node->data; + time_t now = time(NULL); + bool active = false; + + if (key->send.start == 0) + active = true; + else if (key->send.start <= now) + if (key->send.end >= now || key->send.end == -1) + active = true; + + return yang_data_new_bool(args->xpath, active); } /* @@ -765,13 +672,29 @@ static struct yang_data *key_chains_key_chain_key_send_lifetime_active_get_elem( */ static struct yang_data *key_chains_key_chain_key_accept_lifetime_active_get_elem(struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + const struct listnode *node = args->list_entry; + const struct key *key = node->data; + time_t now = time(NULL); + bool active = false; + + if (key->accept.start == 0) + active = true; + else if (key->accept.start <= now) + if (key->accept.end >= now || key->accept.end == -1) + active = true; + + return yang_data_new_bool(args->xpath, active); } +static const char * const keychain_features[] = { + "independent-send-accept-lifetime", + NULL, +}; + /* clang-format off */ -const struct frr_yang_module_info ietf_key_chain_nb_info = { +const struct frr_yang_module_info ietf_key_chain_info = { .name = "ietf-key-chain", + .features = (const char **)keychain_features, .nodes = { { .xpath = "/ietf-key-chain:key-chains/key-chain", @@ -781,6 +704,8 @@ const struct frr_yang_module_info ietf_key_chain_nb_info = { .get_next = key_chains_key_chain_get_next, .get_keys = key_chains_key_chain_get_keys, .lookup_entry = key_chains_key_chain_lookup_entry, + .cli_show = key_chains_key_chain_cli_write, + .cli_show_end = key_chains_key_chain_cli_write_end, } }, { @@ -788,6 +713,7 @@ const struct frr_yang_module_info ietf_key_chain_nb_info = { .cbs = { .modify = key_chains_key_chain_description_modify, .destroy = key_chains_key_chain_description_destroy, + .cli_show = key_chains_key_chain_description_cli_write, } }, { @@ -804,117 +730,145 @@ const struct frr_yang_module_info ietf_key_chain_nb_info = { .get_next = key_chains_key_chain_key_get_next, .get_keys = key_chains_key_chain_key_get_keys, .lookup_entry = key_chains_key_chain_key_lookup_entry, + .cli_show = key_chains_key_chain_key_cli_write, + .cli_show_end = key_chains_key_chain_key_cli_write_end, + } + }, + { + .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime", + .cbs = { + .create = key_chains_key_chain_key_lifetime_send_accept_lifetime_create, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/always", .cbs = { .create = key_chains_key_chain_key_lifetime_send_accept_lifetime_always_create, - .destroy = key_chains_key_chain_key_lifetime_send_accept_lifetime_always_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/start-date-time", .cbs = { .modify = key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_modify, - .destroy = key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_destroy, + .destroy = __destroy_nop, + .cli_show = key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_cli_write, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/no-end-time", .cbs = { .create = key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_create, - .destroy = key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/duration", .cbs = { .modify = key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_modify, - .destroy = key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/end-date-time", .cbs = { .modify = key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_modify, - .destroy = key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_destroy, + .destroy = __destroy_nop, + } + }, + { + .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime", + .cbs = { + .create = key_chains_key_chain_key_lifetime_send_lifetime_create, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/always", .cbs = { .create = key_chains_key_chain_key_lifetime_send_lifetime_always_create, - .destroy = key_chains_key_chain_key_lifetime_send_lifetime_always_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/start-date-time", .cbs = { .modify = key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_modify, - .destroy = key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_destroy, + .destroy = __destroy_nop, + .cli_show = key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_cli_write, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/no-end-time", .cbs = { .create = key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_create, - .destroy = key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/duration", .cbs = { .modify = key_chains_key_chain_key_lifetime_send_lifetime_duration_modify, - .destroy = key_chains_key_chain_key_lifetime_send_lifetime_duration_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/end-date-time", .cbs = { .modify = key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_modify, - .destroy = key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_destroy, + .destroy = __destroy_nop, + } + }, + { + .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime", + .cbs = { + .create = key_chains_key_chain_key_lifetime_accept_lifetime_create, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/always", .cbs = { .create = key_chains_key_chain_key_lifetime_accept_lifetime_always_create, - .destroy = key_chains_key_chain_key_lifetime_accept_lifetime_always_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/start-date-time", .cbs = { .modify = key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_modify, - .destroy = key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_destroy, + .destroy = __destroy_nop, + .cli_show = key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_cli_write, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/no-end-time", .cbs = { .create = key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_create, - .destroy = key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/duration", .cbs = { .modify = key_chains_key_chain_key_lifetime_accept_lifetime_duration_modify, - .destroy = key_chains_key_chain_key_lifetime_accept_lifetime_duration_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/end-date-time", .cbs = { .modify = key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_modify, - .destroy = key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_destroy, + .destroy = __destroy_nop, } }, { .xpath = "/ietf-key-chain:key-chains/key-chain/key/crypto-algorithm", .cbs = { .modify = key_chains_key_chain_key_crypto_algorithm_modify, + .destroy = key_chains_key_chain_key_crypto_algorithm_destroy, + .cli_show = key_chains_key_chain_key_crypto_algorithm_cli_write, } }, { @@ -922,6 +876,7 @@ const struct frr_yang_module_info ietf_key_chain_nb_info = { .cbs = { .modify = key_chains_key_chain_key_key_string_keystring_modify, .destroy = key_chains_key_chain_key_key_string_keystring_destroy, + .cli_show = key_chains_key_chain_key_key_string_keystring_cli_write, } }, { @@ -939,135 +894,5 @@ const struct frr_yang_module_info ietf_key_chain_nb_info = { { .xpath = NULL, }, - } -}; - -/* clang-format off */ -const struct frr_yang_module_info ietf_key_chain_cli_info = { - .name = "ietf-key-chain", - .nodes = { - { - .xpath = "/ietf-key-chain:key-chains/key-chain", - .cbs = { - .cli_show = key_chains_key_chain_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/description", - .cbs = { - .cli_show = key_chains_key_chain_description_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key", - .cbs = { - .cli_show = key_chains_key_chain_key_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/always", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_accept_lifetime_always_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/start-date-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_accept_lifetime_start_date_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/no-end-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_accept_lifetime_no_end_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/duration", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_accept_lifetime_duration_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-accept-lifetime/end-date-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_accept_lifetime_end_date_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/always", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_lifetime_always_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/start-date-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_lifetime_start_date_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/no-end-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_lifetime_no_end_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/duration", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_lifetime_duration_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/send-lifetime/end-date-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_send_lifetime_end_date_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/always", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_accept_lifetime_always_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/start-date-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_accept_lifetime_start_date_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/no-end-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_accept_lifetime_no_end_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/duration", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_accept_lifetime_duration_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/lifetime/accept-lifetime/end-date-time", - .cbs = { - .cli_show = key_chains_key_chain_key_lifetime_accept_lifetime_end_date_time_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/crypto-algorithm", - .cbs = { - .cli_show = key_chains_key_chain_key_crypto_algorithm_cli_write, - } - }, - { - .xpath = "/ietf-key-chain:key-chains/key-chain/key/key-string/keystring", - .cbs = { - .cli_show = key_chains_key_chain_key_key_string_keystring_cli_write, - } - }, - { - .xpath = NULL, - }, - } + }, }; |
