summaryrefslogtreecommitdiff
path: root/net/psp
diff options
context:
space:
mode:
Diffstat (limited to 'net/psp')
-rw-r--r--net/psp/psp-nl-gen.c20
-rw-r--r--net/psp/psp-nl-gen.h3
-rw-r--r--net/psp/psp_main.c3
-rw-r--r--net/psp/psp_nl.c93
-rw-r--r--net/psp/psp_sock.c4
5 files changed, 121 insertions, 2 deletions
diff --git a/net/psp/psp-nl-gen.c b/net/psp/psp-nl-gen.c
index 9fdd6f831803..22a48d0fa378 100644
--- a/net/psp/psp-nl-gen.c
+++ b/net/psp/psp-nl-gen.c
@@ -2,6 +2,7 @@
/* Do not edit directly, auto-generated from: */
/* Documentation/netlink/specs/psp.yaml */
/* YNL-GEN kernel source */
+/* To regenerate run: tools/net/ynl/ynl-regen.sh */
#include <net/netlink.h>
#include <net/genetlink.h>
@@ -47,6 +48,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 +105,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[] = {
diff --git a/net/psp/psp-nl-gen.h b/net/psp/psp-nl-gen.h
index 25268ed11fb5..599c5f1c82f2 100644
--- a/net/psp/psp-nl-gen.h
+++ b/net/psp/psp-nl-gen.h
@@ -2,6 +2,7 @@
/* Do not edit directly, auto-generated from: */
/* Documentation/netlink/specs/psp.yaml */
/* YNL-GEN kernel header */
+/* To regenerate run: tools/net/ynl/ynl-regen.sh */
#ifndef _LINUX_PSP_GEN_H
#define _LINUX_PSP_GEN_H
@@ -28,6 +29,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,
diff --git a/net/psp/psp_main.c b/net/psp/psp_main.c
index 481aaf0fc9fc..a8534124f626 100644
--- a/net/psp/psp_main.c
+++ b/net/psp/psp_main.c
@@ -60,7 +60,8 @@ psp_dev_create(struct net_device *netdev,
!psd_ops->key_rotate ||
!psd_ops->rx_spi_alloc ||
!psd_ops->tx_key_add ||
- !psd_ops->tx_key_del))
+ !psd_ops->tx_key_del ||
+ !psd_ops->get_stats))
return ERR_PTR(-EINVAL);
psd = kzalloc(sizeof(*psd), GFP_KERNEL);
diff --git a/net/psp/psp_nl.c b/net/psp/psp_nl.c
index 8aaca62744c3..6afd7707ec12 100644
--- a/net/psp/psp_nl.c
+++ b/net/psp/psp_nl.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/ethtool.h>
#include <linux/skbuff.h>
#include <linux/xarray.h>
#include <net/genetlink.h>
@@ -262,6 +263,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 +505,94 @@ err_free_msg:
nlmsg_free(rsp);
return err;
}
+
+static int
+psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp,
+ const struct genl_info *info)
+{
+ unsigned int required_cnt = sizeof(struct psp_dev_stats) / sizeof(u64);
+ struct psp_dev_stats stats;
+ void *hdr;
+ int i;
+
+ memset(&stats, 0xff, sizeof(stats));
+ psd->ops->get_stats(psd, &stats);
+
+ for (i = 0; i < required_cnt; i++)
+ if (WARN_ON_ONCE(stats.required[i] == ETHTOOL_STAT_NOT_SET))
+ return -EOPNOTSUPP;
+
+ 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) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_PACKETS, stats.rx_packets) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_BYTES, stats.rx_bytes) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_AUTH_FAIL, stats.rx_auth_fail) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_ERROR, stats.rx_error) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_BAD, stats.rx_bad) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_PACKETS, stats.tx_packets) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_BYTES, stats.tx_bytes) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_ERROR, stats.tx_error))
+ 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;
+}
diff --git a/net/psp/psp_sock.c b/net/psp/psp_sock.c
index a931d825d1cc..f785672b7df6 100644
--- a/net/psp/psp_sock.c
+++ b/net/psp/psp_sock.c
@@ -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);