| /* SPDX-License-Identifier: GPL-2.0-only */ | |
| #ifndef __NET_PSP_H | |
| #define __NET_PSP_H | |
| #include <linux/mutex.h> | |
| #include <linux/refcount.h> | |
| #include <net/net_trackers.h> | |
| struct netlink_ext_ack; | |
| #define PSP_DEFAULT_UDP_PORT 1000 | |
| struct psphdr { | |
| u8 nexthdr; | |
| u8 hdrlen; | |
| u8 crypt_offset; | |
| u8 verfl; | |
| __be32 spi; | |
| __be64 iv; | |
| __be64 vc[]; /* optional */ | |
| }; | |
| #define PSP_ENCAP_HLEN (sizeof(struct udphdr) + sizeof(struct psphdr)) | |
| #define PSP_SPI_KEY_ID GENMASK(30, 0) | |
| #define PSP_SPI_KEY_PHASE BIT(31) | |
| #define PSPHDR_CRYPT_OFFSET GENMASK(5, 0) | |
| #define PSPHDR_VERFL_SAMPLE BIT(7) | |
| #define PSPHDR_VERFL_DROP BIT(6) | |
| #define PSPHDR_VERFL_VERSION GENMASK(5, 2) | |
| #define PSPHDR_VERFL_VIRT BIT(1) | |
| #define PSPHDR_VERFL_ONE BIT(0) | |
| #define PSP_HDRLEN_NOOPT ((sizeof(struct psphdr) - 8) / 8) | |
| /** | |
| * struct psp_dev_config - PSP device configuration | |
| * @versions: PSP versions enabled on the device | |
| */ | |
| struct psp_dev_config { | |
| u32 versions; | |
| }; | |
| /* Max number of devices that can be associated with a single PSP device. | |
| * Each entry consumes ~24 bytes in the netlink dev-get response, and the | |
| * response must fit in GENLMSG_DEFAULT_SIZE (~3.7KB). | |
| */ | |
| #define PSP_ASSOC_DEV_MAX 128 | |
| /** | |
| * struct psp_assoc_dev - wrapper for associated net_device | |
| * @dev_list: list node for psp_dev::assoc_dev_list | |
| * @assoc_dev: the associated net_device | |
| * @dev_tracker: tracker for the net_device reference | |
| */ | |
| struct psp_assoc_dev { | |
| struct list_head dev_list; | |
| struct net_device *assoc_dev; | |
| netdevice_tracker dev_tracker; | |
| }; | |
| /** | |
| * struct psp_dev - PSP device struct | |
| * @main_netdev: original netdevice of this PSP device | |
| * @assoc_dev_list: list of psp_assoc_dev entries associated with this PSP device | |
| * @assoc_dev_cnt: number of entries in @assoc_dev_list | |
| * @ops: driver callbacks | |
| * @caps: device capabilities | |
| * @drv_priv: driver priv pointer | |
| * @lock: instance lock, protects all fields | |
| * @refcnt: reference count for the instance | |
| * @id: instance id | |
| * @generation: current generation of the device key | |
| * @config: current device configuration | |
| * @active_assocs: list of registered associations | |
| * @prev_assocs: associations which use old (but still usable) | |
| * 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 { | |
| struct net_device *main_netdev; | |
| struct list_head assoc_dev_list; | |
| int assoc_dev_cnt; | |
| struct psp_dev_ops *ops; | |
| struct psp_dev_caps *caps; | |
| void *drv_priv; | |
| struct mutex lock; | |
| refcount_t refcnt; | |
| u32 id; | |
| u8 generation; | |
| struct psp_dev_config config; | |
| struct list_head active_assocs; | |
| struct list_head prev_assocs; | |
| struct list_head stale_assocs; | |
| struct { | |
| unsigned long rotations; | |
| unsigned long stales; | |
| } stats; | |
| struct rcu_head rcu; | |
| }; | |
| #define PSP_GEN_VALID_MASK 0x7f | |
| /** | |
| * struct psp_dev_caps - PSP device capabilities | |
| */ | |
| struct psp_dev_caps { | |
| /** | |
| * @versions: mask of supported PSP versions | |
| * Set this field to 0 to indicate PSP is not supported at all. | |
| */ | |
| u32 versions; | |
| /** | |
| * @assoc_drv_spc: size of driver-specific state in Tx assoc | |
| * Determines the size of struct psp_assoc::drv_data | |
| */ | |
| u32 assoc_drv_spc; | |
| }; | |
| #define PSP_MAX_KEY 32 | |
| #define PSP_HDR_SIZE 16 /* We don't support optional fields, yet */ | |
| #define PSP_TRL_SIZE 16 /* AES-GCM/GMAC trailer size */ | |
| struct psp_skb_ext { | |
| __be32 spi; | |
| u16 dev_id; | |
| u8 generation; | |
| u8 version; | |
| }; | |
| struct psp_key_parsed { | |
| __be32 spi; | |
| u8 key[PSP_MAX_KEY]; | |
| }; | |
| struct psp_assoc { | |
| struct psp_dev *psd; | |
| u16 dev_id; | |
| u8 generation; | |
| u8 version; | |
| u8 peer_tx; | |
| u32 upgrade_seq; | |
| struct psp_key_parsed tx; | |
| struct psp_key_parsed rx; | |
| refcount_t refcnt; | |
| struct rcu_head rcu; | |
| struct work_struct work; | |
| struct list_head assocs_list; | |
| u8 drv_data[] __aligned(8); | |
| }; | |
| struct psp_dev_stats { | |
| union { | |
| struct { | |
| u64 rx_packets; | |
| u64 rx_bytes; | |
| u64 rx_auth_fail; | |
| u64 rx_error; | |
| u64 rx_bad; | |
| u64 tx_packets; | |
| u64 tx_bytes; | |
| u64 tx_error; | |
| }; | |
| DECLARE_FLEX_ARRAY(u64, required); | |
| }; | |
| }; | |
| /** | |
| * struct psp_dev_ops - netdev driver facing PSP callbacks | |
| */ | |
| struct psp_dev_ops { | |
| /** | |
| * @set_config: set configuration of a PSP device | |
| * Driver can inspect @psd->config for the previous configuration. | |
| * Core will update @psd->config with @config on success. | |
| */ | |
| int (*set_config)(struct psp_dev *psd, struct psp_dev_config *conf, | |
| struct netlink_ext_ack *extack); | |
| /** | |
| * @key_rotate: rotate the device key | |
| */ | |
| int (*key_rotate)(struct psp_dev *psd, struct netlink_ext_ack *extack); | |
| /** | |
| * @rx_spi_alloc: allocate an Rx SPI+key pair | |
| * Allocate an Rx SPI and resulting derived key. | |
| * This key should remain valid until key rotation. | |
| */ | |
| int (*rx_spi_alloc)(struct psp_dev *psd, u32 version, | |
| struct psp_key_parsed *assoc, | |
| struct netlink_ext_ack *extack); | |
| /** | |
| * @tx_key_add: add a Tx key to the device | |
| * Install an association in the device. Core will allocate space | |
| * for the driver to use at drv_data. | |
| */ | |
| int (*tx_key_add)(struct psp_dev *psd, struct psp_assoc *pas, | |
| struct netlink_ext_ack *extack); | |
| /** | |
| * @tx_key_del: remove a Tx key from the device | |
| * Remove an association from the device. | |
| */ | |
| void (*tx_key_del)(struct psp_dev *psd, struct psp_assoc *pas); | |
| /** | |
| * @get_stats: get statistics from the device | |
| * Stats required by the spec must be maintained and filled in. | |
| * Stats must be filled in member-by-member, never memset the struct. | |
| */ | |
| void (*get_stats)(struct psp_dev *psd, struct psp_dev_stats *stats); | |
| }; | |
| #endif /* __NET_PSP_H */ |