Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+157 -1
+40
Documentation/netlink/specs/psp.yaml
··· 76 76 name: spi 77 77 doc: Security Parameters Index (SPI) of the association. 78 78 type: u32 79 + - 80 + name: stats 81 + attributes: 82 + - 83 + name: dev-id 84 + doc: PSP device ID. 85 + type: u32 86 + checks: 87 + min: 1 88 + - 89 + name: key-rotations 90 + type: uint 91 + doc: | 92 + Number of key rotations during the lifetime of the device. 93 + Kernel statistic. 94 + - 95 + name: stale-events 96 + type: uint 97 + doc: | 98 + Number of times a socket's Rx got shut down due to using 99 + a key which went stale (fully rotated out). 100 + Kernel statistic. 79 101 80 102 operations: 81 103 list: ··· 198 176 attributes: [] 199 177 pre: psp-assoc-device-get-locked 200 178 post: psp-device-unlock 179 + 180 + - 181 + name: get-stats 182 + doc: Get device statistics. 183 + attribute-set: stats 184 + do: 185 + request: 186 + attributes: 187 + - dev-id 188 + reply: &stats-all 189 + attributes: 190 + - dev-id 191 + - key-rotations 192 + - stale-events 193 + pre: psp-device-get-locked 194 + post: psp-device-unlock 195 + dump: 196 + reply: *stats-all 201 197 202 198 mcast-groups: 203 199 list:
+9
include/net/psp/types.h
··· 59 59 * device key 60 60 * @stale_assocs: associations which use a rotated out key 61 61 * 62 + * @stats: statistics maintained by the core 63 + * @stats.rotations: See stats attr key-rotations 64 + * @stats.stales: See stats attr stale-events 65 + * 62 66 * @rcu: RCU head for freeing the structure 63 67 */ 64 68 struct psp_dev { ··· 84 80 struct list_head active_assocs; 85 81 struct list_head prev_assocs; 86 82 struct list_head stale_assocs; 83 + 84 + struct { 85 + unsigned long rotations; 86 + unsigned long stales; 87 + } stats; 87 88 88 89 struct rcu_head rcu; 89 90 };
+10
include/uapi/linux/psp.h
··· 46 46 }; 47 47 48 48 enum { 49 + PSP_A_STATS_DEV_ID = 1, 50 + PSP_A_STATS_KEY_ROTATIONS, 51 + PSP_A_STATS_STALE_EVENTS, 52 + 53 + __PSP_A_STATS_MAX, 54 + PSP_A_STATS_MAX = (__PSP_A_STATS_MAX - 1) 55 + }; 56 + 57 + enum { 49 58 PSP_CMD_DEV_GET = 1, 50 59 PSP_CMD_DEV_ADD_NTF, 51 60 PSP_CMD_DEV_DEL_NTF, ··· 64 55 PSP_CMD_KEY_ROTATE_NTF, 65 56 PSP_CMD_RX_ASSOC, 66 57 PSP_CMD_TX_ASSOC, 58 + PSP_CMD_GET_STATS, 67 59 68 60 __PSP_CMD_MAX, 69 61 PSP_CMD_MAX = (__PSP_CMD_MAX - 1)
+19
net/psp/psp-nl-gen.c
··· 47 47 [PSP_A_ASSOC_SOCK_FD] = { .type = NLA_U32, }, 48 48 }; 49 49 50 + /* PSP_CMD_GET_STATS - do */ 51 + static const struct nla_policy psp_get_stats_nl_policy[PSP_A_STATS_DEV_ID + 1] = { 52 + [PSP_A_STATS_DEV_ID] = NLA_POLICY_MIN(NLA_U32, 1), 53 + }; 54 + 50 55 /* Ops table for psp */ 51 56 static const struct genl_split_ops psp_nl_ops[] = { 52 57 { ··· 103 98 .policy = psp_tx_assoc_nl_policy, 104 99 .maxattr = PSP_A_ASSOC_SOCK_FD, 105 100 .flags = GENL_CMD_CAP_DO, 101 + }, 102 + { 103 + .cmd = PSP_CMD_GET_STATS, 104 + .pre_doit = psp_device_get_locked, 105 + .doit = psp_nl_get_stats_doit, 106 + .post_doit = psp_device_unlock, 107 + .policy = psp_get_stats_nl_policy, 108 + .maxattr = PSP_A_STATS_DEV_ID, 109 + .flags = GENL_CMD_CAP_DO, 110 + }, 111 + { 112 + .cmd = PSP_CMD_GET_STATS, 113 + .dumpit = psp_nl_get_stats_dumpit, 114 + .flags = GENL_CMD_CAP_DUMP, 106 115 }, 107 116 }; 108 117
+2
net/psp/psp-nl-gen.h
··· 28 28 int psp_nl_key_rotate_doit(struct sk_buff *skb, struct genl_info *info); 29 29 int psp_nl_rx_assoc_doit(struct sk_buff *skb, struct genl_info *info); 30 30 int psp_nl_tx_assoc_doit(struct sk_buff *skb, struct genl_info *info); 31 + int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info); 32 + int psp_nl_get_stats_dumpit(struct sk_buff *skb, struct netlink_callback *cb); 31 33 32 34 enum { 33 35 PSP_NLGRP_MGMT,
+74
net/psp/psp_nl.c
··· 262 262 psd->generation & ~PSP_GEN_VALID_MASK); 263 263 264 264 psp_assocs_key_rotated(psd); 265 + psd->stats.rotations++; 265 266 266 267 nlmsg_end(ntf, (struct nlmsghdr *)ntf->data); 267 268 genlmsg_multicast_netns(&psp_nl_family, dev_net(psd->main_netdev), ntf, ··· 502 501 503 502 err_free_msg: 504 503 nlmsg_free(rsp); 504 + return err; 505 + } 506 + 507 + static int 508 + psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp, 509 + const struct genl_info *info) 510 + { 511 + void *hdr; 512 + 513 + hdr = genlmsg_iput(rsp, info); 514 + if (!hdr) 515 + return -EMSGSIZE; 516 + 517 + if (nla_put_u32(rsp, PSP_A_STATS_DEV_ID, psd->id) || 518 + nla_put_uint(rsp, PSP_A_STATS_KEY_ROTATIONS, 519 + psd->stats.rotations) || 520 + nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales)) 521 + goto err_cancel_msg; 522 + 523 + genlmsg_end(rsp, hdr); 524 + return 0; 525 + 526 + err_cancel_msg: 527 + genlmsg_cancel(rsp, hdr); 528 + return -EMSGSIZE; 529 + } 530 + 531 + int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info) 532 + { 533 + struct psp_dev *psd = info->user_ptr[0]; 534 + struct sk_buff *rsp; 535 + int err; 536 + 537 + rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 538 + if (!rsp) 539 + return -ENOMEM; 540 + 541 + err = psp_nl_stats_fill(psd, rsp, info); 542 + if (err) 543 + goto err_free_msg; 544 + 545 + return genlmsg_reply(rsp, info); 546 + 547 + err_free_msg: 548 + nlmsg_free(rsp); 549 + return err; 550 + } 551 + 552 + static int 553 + psp_nl_stats_get_dumpit_one(struct sk_buff *rsp, struct netlink_callback *cb, 554 + struct psp_dev *psd) 555 + { 556 + if (psp_dev_check_access(psd, sock_net(rsp->sk))) 557 + return 0; 558 + 559 + return psp_nl_stats_fill(psd, rsp, genl_info_dump(cb)); 560 + } 561 + 562 + int psp_nl_get_stats_dumpit(struct sk_buff *rsp, struct netlink_callback *cb) 563 + { 564 + struct psp_dev *psd; 565 + int err = 0; 566 + 567 + mutex_lock(&psp_devs_lock); 568 + xa_for_each_start(&psp_devs, cb->args[0], psd, cb->args[0]) { 569 + mutex_lock(&psd->lock); 570 + err = psp_nl_stats_get_dumpit_one(rsp, cb, psd); 571 + mutex_unlock(&psd->lock); 572 + if (err) 573 + break; 574 + } 575 + mutex_unlock(&psp_devs_lock); 576 + 505 577 return err; 506 578 }
+3 -1
net/psp/psp_sock.c
··· 253 253 /* Mark the stale associations as invalid, they will no longer 254 254 * be able to Rx any traffic. 255 255 */ 256 - list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list) 256 + list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list) { 257 257 pas->generation |= ~PSP_GEN_VALID_MASK; 258 + psd->stats.stales++; 259 + } 258 260 list_splice_init(&psd->prev_assocs, &psd->stale_assocs); 259 261 list_splice_init(&psd->active_assocs, &psd->prev_assocs); 260 262