Loading include/uapi/linux/qrtr.h +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -43,6 +45,11 @@ struct qrtr_ctrl_pkt { __le32 node; __le32 port; } client; struct { __le32 rsvd; __le32 node; } proc; }; } __packed; Loading net/qrtr/qrtr.c +57 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); Loading net/qrtr/qrtr.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
include/uapi/linux/qrtr.h +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -43,6 +45,11 @@ struct qrtr_ctrl_pkt { __le32 node; __le32 port; } client; struct { __le32 rsvd; __le32 node; } proc; }; } __packed; Loading
net/qrtr/qrtr.c +57 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); Loading
net/qrtr/qrtr.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 Loading