mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 10:01:39 -05:00
psp: report basic stats from the core
Track and report stats common to all psp devices from the core. A 'stale-event' is when the core marks the rx state of an active psp_assoc as incapable of authenticating psp encapsulated data. Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com> Link: https://patch.msgid.link/20251106002608.1578518-2-daniel.zahka@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -76,6 +76,28 @@ attribute-sets:
|
||||
name: spi
|
||||
doc: Security Parameters Index (SPI) of the association.
|
||||
type: u32
|
||||
-
|
||||
name: stats
|
||||
attributes:
|
||||
-
|
||||
name: dev-id
|
||||
doc: PSP device ID.
|
||||
type: u32
|
||||
checks:
|
||||
min: 1
|
||||
-
|
||||
name: key-rotations
|
||||
type: uint
|
||||
doc: |
|
||||
Number of key rotations during the lifetime of the device.
|
||||
Kernel statistic.
|
||||
-
|
||||
name: stale-events
|
||||
type: uint
|
||||
doc: |
|
||||
Number of times a socket's Rx got shut down due to using
|
||||
a key which went stale (fully rotated out).
|
||||
Kernel statistic.
|
||||
|
||||
operations:
|
||||
list:
|
||||
@@ -177,6 +199,24 @@ operations:
|
||||
pre: psp-assoc-device-get-locked
|
||||
post: psp-device-unlock
|
||||
|
||||
-
|
||||
name: get-stats
|
||||
doc: Get device statistics.
|
||||
attribute-set: stats
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- dev-id
|
||||
reply: &stats-all
|
||||
attributes:
|
||||
- dev-id
|
||||
- key-rotations
|
||||
- stale-events
|
||||
pre: psp-device-get-locked
|
||||
post: psp-device-unlock
|
||||
dump:
|
||||
reply: *stats-all
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
-
|
||||
|
||||
@@ -59,6 +59,10 @@ struct psp_dev_config {
|
||||
* device key
|
||||
* @stale_assocs: associations which use a rotated out key
|
||||
*
|
||||
* @stats: statistics maintained by the core
|
||||
* @stats.rotations: See stats attr key-rotations
|
||||
* @stats.stales: See stats attr stale-events
|
||||
*
|
||||
* @rcu: RCU head for freeing the structure
|
||||
*/
|
||||
struct psp_dev {
|
||||
@@ -81,6 +85,11 @@ struct psp_dev {
|
||||
struct list_head prev_assocs;
|
||||
struct list_head stale_assocs;
|
||||
|
||||
struct {
|
||||
unsigned long rotations;
|
||||
unsigned long stales;
|
||||
} stats;
|
||||
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
|
||||
@@ -45,6 +45,15 @@ enum {
|
||||
PSP_A_KEYS_MAX = (__PSP_A_KEYS_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
PSP_A_STATS_DEV_ID = 1,
|
||||
PSP_A_STATS_KEY_ROTATIONS,
|
||||
PSP_A_STATS_STALE_EVENTS,
|
||||
|
||||
__PSP_A_STATS_MAX,
|
||||
PSP_A_STATS_MAX = (__PSP_A_STATS_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
PSP_CMD_DEV_GET = 1,
|
||||
PSP_CMD_DEV_ADD_NTF,
|
||||
@@ -55,6 +64,7 @@ enum {
|
||||
PSP_CMD_KEY_ROTATE_NTF,
|
||||
PSP_CMD_RX_ASSOC,
|
||||
PSP_CMD_TX_ASSOC,
|
||||
PSP_CMD_GET_STATS,
|
||||
|
||||
__PSP_CMD_MAX,
|
||||
PSP_CMD_MAX = (__PSP_CMD_MAX - 1)
|
||||
|
||||
@@ -47,6 +47,11 @@ static const struct nla_policy psp_tx_assoc_nl_policy[PSP_A_ASSOC_SOCK_FD + 1] =
|
||||
[PSP_A_ASSOC_SOCK_FD] = { .type = NLA_U32, },
|
||||
};
|
||||
|
||||
/* PSP_CMD_GET_STATS - do */
|
||||
static const struct nla_policy psp_get_stats_nl_policy[PSP_A_STATS_DEV_ID + 1] = {
|
||||
[PSP_A_STATS_DEV_ID] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||
};
|
||||
|
||||
/* Ops table for psp */
|
||||
static const struct genl_split_ops psp_nl_ops[] = {
|
||||
{
|
||||
@@ -99,6 +104,20 @@ static const struct genl_split_ops psp_nl_ops[] = {
|
||||
.maxattr = PSP_A_ASSOC_SOCK_FD,
|
||||
.flags = GENL_CMD_CAP_DO,
|
||||
},
|
||||
{
|
||||
.cmd = PSP_CMD_GET_STATS,
|
||||
.pre_doit = psp_device_get_locked,
|
||||
.doit = psp_nl_get_stats_doit,
|
||||
.post_doit = psp_device_unlock,
|
||||
.policy = psp_get_stats_nl_policy,
|
||||
.maxattr = PSP_A_STATS_DEV_ID,
|
||||
.flags = GENL_CMD_CAP_DO,
|
||||
},
|
||||
{
|
||||
.cmd = PSP_CMD_GET_STATS,
|
||||
.dumpit = psp_nl_get_stats_dumpit,
|
||||
.flags = GENL_CMD_CAP_DUMP,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct genl_multicast_group psp_nl_mcgrps[] = {
|
||||
|
||||
@@ -28,6 +28,8 @@ int psp_nl_dev_set_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int psp_nl_key_rotate_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int psp_nl_rx_assoc_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int psp_nl_tx_assoc_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int psp_nl_get_stats_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
|
||||
enum {
|
||||
PSP_NLGRP_MGMT,
|
||||
|
||||
@@ -262,6 +262,7 @@ int psp_nl_key_rotate_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
psd->generation & ~PSP_GEN_VALID_MASK);
|
||||
|
||||
psp_assocs_key_rotated(psd);
|
||||
psd->stats.rotations++;
|
||||
|
||||
nlmsg_end(ntf, (struct nlmsghdr *)ntf->data);
|
||||
genlmsg_multicast_netns(&psp_nl_family, dev_net(psd->main_netdev), ntf,
|
||||
@@ -503,3 +504,76 @@ int psp_nl_tx_assoc_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
nlmsg_free(rsp);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp,
|
||||
const struct genl_info *info)
|
||||
{
|
||||
void *hdr;
|
||||
|
||||
hdr = genlmsg_iput(rsp, info);
|
||||
if (!hdr)
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (nla_put_u32(rsp, PSP_A_STATS_DEV_ID, psd->id) ||
|
||||
nla_put_uint(rsp, PSP_A_STATS_KEY_ROTATIONS,
|
||||
psd->stats.rotations) ||
|
||||
nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales))
|
||||
goto err_cancel_msg;
|
||||
|
||||
genlmsg_end(rsp, hdr);
|
||||
return 0;
|
||||
|
||||
err_cancel_msg:
|
||||
genlmsg_cancel(rsp, hdr);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct psp_dev *psd = info->user_ptr[0];
|
||||
struct sk_buff *rsp;
|
||||
int err;
|
||||
|
||||
rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!rsp)
|
||||
return -ENOMEM;
|
||||
|
||||
err = psp_nl_stats_fill(psd, rsp, info);
|
||||
if (err)
|
||||
goto err_free_msg;
|
||||
|
||||
return genlmsg_reply(rsp, info);
|
||||
|
||||
err_free_msg:
|
||||
nlmsg_free(rsp);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
psp_nl_stats_get_dumpit_one(struct sk_buff *rsp, struct netlink_callback *cb,
|
||||
struct psp_dev *psd)
|
||||
{
|
||||
if (psp_dev_check_access(psd, sock_net(rsp->sk)))
|
||||
return 0;
|
||||
|
||||
return psp_nl_stats_fill(psd, rsp, genl_info_dump(cb));
|
||||
}
|
||||
|
||||
int psp_nl_get_stats_dumpit(struct sk_buff *rsp, struct netlink_callback *cb)
|
||||
{
|
||||
struct psp_dev *psd;
|
||||
int err = 0;
|
||||
|
||||
mutex_lock(&psp_devs_lock);
|
||||
xa_for_each_start(&psp_devs, cb->args[0], psd, cb->args[0]) {
|
||||
mutex_lock(&psd->lock);
|
||||
err = psp_nl_stats_get_dumpit_one(rsp, cb, psd);
|
||||
mutex_unlock(&psd->lock);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&psp_devs_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -253,8 +253,10 @@ void psp_assocs_key_rotated(struct psp_dev *psd)
|
||||
/* Mark the stale associations as invalid, they will no longer
|
||||
* be able to Rx any traffic.
|
||||
*/
|
||||
list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list)
|
||||
list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list) {
|
||||
pas->generation |= ~PSP_GEN_VALID_MASK;
|
||||
psd->stats.stales++;
|
||||
}
|
||||
list_splice_init(&psd->prev_assocs, &psd->stale_assocs);
|
||||
list_splice_init(&psd->active_assocs, &psd->prev_assocs);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user