summaryrefslogtreecommitdiffstats
path: root/net/qrtr
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2017-06-07 17:07:38 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-08 11:34:57 -0400
commit1784473b242585f407d3e75654d5b06f462a355b (patch)
treec70b725db6818936a335a95948ac2e9a6b92eb42 /net/qrtr
parent8acc8ee465e69ed47bc9cde8d271a1189648d762 (diff)
net: qrtr: Broadcast DEL_CLIENT message when endpoint is closed
Per the QMUXv2 protocol specificiation a DEL_CLIENT message should be broadcasted when an endpoint is disconnected. The protocol specification does suggest that the router can keep track of which nodes the endpoint has been communicating with to not wake up sleeping remotes unecessarily, but implementation of this suggestion is left for the future. Cc: Courtney Cavin <ccavin@gmail.com> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/qrtr')
-rw-r--r--net/qrtr/qrtr.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index e8cbab23d667..d7516098b5aa 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -112,6 +112,7 @@ struct qrtr_node {
112}; 112};
113 113
114static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb); 114static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb);
115static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb);
115 116
116/* Release node resources and free the node. 117/* Release node resources and free the node.
117 * 118 *
@@ -312,6 +313,26 @@ static struct sk_buff *qrtr_alloc_local_bye(u32 src_node)
312 return skb; 313 return skb;
313} 314}
314 315
316static struct sk_buff *qrtr_alloc_del_client(struct sockaddr_qrtr *sq)
317{
318 const int pkt_len = 20;
319 struct sk_buff *skb;
320 __le32 *buf;
321
322 skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_DEL_CLIENT, pkt_len,
323 sq->sq_node, QRTR_NODE_BCAST);
324 if (!skb)
325 return NULL;
326
327 buf = (__le32 *)skb_put(skb, pkt_len);
328 memset(buf, 0, pkt_len);
329 buf[0] = cpu_to_le32(QRTR_TYPE_DEL_CLIENT);
330 buf[1] = cpu_to_le32(sq->sq_node);
331 buf[2] = cpu_to_le32(sq->sq_port);
332
333 return skb;
334}
335
315static struct qrtr_sock *qrtr_port_lookup(int port); 336static struct qrtr_sock *qrtr_port_lookup(int port);
316static void qrtr_port_put(struct qrtr_sock *ipc); 337static void qrtr_port_put(struct qrtr_sock *ipc);
317 338
@@ -448,8 +469,15 @@ static void qrtr_port_put(struct qrtr_sock *ipc)
448/* Remove port assignment. */ 469/* Remove port assignment. */
449static void qrtr_port_remove(struct qrtr_sock *ipc) 470static void qrtr_port_remove(struct qrtr_sock *ipc)
450{ 471{
472 struct sk_buff *skb;
451 int port = ipc->us.sq_port; 473 int port = ipc->us.sq_port;
452 474
475 skb = qrtr_alloc_del_client(&ipc->us);
476 if (skb) {
477 skb_set_owner_w(skb, &ipc->sk);
478 qrtr_bcast_enqueue(NULL, skb);
479 }
480
453 if (port == QRTR_PORT_CTRL) 481 if (port == QRTR_PORT_CTRL)
454 port = 0; 482 port = 0;
455 483