Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22e63b1f authored by Chris Lew's avatar Chris Lew
Browse files

net: qrtr: Add support for DEL_PROC control message



Add the DEL_PROC control message for forwarding usecases. If this proc
acts as a gateway between two procs then they need a notification to
clean up servers and client ports when either goes down. This message
acts as notification to clean up all resources associated with the node
in the message.

Change-Id: I3514f54aa0221e104196e2120e929cc9f351847d
Signed-off-by: default avatarChris Lew <clew@codeaurora.org>
parent 8eef6a4a
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ enum qrtr_pkt_type {
	QRTR_TYPE_NEW_LOOKUP	= 10,
	QRTR_TYPE_DEL_LOOKUP	= 11,
};
#define QRTR_TYPE_DEL_PROC	13


struct qrtr_ctrl_pkt {
	__le32 cmd;
@@ -43,6 +45,11 @@ struct qrtr_ctrl_pkt {
			__le32 node;
			__le32 port;
		} client;

		struct {
			__le32 rsvd;
			__le32 node;
		} proc;
	};
} __packed;

+57 −0
Original line number Diff line number Diff line
@@ -838,6 +838,60 @@ static void qrtr_notify_bye(u32 nid)
	qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst, 0);
}

static u32 qrtr_calc_checksum(struct qrtr_ctrl_pkt *pkt)
{
	u32 checksum = 0;
	u32 mask = 0xffff;
	u16 upper_nb;
	u16 lower_nb;
	u32 *msg;
	int i;

	if (!pkt)
		return checksum;
	msg = (u32 *)pkt;

	for (i = 0; i < sizeof(*pkt) / sizeof(*msg); i++) {
		lower_nb = *msg & mask;
		upper_nb = (*msg >> 16) & mask;
		checksum += (upper_nb + lower_nb);
		msg++;
	}
	while (checksum > 0xffff)
		checksum = (checksum & mask) + ((checksum >> 16) & mask);

	checksum = ~checksum & mask;

	return checksum;
}

static void qrtr_fwd_del_proc(struct qrtr_node *src, unsigned int nid)
{
	struct sockaddr_qrtr from = {AF_QIPCRTR, 0, QRTR_PORT_CTRL};
	struct sockaddr_qrtr to = {AF_QIPCRTR, 0, QRTR_PORT_CTRL};
	struct qrtr_ctrl_pkt *pkt;
	struct qrtr_node *dst;
	struct sk_buff *skb;

	list_for_each_entry(dst, &qrtr_all_epts, item) {
		if (!qrtr_must_forward(src, dst, QRTR_TYPE_DEL_PROC))
			continue;

		skb = qrtr_alloc_ctrl_packet(&pkt);
		if (!skb)
			return;

		pkt->cmd = cpu_to_le32(QRTR_TYPE_DEL_PROC);
		pkt->proc.rsvd = QRTR_DEL_PROC_MAGIC;
		pkt->proc.node = cpu_to_le32(nid);
		pkt->proc.rsvd = cpu_to_le32(qrtr_calc_checksum(pkt));

		from.sq_node = src->nid;
		to.sq_node = dst->nid;
		qrtr_node_enqueue(dst, skb, QRTR_TYPE_DEL_PROC, &from, &to, 0);
	}
}

/**
 * qrtr_endpoint_unregister - unregister endpoint
 * @ep: endpoint to unregister
@@ -861,7 +915,10 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
			continue;

		spin_unlock_irqrestore(&qrtr_nodes_lock, flags);

		qrtr_notify_bye(iter.index);
		qrtr_fwd_del_proc(node, iter.index);

		spin_lock_irqsave(&qrtr_nodes_lock, flags);
	}
	spin_unlock_irqrestore(&qrtr_nodes_lock, flags);
+2 −0
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@ struct sk_buff;
#define QRTR_EP_NID_AUTO (-1)
#define QRTR_EP_NET_ID_AUTO (1)

#define QRTR_DEL_PROC_MAGIC	0xe111

/**
 * struct qrtr_endpoint - endpoint handle
 * @xmit: Callback for outgoing packets