/** * tipc_msg_eval: determine fate of message that found no destination * @buf: the buffer containing the message. * @dnode: return value: next-hop node, if message to be forwarded * @err: error code to use, if message to be rejected * * Does not consume buffer * Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error * code if message to be rejected */ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode) { struct tipc_msg *msg = buf_msg(buf); u32 dport; if (msg_type(msg) != TIPC_NAMED_MSG) return -TIPC_ERR_NO_PORT; if (skb_linearize(buf)) return -TIPC_ERR_NO_NAME; if (msg_data_sz(msg) > MAX_FORWARD_SIZE) return -TIPC_ERR_NO_NAME; if (msg_reroute_cnt(msg) > 0) return -TIPC_ERR_NO_NAME; *dnode = addr_domain(msg_lookup_scope(msg)); dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), dnode); if (!dport) return -TIPC_ERR_NO_NAME; msg_incr_reroute_cnt(msg); msg_set_destnode(msg, *dnode); msg_set_destport(msg, dport); return TIPC_OK; }
void tipc_net_route_msg(struct sk_buff *buf) { struct tipc_msg *msg; u32 dnode; if (!buf) return; msg = buf_msg(buf); msg_incr_reroute_cnt(msg); if (msg_reroute_cnt(msg) > 6) { if (msg_errcode(msg)) { msg_dbg(msg, "NET>DISC>:"); buf_discard(buf); } else { msg_dbg(msg, "NET>REJ>:"); tipc_reject_msg(buf, msg_destport(msg) ? TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME); } return; } msg_dbg(msg, "tipc_net->rout: "); /* Handle message for this node */ dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); if (tipc_in_scope(dnode, tipc_own_addr)) { if (msg_isdata(msg)) { if (msg_mcast(msg)) tipc_port_recv_mcast(buf, NULL); else if (msg_destport(msg)) tipc_port_recv_msg(buf); else net_route_named_msg(buf); return; } switch (msg_user(msg)) { case ROUTE_DISTRIBUTOR: tipc_cltr_recv_routing_table(buf); break; case NAME_DISTRIBUTOR: tipc_named_recv(buf); break; case CONN_MANAGER: tipc_port_recv_proto_msg(buf); break; default: msg_dbg(msg,"DROP/NET/<REC<"); buf_discard(buf); } return; } /* Handle message for another node */ msg_dbg(msg, "NET>SEND>: "); tipc_link_send(buf, dnode, msg_link_selector(msg)); }