ieee802154: hwsim: Save the current filtering level and use it

Save the requested filtering level in the ->set_promiscuous()
helper. The logic is: either we want to enable promiscuous mode and we
want to disable filters entirely, or we want to use the highest
filtering level by default. This is of course an assumption that only
works today, but if in the future intermediate levels (such as scan
filtering level) are implemented in the core, this logic will need to be
updated. This would imply replacing ->set_promiscuous() by something
more fine grained anyway, so we are probably safe with this assumption.

Once saved in the PIB structure, we can use this value instead of trying
to access the PHY structure to know what hardware filtering level has
been advertised.

Suggested-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Acked-by: Alexander Aring <aahringo@redhat.com>
Link: https://lore.kernel.org/r/20221019134423.877169-3-miquel.raynal@bootlin.com
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
This commit is contained in:
Miquel Raynal 2022-10-19 15:44:22 +02:00 committed by Stefan Schmidt
parent 9a60850e8c
commit 19177eedcf

View File

@ -49,6 +49,7 @@ struct hwsim_pib {
u8 page;
u8 channel;
struct ieee802154_hw_addr_filt filt;
enum ieee802154_filtering_level filt_level;
struct rcu_head rcu;
};
@ -91,7 +92,8 @@ static int hwsim_hw_ed(struct ieee802154_hw *hw, u8 *level)
}
static int hwsim_update_pib(struct ieee802154_hw *hw, u8 page, u8 channel,
struct ieee802154_hw_addr_filt *filt)
struct ieee802154_hw_addr_filt *filt,
enum ieee802154_filtering_level filt_level)
{
struct hwsim_phy *phy = hw->priv;
struct hwsim_pib *pib, *pib_old;
@ -108,6 +110,7 @@ static int hwsim_update_pib(struct ieee802154_hw *hw, u8 page, u8 channel,
pib->filt.pan_id = filt->pan_id;
pib->filt.ieee_addr = filt->ieee_addr;
pib->filt.pan_coord = filt->pan_coord;
pib->filt_level = filt_level;
rcu_assign_pointer(phy->pib, pib);
kfree_rcu(pib_old, rcu);
@ -122,7 +125,7 @@ static int hwsim_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
rcu_read_lock();
pib = rcu_dereference(phy->pib);
ret = hwsim_update_pib(hw, page, channel, &pib->filt);
ret = hwsim_update_pib(hw, page, channel, &pib->filt, pib->filt_level);
rcu_read_unlock();
return ret;
@ -138,7 +141,7 @@ static int hwsim_hw_addr_filt(struct ieee802154_hw *hw,
rcu_read_lock();
pib = rcu_dereference(phy->pib);
ret = hwsim_update_pib(hw, pib->page, pib->channel, filt);
ret = hwsim_update_pib(hw, pib->page, pib->channel, filt, pib->filt_level);
rcu_read_unlock();
return ret;
@ -162,7 +165,7 @@ static void hwsim_hw_receive(struct ieee802154_hw *hw, struct sk_buff *skb,
memcpy(&hdr, skb->data, 3);
/* Level 4 filtering: Frame fields validity */
if (hw->phy->filtering == IEEE802154_FILTERING_4_FRAME_FIELDS) {
if (pib->filt_level == IEEE802154_FILTERING_4_FRAME_FIELDS) {
/* a) Drop reserved frame types */
switch (mac_cb(skb)->type) {
case IEEE802154_FC_TYPE_BEACON:
@ -305,7 +308,22 @@ static void hwsim_hw_stop(struct ieee802154_hw *hw)
static int
hwsim_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
{
return 0;
enum ieee802154_filtering_level filt_level;
struct hwsim_phy *phy = hw->priv;
struct hwsim_pib *pib;
int ret;
if (on)
filt_level = IEEE802154_FILTERING_NONE;
else
filt_level = IEEE802154_FILTERING_4_FRAME_FIELDS;
rcu_read_lock();
pib = rcu_dereference(phy->pib);
ret = hwsim_update_pib(hw, pib->page, pib->channel, &pib->filt, filt_level);
rcu_read_unlock();
return ret;
}
static const struct ieee802154_ops hwsim_ops = {