net/mac802154/rx.c

Source file repositories/reference/linux-study-clean/net/mac802154/rx.c

File Facts

System
Linux kernel
Corpus path
net/mac802154/rx.c
Extension
.c
Size
11488 bytes
Lines
451
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (mac_cb(skb)->type != IEEE802154_FC_TYPE_BEACON) {
			dev_dbg(&sdata->dev->dev,
				"drop non-beacon frame (0x%x) during scan\n",
				mac_cb(skb)->type);
			goto fail;
		}
	}

	switch (mac_cb(skb)->dest.mode) {
	case IEEE802154_ADDR_NONE:
		if (hdr->source.mode == IEEE802154_ADDR_NONE)
			/* ACK comes with both addresses empty */
			skb->pkt_type = PACKET_HOST;
		else if (!wpan_dev->parent)
			/* No dest means PAN coordinator is the recipient */
			skb->pkt_type = PACKET_HOST;
		else
			/* We are not the PAN coordinator, just relaying */
			skb->pkt_type = PACKET_OTHERHOST;
		break;
	case IEEE802154_ADDR_LONG:
		if (mac_cb(skb)->dest.pan_id != span &&
		    mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
			skb->pkt_type = PACKET_OTHERHOST;
		else if (mac_cb(skb)->dest.extended_addr == wpan_dev->extended_addr)
			skb->pkt_type = PACKET_HOST;
		else
			skb->pkt_type = PACKET_OTHERHOST;
		break;
	case IEEE802154_ADDR_SHORT:
		if (mac_cb(skb)->dest.pan_id != span &&
		    mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST))
			skb->pkt_type = PACKET_OTHERHOST;
		else if (mac_cb(skb)->dest.short_addr == sshort)
			skb->pkt_type = PACKET_HOST;
		else if (mac_cb(skb)->dest.short_addr ==
			  cpu_to_le16(IEEE802154_ADDR_BROADCAST))
			skb->pkt_type = PACKET_BROADCAST;
		else
			skb->pkt_type = PACKET_OTHERHOST;
		break;
	default:
		pr_debug("invalid dest mode\n");
		goto fail;
	}

	skb->dev = sdata->dev;

	/* TODO this should be moved after netif_receive_skb call, otherwise
	 * wireshark will show a mac header with security fields and the
	 * payload is already decrypted.
	 */
	rc = mac802154_llsec_decrypt(&sdata->sec, skb);
	if (rc) {
		pr_debug("decryption failed: %i\n", rc);
		goto fail;
	}

	sdata->dev->stats.rx_packets++;
	sdata->dev->stats.rx_bytes += skb->len;

	switch (mac_cb(skb)->type) {
	case IEEE802154_FC_TYPE_BEACON:
		dev_dbg(&sdata->dev->dev, "BEACON received\n");
		if (!mac802154_is_scanning(sdata->local))
			goto fail;

		mac_pkt = kzalloc_obj(*mac_pkt, GFP_ATOMIC);
		if (!mac_pkt)
			goto fail;

		mac_pkt->skb = skb_get(skb);
		mac_pkt->sdata = sdata;
		mac_pkt->page = sdata->local->scan_page;
		mac_pkt->channel = sdata->local->scan_channel;
		list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list);
		queue_work(sdata->local->mac_wq, &sdata->local->rx_beacon_work);
		return NET_RX_SUCCESS;

	case IEEE802154_FC_TYPE_MAC_CMD:
		dev_dbg(&sdata->dev->dev, "MAC COMMAND received\n");
		mac_pkt = kzalloc_obj(*mac_pkt, GFP_ATOMIC);
		if (!mac_pkt)
			goto fail;

		mac_pkt->skb = skb_get(skb);
		mac_pkt->sdata = sdata;
		list_add_tail(&mac_pkt->node, &sdata->local->rx_mac_cmd_list);
		queue_work(sdata->local->mac_wq, &sdata->local->rx_mac_cmd_work);
		return NET_RX_SUCCESS;

Annotation

Implementation Notes