⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 port.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	    ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);	if (p_ptr->publ.connected)		goto exit;	if (seq->lower > seq->upper)		goto exit;	if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE))		goto exit;	key = ref + p_ptr->pub_count + 1;	if (key == ref) {		res = -EADDRINUSE;		goto exit;	}	publ = tipc_nametbl_publish(seq->type, seq->lower, seq->upper,				    scope, p_ptr->publ.ref, key);	if (publ) {		list_add(&publ->pport_list, &p_ptr->publications);		p_ptr->pub_count++;		p_ptr->publ.published = 1;		res = TIPC_OK;	}exit:	tipc_port_unlock(p_ptr);	return res;}int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq){	struct port *p_ptr;	struct publication *publ;	struct publication *tpubl;	int res = -EINVAL;	p_ptr = tipc_port_lock(ref);	if (!p_ptr)		return -EINVAL;	if (!seq) {		list_for_each_entry_safe(publ, tpubl,					 &p_ptr->publications, pport_list) {			tipc_nametbl_withdraw(publ->type, publ->lower,					      publ->ref, publ->key);		}		res = TIPC_OK;	} else {		list_for_each_entry_safe(publ, tpubl,					 &p_ptr->publications, pport_list) {			if (publ->scope != scope)				continue;			if (publ->type != seq->type)				continue;			if (publ->lower != seq->lower)				continue;			if (publ->upper != seq->upper)				break;			tipc_nametbl_withdraw(publ->type, publ->lower,					      publ->ref, publ->key);			res = TIPC_OK;			break;		}	}	if (list_empty(&p_ptr->publications))		p_ptr->publ.published = 0;	tipc_port_unlock(p_ptr);	return res;}int tipc_connect2port(u32 ref, struct tipc_portid const *peer){	struct port *p_ptr;	struct tipc_msg *msg;	int res = -EINVAL;	p_ptr = tipc_port_lock(ref);	if (!p_ptr)		return -EINVAL;	if (p_ptr->publ.published || p_ptr->publ.connected)		goto exit;	if (!peer->ref)		goto exit;	msg = &p_ptr->publ.phdr;	msg_set_destnode(msg, peer->node);	msg_set_destport(msg, peer->ref);	msg_set_orignode(msg, tipc_own_addr);	msg_set_origport(msg, p_ptr->publ.ref);	msg_set_transp_seqno(msg, 42);	msg_set_type(msg, TIPC_CONN_MSG);	if (!may_route(peer->node))		msg_set_hdr_sz(msg, SHORT_H_SIZE);	else		msg_set_hdr_sz(msg, LONG_H_SIZE);	p_ptr->probing_interval = PROBING_INTERVAL;	p_ptr->probing_state = CONFIRMED;	p_ptr->publ.connected = 1;	k_start_timer(&p_ptr->timer, p_ptr->probing_interval);	tipc_nodesub_subscribe(&p_ptr->subscription,peer->node,			  (void *)(unsigned long)ref,			  (net_ev_handler)port_handle_node_down);	res = TIPC_OK;exit:	tipc_port_unlock(p_ptr);	p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref);	return res;}/* * tipc_disconnect(): Disconnect port form peer. *                    This is a node local operation. */int tipc_disconnect(u32 ref){	struct port *p_ptr;	int res = -ENOTCONN;	p_ptr = tipc_port_lock(ref);	if (!p_ptr)		return -EINVAL;	if (p_ptr->publ.connected) {		p_ptr->publ.connected = 0;		/* let timer expire on it's own to avoid deadlock! */		tipc_nodesub_unsubscribe(&p_ptr->subscription);		res = TIPC_OK;	}	tipc_port_unlock(p_ptr);	return res;}/* * tipc_shutdown(): Send a SHUTDOWN msg to peer and disconnect */int tipc_shutdown(u32 ref){	struct port *p_ptr;	struct sk_buff *buf = NULL;	p_ptr = tipc_port_lock(ref);	if (!p_ptr)		return -EINVAL;	if (p_ptr->publ.connected) {		u32 imp = msg_importance(&p_ptr->publ.phdr);		if (imp < TIPC_CRITICAL_IMPORTANCE)			imp++;		buf = port_build_proto_msg(port_peerport(p_ptr),					   port_peernode(p_ptr),					   ref,					   tipc_own_addr,					   imp,					   TIPC_CONN_MSG,					   TIPC_CONN_SHUTDOWN,					   port_out_seqno(p_ptr),					   0);	}	tipc_port_unlock(p_ptr);	tipc_net_route_msg(buf);	return tipc_disconnect(ref);}int tipc_isconnected(u32 ref, int *isconnected){	struct port *p_ptr;	p_ptr = tipc_port_lock(ref);	if (!p_ptr)		return -EINVAL;	*isconnected = p_ptr->publ.connected;	tipc_port_unlock(p_ptr);	return TIPC_OK;}int tipc_peer(u32 ref, struct tipc_portid *peer){	struct port *p_ptr;	int res;	p_ptr = tipc_port_lock(ref);	if (!p_ptr)		return -EINVAL;	if (p_ptr->publ.connected) {		peer->ref = port_peerport(p_ptr);		peer->node = port_peernode(p_ptr);		res = TIPC_OK;	} else		res = -ENOTCONN;	tipc_port_unlock(p_ptr);	return res;}int tipc_ref_valid(u32 ref){	/* Works irrespective of type */	return !!tipc_ref_deref(ref);}/* *  tipc_port_recv_sections(): Concatenate and deliver sectioned *                        message for this node. */int tipc_port_recv_sections(struct port *sender, unsigned int num_sect,		       struct iovec const *msg_sect){	struct sk_buff *buf;	int res;	res = msg_build(&sender->publ.phdr, msg_sect, num_sect,			MAX_MSG_SIZE, !sender->user_port, &buf);	if (likely(buf))		tipc_port_recv_msg(buf);	return res;}/** * tipc_send - send message sections on connection */int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect){	struct port *p_ptr;	u32 destnode;	int res;	p_ptr = tipc_port_deref(ref);	if (!p_ptr || !p_ptr->publ.connected)		return -EINVAL;	p_ptr->publ.congested = 1;	if (!tipc_port_congested(p_ptr)) {		destnode = port_peernode(p_ptr);		if (likely(destnode != tipc_own_addr))			res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,							   destnode);		else			res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);		if (likely(res != -ELINKCONG)) {			port_incr_out_seqno(p_ptr);			p_ptr->publ.congested = 0;			p_ptr->sent++;			return res;		}	}	if (port_unreliable(p_ptr)) {		p_ptr->publ.congested = 0;		/* Just calculate msg length and return */		return msg_calc_data_size(msg_sect, num_sect);	}	return -ELINKCONG;}/** * tipc_send_buf - send message buffer on connection */int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz){	struct port *p_ptr;	struct tipc_msg *msg;	u32 destnode;	u32 hsz;	u32 sz;	u32 res;	p_ptr = tipc_port_deref(ref);	if (!p_ptr || !p_ptr->publ.connected)		return -EINVAL;	msg = &p_ptr->publ.phdr;	hsz = msg_hdr_sz(msg);	sz = hsz + dsz;	msg_set_size(msg, sz);	if (skb_cow(buf, hsz))		return -ENOMEM;	skb_push(buf, hsz);	skb_copy_to_linear_data(buf, msg, hsz);	destnode = msg_destnode(msg);	p_ptr->publ.congested = 1;	if (!tipc_port_congested(p_ptr)) {		if (likely(destnode != tipc_own_addr))			res = tipc_send_buf_fast(buf, destnode);		else {			tipc_port_recv_msg(buf);			res = sz;		}		if (likely(res != -ELINKCONG)) {			port_incr_out_seqno(p_ptr);			p_ptr->sent++;			p_ptr->publ.congested = 0;			return res;		}	}	if (port_unreliable(p_ptr)) {		p_ptr->publ.congested = 0;		return dsz;	}	return -ELINKCONG;}/** * tipc_forward2name - forward message sections to port name */int tipc_forward2name(u32 ref,		      struct tipc_name const *name,		      u32 domain,		      u32 num_sect,		      struct iovec const *msg_sect,		      struct tipc_portid const *orig,		      unsigned int importance){	struct port *p_ptr;	struct tipc_msg *msg;	u32 destnode = domain;	u32 destport = 0;	int res;	p_ptr = tipc_port_deref(ref);	if (!p_ptr || p_ptr->publ.connected)		return -EINVAL;	msg = &p_ptr->publ.phdr;	msg_set_type(msg, TIPC_NAMED_MSG);	msg_set_orignode(msg, orig->node);	msg_set_origport(msg, orig->ref);	msg_set_hdr_sz(msg, LONG_H_SIZE);	msg_set_nametype(msg, name->type);	msg_set_nameinst(msg, name->instance);	msg_set_lookup_scope(msg, addr_scope(domain));	if (importance <= TIPC_CRITICAL_IMPORTANCE)		msg_set_importance(msg,importance);	destport = tipc_nametbl_translate(name->type, name->instance, &destnode);	msg_set_destnode(msg, destnode);	msg_set_destport(msg, destport);	if (likely(destport || destnode)) {		p_ptr->sent++;		if (likely(destnode == tipc_own_addr))			return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);		res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,						   destnode);		if (likely(res != -ELINKCONG))			return res;		if (port_unreliable(p_ptr)) {			/* Just calculate msg length and return */			return msg_calc_data_size(msg_sect, num_sect);		}		return -ELINKCONG;	}	return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect,					 TIPC_ERR_NO_NAME);}/** * tipc_send2name - send message sections to port name */int tipc_send2name(u32 ref,		   struct tipc_name const *name,		   unsigned int domain,		   unsigned int num_sect,		   struct iovec const *msg_sect){	struct tipc_portid orig;	orig.ref = ref;	orig.node = tipc_own_addr;	return tipc_forward2name(ref, name, domain, num_sect, msg_sect, &orig,				 TIPC_PORT_IMPORTANCE);}/** * tipc_forward_buf2name - forward message buffer to port name */int tipc_forward_buf2name(u32 ref,			  struct tipc_name const *name,			  u32 domain,			  struct sk_buff *buf,			  unsigned int dsz,			  struct tipc_portid const *orig,			  unsigned int importance){	struct port *p_ptr;	struct tipc_msg *msg;	u32 destnode = domain;	u32 destport = 0;	int res;	p_ptr = (struct port *)tipc_ref_deref(ref);	if (!p_ptr || p_ptr->publ.connected)		return -EINVAL;	msg = &p_ptr->publ.phdr;	if (importance <= TIPC_CRITICAL_IMPORTANCE)		msg_set_importance(msg, importance);	msg_set_type(msg, TIPC_NAMED_MSG);	msg_set_orignode(msg, orig->node);	msg_set_origport(msg, orig->ref);	msg_set_nametype(msg, name->type);	msg_set_nameinst(msg, name->instance);	msg_set_lookup_scope(msg, addr_scope(domain));	msg_set_hdr_sz(msg, LONG_H_SIZE);	msg_set_size(msg, LONG_H_SIZE + dsz);	destport = tipc_nametbl_translate(name->type, name->instance, &destnode);	msg_set_destnode(msg, destnode);	msg_set_destport(msg, destport);	msg_dbg(msg, "forw2name ==> ");	if (skb_cow(buf, LONG_H_SIZE))		return -ENOMEM;	skb_push(buf, LONG_H_SIZE);	skb_copy_to_linear_data(buf, msg, LONG_H_SIZE);	msg_dbg(buf_msg(buf),"PREP:");	if (likely(destport || destnode)) {		p_ptr->sent++;		if (destnode == tipc_own_addr)			return tipc_port_recv_msg(buf);		res = tipc_send_buf_fast(buf, destnode);		if (likely(res != -ELINKCONG))			return res;		if (port_unreliable(p_ptr))			return dsz;		return -ELINKCONG;	}	return tipc_reject_msg(buf, TIPC_ERR_NO_NAME);}/** * tipc_send_buf2name - send message buffer to port name */int tipc_send_buf2name(u32 ref,		       struct tipc_name const *dest,		       u32 domain,		       struct sk_buff *buf,		       unsigned int dsz){	struct tipc_portid orig;	orig.ref = ref;	orig.node = tipc_own_addr;	return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig,				     TIPC_PORT_IMPORTANCE);}/** * tipc_forward2port - forward message sections to port identity */int tipc_forward2port(u32 ref,		      struct tipc_portid const *dest,		      unsigned int num_sect,		      struct iovec const *msg_sect,		      struct tipc_portid const *orig,		      unsigned int importance){	struct port *p_ptr;	struct tipc_msg *msg;	int res;	p_ptr = tipc_port_deref(ref);	if (!p_ptr || p_ptr->publ.connected)		return -EINVAL;	msg = &p_ptr->publ.phdr;	msg_set_type(msg, TIPC_DIRECT_MSG);	msg_set_orignode(msg, orig->node);	msg_set_origport(msg, orig->ref);	msg_set_destnode(msg, dest->node);	msg_set_destport(msg, dest->ref);	msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);	if (importance <= TIPC_CRITICAL_IMPORTANCE)		msg_set_importance(msg, importance);	p_ptr->sent++;	if (dest->node == tipc_own_addr)		return tipc_port_recv_sections(p_ptr, num_sect, msg_sect);	res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node);	if (likely(res != -ELINKCONG))		return res;	if (port_unreliable(p_ptr)) {		/* Just calculate msg length and return */		return msg_calc_data_size(msg_sect, num_sect);	}	return -ELINKCONG;}/** * tipc_send2port - send message sections to port identity */int tipc_send2port(u32 ref,		   struct tipc_portid const *dest,		   unsigned int num_sect,		   struct iovec const *msg_sect){	struct tipc_portid orig;	orig.ref = ref;	orig.node = tipc_own_addr;	return tipc_forward2port(ref, dest, num_sect, msg_sect, &orig,				 TIPC_PORT_IMPORTANCE);}/** * tipc_forward_buf2port - forward message buffer to port identity */int tipc_forward_buf2port(u32 ref,			  struct tipc_portid const *dest,			  struct sk_buff *buf,			  unsigned int dsz,			  struct tipc_portid const *orig,			  unsigned int importance){	struct port *p_ptr;	struct tipc_msg *msg;	int res;	p_ptr = (struct port *)tipc_ref_deref(ref);	if (!p_ptr || p_ptr->publ.connected)		return -EINVAL;	msg = &p_ptr->publ.phdr;	msg_set_type(msg, TIPC_DIRECT_MSG);	msg_set_orignode(msg, orig->node);	msg_set_origport(msg, orig->ref);	msg_set_destnode(msg, dest->node);	msg_set_destport(msg, dest->ref);	msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);	if (importance <= TIPC_CRITICAL_IMPORTANCE)		msg_set_importance(msg, importance);	msg_set_size(msg, DIR_MSG_H_SIZE + dsz);	if (skb_cow(buf, DIR_MSG_H_SIZE))		return -ENOMEM;	skb_push(buf, DIR_MSG_H_SIZE);	skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);	msg_dbg(msg, "buf2port: ");	p_ptr->sent++;	if (dest->node == tipc_own_addr)		return tipc_port_recv_msg(buf);	res = tipc_send_buf_fast(buf, dest->node);	if (likely(res != -ELINKCONG))		return res;	if (port_unreliable(p_ptr))		return dsz;	return -ELINKCONG;}/** * tipc_send_buf2port - send message buffer to port identity */int tipc_send_buf2port(u32 ref,		       struct tipc_portid const *dest,		       struct sk_buff *buf,		       unsigned int dsz){	struct tipc_portid orig;	orig.ref = ref;	orig.node = tipc_own_addr;	return tipc_forward_buf2port(ref, dest, buf, dsz, &orig,				     TIPC_PORT_IMPORTANCE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -