Commit f507a9b6 authored by Bjorn Andersson's avatar Bjorn Andersson Committed by David S. Miller

net: qrtr: Use sk_buff->cb in receive path

Rather than parsing the header of incoming messages throughout the
implementation do it once when we retrieve the message and store the
relevant information in the "cb" member of the sk_buff.

This allows us to, in a later commit, decode version 2 messages into
this same structure.
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a7959c7
...@@ -48,6 +48,16 @@ struct qrtr_hdr { ...@@ -48,6 +48,16 @@ struct qrtr_hdr {
__le32 dst_port_id; __le32 dst_port_id;
} __packed; } __packed;
struct qrtr_cb {
u32 src_node;
u32 src_port;
u32 dst_node;
u32 dst_port;
u8 type;
u8 confirm_rx;
};
#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr) #define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
struct qrtr_sock { struct qrtr_sock {
...@@ -216,6 +226,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) ...@@ -216,6 +226,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
struct qrtr_node *node = ep->node; struct qrtr_node *node = ep->node;
const struct qrtr_hdr *phdr = data; const struct qrtr_hdr *phdr = data;
struct sk_buff *skb; struct sk_buff *skb;
struct qrtr_cb *cb;
unsigned int psize; unsigned int psize;
unsigned int size; unsigned int size;
unsigned int type; unsigned int type;
...@@ -245,8 +256,15 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) ...@@ -245,8 +256,15 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
skb_reset_transport_header(skb); cb = (struct qrtr_cb *)skb->cb;
skb_put_data(skb, data, len); cb->src_node = le32_to_cpu(phdr->src_node_id);
cb->src_port = le32_to_cpu(phdr->src_port_id);
cb->dst_node = le32_to_cpu(phdr->dst_node_id);
cb->dst_port = le32_to_cpu(phdr->dst_port_id);
cb->type = type;
cb->confirm_rx = !!phdr->confirm_rx;
skb_put_data(skb, data + QRTR_HDR_SIZE, size);
skb_queue_tail(&node->rx_queue, skb); skb_queue_tail(&node->rx_queue, skb);
schedule_work(&node->work); schedule_work(&node->work);
...@@ -295,26 +313,20 @@ static void qrtr_node_rx_work(struct work_struct *work) ...@@ -295,26 +313,20 @@ static void qrtr_node_rx_work(struct work_struct *work)
struct sk_buff *skb; struct sk_buff *skb;
while ((skb = skb_dequeue(&node->rx_queue)) != NULL) { while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
const struct qrtr_hdr *phdr;
u32 dst_node, dst_port;
struct qrtr_sock *ipc; struct qrtr_sock *ipc;
u32 src_node; struct qrtr_cb *cb;
int confirm; int confirm;
phdr = (const struct qrtr_hdr *)skb_transport_header(skb); cb = (struct qrtr_cb *)skb->cb;
src_node = le32_to_cpu(phdr->src_node_id); src.sq_node = cb->src_node;
dst_node = le32_to_cpu(phdr->dst_node_id); src.sq_port = cb->src_port;
dst_port = le32_to_cpu(phdr->dst_port_id); dst.sq_node = cb->dst_node;
confirm = !!phdr->confirm_rx; dst.sq_port = cb->dst_port;
confirm = !!cb->confirm_rx;
src.sq_node = src_node; qrtr_node_assign(node, cb->src_node);
src.sq_port = le32_to_cpu(phdr->src_port_id);
dst.sq_node = dst_node;
dst.sq_port = dst_port;
qrtr_node_assign(node, src_node); ipc = qrtr_port_lookup(cb->dst_port);
ipc = qrtr_port_lookup(dst_port);
if (!ipc) { if (!ipc) {
kfree_skb(skb); kfree_skb(skb);
} else { } else {
...@@ -604,7 +616,7 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb, ...@@ -604,7 +616,7 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
struct sockaddr_qrtr *to) struct sockaddr_qrtr *to)
{ {
struct qrtr_sock *ipc; struct qrtr_sock *ipc;
struct qrtr_hdr *phdr; struct qrtr_cb *cb;
ipc = qrtr_port_lookup(to->sq_port); ipc = qrtr_port_lookup(to->sq_port);
if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */ if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
...@@ -612,11 +624,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb, ...@@ -612,11 +624,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
return -ENODEV; return -ENODEV;
} }
phdr = skb_push(skb, QRTR_HDR_SIZE); cb = (struct qrtr_cb *)skb->cb;
skb_reset_transport_header(skb); cb->src_node = from->sq_node;
cb->src_port = from->sq_port;
phdr->src_node_id = cpu_to_le32(from->sq_node);
phdr->src_port_id = cpu_to_le32(from->sq_port);
if (sock_queue_rcv_skb(&ipc->sk, skb)) { if (sock_queue_rcv_skb(&ipc->sk, skb)) {
qrtr_port_put(ipc); qrtr_port_put(ipc);
...@@ -750,9 +760,9 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, ...@@ -750,9 +760,9 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags) size_t size, int flags)
{ {
DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name); DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
const struct qrtr_hdr *phdr;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sk_buff *skb; struct sk_buff *skb;
struct qrtr_cb *cb;
int copied, rc; int copied, rc;
lock_sock(sk); lock_sock(sk);
...@@ -769,22 +779,22 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, ...@@ -769,22 +779,22 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
return rc; return rc;
} }
phdr = (const struct qrtr_hdr *)skb_transport_header(skb); copied = skb->len;
copied = le32_to_cpu(phdr->size);
if (copied > size) { if (copied > size) {
copied = size; copied = size;
msg->msg_flags |= MSG_TRUNC; msg->msg_flags |= MSG_TRUNC;
} }
rc = skb_copy_datagram_msg(skb, QRTR_HDR_SIZE, msg, copied); rc = skb_copy_datagram_msg(skb, 0, msg, copied);
if (rc < 0) if (rc < 0)
goto out; goto out;
rc = copied; rc = copied;
if (addr) { if (addr) {
cb = (struct qrtr_cb *)skb->cb;
addr->sq_family = AF_QIPCRTR; addr->sq_family = AF_QIPCRTR;
addr->sq_node = le32_to_cpu(phdr->src_node_id); addr->sq_node = cb->src_node;
addr->sq_port = le32_to_cpu(phdr->src_port_id); addr->sq_port = cb->src_port;
msg->msg_namelen = sizeof(*addr); msg->msg_namelen = sizeof(*addr);
} }
...@@ -877,7 +887,7 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) ...@@ -877,7 +887,7 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case TIOCINQ: case TIOCINQ:
skb = skb_peek(&sk->sk_receive_queue); skb = skb_peek(&sk->sk_receive_queue);
if (skb) if (skb)
len = skb->len - QRTR_HDR_SIZE; len = skb->len;
rc = put_user(len, (int __user *)argp); rc = put_user(len, (int __user *)argp);
break; break;
case SIOCGIFADDR: case SIOCGIFADDR:
......
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