From 6beb19a62a87ef6f7107fcd43c2cc1ebad3edfb5 Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Thu, 22 Oct 2015 08:51:33 -0400 Subject: tipc: move bcast definitions to bcast.c Currently, a number of structure and function definitions related to the broadcast functionality are unnecessarily exposed in the file bcast.h. This obscures the fact that the external interface towards the broadcast link in fact is very narrow, and causes unnecessary recompilations of other files when anything changes in those definitions. In this commit, we move as many of those definitions as is currently possible to the file bcast.c. We also rename the structure 'tipc_bclink' to 'tipc_bc_base', both since the name does not correctly describe the contents of this struct, and will do so even less in the future, and because we want to use the term 'link' more appropriately in the functionality introduced later in this series. Finally, we rename a couple of functions, such as tipc_bclink_xmit() and others that will be kept in the future, to include the term 'bcast' instead. There are no functional changes in this commit. Signed-off-by: Jon Maloy Reviewed-by: Ying Xue Signed-off-by: David S. Miller --- net/tipc/socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/tipc/socket.c') diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 1060d52ff23e..e2e35b7b1d09 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -689,13 +689,13 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, msg_set_hdr_sz(mhdr, MCAST_H_SIZE); new_mtu: - mtu = tipc_bclink_get_mtu(); + mtu = tipc_bcast_get_mtu(); rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, pktchain); if (unlikely(rc < 0)) return rc; do { - rc = tipc_bclink_xmit(net, pktchain); + rc = tipc_bcast_xmit(net, pktchain); if (likely(!rc)) return dsz; -- cgit v1.2.3 From 959e1781aa230aecc90e4deb80117fd9a53dede7 Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Thu, 22 Oct 2015 08:51:43 -0400 Subject: tipc: introduce jumbo frame support for broadcast Until now, we have only been supporting a fix MTU size of 1500 bytes for all broadcast media, irrespective of their actual capability. We now make the broadcast MTU adaptable to the carrying media, i.e., we use the smallest MTU supported by any of the interfaces attached to TIPC. Signed-off-by: Jon Maloy Reviewed-by: Ying Xue Signed-off-by: David S. Miller --- net/tipc/bcast.c | 15 +++++++++++---- net/tipc/bcast.h | 2 +- net/tipc/bearer.c | 13 +++++++++++++ net/tipc/bearer.h | 1 + net/tipc/link.c | 10 ++++++++++ net/tipc/link.h | 2 ++ net/tipc/socket.c | 2 +- 7 files changed, 39 insertions(+), 6 deletions(-) (limited to 'net/tipc/socket.c') diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 74ee09ac430d..d8c399d31288 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -148,9 +148,9 @@ void tipc_bclink_input(struct net *net) tipc_sk_mcast_rcv(net, &tn->bcbase->arrvq, &tn->bcbase->inputq); } -uint tipc_bcast_get_mtu(void) +int tipc_bcast_get_mtu(struct net *net) { - return MAX_PKT_DEFAULT_MCAST; + return tipc_link_mtu(tipc_bc_sndlink(net)); } static u16 bcbuf_acks(struct sk_buff *skb) @@ -175,7 +175,7 @@ static void tipc_bcbase_select_primary(struct net *net) { struct tipc_bc_base *bb = tipc_bc_base(net); int all_dests = tipc_link_bc_peers(bb->link); - int i; + int i, mtu; bb->primary_bearer = INVALID_BEARER_ID; @@ -183,6 +183,13 @@ static void tipc_bcbase_select_primary(struct net *net) return; for (i = 0; i < MAX_BEARERS; i++) { + if (!bb->dests[i]) + continue; + + mtu = tipc_bearer_mtu(net, i); + if (mtu < tipc_link_mtu(bb->link)) + tipc_link_set_mtu(bb->link, mtu); + if (bb->dests[i] < all_dests) continue; @@ -1220,7 +1227,7 @@ int tipc_bcast_init(struct net *net) bb->node.net = net; if (!tipc_link_bc_create(&bb->node, 0, 0, - MAX_PKT_DEFAULT_MCAST, + U16_MAX, BCLINK_WIN_DEFAULT, 0, &bb->inputq, diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index 76b747a73b0b..0cc72200f1cd 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h @@ -63,7 +63,7 @@ void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr, u32 node, bool action); int tipc_bclink_reset_stats(struct net *net); int tipc_bclink_set_queue_limits(struct net *net, u32 limit); -uint tipc_bcast_get_mtu(void); +int tipc_bcast_get_mtu(struct net *net); int tipc_bcast_xmit(struct net *net, struct sk_buff_head *list); int tipc_bcast_rcv(struct net *net, struct tipc_link *l, struct sk_buff *skb); void tipc_bcast_ack_rcv(struct net *net, struct tipc_link *l, u32 acked); diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 62f47ecc6b84..b39f631fd6d7 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -464,6 +464,19 @@ void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf, rcu_read_unlock(); } +int tipc_bearer_mtu(struct net *net, u32 bearer_id) +{ + int mtu = 0; + struct tipc_bearer *b; + + rcu_read_lock(); + b = rcu_dereference_rtnl(tipc_net(net)->bearer_list[bearer_id]); + if (b) + mtu = b->mtu; + rcu_read_unlock(); + return mtu; +} + /* tipc_bearer_xmit() -send buffer to destination over bearer */ void tipc_bearer_xmit(struct net *net, u32 bearer_id, diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 9fc1e074f7c0..2ba8a7e274a5 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -218,6 +218,7 @@ void tipc_bearer_cleanup(void); void tipc_bearer_stop(struct net *net); void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf, struct tipc_media_addr *dest); +int tipc_bearer_mtu(struct net *net, u32 bearer_id); void tipc_bearer_xmit(struct net *net, u32 bearer_id, struct sk_buff_head *xmitq, struct tipc_media_addr *dst); diff --git a/net/tipc/link.c b/net/tipc/link.c index ff725c398914..3b98f8e70626 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -212,6 +212,16 @@ int tipc_link_bc_peers(struct tipc_link *l) return l->ackers; } +void tipc_link_set_mtu(struct tipc_link *l, int mtu) +{ + l->mtu = mtu; +} + +int tipc_link_mtu(struct tipc_link *l) +{ + return l->mtu; +} + static u32 link_own_addr(struct tipc_link *l) { return msg_prevnode(l->pmsg); diff --git a/net/tipc/link.h b/net/tipc/link.h index 28a6396b6d31..9b5198e90fdf 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -281,6 +281,8 @@ void tipc_link_remove_bc_peer(struct tipc_link *snd_l, struct tipc_link *rcv_l, struct sk_buff_head *xmitq); int tipc_link_bc_peers(struct tipc_link *l); +void tipc_link_set_mtu(struct tipc_link *l, int mtu); +int tipc_link_mtu(struct tipc_link *l); void tipc_link_bc_ack_rcv(struct tipc_link *l, u16 acked, struct sk_buff_head *xmitq); void tipc_link_build_bc_sync_msg(struct tipc_link *l, diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e2e35b7b1d09..552dbaba9cf3 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -689,7 +689,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, msg_set_hdr_sz(mhdr, MCAST_H_SIZE); new_mtu: - mtu = tipc_bcast_get_mtu(); + mtu = tipc_bcast_get_mtu(net); rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, pktchain); if (unlikely(rc < 0)) return rc; -- cgit v1.2.3 From f4195d1eac954a67adf112dd53404560cc55b942 Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Sun, 22 Nov 2015 15:46:05 +0800 Subject: tipc: avoid packets leaking on socket receive queue Even if we drain receive queue thoroughly in tipc_release() after tipc socket is removed from rhashtable, it is possible that some packets are in flight because some CPU runs receiver and did rhashtable lookup before we removed socket. They will achieve receive queue, but nobody delete them at all. To avoid this leak, we register a private socket destructor to purge receive queue, meaning releasing packets pending on receive queue will be delayed until the last reference of tipc socket will be released. Signed-off-by: Ying Xue Signed-off-by: David S. Miller --- net/tipc/socket.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'net/tipc/socket.c') diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 552dbaba9cf3..b53246fb0412 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -105,6 +105,7 @@ struct tipc_sock { static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb); static void tipc_data_ready(struct sock *sk); static void tipc_write_space(struct sock *sk); +static void tipc_sock_destruct(struct sock *sk); static int tipc_release(struct socket *sock); static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags); static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p); @@ -381,6 +382,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, sk->sk_rcvbuf = sysctl_tipc_rmem[1]; sk->sk_data_ready = tipc_data_ready; sk->sk_write_space = tipc_write_space; + sk->sk_destruct = tipc_sock_destruct; tsk->conn_timeout = CONN_TIMEOUT_DEFAULT; tsk->sent_unacked = 0; atomic_set(&tsk->dupl_rcvcnt, 0); @@ -470,9 +472,6 @@ static int tipc_release(struct socket *sock) tipc_node_remove_conn(net, dnode, tsk->portid); } - /* Discard any remaining (connection-based) messages in receive queue */ - __skb_queue_purge(&sk->sk_receive_queue); - /* Reject any messages that accumulated in backlog queue */ sock->state = SS_DISCONNECTING; release_sock(sk); @@ -1515,6 +1514,11 @@ static void tipc_data_ready(struct sock *sk) rcu_read_unlock(); } +static void tipc_sock_destruct(struct sock *sk) +{ + __skb_queue_purge(&sk->sk_receive_queue); +} + /** * filter_connect - Handle all incoming messages for a connection-based socket * @tsk: TIPC socket -- cgit v1.2.3