Commit 601f160b authored by Miquel Raynal's avatar Miquel Raynal
Browse files

mac802154: Handle association requests from peers



Coordinators may have to handle association requests from peers which
want to join the PAN. The logic involves:
- Acknowledging the request (done by hardware)
- If requested, a random short address that is free on this PAN should
  be chosen for the device.
- Sending an association response with the short address allocated for
  the peer and expecting it to be ack'ed.

If anything fails during this procedure, the peer is considered not
associated.

Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Acked-by: default avatarStefan Schmidt <stefan@datenfreihafen.org>
Acked-by: default avatarAlexander Aring <aahringo@redhat.com>
Link: https://lore.kernel.org/linux-wpan/20230927181214.129346-8-miquel.raynal@bootlin.com
parent 9860d9be
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -583,4 +583,11 @@ struct ieee802154_pan_device *
cfg802154_device_is_child(struct wpan_dev *wpan_dev,
			  struct ieee802154_addr *target);

/**
 * cfg802154_get_free_short_addr - Get a free address among the known devices
 * @wpan_dev: the wpan device
 * @return: a random short address expectedly unused on our PAN
 */
__le16 cfg802154_get_free_short_addr(struct wpan_dev *wpan_dev);

#endif /* __NET_CFG802154_H */
+6 −0
Original line number Diff line number Diff line
@@ -211,6 +211,12 @@ struct ieee802154_association_req_frame {
	struct ieee802154_assoc_req_pl assoc_req_pl;
};

struct ieee802154_association_resp_frame {
	struct ieee802154_hdr mhr;
	struct ieee802154_mac_cmd_pl mac_pl;
	struct ieee802154_assoc_resp_pl assoc_resp_pl;
};

struct ieee802154_disassociation_notif_frame {
	struct ieee802154_hdr mhr;
	struct ieee802154_mac_cmd_pl mac_pl;
+7 −0
Original line number Diff line number Diff line
@@ -200,11 +200,18 @@ EXPORT_SYMBOL(wpan_phy_free);

static void cfg802154_free_peer_structures(struct wpan_dev *wpan_dev)
{
	struct ieee802154_pan_device *child, *tmp;

	mutex_lock(&wpan_dev->association_lock);

	kfree(wpan_dev->parent);
	wpan_dev->parent = NULL;

	list_for_each_entry_safe(child, tmp, &wpan_dev->children, node) {
		list_del(&child->node);
		kfree(child);
	}

	mutex_unlock(&wpan_dev->association_lock);
}

+30 −0
Original line number Diff line number Diff line
@@ -63,3 +63,33 @@ cfg802154_device_is_child(struct wpan_dev *wpan_dev,
	return NULL;
}
EXPORT_SYMBOL_GPL(cfg802154_device_is_child);

__le16 cfg802154_get_free_short_addr(struct wpan_dev *wpan_dev)
{
	struct ieee802154_pan_device *child;
	__le16 addr;

	lockdep_assert_held(&wpan_dev->association_lock);

	do {
		get_random_bytes(&addr, 2);
		if (addr == cpu_to_le16(IEEE802154_ADDR_SHORT_BROADCAST) ||
		    addr == cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC))
			continue;

		if (wpan_dev->short_addr == addr)
			continue;

		if (wpan_dev->parent && wpan_dev->parent->short_addr == addr)
			continue;

		list_for_each_entry(child, &wpan_dev->children, node)
			if (child->short_addr == addr)
				continue;

		break;
	} while (1);

	return addr;
}
EXPORT_SYMBOL_GPL(cfg802154_get_free_short_addr);
+2 −0
Original line number Diff line number Diff line
@@ -318,6 +318,8 @@ static inline bool mac802154_is_associating(struct ieee802154_local *local)
int mac802154_send_disassociation_notif(struct ieee802154_sub_if_data *sdata,
					struct ieee802154_pan_device *target,
					u8 reason);
int mac802154_process_association_req(struct ieee802154_sub_if_data *sdata,
				      struct sk_buff *skb);

/* interface handling */
int ieee802154_iface_init(void);
Loading