0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/netdevice.h>
0015 #include <linux/crc-ccitt.h>
0016 #include <asm/unaligned.h>
0017
0018 #include <net/mac802154.h>
0019 #include <net/ieee802154_netdev.h>
0020 #include <net/nl802154.h>
0021
0022 #include "ieee802154_i.h"
0023
0024 static int ieee802154_deliver_skb(struct sk_buff *skb)
0025 {
0026 skb->ip_summed = CHECKSUM_UNNECESSARY;
0027 skb->protocol = htons(ETH_P_IEEE802154);
0028
0029 return netif_receive_skb(skb);
0030 }
0031
0032 static int
0033 ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata,
0034 struct sk_buff *skb, const struct ieee802154_hdr *hdr)
0035 {
0036 struct wpan_dev *wpan_dev = &sdata->wpan_dev;
0037 __le16 span, sshort;
0038 int rc;
0039
0040 pr_debug("getting packet via slave interface %s\n", sdata->dev->name);
0041
0042 span = wpan_dev->pan_id;
0043 sshort = wpan_dev->short_addr;
0044
0045 switch (mac_cb(skb)->dest.mode) {
0046 case IEEE802154_ADDR_NONE:
0047 if (hdr->source.mode != IEEE802154_ADDR_NONE)
0048
0049 skb->pkt_type = PACKET_OTHERHOST;
0050 else
0051
0052 skb->pkt_type = PACKET_HOST;
0053 break;
0054 case IEEE802154_ADDR_LONG:
0055 if (mac_cb(skb)->dest.pan_id != span &&
0056 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
0057 skb->pkt_type = PACKET_OTHERHOST;
0058 else if (mac_cb(skb)->dest.extended_addr == wpan_dev->extended_addr)
0059 skb->pkt_type = PACKET_HOST;
0060 else
0061 skb->pkt_type = PACKET_OTHERHOST;
0062 break;
0063 case IEEE802154_ADDR_SHORT:
0064 if (mac_cb(skb)->dest.pan_id != span &&
0065 mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
0066 skb->pkt_type = PACKET_OTHERHOST;
0067 else if (mac_cb(skb)->dest.short_addr == sshort)
0068 skb->pkt_type = PACKET_HOST;
0069 else if (mac_cb(skb)->dest.short_addr ==
0070 cpu_to_le16(IEEE802154_ADDR_BROADCAST))
0071 skb->pkt_type = PACKET_BROADCAST;
0072 else
0073 skb->pkt_type = PACKET_OTHERHOST;
0074 break;
0075 default:
0076 pr_debug("invalid dest mode\n");
0077 goto fail;
0078 }
0079
0080 skb->dev = sdata->dev;
0081
0082
0083
0084
0085
0086 rc = mac802154_llsec_decrypt(&sdata->sec, skb);
0087 if (rc) {
0088 pr_debug("decryption failed: %i\n", rc);
0089 goto fail;
0090 }
0091
0092 sdata->dev->stats.rx_packets++;
0093 sdata->dev->stats.rx_bytes += skb->len;
0094
0095 switch (mac_cb(skb)->type) {
0096 case IEEE802154_FC_TYPE_BEACON:
0097 case IEEE802154_FC_TYPE_ACK:
0098 case IEEE802154_FC_TYPE_MAC_CMD:
0099 goto fail;
0100
0101 case IEEE802154_FC_TYPE_DATA:
0102 return ieee802154_deliver_skb(skb);
0103 default:
0104 pr_warn_ratelimited("ieee802154: bad frame received "
0105 "(type = %d)\n", mac_cb(skb)->type);
0106 goto fail;
0107 }
0108
0109 fail:
0110 kfree_skb(skb);
0111 return NET_RX_DROP;
0112 }
0113
0114 static void
0115 ieee802154_print_addr(const char *name, const struct ieee802154_addr *addr)
0116 {
0117 if (addr->mode == IEEE802154_ADDR_NONE)
0118 pr_debug("%s not present\n", name);
0119
0120 pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id));
0121 if (addr->mode == IEEE802154_ADDR_SHORT) {
0122 pr_debug("%s is short: %04x\n", name,
0123 le16_to_cpu(addr->short_addr));
0124 } else {
0125 u64 hw = swab64((__force u64)addr->extended_addr);
0126
0127 pr_debug("%s is hardware: %8phC\n", name, &hw);
0128 }
0129 }
0130
0131 static int
0132 ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr)
0133 {
0134 int hlen;
0135 struct ieee802154_mac_cb *cb = mac_cb_init(skb);
0136
0137 skb_reset_mac_header(skb);
0138
0139 hlen = ieee802154_hdr_pull(skb, hdr);
0140 if (hlen < 0)
0141 return -EINVAL;
0142
0143 skb->mac_len = hlen;
0144
0145 pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr->fc),
0146 hdr->seq);
0147
0148 cb->type = hdr->fc.type;
0149 cb->ackreq = hdr->fc.ack_request;
0150 cb->secen = hdr->fc.security_enabled;
0151
0152 ieee802154_print_addr("destination", &hdr->dest);
0153 ieee802154_print_addr("source", &hdr->source);
0154
0155 cb->source = hdr->source;
0156 cb->dest = hdr->dest;
0157
0158 if (hdr->fc.security_enabled) {
0159 u64 key;
0160
0161 pr_debug("seclevel %i\n", hdr->sec.level);
0162
0163 switch (hdr->sec.key_id_mode) {
0164 case IEEE802154_SCF_KEY_IMPLICIT:
0165 pr_debug("implicit key\n");
0166 break;
0167
0168 case IEEE802154_SCF_KEY_INDEX:
0169 pr_debug("key %02x\n", hdr->sec.key_id);
0170 break;
0171
0172 case IEEE802154_SCF_KEY_SHORT_INDEX:
0173 pr_debug("key %04x:%04x %02x\n",
0174 le32_to_cpu(hdr->sec.short_src) >> 16,
0175 le32_to_cpu(hdr->sec.short_src) & 0xffff,
0176 hdr->sec.key_id);
0177 break;
0178
0179 case IEEE802154_SCF_KEY_HW_INDEX:
0180 key = swab64((__force u64)hdr->sec.extended_src);
0181 pr_debug("key source %8phC %02x\n", &key,
0182 hdr->sec.key_id);
0183 break;
0184 }
0185 }
0186
0187 return 0;
0188 }
0189
0190 static void
0191 __ieee802154_rx_handle_packet(struct ieee802154_local *local,
0192 struct sk_buff *skb)
0193 {
0194 int ret;
0195 struct ieee802154_sub_if_data *sdata;
0196 struct ieee802154_hdr hdr;
0197
0198 ret = ieee802154_parse_frame_start(skb, &hdr);
0199 if (ret) {
0200 pr_debug("got invalid frame\n");
0201 kfree_skb(skb);
0202 return;
0203 }
0204
0205 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
0206 if (sdata->wpan_dev.iftype != NL802154_IFTYPE_NODE)
0207 continue;
0208
0209 if (!ieee802154_sdata_running(sdata))
0210 continue;
0211
0212 ieee802154_subif_frame(sdata, skb, &hdr);
0213 skb = NULL;
0214 break;
0215 }
0216
0217 kfree_skb(skb);
0218 }
0219
0220 static void
0221 ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
0222 {
0223 struct sk_buff *skb2;
0224 struct ieee802154_sub_if_data *sdata;
0225
0226 skb_reset_mac_header(skb);
0227 skb->ip_summed = CHECKSUM_UNNECESSARY;
0228 skb->pkt_type = PACKET_OTHERHOST;
0229 skb->protocol = htons(ETH_P_IEEE802154);
0230
0231 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
0232 if (sdata->wpan_dev.iftype != NL802154_IFTYPE_MONITOR)
0233 continue;
0234
0235 if (!ieee802154_sdata_running(sdata))
0236 continue;
0237
0238 skb2 = skb_clone(skb, GFP_ATOMIC);
0239 if (skb2) {
0240 skb2->dev = sdata->dev;
0241 ieee802154_deliver_skb(skb2);
0242
0243 sdata->dev->stats.rx_packets++;
0244 sdata->dev->stats.rx_bytes += skb->len;
0245 }
0246 }
0247 }
0248
0249 void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb)
0250 {
0251 u16 crc;
0252
0253 WARN_ON_ONCE(softirq_count() == 0);
0254
0255 if (local->suspended)
0256 goto drop;
0257
0258
0259
0260
0261
0262 if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) {
0263 crc = crc_ccitt(0, skb->data, skb->len);
0264 put_unaligned_le16(crc, skb_put(skb, 2));
0265 }
0266
0267 rcu_read_lock();
0268
0269 ieee802154_monitors_rx(local, skb);
0270
0271
0272
0273
0274 if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) {
0275 crc = crc_ccitt(0, skb->data, skb->len);
0276 if (crc) {
0277 rcu_read_unlock();
0278 goto drop;
0279 }
0280 }
0281
0282 skb_trim(skb, skb->len - 2);
0283
0284 __ieee802154_rx_handle_packet(local, skb);
0285
0286 rcu_read_unlock();
0287
0288 return;
0289 drop:
0290 kfree_skb(skb);
0291 }
0292
0293 void
0294 ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi)
0295 {
0296 struct ieee802154_local *local = hw_to_local(hw);
0297
0298 mac_cb(skb)->lqi = lqi;
0299 skb->pkt_type = IEEE802154_RX_MSG;
0300 skb_queue_tail(&local->skb_queue, skb);
0301 tasklet_schedule(&local->tasklet);
0302 }
0303 EXPORT_SYMBOL(ieee802154_rx_irqsafe);