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>
This commit is contained in:
parent
64f9eca064
commit
8acc8ee465
|
@ -111,6 +111,8 @@ struct qrtr_node {
|
||||||
struct list_head item;
|
struct list_head item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb);
|
||||||
|
|
||||||
/* Release node resources and free the node.
|
/* Release node resources and free the node.
|
||||||
*
|
*
|
||||||
* Do not call directly, use qrtr_node_release. To be used with
|
* 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,
|
||||||
return skb;
|
return skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate and construct a BYE message to signal remote termination */
|
||||||
|
static struct sk_buff *qrtr_alloc_local_bye(u32 src_node)
|
||||||
|
{
|
||||||
|
const int pkt_len = 20;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
__le32 *buf;
|
||||||
|
|
||||||
|
skb = qrtr_alloc_ctrl_packet(QRTR_TYPE_BYE, pkt_len,
|
||||||
|
src_node, qrtr_local_nid);
|
||||||
|
if (!skb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
buf = (__le32 *)skb_put(skb, pkt_len);
|
||||||
|
memset(buf, 0, pkt_len);
|
||||||
|
buf[0] = cpu_to_le32(QRTR_TYPE_BYE);
|
||||||
|
|
||||||
|
return skb;
|
||||||
|
}
|
||||||
|
|
||||||
static struct qrtr_sock *qrtr_port_lookup(int port);
|
static struct qrtr_sock *qrtr_port_lookup(int port);
|
||||||
static void qrtr_port_put(struct qrtr_sock *ipc);
|
static void qrtr_port_put(struct qrtr_sock *ipc);
|
||||||
|
|
||||||
|
@ -382,11 +403,17 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_register);
|
||||||
void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
|
void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
|
||||||
{
|
{
|
||||||
struct qrtr_node *node = ep->node;
|
struct qrtr_node *node = ep->node;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
mutex_lock(&node->ep_lock);
|
mutex_lock(&node->ep_lock);
|
||||||
node->ep = NULL;
|
node->ep = NULL;
|
||||||
mutex_unlock(&node->ep_lock);
|
mutex_unlock(&node->ep_lock);
|
||||||
|
|
||||||
|
/* Notify the local controller about the event */
|
||||||
|
skb = qrtr_alloc_local_bye(node->nid);
|
||||||
|
if (skb)
|
||||||
|
qrtr_local_enqueue(NULL, skb);
|
||||||
|
|
||||||
qrtr_node_release(node);
|
qrtr_node_release(node);
|
||||||
ep->node = NULL;
|
ep->node = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue