diff options
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r-- | net/tipc/bcast.c | 105 |
1 files changed, 82 insertions, 23 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 412d3351abb7..672e6ef93cab 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -70,7 +70,7 @@ static struct tipc_bc_base *tipc_bc_base(struct net *net) | |||
70 | 70 | ||
71 | int tipc_bcast_get_mtu(struct net *net) | 71 | int tipc_bcast_get_mtu(struct net *net) |
72 | { | 72 | { |
73 | return tipc_link_mtu(tipc_bc_sndlink(net)); | 73 | return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE; |
74 | } | 74 | } |
75 | 75 | ||
76 | /* tipc_bcbase_select_primary(): find a bearer with links to all destinations, | 76 | /* tipc_bcbase_select_primary(): find a bearer with links to all destinations, |
@@ -175,42 +175,101 @@ static void tipc_bcbase_xmit(struct net *net, struct sk_buff_head *xmitq) | |||
175 | __skb_queue_purge(&_xmitq); | 175 | __skb_queue_purge(&_xmitq); |
176 | } | 176 | } |
177 | 177 | ||
178 | /* tipc_bcast_xmit - deliver buffer chain to all nodes in cluster | 178 | /* tipc_bcast_xmit - broadcast the buffer chain to all external nodes |
179 | * and to identified node local sockets | ||
180 | * @net: the applicable net namespace | 179 | * @net: the applicable net namespace |
181 | * @list: chain of buffers containing message | 180 | * @pkts: chain of buffers containing message |
181 | * @cong_link_cnt: set to 1 if broadcast link is congested, otherwise 0 | ||
182 | * Consumes the buffer chain. | 182 | * Consumes the buffer chain. |
183 | * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE | 183 | * Returns 0 if success, otherwise errno: -EHOSTUNREACH,-EMSGSIZE |
184 | */ | 184 | */ |
185 | int tipc_bcast_xmit(struct net *net, struct sk_buff_head *list) | 185 | static int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts, |
186 | u16 *cong_link_cnt) | ||
186 | { | 187 | { |
187 | struct tipc_link *l = tipc_bc_sndlink(net); | 188 | struct tipc_link *l = tipc_bc_sndlink(net); |
188 | struct sk_buff_head xmitq, inputq, rcvq; | 189 | struct sk_buff_head xmitq; |
189 | int rc = 0; | 190 | int rc = 0; |
190 | 191 | ||
191 | __skb_queue_head_init(&rcvq); | ||
192 | __skb_queue_head_init(&xmitq); | 192 | __skb_queue_head_init(&xmitq); |
193 | skb_queue_head_init(&inputq); | ||
194 | |||
195 | /* Prepare message clone for local node */ | ||
196 | if (unlikely(!tipc_msg_reassemble(list, &rcvq))) | ||
197 | return -EHOSTUNREACH; | ||
198 | |||
199 | tipc_bcast_lock(net); | 193 | tipc_bcast_lock(net); |
200 | if (tipc_link_bc_peers(l)) | 194 | if (tipc_link_bc_peers(l)) |
201 | rc = tipc_link_xmit(l, list, &xmitq); | 195 | rc = tipc_link_xmit(l, pkts, &xmitq); |
202 | tipc_bcast_unlock(net); | 196 | tipc_bcast_unlock(net); |
197 | tipc_bcbase_xmit(net, &xmitq); | ||
198 | __skb_queue_purge(pkts); | ||
199 | if (rc == -ELINKCONG) { | ||
200 | *cong_link_cnt = 1; | ||
201 | rc = 0; | ||
202 | } | ||
203 | return rc; | ||
204 | } | ||
203 | 205 | ||
204 | /* Don't send to local node if adding to link failed */ | 206 | /* tipc_rcast_xmit - replicate and send a message to given destination nodes |
205 | if (unlikely(rc && (rc != -ELINKCONG))) { | 207 | * @net: the applicable net namespace |
206 | __skb_queue_purge(&rcvq); | 208 | * @pkts: chain of buffers containing message |
207 | return rc; | 209 | * @dests: list of destination nodes |
210 | * @cong_link_cnt: returns number of congested links | ||
211 | * @cong_links: returns identities of congested links | ||
212 | * Returns 0 if success, otherwise errno | ||
213 | */ | ||
214 | static int tipc_rcast_xmit(struct net *net, struct sk_buff_head *pkts, | ||
215 | struct tipc_nlist *dests, u16 *cong_link_cnt) | ||
216 | { | ||
217 | struct sk_buff_head _pkts; | ||
218 | struct u32_item *n, *tmp; | ||
219 | u32 dst, selector; | ||
220 | |||
221 | selector = msg_link_selector(buf_msg(skb_peek(pkts))); | ||
222 | __skb_queue_head_init(&_pkts); | ||
223 | |||
224 | list_for_each_entry_safe(n, tmp, &dests->list, list) { | ||
225 | dst = n->value; | ||
226 | if (!tipc_msg_pskb_copy(dst, pkts, &_pkts)) | ||
227 | return -ENOMEM; | ||
228 | |||
229 | /* Any other return value than -ELINKCONG is ignored */ | ||
230 | if (tipc_node_xmit(net, &_pkts, dst, selector) == -ELINKCONG) | ||
231 | (*cong_link_cnt)++; | ||
208 | } | 232 | } |
233 | return 0; | ||
234 | } | ||
209 | 235 | ||
210 | /* Broadcast to all nodes, inluding local node */ | 236 | /* tipc_mcast_xmit - deliver message to indicated destination nodes |
211 | tipc_bcbase_xmit(net, &xmitq); | 237 | * and to identified node local sockets |
212 | tipc_sk_mcast_rcv(net, &rcvq, &inputq); | 238 | * @net: the applicable net namespace |
213 | __skb_queue_purge(list); | 239 | * @pkts: chain of buffers containing message |
240 | * @dests: destination nodes for message. Not consumed. | ||
241 | * @cong_link_cnt: returns number of encountered congested destination links | ||
242 | * @cong_links: returns identities of congested links | ||
243 | * Consumes buffer chain. | ||
244 | * Returns 0 if success, otherwise errno | ||
245 | */ | ||
246 | int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts, | ||
247 | struct tipc_nlist *dests, u16 *cong_link_cnt) | ||
248 | { | ||
249 | struct tipc_bc_base *bb = tipc_bc_base(net); | ||
250 | struct sk_buff_head inputq, localq; | ||
251 | int rc = 0; | ||
252 | |||
253 | skb_queue_head_init(&inputq); | ||
254 | skb_queue_head_init(&localq); | ||
255 | |||
256 | /* Clone packets before they are consumed by next call */ | ||
257 | if (dests->local && !tipc_msg_reassemble(pkts, &localq)) { | ||
258 | rc = -ENOMEM; | ||
259 | goto exit; | ||
260 | } | ||
261 | |||
262 | if (dests->remote) { | ||
263 | if (!bb->bcast_support) | ||
264 | rc = tipc_rcast_xmit(net, pkts, dests, cong_link_cnt); | ||
265 | else | ||
266 | rc = tipc_bcast_xmit(net, pkts, cong_link_cnt); | ||
267 | } | ||
268 | |||
269 | if (dests->local) | ||
270 | tipc_sk_mcast_rcv(net, &localq, &inputq); | ||
271 | exit: | ||
272 | __skb_queue_purge(pkts); | ||
214 | return rc; | 273 | return rc; |
215 | } | 274 | } |
216 | 275 | ||