From: Tobias Brunner Date: Thu, 10 Oct 2019 13:33:45 +0000 (+0200) Subject: vici: List additional information for deleted CHILD_SAs X-Git-Tag: 5.8.2dr2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08d0342ca60c417280144e962956baf9ab3163ca;p=thirdparty%2Fstrongswan.git vici: List additional information for deleted CHILD_SAs If a CHILD_SA is terminated, the updown event is triggered after the CHILD_SA is set to state CHILD_DELETED, so no usage stats or detail information like SPIs were reported. However, when an IKEv2 SA is terminated, the updown event for its children is triggered without changing the state first, that is, they usually remain in state INSTALLED and detailed data was reported in the event. IKEv1 CHILD_SAs are always terminated individually, i.e. with state change and no extra data so far. With this change usage stats are also returned for individually deleted CHILD_SAs as long as the SA has not yet expired. Fixes #3198. --- diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index 0b300a318c..81d692c84b 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -111,6 +111,9 @@ struct private_vici_query_t { time_t uptime; }; +/** + * Add the given mark/mask to the message using the provided labels + */ static void add_mark(vici_builder_t *b, mark_t mark, char *label, char *mask_label) { @@ -148,115 +151,143 @@ static void list_mode(vici_builder_t *b, child_sa_t *child, child_cfg_t *cfg) } /** - * List details of a CHILD_SA + * List IPsec-related details about a CHILD_SA */ -static void list_child(private_vici_query_t *this, vici_builder_t *b, - child_sa_t *child, time_t now) +static void list_child_ipsec(vici_builder_t *b, child_sa_t *child) { - time_t t; - uint64_t bytes, packets; - uint32_t if_id; - uint16_t alg, ks; proposal_t *proposal; - enumerator_t *enumerator; - traffic_selector_t *ts; + uint16_t alg, ks; + uint32_t if_id; - b->add_kv(b, "name", "%s", child->get_name(child)); - b->add_kv(b, "uniqueid", "%u", child->get_unique_id(child)); - b->add_kv(b, "reqid", "%u", child->get_reqid(child)); - b->add_kv(b, "state", "%N", child_sa_state_names, child->get_state(child)); - list_mode(b, child, NULL); - if (child->get_state(child) == CHILD_INSTALLED || - child->get_state(child) == CHILD_REKEYING || - child->get_state(child) == CHILD_REKEYED) + b->add_kv(b, "protocol", "%N", protocol_id_names, + child->get_protocol(child)); + if (child->has_encap(child)) { - b->add_kv(b, "protocol", "%N", protocol_id_names, - child->get_protocol(child)); - if (child->has_encap(child)) - { - b->add_kv(b, "encap", "yes"); - } - b->add_kv(b, "spi-in", "%.8x", ntohl(child->get_spi(child, TRUE))); - b->add_kv(b, "spi-out", "%.8x", ntohl(child->get_spi(child, FALSE))); + b->add_kv(b, "encap", "yes"); + } + b->add_kv(b, "spi-in", "%.8x", ntohl(child->get_spi(child, TRUE))); + b->add_kv(b, "spi-out", "%.8x", ntohl(child->get_spi(child, FALSE))); - if (child->get_ipcomp(child) != IPCOMP_NONE) - { - b->add_kv(b, "cpi-in", "%.4x", ntohs(child->get_cpi(child, TRUE))); - b->add_kv(b, "cpi-out", "%.4x", ntohs(child->get_cpi(child, FALSE))); - } - add_mark(b, child->get_mark(child, TRUE), "mark-in", "mark-mask-in"); - add_mark(b, child->get_mark(child, FALSE), "mark-out", "mark-mask-out"); - if_id = child->get_if_id(child, TRUE); - if (if_id) - { - b->add_kv(b, "if-id-in", "%.8x", if_id); - } - if_id = child->get_if_id(child, FALSE); - if (if_id) - { - b->add_kv(b, "if-id-out", "%.8x", if_id); - } - proposal = child->get_proposal(child); - if (proposal) + if (child->get_ipcomp(child) != IPCOMP_NONE) + { + b->add_kv(b, "cpi-in", "%.4x", ntohs(child->get_cpi(child, TRUE))); + b->add_kv(b, "cpi-out", "%.4x", ntohs(child->get_cpi(child, FALSE))); + } + add_mark(b, child->get_mark(child, TRUE), "mark-in", "mark-mask-in"); + add_mark(b, child->get_mark(child, FALSE), "mark-out", "mark-mask-out"); + + if_id = child->get_if_id(child, TRUE); + if (if_id) + { + b->add_kv(b, "if-id-in", "%.8x", if_id); + } + if_id = child->get_if_id(child, FALSE); + if (if_id) + { + b->add_kv(b, "if-id-out", "%.8x", if_id); + } + + proposal = child->get_proposal(child); + if (proposal) + { + if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, + &alg, &ks) && alg != ENCR_UNDEFINED) { - if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, - &alg, &ks) && alg != ENCR_UNDEFINED) - { - b->add_kv(b, "encr-alg", "%N", encryption_algorithm_names, alg); - if (ks) - { - b->add_kv(b, "encr-keysize", "%u", ks); - } - } - if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, - &alg, &ks) && alg != AUTH_UNDEFINED) - { - b->add_kv(b, "integ-alg", "%N", integrity_algorithm_names, alg); - if (ks) - { - b->add_kv(b, "integ-keysize", "%u", ks); - } - } - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, - &alg, NULL)) + b->add_kv(b, "encr-alg", "%N", encryption_algorithm_names, alg); + if (ks) { - b->add_kv(b, "dh-group", "%N", diffie_hellman_group_names, alg); + b->add_kv(b, "encr-keysize", "%u", ks); } - if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, - &alg, NULL) && alg == EXT_SEQ_NUMBERS) + } + if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, + &alg, &ks) && alg != AUTH_UNDEFINED) + { + b->add_kv(b, "integ-alg", "%N", integrity_algorithm_names, alg); + if (ks) { - b->add_kv(b, "esn", "1"); + b->add_kv(b, "integ-keysize", "%u", ks); } } - - child->get_usestats(child, TRUE, &t, &bytes, &packets); - b->add_kv(b, "bytes-in", "%" PRIu64, bytes); - b->add_kv(b, "packets-in", "%" PRIu64, packets); - if (t) + if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + &alg, NULL)) { - b->add_kv(b, "use-in", "%"PRIu64, (uint64_t)(now - t)); + b->add_kv(b, "dh-group", "%N", diffie_hellman_group_names, alg); } - - child->get_usestats(child, FALSE, &t, &bytes, &packets); - b->add_kv(b, "bytes-out", "%"PRIu64, bytes); - b->add_kv(b, "packets-out", "%"PRIu64, packets); - if (t) + if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, + &alg, NULL) && alg == EXT_SEQ_NUMBERS) { - b->add_kv(b, "use-out", "%"PRIu64, (uint64_t)(now - t)); + b->add_kv(b, "esn", "1"); } + } +} - t = child->get_lifetime(child, FALSE); - if (t) - { - b->add_kv(b, "rekey-time", "%"PRId64, (int64_t)(t - now)); - } - t = child->get_lifetime(child, TRUE); - if (t) - { - b->add_kv(b, "life-time", "%"PRId64, (int64_t)(t - now)); - } - t = child->get_installtime(child); - b->add_kv(b, "install-time", "%"PRId64, (int64_t)(now - t)); +/** + * List usage and lifetime stats of a CHILD_SA + */ +static void list_child_stats(vici_builder_t *b, child_sa_t *child, time_t now) +{ + uint64_t bytes, packets; + time_t t; + + child->get_usestats(child, TRUE, &t, &bytes, &packets); + b->add_kv(b, "bytes-in", "%" PRIu64, bytes); + b->add_kv(b, "packets-in", "%" PRIu64, packets); + if (t) + { + b->add_kv(b, "use-in", "%"PRIu64, (uint64_t)(now - t)); + } + + child->get_usestats(child, FALSE, &t, &bytes, &packets); + b->add_kv(b, "bytes-out", "%"PRIu64, bytes); + b->add_kv(b, "packets-out", "%"PRIu64, packets); + if (t) + { + b->add_kv(b, "use-out", "%"PRIu64, (uint64_t)(now - t)); + } + + t = child->get_lifetime(child, FALSE); + if (t) + { + b->add_kv(b, "rekey-time", "%"PRId64, (int64_t)(t - now)); + } + t = child->get_lifetime(child, TRUE); + if (t) + { + b->add_kv(b, "life-time", "%"PRId64, (int64_t)(t - now)); + } + t = child->get_installtime(child); + b->add_kv(b, "install-time", "%"PRId64, (int64_t)(now - t)); +} + +/** + * List details of a CHILD_SA + */ +static void list_child(private_vici_query_t *this, vici_builder_t *b, + child_sa_t *child, time_t now) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + child_sa_state_t state; + + b->add_kv(b, "name", "%s", child->get_name(child)); + b->add_kv(b, "uniqueid", "%u", child->get_unique_id(child)); + b->add_kv(b, "reqid", "%u", child->get_reqid(child)); + state = child->get_state(child); + b->add_kv(b, "state", "%N", child_sa_state_names, state); + list_mode(b, child, NULL); + + switch (state) + { + case CHILD_INSTALLED: + case CHILD_REKEYING: + case CHILD_REKEYED: + case CHILD_DELETING: + case CHILD_DELETED: + list_child_ipsec(b, child); + list_child_stats(b, child, now); + break; + default: + break; } b->begin_list(b, "local-ts");