Commit 2b531294 authored by Marcel Holtmann's avatar Marcel Holtmann Committed by Johan Hedberg

Bluetooth: Simplify packet copy in hci_send_to_monitor function

Within the monitor functionality, the global atomic variable called
monitor_promisc ensures that no memory allocation happend when there
is actually no client listening. This means it is safe to just create
a copy of the skb since it is guaranteed that at least one client
exists. No extra checks needed.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
parent 15762fa7
...@@ -221,6 +221,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -221,6 +221,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct sock *sk; struct sock *sk;
struct sk_buff *skb_copy = NULL; struct sk_buff *skb_copy = NULL;
struct hci_mon_hdr *hdr;
__le16 opcode; __le16 opcode;
if (!atomic_read(&monitor_promisc)) if (!atomic_read(&monitor_promisc))
...@@ -251,6 +252,17 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -251,6 +252,17 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
return; return;
} }
/* Create a private copy with headroom */
skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC, true);
if (!skb_copy)
return;
/* Put header before the data */
hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
hdr->opcode = opcode;
hdr->index = cpu_to_le16(hdev->id);
hdr->len = cpu_to_le16(skb->len);
read_lock(&hci_sk_list.lock); read_lock(&hci_sk_list.lock);
sk_for_each(sk, &hci_sk_list.head) { sk_for_each(sk, &hci_sk_list.head) {
...@@ -262,22 +274,6 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -262,22 +274,6 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR) if (hci_pi(sk)->channel != HCI_CHANNEL_MONITOR)
continue; continue;
if (!skb_copy) {
struct hci_mon_hdr *hdr;
/* Create a private copy with headroom */
skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE,
GFP_ATOMIC, true);
if (!skb_copy)
continue;
/* Put header before the data */
hdr = (void *) skb_push(skb_copy, HCI_MON_HDR_SIZE);
hdr->opcode = opcode;
hdr->index = cpu_to_le16(hdev->id);
hdr->len = cpu_to_le16(skb->len);
}
nskb = skb_clone(skb_copy, GFP_ATOMIC); nskb = skb_clone(skb_copy, GFP_ATOMIC);
if (!nskb) if (!nskb)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment