summaryrefslogtreecommitdiffstats
path: root/net/qrtr
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2017-06-07 17:07:37 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-08 11:34:57 -0400
commit8acc8ee465e69ed47bc9cde8d271a1189648d762 (patch)
treea6adef6a37a945006f5cca34320101de800e8b87 /net/qrtr
parent64f9eca06415dc820ff8a2263f846dc8199adb50 (diff)
net: qrtr: Inject BYE on remote termination
Per the QMUX protocol specification a terminating node can send a BYE control message to signal that the link is going down, upon receiving this all information about remote services should be discarded and local clients should be notified. In the event that the link was brought down abruptly the router is supposed to act like a BYE message has arrived. As there is no harm in receiving an extra BYE from the remote this patch implements the latter by injecting a BYE when the link to the remote is unregistered. The name service will receive the BYE and can implement the notification to the local clients. 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.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 86d35ed50da9..e8cbab23d667 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -111,6 +111,8 @@ struct qrtr_node {
111 struct list_head item; 111 struct list_head item;
112}; 112};
113 113
114static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb);
115
114/* Release node resources and free the node. 116/* Release node resources and free the node.
115 * 117 *
116 * Do not call directly, use qrtr_node_release. To be used with 118 * Do not call directly, use qrtr_node_release. To be used with
@@ -291,6 +293,25 @@ static struct sk_buff *qrtr_alloc_resume_tx(u32 src_node,
291 return skb; 293 return skb;
292} 294}
293 295
296/* Allocate and construct a BYE message to signal remote termination */
297static struct sk_buff *qrtr_alloc_local_bye(u32 src_node)
298{
299 const int pkt_len = 20;
300 struct sk_buff *skb;
301 __le32 *buf;
302
303 skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_BYE, pkt_len,
304 src_node, qrtr_local_nid);
305 if (!skb)
306 return NULL;
307
308 buf = (__le32 *)skb_put(skb, pkt_len);
309 memset(buf, 0, pkt_len);
310 buf[0] = cpu_to_le32(QRTR_TYPE_BYE);
311
312 return skb;
313}
314
294static struct qrtr_sock *qrtr_port_lookup(int port); 315static struct qrtr_sock *qrtr_port_lookup(int port);
295static void qrtr_port_put(struct qrtr_sock *ipc); 316static void qrtr_port_put(struct qrtr_sock *ipc);
296 317
@@ -382,11 +403,17 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_register);
382void qrtr_endpoint_unregister(struct qrtr_endpoint *ep) 403void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
383{ 404{
384 struct qrtr_node *node = ep->node; 405 struct qrtr_node *node = ep->node;
406 struct sk_buff *skb;
385 407
386 mutex_lock(&node->ep_lock); 408 mutex_lock(&node->ep_lock);
387 node->ep = NULL; 409 node->ep = NULL;
388 mutex_unlock(&node->ep_lock); 410 mutex_unlock(&node->ep_lock);
389 411
412 /* Notify the local controller about the event */
413 skb = qrtr_alloc_local_bye(node->nid);
414 if (skb)
415 qrtr_local_enqueue(NULL, skb);
416
390 qrtr_node_release(node); 417 qrtr_node_release(node);
391 ep->node = NULL; 418 ep->node = NULL;
392} 419}