3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-22 04:32:37 +01:00

hwsim: add DropAck rule property

The hwsim rules did not treat frames and ACKs any differently which
can mislead the developer especially when setting a rule prefix.
If a prefix was used the frame ACK was actually being matched against
the original frame payload which seems wrong because the ACK is not
the original frame.

Though strange, matching the frame prefix on an ACK has its place if
the developer wants to block just the ACK rather than the frame so
to make this case more clear 'DropAck' was added as a rule property.
And only if this is true will an ACK be checked and potentially
dropped.

To maintain the current hwsim behavior DropAck will default to true.
This commit is contained in:
James Prestwood 2021-09-07 14:14:44 -07:00 committed by Denis Kenzior
parent 06ee649a91
commit bedd20b08e

View File

@ -124,6 +124,7 @@ struct hwsim_rule {
bool destination_any : 1;
bool bidirectional : 1;
bool drop : 1;
bool drop_ack : 1;
bool enabled : 1;
uint32_t frequency;
int priority;
@ -1170,7 +1171,7 @@ static bool radio_match_addr(const struct radio_info_rec *radio,
static void process_rules(const struct radio_info_rec *src_radio,
const struct radio_info_rec *dst_radio,
struct hwsim_frame *frame, bool *drop,
struct hwsim_frame *frame, bool ack, bool *drop,
uint32_t *delay)
{
const struct l_queue_entry *rule_entry;
@ -1224,7 +1225,9 @@ static void process_rules(const struct radio_info_rec *src_radio,
if (rule->signal)
frame->signal = rule->signal / 100;
*drop = rule->drop;
/* Don't drop if this is an ACK, unless drop_ack is set */
if (!ack || (ack && rule->drop_ack))
*drop = rule->drop;
if (delay)
*delay = rule->delay;
@ -1314,7 +1317,7 @@ static void hwsim_frame_unref(struct hwsim_frame *frame)
bool drop = false;
process_rules(frame->ack_radio, frame->src_radio,
frame, &drop, NULL);
frame, true, &drop, NULL);
if (!drop)
frame->flags |= HWSIM_TX_STAT_ACK;
@ -1458,7 +1461,8 @@ static void process_frame(struct hwsim_frame *frame)
bool drop_mcast = false;
if (util_is_broadcast_address(frame->dst_ether_addr))
process_rules(frame->src_radio, NULL, frame, &drop_mcast, NULL);
process_rules(frame->src_radio, NULL, frame, false,
&drop_mcast, NULL);
for (entry = l_queue_get_entries(radio_info); entry;
entry = entry->next) {
@ -1498,7 +1502,8 @@ static void process_frame(struct hwsim_frame *frame)
continue;
}
process_rules(frame->src_radio, radio, frame, &drop, &delay);
process_rules(frame->src_radio, radio, frame, false,
&drop, &delay);
if (drop)
continue;
@ -2015,6 +2020,7 @@ static struct l_dbus_message *rule_add(struct l_dbus *dbus,
rule->delay = 0;
rule->enabled = false;
rule->match_times = -1;
rule->drop_ack = true;
if (!rules)
rules = l_queue_new();
@ -2450,6 +2456,37 @@ static struct l_dbus_message *rule_property_set_match_times(
return l_dbus_message_new_method_return(message);
}
static bool rule_property_get_drop_ack(struct l_dbus *dbus,
struct l_dbus_message *message,
struct l_dbus_message_builder *builder,
void *user_data)
{
struct hwsim_rule *rule = user_data;
bool bval = rule->drop_ack;
l_dbus_message_builder_append_basic(builder, 'b', &bval);
return true;
}
static struct l_dbus_message *rule_property_set_drop_ack(
struct l_dbus *dbus,
struct l_dbus_message *message,
struct l_dbus_message_iter *new_value,
l_dbus_property_complete_cb_t complete,
void *user_data)
{
struct hwsim_rule *rule = user_data;
bool bval;
if (!l_dbus_message_iter_get_variant(new_value, "b", &bval))
return dbus_error_invalid_args(message);
rule->drop_ack = bval;
return l_dbus_message_new_method_return(message);
}
static void setup_rule_interface(struct l_dbus_interface *interface)
{
l_dbus_interface_method(interface, "Remove", 0, rule_remove, "", "");
@ -2498,6 +2535,10 @@ static void setup_rule_interface(struct l_dbus_interface *interface)
L_DBUS_PROPERTY_FLAG_AUTO_EMIT, "q",
rule_property_get_match_times,
rule_property_set_match_times);
l_dbus_interface_property(interface, "DropAck",
L_DBUS_PROPERTY_FLAG_AUTO_EMIT, "b",
rule_property_get_drop_ack,
rule_property_set_drop_ack);
}
static void request_name_callback(struct l_dbus *dbus, bool success,