/** * tipc_msg_reverse(): swap source and destination addresses and add error code * @buf: buffer containing message to be reversed * @dnode: return value: node where to send message after reversal * @err: error code to be set in message * Consumes buffer if failure * Returns true if success, otherwise false */ bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err) { struct tipc_msg *msg = buf_msg(buf); uint imp = msg_importance(msg); struct tipc_msg ohdr; uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE); if (skb_linearize(buf)) goto exit; if (msg_dest_droppable(msg)) goto exit; if (msg_errcode(msg)) goto exit; memcpy(&ohdr, msg, msg_hdr_sz(msg)); imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE); if (msg_isdata(msg)) msg_set_importance(msg, imp); msg_set_errcode(msg, err); msg_set_origport(msg, msg_destport(&ohdr)); msg_set_destport(msg, msg_origport(&ohdr)); msg_set_prevnode(msg, tipc_own_addr); if (!msg_short(msg)) { msg_set_orignode(msg, msg_destnode(&ohdr)); msg_set_destnode(msg, msg_orignode(&ohdr)); } msg_set_size(msg, msg_hdr_sz(msg) + rdsz); skb_trim(buf, msg_size(msg)); skb_orphan(buf); *dnode = msg_orignode(&ohdr); return true; exit: kfree_skb(buf); return false; }
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, u32 destnode) { memset(m, 0, hsize); msg_set_version(m); msg_set_user(m, user); msg_set_hdr_sz(m, hsize); msg_set_size(m, hsize); msg_set_prevnode(m, tipc_own_addr); msg_set_type(m, type); msg_set_orignode(m, tipc_own_addr); msg_set_destnode(m, destnode); }
struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz, uint data_sz, u32 dnode, u32 onode, u32 dport, u32 oport, int errcode) { struct tipc_msg *msg; struct sk_buff *buf; buf = tipc_buf_acquire(hdr_sz + data_sz); if (unlikely(!buf)) return NULL; msg = buf_msg(buf); tipc_msg_init(msg, user, type, hdr_sz, dnode); msg_set_size(msg, hdr_sz + data_sz); msg_set_prevnode(msg, onode); msg_set_origport(msg, oport); msg_set_destport(msg, dport); msg_set_errcode(msg, errcode); if (hdr_sz > SHORT_H_SIZE) { msg_set_orignode(msg, onode); msg_set_destnode(msg, dnode); } return buf; }