提交 f81fe64f 编写于 作者: M Marcel Holtmann 提交者: Gustavo Padovan

Bluetooth: Refactor raw socket filter into more readable code

The handling of the raw socket filter is rather obscure code and it gets
in the way of future extensions. Instead of inline filtering in the raw
socket packet routine, refactor it into its own function.
Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: NGustavo Padovan <gustavo.padovan@collabora.co.uk>
上级 f2127810
......@@ -66,6 +66,46 @@ static struct bt_sock_list hci_sk_list = {
.lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
};
static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
{
struct hci_filter *flt;
int flt_type, flt_event;
/* Apply filter */
flt = &hci_pi(sk)->filter;
if (bt_cb(skb)->pkt_type == HCI_VENDOR_PKT)
flt_type = 0;
else
flt_type = bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS;
if (!test_bit(flt_type, &flt->type_mask))
return true;
/* Extra filter for event packets only */
if (bt_cb(skb)->pkt_type != HCI_EVENT_PKT)
return false;
flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
if (!hci_test_bit(flt_event, &flt->event_mask))
return true;
/* Check filter only when opcode is set */
if (!flt->opcode)
return false;
if (flt_event == HCI_EV_CMD_COMPLETE &&
flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
return true;
if (flt_event == HCI_EV_CMD_STATUS &&
flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
return true;
return false;
}
/* Send frame to RAW socket */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
{
......@@ -77,7 +117,6 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
read_lock(&hci_sk_list.lock);
sk_for_each(sk, &hci_sk_list.head) {
struct hci_filter *flt;
struct sk_buff *nskb;
if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
......@@ -90,30 +129,9 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
continue;
/* Apply filter */
flt = &hci_pi(sk)->filter;
if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ?
0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS),
&flt->type_mask))
if (is_filtered_packet(sk, skb))
continue;
if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) {
int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
if (!hci_test_bit(evt, &flt->event_mask))
continue;
if (flt->opcode &&
((evt == HCI_EV_CMD_COMPLETE &&
flt->opcode !=
get_unaligned((__le16 *)(skb->data + 3))) ||
(evt == HCI_EV_CMD_STATUS &&
flt->opcode !=
get_unaligned((__le16 *)(skb->data + 4)))))
continue;
}
if (!skb_copy) {
/* Create a private copy with headroom */
skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册