Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85fa006f authored by Dedy Lansky's avatar Dedy Lansky Committed by Greg Kroah-Hartman
Browse files

cfg80211/mac80211: make ieee80211_send_layer2_update a public function



commit 30ca1aa536211f5ac3de0173513a7a99a98a97f3 upstream.

Make ieee80211_send_layer2_update() a common function so other drivers
can re-use it.

Signed-off-by: default avatarDedy Lansky <dlansky@codeaurora.org>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
[bwh: Backported to 4.19 as dependency of commit 3e493173b784
 "mac80211: Do not send Layer 2 Update frame before authorization"]
Signed-off-by: default avatarBen Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e5caf1d5
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -4733,6 +4733,17 @@ static inline const u8 *cfg80211_find_ext_ie(u8 ext_eid, const u8 *ies, int len)
const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
				  const u8 *ies, int len);

/**
 * cfg80211_send_layer2_update - send layer 2 update frame
 *
 * @dev: network device
 * @addr: STA MAC address
 *
 * Wireless drivers can use this function to update forwarding tables in bridge
 * devices upon STA association.
 */
void cfg80211_send_layer2_update(struct net_device *dev, const u8 *addr);

/**
 * DOC: Regulatory enforcement infrastructure
 *
+2 −46
Original line number Diff line number Diff line
@@ -1096,50 +1096,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
	return 0;
}

/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
struct iapp_layer2_update {
	u8 da[ETH_ALEN];	/* broadcast */
	u8 sa[ETH_ALEN];	/* STA addr */
	__be16 len;		/* 6 */
	u8 dsap;		/* 0 */
	u8 ssap;		/* 0 */
	u8 control;
	u8 xid_info[3];
} __packed;

static void ieee80211_send_layer2_update(struct sta_info *sta)
{
	struct iapp_layer2_update *msg;
	struct sk_buff *skb;

	/* Send Level 2 Update Frame to update forwarding tables in layer 2
	 * bridge devices */

	skb = dev_alloc_skb(sizeof(*msg));
	if (!skb)
		return;
	msg = skb_put(skb, sizeof(*msg));

	/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
	 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */

	eth_broadcast_addr(msg->da);
	memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
	msg->len = htons(6);
	msg->dsap = 0;
	msg->ssap = 0x01;	/* NULL LSAP, CR Bit: Response */
	msg->control = 0xaf;	/* XID response lsb.1111F101.
				 * F=0 (no poll command; unsolicited frame) */
	msg->xid_info[0] = 0x81;	/* XID format identifier */
	msg->xid_info[1] = 1;	/* LLC types/classes: Type 1 LLC */
	msg->xid_info[2] = 0;	/* XID sender's receive window size (RW) */

	skb->dev = sta->sdata->dev;
	skb->protocol = eth_type_trans(skb, sta->sdata->dev);
	memset(skb->cb, 0, sizeof(skb->cb));
	netif_rx_ni(skb);
}

static int sta_apply_auth_flags(struct ieee80211_local *local,
				struct sta_info *sta,
				u32 mask, u32 set)
@@ -1508,7 +1464,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
	}

	if (layer2_update)
		ieee80211_send_layer2_update(sta);
		cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);

	rcu_read_unlock();

@@ -1610,7 +1566,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
		if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
			ieee80211_vif_inc_num_mcast(sta->sdata);

		ieee80211_send_layer2_update(sta);
		cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
	}

	err = sta_apply_parameters(local, sta, params);
+45 −0
Original line number Diff line number Diff line
@@ -1919,3 +1919,48 @@ bool cfg80211_iftype_allowed(struct wiphy *wiphy, enum nl80211_iftype iftype,
	return false;
}
EXPORT_SYMBOL(cfg80211_iftype_allowed);

/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
struct iapp_layer2_update {
	u8 da[ETH_ALEN];	/* broadcast */
	u8 sa[ETH_ALEN];	/* STA addr */
	__be16 len;		/* 6 */
	u8 dsap;		/* 0 */
	u8 ssap;		/* 0 */
	u8 control;
	u8 xid_info[3];
} __packed;

void cfg80211_send_layer2_update(struct net_device *dev, const u8 *addr)
{
	struct iapp_layer2_update *msg;
	struct sk_buff *skb;

	/* Send Level 2 Update Frame to update forwarding tables in layer 2
	 * bridge devices */

	skb = dev_alloc_skb(sizeof(*msg));
	if (!skb)
		return;
	msg = skb_put(skb, sizeof(*msg));

	/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
	 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */

	eth_broadcast_addr(msg->da);
	ether_addr_copy(msg->sa, addr);
	msg->len = htons(6);
	msg->dsap = 0;
	msg->ssap = 0x01;	/* NULL LSAP, CR Bit: Response */
	msg->control = 0xaf;	/* XID response lsb.1111F101.
				 * F=0 (no poll command; unsolicited frame) */
	msg->xid_info[0] = 0x81;	/* XID format identifier */
	msg->xid_info[1] = 1;	/* LLC types/classes: Type 1 LLC */
	msg->xid_info[2] = 0;	/* XID sender's receive window size (RW) */

	skb->dev = dev;
	skb->protocol = eth_type_trans(skb, dev);
	memset(skb->cb, 0, sizeof(skb->cb));
	netif_rx_ni(skb);
}
EXPORT_SYMBOL(cfg80211_send_layer2_update);