diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index f132d5c39e93..8e6a392ea34c 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -116,6 +116,7 @@ static DEFINE_MUTEX(qrtr_port_lock); * @ep: endpoint * @ref: reference count for node * @nid: node id + * @hello_sent: hello packet sent to endpoint * @qrtr_tx_flow: tree with tx counts per flow * @resume_tx: waiters for a resume tx from the remote * @qrtr_tx_lock: lock for qrtr_tx_flow @@ -128,6 +129,7 @@ struct qrtr_node { struct qrtr_endpoint *ep; struct kref ref; unsigned int nid; + atomic_t hello_sent; struct radix_tree_root qrtr_tx_flow; struct wait_queue_head resume_tx; @@ -336,6 +338,11 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, int rc = -ENODEV; int confirm_rx; + if (!atomic_read(&node->hello_sent) && type != QRTR_TYPE_HELLO) { + kfree_skb(skb); + return rc; + } + confirm_rx = qrtr_tx_wait(node, to->sq_node, to->sq_port, type); if (confirm_rx < 0) { kfree_skb(skb); @@ -371,6 +378,8 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, * confirm_rx flag if we dropped this one */ if (rc && confirm_rx) qrtr_tx_flow_failed(node, to->sq_node, to->sq_port); + if (!rc && type == QRTR_TYPE_HELLO) + atomic_inc(&node->hello_sent); return rc; } @@ -560,6 +569,7 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid) skb_queue_head_init(&node->rx_queue); node->nid = QRTR_EP_NID_AUTO; node->ep = ep; + atomic_set(&node->hello_sent, 0); mutex_init(&node->qrtr_tx_lock); INIT_RADIX_TREE(&node->qrtr_tx_flow, GFP_KERNEL); @@ -842,6 +852,8 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb, mutex_lock(&qrtr_node_lock); list_for_each_entry(node, &qrtr_all_nodes, item) { + if (node->nid == QRTR_EP_NID_AUTO) + continue; skbn = skb_clone(skb, GFP_KERNEL); if (!skbn) break;