cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ieee802154_netdev.h (8963B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * An interface between IEEE802.15.4 device and rest of the kernel.
      4 *
      5 * Copyright (C) 2007-2012 Siemens AG
      6 *
      7 * Written by:
      8 * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
      9 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
     10 * Maxim Osipov <maxim.osipov@siemens.com>
     11 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
     12 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
     13 */
     14
     15#ifndef IEEE802154_NETDEVICE_H
     16#define IEEE802154_NETDEVICE_H
     17
     18#include <net/af_ieee802154.h>
     19#include <linux/netdevice.h>
     20#include <linux/skbuff.h>
     21#include <linux/ieee802154.h>
     22
     23#include <net/cfg802154.h>
     24
     25struct ieee802154_sechdr {
     26#if defined(__LITTLE_ENDIAN_BITFIELD)
     27	u8 level:3,
     28	   key_id_mode:2,
     29	   reserved:3;
     30#elif defined(__BIG_ENDIAN_BITFIELD)
     31	u8 reserved:3,
     32	   key_id_mode:2,
     33	   level:3;
     34#else
     35#error	"Please fix <asm/byteorder.h>"
     36#endif
     37	u8 key_id;
     38	__le32 frame_counter;
     39	union {
     40		__le32 short_src;
     41		__le64 extended_src;
     42	};
     43};
     44
     45struct ieee802154_hdr_fc {
     46#if defined(__LITTLE_ENDIAN_BITFIELD)
     47	u16 type:3,
     48	    security_enabled:1,
     49	    frame_pending:1,
     50	    ack_request:1,
     51	    intra_pan:1,
     52	    reserved:3,
     53	    dest_addr_mode:2,
     54	    version:2,
     55	    source_addr_mode:2;
     56#elif defined(__BIG_ENDIAN_BITFIELD)
     57	u16 reserved:1,
     58	    intra_pan:1,
     59	    ack_request:1,
     60	    frame_pending:1,
     61	    security_enabled:1,
     62	    type:3,
     63	    source_addr_mode:2,
     64	    version:2,
     65	    dest_addr_mode:2,
     66	    reserved2:2;
     67#else
     68#error	"Please fix <asm/byteorder.h>"
     69#endif
     70};
     71
     72struct ieee802154_hdr {
     73	struct ieee802154_hdr_fc fc;
     74	u8 seq;
     75	struct ieee802154_addr source;
     76	struct ieee802154_addr dest;
     77	struct ieee802154_sechdr sec;
     78};
     79
     80/* pushes hdr onto the skb. fields of hdr->fc that can be calculated from
     81 * the contents of hdr will be, and the actual value of those bits in
     82 * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame
     83 * version, if SECEN is set.
     84 */
     85int ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr);
     86
     87/* pulls the entire 802.15.4 header off of the skb, including the security
     88 * header, and performs pan id decompression
     89 */
     90int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr);
     91
     92/* parses the frame control, sequence number of address fields in a given skb
     93 * and stores them into hdr, performing pan id decompression and length checks
     94 * to be suitable for use in header_ops.parse
     95 */
     96int ieee802154_hdr_peek_addrs(const struct sk_buff *skb,
     97			      struct ieee802154_hdr *hdr);
     98
     99/* parses the full 802.15.4 header a given skb and stores them into hdr,
    100 * performing pan id decompression and length checks to be suitable for use in
    101 * header_ops.parse
    102 */
    103int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr);
    104
    105int ieee802154_max_payload(const struct ieee802154_hdr *hdr);
    106
    107static inline int
    108ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec)
    109{
    110	switch (sec->level) {
    111	case IEEE802154_SCF_SECLEVEL_MIC32:
    112	case IEEE802154_SCF_SECLEVEL_ENC_MIC32:
    113		return 4;
    114	case IEEE802154_SCF_SECLEVEL_MIC64:
    115	case IEEE802154_SCF_SECLEVEL_ENC_MIC64:
    116		return 8;
    117	case IEEE802154_SCF_SECLEVEL_MIC128:
    118	case IEEE802154_SCF_SECLEVEL_ENC_MIC128:
    119		return 16;
    120	case IEEE802154_SCF_SECLEVEL_NONE:
    121	case IEEE802154_SCF_SECLEVEL_ENC:
    122	default:
    123		return 0;
    124	}
    125}
    126
    127static inline int ieee802154_hdr_length(struct sk_buff *skb)
    128{
    129	struct ieee802154_hdr hdr;
    130	int len = ieee802154_hdr_pull(skb, &hdr);
    131
    132	if (len > 0)
    133		skb_push(skb, len);
    134
    135	return len;
    136}
    137
    138static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1,
    139					 const struct ieee802154_addr *a2)
    140{
    141	if (a1->pan_id != a2->pan_id || a1->mode != a2->mode)
    142		return false;
    143
    144	if ((a1->mode == IEEE802154_ADDR_LONG &&
    145	     a1->extended_addr != a2->extended_addr) ||
    146	    (a1->mode == IEEE802154_ADDR_SHORT &&
    147	     a1->short_addr != a2->short_addr))
    148		return false;
    149
    150	return true;
    151}
    152
    153static inline __le64 ieee802154_devaddr_from_raw(const void *raw)
    154{
    155	u64 temp;
    156
    157	memcpy(&temp, raw, IEEE802154_ADDR_LEN);
    158	return (__force __le64)swab64(temp);
    159}
    160
    161static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr)
    162{
    163	u64 temp = swab64((__force u64)addr);
    164
    165	memcpy(raw, &temp, IEEE802154_ADDR_LEN);
    166}
    167
    168static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
    169					   const struct ieee802154_addr_sa *sa)
    170{
    171	a->mode = sa->addr_type;
    172	a->pan_id = cpu_to_le16(sa->pan_id);
    173
    174	switch (a->mode) {
    175	case IEEE802154_ADDR_SHORT:
    176		a->short_addr = cpu_to_le16(sa->short_addr);
    177		break;
    178	case IEEE802154_ADDR_LONG:
    179		a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr);
    180		break;
    181	}
    182}
    183
    184static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa,
    185					 const struct ieee802154_addr *a)
    186{
    187	sa->addr_type = a->mode;
    188	sa->pan_id = le16_to_cpu(a->pan_id);
    189
    190	switch (a->mode) {
    191	case IEEE802154_ADDR_SHORT:
    192		sa->short_addr = le16_to_cpu(a->short_addr);
    193		break;
    194	case IEEE802154_ADDR_LONG:
    195		ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr);
    196		break;
    197	}
    198}
    199
    200/*
    201 * A control block of skb passed between the ARPHRD_IEEE802154 device
    202 * and other stack parts.
    203 */
    204struct ieee802154_mac_cb {
    205	u8 lqi;
    206	u8 type;
    207	bool ackreq;
    208	bool secen;
    209	bool secen_override;
    210	u8 seclevel;
    211	bool seclevel_override;
    212	struct ieee802154_addr source;
    213	struct ieee802154_addr dest;
    214};
    215
    216static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
    217{
    218	return (struct ieee802154_mac_cb *)skb->cb;
    219}
    220
    221static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb)
    222{
    223	BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb));
    224
    225	memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb));
    226	return mac_cb(skb);
    227}
    228
    229enum {
    230	IEEE802154_LLSEC_DEVKEY_IGNORE,
    231	IEEE802154_LLSEC_DEVKEY_RESTRICT,
    232	IEEE802154_LLSEC_DEVKEY_RECORD,
    233
    234	__IEEE802154_LLSEC_DEVKEY_MAX,
    235};
    236
    237#define IEEE802154_MAC_SCAN_ED		0
    238#define IEEE802154_MAC_SCAN_ACTIVE	1
    239#define IEEE802154_MAC_SCAN_PASSIVE	2
    240#define IEEE802154_MAC_SCAN_ORPHAN	3
    241
    242struct ieee802154_mac_params {
    243	s8 transmit_power;
    244	u8 min_be;
    245	u8 max_be;
    246	u8 csma_retries;
    247	s8 frame_retries;
    248
    249	bool lbt;
    250	struct wpan_phy_cca cca;
    251	s32 cca_ed_level;
    252};
    253
    254struct wpan_phy;
    255
    256enum {
    257	IEEE802154_LLSEC_PARAM_ENABLED		= BIT(0),
    258	IEEE802154_LLSEC_PARAM_FRAME_COUNTER	= BIT(1),
    259	IEEE802154_LLSEC_PARAM_OUT_LEVEL	= BIT(2),
    260	IEEE802154_LLSEC_PARAM_OUT_KEY		= BIT(3),
    261	IEEE802154_LLSEC_PARAM_KEY_SOURCE	= BIT(4),
    262	IEEE802154_LLSEC_PARAM_PAN_ID		= BIT(5),
    263	IEEE802154_LLSEC_PARAM_HWADDR		= BIT(6),
    264	IEEE802154_LLSEC_PARAM_COORD_HWADDR	= BIT(7),
    265	IEEE802154_LLSEC_PARAM_COORD_SHORTADDR	= BIT(8),
    266};
    267
    268struct ieee802154_llsec_ops {
    269	int (*get_params)(struct net_device *dev,
    270			  struct ieee802154_llsec_params *params);
    271	int (*set_params)(struct net_device *dev,
    272			  const struct ieee802154_llsec_params *params,
    273			  int changed);
    274
    275	int (*add_key)(struct net_device *dev,
    276		       const struct ieee802154_llsec_key_id *id,
    277		       const struct ieee802154_llsec_key *key);
    278	int (*del_key)(struct net_device *dev,
    279		       const struct ieee802154_llsec_key_id *id);
    280
    281	int (*add_dev)(struct net_device *dev,
    282		       const struct ieee802154_llsec_device *llsec_dev);
    283	int (*del_dev)(struct net_device *dev, __le64 dev_addr);
    284
    285	int (*add_devkey)(struct net_device *dev,
    286			  __le64 device_addr,
    287			  const struct ieee802154_llsec_device_key *key);
    288	int (*del_devkey)(struct net_device *dev,
    289			  __le64 device_addr,
    290			  const struct ieee802154_llsec_device_key *key);
    291
    292	int (*add_seclevel)(struct net_device *dev,
    293			    const struct ieee802154_llsec_seclevel *sl);
    294	int (*del_seclevel)(struct net_device *dev,
    295			    const struct ieee802154_llsec_seclevel *sl);
    296
    297	void (*lock_table)(struct net_device *dev);
    298	void (*get_table)(struct net_device *dev,
    299			  struct ieee802154_llsec_table **t);
    300	void (*unlock_table)(struct net_device *dev);
    301};
    302/*
    303 * This should be located at net_device->ml_priv
    304 *
    305 * get_phy should increment the reference counting on returned phy.
    306 * Use wpan_wpy_put to put that reference.
    307 */
    308struct ieee802154_mlme_ops {
    309	/* The following fields are optional (can be NULL). */
    310
    311	int (*assoc_req)(struct net_device *dev,
    312			struct ieee802154_addr *addr,
    313			u8 channel, u8 page, u8 cap);
    314	int (*assoc_resp)(struct net_device *dev,
    315			struct ieee802154_addr *addr,
    316			__le16 short_addr, u8 status);
    317	int (*disassoc_req)(struct net_device *dev,
    318			struct ieee802154_addr *addr,
    319			u8 reason);
    320	int (*start_req)(struct net_device *dev,
    321			struct ieee802154_addr *addr,
    322			u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
    323			u8 pan_coord, u8 blx, u8 coord_realign);
    324	int (*scan_req)(struct net_device *dev,
    325			u8 type, u32 channels, u8 page, u8 duration);
    326
    327	int (*set_mac_params)(struct net_device *dev,
    328			      const struct ieee802154_mac_params *params);
    329	void (*get_mac_params)(struct net_device *dev,
    330			       struct ieee802154_mac_params *params);
    331
    332	const struct ieee802154_llsec_ops *llsec;
    333};
    334
    335static inline struct ieee802154_mlme_ops *
    336ieee802154_mlme_ops(const struct net_device *dev)
    337{
    338	return dev->ml_priv;
    339}
    340
    341#endif