diff options
| author | James Morris <james.l.morris@oracle.com> | 2017-12-11 17:01:08 +1100 | 
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2017-12-11 17:01:08 +1100 | 
| commit | d21bd6898336a7892914d308d5e0868f0b863571 (patch) | |
| tree | f5f756c25348b5a6c1ce9ddbaa7d1ecd1bef40b0 /net/tipc/node.c | |
| parent | 34d8751fd4ffa34e85ee7e85d34168b3f3f62b42 (diff) | |
| parent | 50c4c4e268a2d7a3e58ebb698ac74da0de40ae36 (diff) | |
Sync to v4.15-rc3 for security subsystem developers to work against.
Diffstat (limited to 'net/tipc/node.c')
| -rw-r--r-- | net/tipc/node.c | 52 | 
1 files changed, 42 insertions, 10 deletions
| diff --git a/net/tipc/node.c b/net/tipc/node.c index 198dbc7adbe1..507017fe0f1b 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -153,11 +153,11 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id,  				bool delete);  static void node_lost_contact(struct tipc_node *n, struct sk_buff_head *inputq);  static void tipc_node_delete(struct tipc_node *node); -static void tipc_node_timeout(unsigned long data); +static void tipc_node_timeout(struct timer_list *t);  static void tipc_node_fsm_evt(struct tipc_node *n, int evt);  static struct tipc_node *tipc_node_find(struct net *net, u32 addr);  static void tipc_node_put(struct tipc_node *node); -static bool tipc_node_is_up(struct tipc_node *n); +static bool node_is_up(struct tipc_node *n);  struct tipc_sock_conn {  	u32 port; @@ -361,7 +361,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)  		goto exit;  	}  	tipc_node_get(n); -	setup_timer(&n->timer, tipc_node_timeout, (unsigned long)n); +	timer_setup(&n->timer, tipc_node_timeout, 0);  	n->keepalive_intv = U32_MAX;  	hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]);  	list_for_each_entry_rcu(temp_node, &tn->node_list, list) { @@ -500,9 +500,9 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)  /* tipc_node_timeout - handle expiration of node timer   */ -static void tipc_node_timeout(unsigned long data) +static void tipc_node_timeout(struct timer_list *t)  { -	struct tipc_node *n = (struct tipc_node *)data; +	struct tipc_node *n = from_timer(n, t, timer);  	struct tipc_link_entry *le;  	struct sk_buff_head xmitq;  	int bearer_id; @@ -657,7 +657,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,  		*slot1 = i;  	} -	if (!tipc_node_is_up(n)) { +	if (!node_is_up(n)) {  		if (tipc_link_peer_is_down(l))  			tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT);  		tipc_node_fsm_evt(n, SELF_LOST_CONTACT_EVT); @@ -717,11 +717,27 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete)  	tipc_sk_rcv(n->net, &le->inputq);  } -static bool tipc_node_is_up(struct tipc_node *n) +static bool node_is_up(struct tipc_node *n)  {  	return n->active_links[0] != INVALID_BEARER_ID;  } +bool tipc_node_is_up(struct net *net, u32 addr) +{ +	struct tipc_node *n; +	bool retval = false; + +	if (in_own_node(net, addr)) +		return true; + +	n = tipc_node_find(net, addr); +	if (!n) +		return false; +	retval = node_is_up(n); +	tipc_node_put(n); +	return retval; +} +  void tipc_node_check_dest(struct net *net, u32 onode,  			  struct tipc_bearer *b,  			  u16 capabilities, u32 signature, @@ -1149,7 +1165,7 @@ static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)  	if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr))  		goto attr_msg_full; -	if (tipc_node_is_up(node)) +	if (node_is_up(node))  		if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP))  			goto attr_msg_full; @@ -1238,6 +1254,22 @@ int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,  	return 0;  } +/* tipc_node_distr_xmit(): send single buffer msgs to individual destinations + * Note: this is only for SYSTEM_IMPORTANCE messages, which cannot be rejected + */ +int tipc_node_distr_xmit(struct net *net, struct sk_buff_head *xmitq) +{ +	struct sk_buff *skb; +	u32 selector, dnode; + +	while ((skb = __skb_dequeue(xmitq))) { +		selector = msg_origport(buf_msg(skb)); +		dnode = msg_destnode(buf_msg(skb)); +		tipc_node_xmit_skb(net, skb, dnode, selector); +	} +	return 0; +} +  void tipc_node_broadcast(struct net *net, struct sk_buff *skb)  {  	struct sk_buff *txskb; @@ -1249,7 +1281,7 @@ void tipc_node_broadcast(struct net *net, struct sk_buff *skb)  		dst = n->addr;  		if (in_own_node(net, dst))  			continue; -		if (!tipc_node_is_up(n)) +		if (!node_is_up(n))  			continue;  		txskb = pskb_copy(skb, GFP_ATOMIC);  		if (!txskb) @@ -1507,7 +1539,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)  	__skb_queue_head_init(&xmitq);  	/* Ensure message is well-formed before touching the header */ -	if (unlikely(!tipc_msg_validate(skb))) +	if (unlikely(!tipc_msg_validate(&skb)))  		goto discard;  	hdr = buf_msg(skb);  	usr = msg_user(hdr); | 
