Blame view
net/tipc/link.c
56.6 KB
b97bf3fd8 [TIPC] Initial merge |
1 2 |
/* * net/tipc/link.c: TIPC link code |
c43072852 [NET] TIPC: Fix w... |
3 |
* |
e74a386d7 tipc: remove pre-... |
4 |
* Copyright (c) 1996-2007, 2012-2016, Ericsson AB |
198d73b82 tipc: delete code... |
5 |
* Copyright (c) 2004-2007, 2010-2013, Wind River Systems |
b97bf3fd8 [TIPC] Initial merge |
6 7 |
* All rights reserved. * |
9ea1fd3c1 [TIPC] License he... |
8 |
* Redistribution and use in source and binary forms, with or without |
b97bf3fd8 [TIPC] Initial merge |
9 10 |
* modification, are permitted provided that the following conditions are met: * |
9ea1fd3c1 [TIPC] License he... |
11 12 13 14 15 16 17 18 |
* 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the names of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. |
b97bf3fd8 [TIPC] Initial merge |
19 |
* |
9ea1fd3c1 [TIPC] License he... |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
* Alternatively, this software may be distributed under the terms of the * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
b97bf3fd8 [TIPC] Initial merge |
34 35 36 37 |
* POSSIBILITY OF SUCH DAMAGE. */ #include "core.h" |
e3eea1eb4 tipc: clean up ha... |
38 |
#include "subscr.h" |
b97bf3fd8 [TIPC] Initial merge |
39 |
#include "link.h" |
7be57fc69 tipc: add link ge... |
40 |
#include "bcast.h" |
9816f0615 tipc: merge port ... |
41 |
#include "socket.h" |
b97bf3fd8 [TIPC] Initial merge |
42 |
#include "name_distr.h" |
b97bf3fd8 [TIPC] Initial merge |
43 |
#include "discover.h" |
0655f6a86 tipc: add bearer ... |
44 |
#include "netlink.h" |
35c55c987 tipc: add neighbo... |
45 |
#include "monitor.h" |
b97bf3fd8 [TIPC] Initial merge |
46 |
|
796c75d0d tipc: enhance pri... |
47 |
#include <linux/pkt_sched.h> |
38206d593 tipc: narrow down... |
48 |
struct tipc_stats { |
959011224 tipc: fix link st... |
49 50 |
u32 sent_pkts; u32 recv_pkts; |
38206d593 tipc: narrow down... |
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
u32 sent_states; u32 recv_states; u32 sent_probes; u32 recv_probes; u32 sent_nacks; u32 recv_nacks; u32 sent_acks; u32 sent_bundled; u32 sent_bundles; u32 recv_bundled; u32 recv_bundles; u32 retransmitted; u32 sent_fragmented; u32 sent_fragments; u32 recv_fragmented; u32 recv_fragments; u32 link_congs; /* # port sends blocked by congestion */ u32 deferred_recv; u32 duplicates; u32 max_queue_sz; /* send queue size high water mark */ u32 accu_queue_sz; /* used for send queue size profiling */ u32 queue_sz_counts; /* used for send queue size profiling */ u32 msg_length_counts; /* used for message length profiling */ u32 msg_lengths_total; /* used for message length profiling */ u32 msg_length_profile[7]; /* used for msg. length profiling */ }; /** * struct tipc_link - TIPC link data structure * @addr: network address of link's peer node * @name: link name character string * @media_addr: media address to use when sending messages over link * @timer: link timer * @net: pointer to namespace struct * @refcnt: reference counter for permanent references (owner node & timer) * @peer_session: link session # being used by peer end of link * @peer_bearer_id: bearer id used by link's peer endpoint * @bearer_id: local bearer id used by link * @tolerance: minimum link continuity loss needed to reset link [in ms] |
38206d593 tipc: narrow down... |
90 91 92 93 94 95 96 97 |
* @abort_limit: # of unacknowledged continuity probes needed to reset link * @state: current state of link FSM * @peer_caps: bitmap describing capabilities of peer node * @silent_intv_cnt: # of timer intervals without any reception from peer * @proto_msg: template for control messages generated by link * @pmsg: convenience pointer to "proto_msg" field * @priority: current link priority * @net_plane: current link network plane ('A' through 'H') |
35c55c987 tipc: add neighbo... |
98 |
* @mon_state: cookie with information needed by link monitor |
38206d593 tipc: narrow down... |
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
* @backlog_limit: backlog queue congestion thresholds (indexed by importance) * @exp_msg_count: # of tunnelled messages expected during link changeover * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset * @mtu: current maximum packet size for this link * @advertised_mtu: advertised own mtu when link is being established * @transmitq: queue for sent, non-acked messages * @backlogq: queue for messages waiting to be sent * @snt_nxt: next sequence number to use for outbound messages * @last_retransmitted: sequence number of most recently retransmitted message * @stale_count: # of identical retransmit requests made by peer * @ackers: # of peers that needs to ack each packet before it can be released * @acked: # last packet acked by a certain peer. Used for broadcast. * @rcv_nxt: next sequence number to expect for inbound messages * @deferred_queue: deferred queue saved OOS b'cast message received from node * @unacked_window: # of inbound messages rx'd without ack'ing back to peer * @inputq: buffer queue for messages to be delivered upwards * @namedq: buffer queue for name table messages to be delivered upwards * @next_out: ptr to first unsent outbound message in queue * @wakeupq: linked list of wakeup msgs waiting for link congestion to abate * @long_msg_seq_no: next identifier to use for outbound fragmented messages * @reasm_buf: head of partially reassembled inbound message fragments * @bc_rcvr: marks that this is a broadcast receiver link * @stats: collects statistics regarding link activity */ struct tipc_link { u32 addr; char name[TIPC_MAX_LINK_NAME]; |
38206d593 tipc: narrow down... |
126 127 128 129 |
struct net *net; /* Management and link supervision data */ u32 peer_session; |
e74a386d7 tipc: remove pre-... |
130 |
u32 session; |
38206d593 tipc: narrow down... |
131 132 133 |
u32 peer_bearer_id; u32 bearer_id; u32 tolerance; |
38206d593 tipc: narrow down... |
134 135 136 137 138 |
u32 abort_limit; u32 state; u16 peer_caps; bool active; u32 silent_intv_cnt; |
e74a386d7 tipc: remove pre-... |
139 |
char if_name[TIPC_MAX_IF_NAME]; |
38206d593 tipc: narrow down... |
140 141 |
u32 priority; char net_plane; |
35c55c987 tipc: add neighbo... |
142 |
struct tipc_mon_state mon_state; |
88e8ac700 tipc: reduce tran... |
143 |
u16 rst_cnt; |
38206d593 tipc: narrow down... |
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
/* Failover/synch */ u16 drop_point; struct sk_buff *failover_reasm_skb; /* Max packet negotiation */ u16 mtu; u16 advertised_mtu; /* Sending */ struct sk_buff_head transmq; struct sk_buff_head backlogq; struct { u16 len; u16 limit; } backlog[5]; u16 snd_nxt; u16 last_retransm; u16 window; u32 stale_count; /* Reception */ u16 rcv_nxt; u32 rcv_unacked; struct sk_buff_head deferdq; struct sk_buff_head *inputq; struct sk_buff_head *namedq; /* Congestion handling */ struct sk_buff_head wakeupq; /* Fragmentation/reassembly */ struct sk_buff *reasm_buf; /* Broadcast */ u16 ackers; u16 acked; struct tipc_link *bc_rcvlink; struct tipc_link *bc_sndlink; |
7c4a54b96 tipc: rate limit ... |
183 184 185 186 |
unsigned long prev_retr; u16 prev_from; u16 prev_to; u8 nack_state; |
38206d593 tipc: narrow down... |
187 188 189 190 191 |
bool bc_peer_is_up; /* Statistics */ struct tipc_stats stats; }; |
2cf8aa19f tipc: use standar... |
192 193 194 |
/* * Error message prefixes */ |
6e498158a tipc: move link s... |
195 |
static const char *link_co_err = "Link tunneling error, "; |
2cf8aa19f tipc: use standar... |
196 |
static const char *link_rst_msg = "Resetting link "; |
7be57fc69 tipc: add link ge... |
197 |
|
526669866 tipc: let broadca... |
198 199 200 201 202 203 204 |
/* Send states for broadcast NACKs */ enum { BC_NACK_SND_CONDITIONAL, BC_NACK_SND_UNCONDITIONAL, BC_NACK_SND_SUPPRESS, }; |
7c4a54b96 tipc: rate limit ... |
205 |
#define TIPC_BC_RETR_LIMIT 10 /* [ms] */ |
c43072852 [NET] TIPC: Fix w... |
206 |
/* |
d999297c3 tipc: reduce lock... |
207 208 209 |
* Interval between NACKs when packets arrive out of order */ #define TIPC_NACK_INTV (TIPC_MIN_LINK_WIN * 2) |
e74a386d7 tipc: remove pre-... |
210 211 212 |
/* Wildcard value for link session numbers. When it is known that * peer endpoint is down, any session number must be accepted. |
a686e6859 tipc: Fix minor b... |
213 |
*/ |
e74a386d7 tipc: remove pre-... |
214 |
#define ANY_SESSION 0x10000 |
a686e6859 tipc: Fix minor b... |
215 |
|
662921cd0 tipc: merge link-... |
216 |
/* Link FSM states: |
b97bf3fd8 [TIPC] Initial merge |
217 |
*/ |
d3504c344 tipc: clean up de... |
218 |
enum { |
662921cd0 tipc: merge link-... |
219 220 221 222 223 224 225 |
LINK_ESTABLISHED = 0xe, LINK_ESTABLISHING = 0xe << 4, LINK_RESET = 0x1 << 8, LINK_RESETTING = 0x2 << 12, LINK_PEER_RESET = 0xd << 16, LINK_FAILINGOVER = 0xf << 20, LINK_SYNCHING = 0xc << 24 |
d3504c344 tipc: clean up de... |
226 227 228 229 |
}; /* Link FSM state checking routines */ |
662921cd0 tipc: merge link-... |
230 |
static int link_is_up(struct tipc_link *l) |
d3504c344 tipc: clean up de... |
231 |
{ |
662921cd0 tipc: merge link-... |
232 |
return l->state & (LINK_ESTABLISHED | LINK_SYNCHING); |
d3504c344 tipc: clean up de... |
233 |
} |
b97bf3fd8 [TIPC] Initial merge |
234 |
|
d999297c3 tipc: reduce lock... |
235 236 |
static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, struct sk_buff_head *xmitq); |
426cc2b86 tipc: introduce n... |
237 238 239 |
static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, u16 rcvgap, int tolerance, int priority, struct sk_buff_head *xmitq); |
1a90632da tipc: eliminate r... |
240 |
static void link_print(struct tipc_link *l, const char *str); |
e0a05ebe2 tipc: send broadc... |
241 242 |
static int tipc_link_build_nack_msg(struct tipc_link *l, struct sk_buff_head *xmitq); |
526669866 tipc: let broadca... |
243 244 245 |
static void tipc_link_build_bc_init_msg(struct tipc_link *l, struct sk_buff_head *xmitq); static bool tipc_link_release_pkts(struct tipc_link *l, u16 to); |
8b4ed8634 tipc: eliminate r... |
246 |
|
b97bf3fd8 [TIPC] Initial merge |
247 |
/* |
05790c645 [TIPC]: Remove in... |
248 |
* Simple non-static link routines (i.e. referenced outside this file) |
b97bf3fd8 [TIPC] Initial merge |
249 |
*/ |
662921cd0 tipc: merge link-... |
250 |
bool tipc_link_is_up(struct tipc_link *l) |
b97bf3fd8 [TIPC] Initial merge |
251 |
{ |
662921cd0 tipc: merge link-... |
252 253 |
return link_is_up(l); } |
c81993009 tipc: update node... |
254 255 256 257 |
bool tipc_link_peer_is_down(struct tipc_link *l) { return l->state == LINK_PEER_RESET; } |
662921cd0 tipc: merge link-... |
258 259 260 261 |
bool tipc_link_is_reset(struct tipc_link *l) { return l->state & (LINK_RESET | LINK_FAILINGOVER | LINK_ESTABLISHING); } |
73f646cec tipc: delay ESTAB... |
262 263 264 265 |
bool tipc_link_is_establishing(struct tipc_link *l) { return l->state == LINK_ESTABLISHING; } |
662921cd0 tipc: merge link-... |
266 267 268 269 270 271 272 273 274 275 276 277 278 |
bool tipc_link_is_synching(struct tipc_link *l) { return l->state == LINK_SYNCHING; } bool tipc_link_is_failingover(struct tipc_link *l) { return l->state == LINK_FAILINGOVER; } bool tipc_link_is_blocked(struct tipc_link *l) { return l->state & (LINK_RESETTING | LINK_PEER_RESET | LINK_FAILINGOVER); |
b97bf3fd8 [TIPC] Initial merge |
279 |
} |
742e03833 tipc: link_is_bc_... |
280 |
static bool link_is_bc_sndlink(struct tipc_link *l) |
526669866 tipc: let broadca... |
281 282 283 |
{ return !l->bc_sndlink; } |
742e03833 tipc: link_is_bc_... |
284 |
static bool link_is_bc_rcvlink(struct tipc_link *l) |
526669866 tipc: let broadca... |
285 286 287 |
{ return ((l->bc_rcvlink == l) && !link_is_bc_sndlink(l)); } |
9d13ec65e tipc: introduce l... |
288 |
int tipc_link_is_active(struct tipc_link *l) |
b97bf3fd8 [TIPC] Initial merge |
289 |
{ |
c72fa872a tipc: eliminate l... |
290 291 |
return l->active; } |
9d13ec65e tipc: introduce l... |
292 |
|
c72fa872a tipc: eliminate l... |
293 294 295 |
void tipc_link_set_active(struct tipc_link *l, bool active) { l->active = active; |
b97bf3fd8 [TIPC] Initial merge |
296 |
} |
38206d593 tipc: narrow down... |
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
u32 tipc_link_id(struct tipc_link *l) { return l->peer_bearer_id << 16 | l->bearer_id; } int tipc_link_window(struct tipc_link *l) { return l->window; } int tipc_link_prio(struct tipc_link *l) { return l->priority; } unsigned long tipc_link_tolerance(struct tipc_link *l) { return l->tolerance; } struct sk_buff_head *tipc_link_inputq(struct tipc_link *l) { return l->inputq; } char tipc_link_plane(struct tipc_link *l) { return l->net_plane; } |
526669866 tipc: let broadca... |
326 327 328 |
void tipc_link_add_bc_peer(struct tipc_link *snd_l, struct tipc_link *uc_l, struct sk_buff_head *xmitq) |
2f5661245 tipc: let broadca... |
329 |
{ |
526669866 tipc: let broadca... |
330 331 332 333 |
struct tipc_link *rcv_l = uc_l->bc_rcvlink; snd_l->ackers++; rcv_l->acked = snd_l->snd_nxt - 1; |
9a6508382 tipc: correct set... |
334 |
snd_l->state = LINK_ESTABLISHED; |
526669866 tipc: let broadca... |
335 |
tipc_link_build_bc_init_msg(uc_l, xmitq); |
2f5661245 tipc: let broadca... |
336 |
} |
526669866 tipc: let broadca... |
337 338 339 |
void tipc_link_remove_bc_peer(struct tipc_link *snd_l, struct tipc_link *rcv_l, struct sk_buff_head *xmitq) |
2f5661245 tipc: let broadca... |
340 |
{ |
526669866 tipc: let broadca... |
341 342 343 |
u16 ack = snd_l->snd_nxt - 1; snd_l->ackers--; |
a71eb7203 tipc: ensure corr... |
344 345 |
rcv_l->bc_peer_is_up = true; rcv_l->state = LINK_ESTABLISHED; |
526669866 tipc: let broadca... |
346 347 348 349 350 |
tipc_link_bc_ack_rcv(rcv_l, ack, xmitq); tipc_link_reset(rcv_l); rcv_l->state = LINK_RESET; if (!snd_l->ackers) { tipc_link_reset(snd_l); |
9a6508382 tipc: correct set... |
351 |
snd_l->state = LINK_RESET; |
526669866 tipc: let broadca... |
352 353 |
__skb_queue_purge(xmitq); } |
2f5661245 tipc: let broadca... |
354 355 356 357 358 359 |
} int tipc_link_bc_peers(struct tipc_link *l) { return l->ackers; } |
02d11ca20 tipc: transfer br... |
360 361 362 363 364 365 366 367 368 369 370 |
u16 link_bc_rcv_gap(struct tipc_link *l) { struct sk_buff *skb = skb_peek(&l->deferdq); u16 gap = 0; if (more(l->snd_nxt, l->rcv_nxt)) gap = l->snd_nxt - l->rcv_nxt; if (skb) gap = buf_seqno(skb) - l->rcv_nxt; return gap; } |
959e1781a tipc: introduce j... |
371 372 373 374 375 376 377 378 379 |
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; } |
38206d593 tipc: narrow down... |
380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
u16 tipc_link_rcv_nxt(struct tipc_link *l) { return l->rcv_nxt; } u16 tipc_link_acked(struct tipc_link *l) { return l->acked; } char *tipc_link_name(struct tipc_link *l) { return l->name; } |
b97bf3fd8 [TIPC] Initial merge |
394 |
/** |
4323add67 [TIPC] Avoid poll... |
395 |
* tipc_link_create - create a new link |
440d8963c tipc: clean up li... |
396 |
* @n: pointer to associated node |
0e05498e9 tipc: make link i... |
397 398 399 400 401 402 403 404 |
* @if_name: associated interface name * @bearer_id: id (index) of associated bearer * @tolerance: link tolerance to be used by link * @net_plane: network plane (A,B,c..) this link belongs to * @mtu: mtu to be advertised by link * @priority: priority to be used by link * @window: send window to be used by link * @session: session to be used by link |
440d8963c tipc: clean up li... |
405 |
* @ownnode: identity of own node |
0e05498e9 tipc: make link i... |
406 |
* @peer: node id of peer node |
fd556f209 tipc: introduce c... |
407 |
* @peer_caps: bitmap describing peer node capabilities |
526669866 tipc: let broadca... |
408 409 |
* @bc_sndlink: the namespace global link used for broadcast sending * @bc_rcvlink: the peer specific link used for broadcast reception |
440d8963c tipc: clean up li... |
410 411 412 |
* @inputq: queue to put messages ready for delivery * @namedq: queue to put binding table update messages ready for delivery * @link: return value, pointer to put the created link |
c43072852 [NET] TIPC: Fix w... |
413 |
* |
440d8963c tipc: clean up li... |
414 |
* Returns true if link was created, otherwise false |
b97bf3fd8 [TIPC] Initial merge |
415 |
*/ |
c72fa872a tipc: eliminate l... |
416 |
bool tipc_link_create(struct net *net, char *if_name, int bearer_id, |
0e05498e9 tipc: make link i... |
417 418 |
int tolerance, char net_plane, u32 mtu, int priority, int window, u32 session, u32 ownnode, u32 peer, |
526669866 tipc: let broadca... |
419 |
u16 peer_caps, |
526669866 tipc: let broadca... |
420 421 422 423 |
struct tipc_link *bc_sndlink, struct tipc_link *bc_rcvlink, struct sk_buff_head *inputq, struct sk_buff_head *namedq, |
440d8963c tipc: clean up li... |
424 |
struct tipc_link **link) |
b97bf3fd8 [TIPC] Initial merge |
425 |
{ |
440d8963c tipc: clean up li... |
426 |
struct tipc_link *l; |
37b9c08a8 tipc: Optimizatio... |
427 |
|
440d8963c tipc: clean up li... |
428 429 430 431 |
l = kzalloc(sizeof(*l), GFP_ATOMIC); if (!l) return false; *link = l; |
e74a386d7 tipc: remove pre-... |
432 |
l->session = session; |
37b9c08a8 tipc: Optimizatio... |
433 |
|
440d8963c tipc: clean up li... |
434 |
/* Note: peer i/f name is completed by reset/activate message */ |
440d8963c tipc: clean up li... |
435 436 437 |
sprintf(l->name, "%u.%u.%u:%s-%u.%u.%u:unknown", tipc_zone(ownnode), tipc_cluster(ownnode), tipc_node(ownnode), if_name, tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); |
e74a386d7 tipc: remove pre-... |
438 |
strcpy(l->if_name, if_name); |
440d8963c tipc: clean up li... |
439 |
l->addr = peer; |
fd556f209 tipc: introduce c... |
440 |
l->peer_caps = peer_caps; |
c72fa872a tipc: eliminate l... |
441 |
l->net = net; |
e74a386d7 tipc: remove pre-... |
442 |
l->peer_session = ANY_SESSION; |
0e05498e9 tipc: make link i... |
443 444 445 446 447 448 449 |
l->bearer_id = bearer_id; l->tolerance = tolerance; l->net_plane = net_plane; l->advertised_mtu = mtu; l->mtu = mtu; l->priority = priority; tipc_link_set_queue_limits(l, window); |
c1ab3f1de tipc: make struct... |
450 |
l->ackers = 1; |
526669866 tipc: let broadca... |
451 452 |
l->bc_sndlink = bc_sndlink; l->bc_rcvlink = bc_rcvlink; |
440d8963c tipc: clean up li... |
453 454 455 |
l->inputq = inputq; l->namedq = namedq; l->state = LINK_RESETTING; |
440d8963c tipc: clean up li... |
456 457 458 459 460 461 |
__skb_queue_head_init(&l->transmq); __skb_queue_head_init(&l->backlogq); __skb_queue_head_init(&l->deferdq); skb_queue_head_init(&l->wakeupq); skb_queue_head_init(l->inputq); return true; |
b97bf3fd8 [TIPC] Initial merge |
462 |
} |
323019069 tipc: use explici... |
463 464 465 466 467 468 469 470 471 472 473 |
/** * tipc_link_bc_create - create new link to be used for broadcast * @n: pointer to associated node * @mtu: mtu to be used * @window: send window to be used * @inputq: queue to put messages ready for delivery * @namedq: queue to put binding table update messages ready for delivery * @link: return value, pointer to put the created link * * Returns true if link was created, otherwise false */ |
c72fa872a tipc: eliminate l... |
474 |
bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer, |
526669866 tipc: let broadca... |
475 |
int mtu, int window, u16 peer_caps, |
323019069 tipc: use explici... |
476 477 |
struct sk_buff_head *inputq, struct sk_buff_head *namedq, |
526669866 tipc: let broadca... |
478 |
struct tipc_link *bc_sndlink, |
323019069 tipc: use explici... |
479 480 481 |
struct tipc_link **link) { struct tipc_link *l; |
c72fa872a tipc: eliminate l... |
482 |
if (!tipc_link_create(net, "", MAX_BEARERS, 0, 'Z', mtu, 0, window, |
2af5ae372 tipc: clean up un... |
483 |
0, ownnode, peer, peer_caps, bc_sndlink, |
526669866 tipc: let broadca... |
484 |
NULL, inputq, namedq, link)) |
323019069 tipc: use explici... |
485 486 487 488 489 |
return false; l = *link; strcpy(l->name, tipc_bclink_name); tipc_link_reset(l); |
526669866 tipc: let broadca... |
490 |
l->state = LINK_RESET; |
2f5661245 tipc: let broadca... |
491 |
l->ackers = 0; |
526669866 tipc: let broadca... |
492 |
l->bc_rcvlink = l; |
323019069 tipc: use explici... |
493 |
|
526669866 tipc: let broadca... |
494 495 496 |
/* Broadcast send link is always up */ if (link_is_bc_sndlink(l)) l->state = LINK_ESTABLISHED; |
d999297c3 tipc: reduce lock... |
497 |
|
01fd12bb1 tipc: make replic... |
498 499 500 |
/* Disable replicast if even a single peer doesn't support it */ if (link_is_bc_rcvlink(l) && !(peer_caps & TIPC_BCAST_RCAST)) tipc_bcast_disable_rcast(net); |
526669866 tipc: let broadca... |
501 |
return true; |
d999297c3 tipc: reduce lock... |
502 |
} |
b97bf3fd8 [TIPC] Initial merge |
503 |
/** |
6ab30f9cb tipc: improve lin... |
504 505 506 |
* tipc_link_fsm_evt - link finite state machine * @l: pointer to link * @evt: state machine event to be processed |
6ab30f9cb tipc: improve lin... |
507 |
*/ |
662921cd0 tipc: merge link-... |
508 |
int tipc_link_fsm_evt(struct tipc_link *l, int evt) |
6ab30f9cb tipc: improve lin... |
509 |
{ |
5045f7b90 tipc: move protoc... |
510 |
int rc = 0; |
6ab30f9cb tipc: improve lin... |
511 512 |
switch (l->state) { |
662921cd0 tipc: merge link-... |
513 |
case LINK_RESETTING: |
6ab30f9cb tipc: improve lin... |
514 |
switch (evt) { |
662921cd0 tipc: merge link-... |
515 516 |
case LINK_PEER_RESET_EVT: l->state = LINK_PEER_RESET; |
6ab30f9cb tipc: improve lin... |
517 |
break; |
662921cd0 tipc: merge link-... |
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 |
case LINK_RESET_EVT: l->state = LINK_RESET; break; case LINK_FAILURE_EVT: case LINK_FAILOVER_BEGIN_EVT: case LINK_ESTABLISH_EVT: case LINK_FAILOVER_END_EVT: case LINK_SYNCH_BEGIN_EVT: case LINK_SYNCH_END_EVT: default: goto illegal_evt; } break; case LINK_RESET: switch (evt) { case LINK_PEER_RESET_EVT: l->state = LINK_ESTABLISHING; |
6ab30f9cb tipc: improve lin... |
535 |
break; |
662921cd0 tipc: merge link-... |
536 537 538 539 540 541 |
case LINK_FAILOVER_BEGIN_EVT: l->state = LINK_FAILINGOVER; case LINK_FAILURE_EVT: case LINK_RESET_EVT: case LINK_ESTABLISH_EVT: case LINK_FAILOVER_END_EVT: |
6ab30f9cb tipc: improve lin... |
542 |
break; |
662921cd0 tipc: merge link-... |
543 544 |
case LINK_SYNCH_BEGIN_EVT: case LINK_SYNCH_END_EVT: |
6ab30f9cb tipc: improve lin... |
545 |
default: |
662921cd0 tipc: merge link-... |
546 |
goto illegal_evt; |
6ab30f9cb tipc: improve lin... |
547 548 |
} break; |
662921cd0 tipc: merge link-... |
549 |
case LINK_PEER_RESET: |
6ab30f9cb tipc: improve lin... |
550 |
switch (evt) { |
662921cd0 tipc: merge link-... |
551 552 |
case LINK_RESET_EVT: l->state = LINK_ESTABLISHING; |
6ab30f9cb tipc: improve lin... |
553 |
break; |
662921cd0 tipc: merge link-... |
554 555 556 |
case LINK_PEER_RESET_EVT: case LINK_ESTABLISH_EVT: case LINK_FAILURE_EVT: |
6ab30f9cb tipc: improve lin... |
557 |
break; |
662921cd0 tipc: merge link-... |
558 559 560 561 562 563 564 565 566 567 568 569 |
case LINK_SYNCH_BEGIN_EVT: case LINK_SYNCH_END_EVT: case LINK_FAILOVER_BEGIN_EVT: case LINK_FAILOVER_END_EVT: default: goto illegal_evt; } break; case LINK_FAILINGOVER: switch (evt) { case LINK_FAILOVER_END_EVT: l->state = LINK_RESET; |
6ab30f9cb tipc: improve lin... |
570 |
break; |
662921cd0 tipc: merge link-... |
571 572 573 574 575 576 577 578 |
case LINK_PEER_RESET_EVT: case LINK_RESET_EVT: case LINK_ESTABLISH_EVT: case LINK_FAILURE_EVT: break; case LINK_FAILOVER_BEGIN_EVT: case LINK_SYNCH_BEGIN_EVT: case LINK_SYNCH_END_EVT: |
6ab30f9cb tipc: improve lin... |
579 |
default: |
662921cd0 tipc: merge link-... |
580 |
goto illegal_evt; |
6ab30f9cb tipc: improve lin... |
581 582 |
} break; |
662921cd0 tipc: merge link-... |
583 |
case LINK_ESTABLISHING: |
6ab30f9cb tipc: improve lin... |
584 |
switch (evt) { |
662921cd0 tipc: merge link-... |
585 586 |
case LINK_ESTABLISH_EVT: l->state = LINK_ESTABLISHED; |
6ab30f9cb tipc: improve lin... |
587 |
break; |
662921cd0 tipc: merge link-... |
588 589 590 |
case LINK_FAILOVER_BEGIN_EVT: l->state = LINK_FAILINGOVER; break; |
662921cd0 tipc: merge link-... |
591 |
case LINK_RESET_EVT: |
73f646cec tipc: delay ESTAB... |
592 593 |
l->state = LINK_RESET; break; |
662921cd0 tipc: merge link-... |
594 |
case LINK_FAILURE_EVT: |
73f646cec tipc: delay ESTAB... |
595 |
case LINK_PEER_RESET_EVT: |
662921cd0 tipc: merge link-... |
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
case LINK_SYNCH_BEGIN_EVT: case LINK_FAILOVER_END_EVT: break; case LINK_SYNCH_END_EVT: default: goto illegal_evt; } break; case LINK_ESTABLISHED: switch (evt) { case LINK_PEER_RESET_EVT: l->state = LINK_PEER_RESET; rc |= TIPC_LINK_DOWN_EVT; break; case LINK_FAILURE_EVT: l->state = LINK_RESETTING; rc |= TIPC_LINK_DOWN_EVT; |
6ab30f9cb tipc: improve lin... |
613 |
break; |
662921cd0 tipc: merge link-... |
614 615 |
case LINK_RESET_EVT: l->state = LINK_RESET; |
6ab30f9cb tipc: improve lin... |
616 |
break; |
662921cd0 tipc: merge link-... |
617 |
case LINK_ESTABLISH_EVT: |
5ae2f8e68 tipc: interrupt l... |
618 |
case LINK_SYNCH_END_EVT: |
6ab30f9cb tipc: improve lin... |
619 |
break; |
662921cd0 tipc: merge link-... |
620 621 622 |
case LINK_SYNCH_BEGIN_EVT: l->state = LINK_SYNCHING; break; |
662921cd0 tipc: merge link-... |
623 624 |
case LINK_FAILOVER_BEGIN_EVT: case LINK_FAILOVER_END_EVT: |
6ab30f9cb tipc: improve lin... |
625 |
default: |
662921cd0 tipc: merge link-... |
626 |
goto illegal_evt; |
6ab30f9cb tipc: improve lin... |
627 628 |
} break; |
662921cd0 tipc: merge link-... |
629 |
case LINK_SYNCHING: |
6ab30f9cb tipc: improve lin... |
630 |
switch (evt) { |
662921cd0 tipc: merge link-... |
631 632 633 634 635 636 637 |
case LINK_PEER_RESET_EVT: l->state = LINK_PEER_RESET; rc |= TIPC_LINK_DOWN_EVT; break; case LINK_FAILURE_EVT: l->state = LINK_RESETTING; rc |= TIPC_LINK_DOWN_EVT; |
6ab30f9cb tipc: improve lin... |
638 |
break; |
662921cd0 tipc: merge link-... |
639 640 |
case LINK_RESET_EVT: l->state = LINK_RESET; |
6ab30f9cb tipc: improve lin... |
641 |
break; |
662921cd0 tipc: merge link-... |
642 643 |
case LINK_ESTABLISH_EVT: case LINK_SYNCH_BEGIN_EVT: |
6ab30f9cb tipc: improve lin... |
644 |
break; |
662921cd0 tipc: merge link-... |
645 646 647 648 649 |
case LINK_SYNCH_END_EVT: l->state = LINK_ESTABLISHED; break; case LINK_FAILOVER_BEGIN_EVT: case LINK_FAILOVER_END_EVT: |
6ab30f9cb tipc: improve lin... |
650 |
default: |
662921cd0 tipc: merge link-... |
651 |
goto illegal_evt; |
6ab30f9cb tipc: improve lin... |
652 653 654 |
} break; default: |
662921cd0 tipc: merge link-... |
655 656 |
pr_err("Unknown FSM state %x in %s ", l->state, l->name); |
6ab30f9cb tipc: improve lin... |
657 |
} |
662921cd0 tipc: merge link-... |
658 659 660 661 662 |
return rc; illegal_evt: pr_err("Illegal FSM event %x in state %x on link %s ", evt, l->state, l->name); |
6ab30f9cb tipc: improve lin... |
663 664 |
return rc; } |
333ef69ed tipc: simplify li... |
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 |
/* link_profile_stats - update statistical profiling of traffic */ static void link_profile_stats(struct tipc_link *l) { struct sk_buff *skb; struct tipc_msg *msg; int length; /* Update counters used in statistical profiling of send traffic */ l->stats.accu_queue_sz += skb_queue_len(&l->transmq); l->stats.queue_sz_counts++; skb = skb_peek(&l->transmq); if (!skb) return; msg = buf_msg(skb); length = msg_size(msg); if (msg_user(msg) == MSG_FRAGMENTER) { if (msg_type(msg) != FIRST_FRAGMENT) return; length = msg_size(msg_get_wrapped(msg)); } l->stats.msg_lengths_total += length; l->stats.msg_length_counts++; if (length <= 64) l->stats.msg_length_profile[0]++; else if (length <= 256) l->stats.msg_length_profile[1]++; else if (length <= 1024) l->stats.msg_length_profile[2]++; else if (length <= 4096) l->stats.msg_length_profile[3]++; else if (length <= 16384) l->stats.msg_length_profile[4]++; else if (length <= 32768) l->stats.msg_length_profile[5]++; else l->stats.msg_length_profile[6]++; } /* tipc_link_timeout - perform periodic task as instructed from node timeout */ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) { |
c91522f86 tipc: eliminate u... |
710 711 |
int mtyp = 0; int rc = 0; |
42b18f605 tipc: refactor fu... |
712 713 714 |
bool state = false; bool probe = false; bool setup = false; |
526669866 tipc: let broadca... |
715 716 |
u16 bc_snt = l->bc_sndlink->snd_nxt - 1; u16 bc_acked = l->bc_rcvlink->acked; |
35c55c987 tipc: add neighbo... |
717 |
struct tipc_mon_state *mstate = &l->mon_state; |
5045f7b90 tipc: move protoc... |
718 |
|
662921cd0 tipc: merge link-... |
719 720 721 |
switch (l->state) { case LINK_ESTABLISHED: case LINK_SYNCHING: |
42b18f605 tipc: refactor fu... |
722 |
mtyp = STATE_MSG; |
35c55c987 tipc: add neighbo... |
723 724 725 726 |
link_profile_stats(l); tipc_mon_get_state(l->net, l->addr, mstate, l->bearer_id); if (mstate->reset || (l->silent_intv_cnt > l->abort_limit)) return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); |
42b18f605 tipc: refactor fu... |
727 |
state = bc_acked != bc_snt; |
35c55c987 tipc: add neighbo... |
728 729 730 731 732 733 734 735 |
state |= l->bc_rcvlink->rcv_unacked; state |= l->rcv_unacked; state |= !skb_queue_empty(&l->transmq); state |= !skb_queue_empty(&l->deferdq); probe = mstate->probing; probe |= l->silent_intv_cnt; if (probe || mstate->monitoring) l->silent_intv_cnt++; |
662921cd0 tipc: merge link-... |
736 737 |
break; case LINK_RESET: |
42b18f605 tipc: refactor fu... |
738 739 |
setup = l->rst_cnt++ <= 4; setup |= !(l->rst_cnt % 16); |
5045f7b90 tipc: move protoc... |
740 |
mtyp = RESET_MSG; |
662921cd0 tipc: merge link-... |
741 742 |
break; case LINK_ESTABLISHING: |
42b18f605 tipc: refactor fu... |
743 |
setup = true; |
5045f7b90 tipc: move protoc... |
744 |
mtyp = ACTIVATE_MSG; |
662921cd0 tipc: merge link-... |
745 |
break; |
662921cd0 tipc: merge link-... |
746 |
case LINK_PEER_RESET: |
598411d70 tipc: make resett... |
747 |
case LINK_RESETTING: |
662921cd0 tipc: merge link-... |
748 749 750 751 |
case LINK_FAILINGOVER: break; default: break; |
5045f7b90 tipc: move protoc... |
752 |
} |
662921cd0 tipc: merge link-... |
753 |
|
42b18f605 tipc: refactor fu... |
754 755 |
if (state || probe || setup) tipc_link_build_proto_msg(l, mtyp, probe, 0, 0, 0, xmitq); |
5045f7b90 tipc: move protoc... |
756 |
|
333ef69ed tipc: simplify li... |
757 758 |
return rc; } |
6ab30f9cb tipc: improve lin... |
759 |
/** |
3127a0200 tipc: clean up ha... |
760 |
* link_schedule_user - schedule a message sender for wakeup after congestion |
365ad353c tipc: reduce risk... |
761 762 |
* @l: congested link * @hdr: header of message that is being sent |
50100a5e3 tipc: use pseudo ... |
763 |
* Create pseudo msg to send back to user when congestion abates |
b97bf3fd8 [TIPC] Initial merge |
764 |
*/ |
365ad353c tipc: reduce risk... |
765 |
static int link_schedule_user(struct tipc_link *l, struct tipc_msg *hdr) |
b97bf3fd8 [TIPC] Initial merge |
766 |
{ |
365ad353c tipc: reduce risk... |
767 768 |
u32 dnode = tipc_own_addr(l->net); u32 dport = msg_origport(hdr); |
3127a0200 tipc: clean up ha... |
769 |
struct sk_buff *skb; |
3127a0200 tipc: clean up ha... |
770 771 |
/* Create and schedule wakeup pseudo message */ skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, |
365ad353c tipc: reduce risk... |
772 |
dnode, l->addr, dport, 0, 0); |
3127a0200 tipc: clean up ha... |
773 |
if (!skb) |
22d85c794 tipc: change sk_b... |
774 |
return -ENOBUFS; |
365ad353c tipc: reduce risk... |
775 776 777 778 |
msg_set_dest_droppable(buf_msg(skb), true); TIPC_SKB_CB(skb)->chain_imp = msg_importance(hdr); skb_queue_tail(&l->wakeupq, skb); l->stats.link_congs++; |
3127a0200 tipc: clean up ha... |
779 |
return -ELINKCONG; |
b97bf3fd8 [TIPC] Initial merge |
780 |
} |
50100a5e3 tipc: use pseudo ... |
781 782 |
/** * link_prepare_wakeup - prepare users for wakeup after congestion |
365ad353c tipc: reduce risk... |
783 784 785 |
* @l: congested link * Wake up a number of waiting users, as permitted by available space * in the send queue |
50100a5e3 tipc: use pseudo ... |
786 |
*/ |
1f66d161a tipc: introduce s... |
787 |
void link_prepare_wakeup(struct tipc_link *l) |
b97bf3fd8 [TIPC] Initial merge |
788 |
{ |
58d78b328 tipc: use skb_que... |
789 |
struct sk_buff *skb, *tmp; |
365ad353c tipc: reduce risk... |
790 |
int imp, i = 0; |
50100a5e3 tipc: use pseudo ... |
791 |
|
1f66d161a tipc: introduce s... |
792 793 |
skb_queue_walk_safe(&l->wakeupq, skb, tmp) { imp = TIPC_SKB_CB(skb)->chain_imp; |
365ad353c tipc: reduce risk... |
794 795 796 797 |
if (l->backlog[imp].len < l->backlog[imp].limit) { skb_unlink(skb, &l->wakeupq); skb_queue_tail(l->inputq, skb); } else if (i++ > 10) { |
b97bf3fd8 [TIPC] Initial merge |
798 |
break; |
365ad353c tipc: reduce risk... |
799 |
} |
b97bf3fd8 [TIPC] Initial merge |
800 |
} |
b97bf3fd8 [TIPC] Initial merge |
801 |
} |
6e498158a tipc: move link s... |
802 |
void tipc_link_reset(struct tipc_link *l) |
b97bf3fd8 [TIPC] Initial merge |
803 |
{ |
e74a386d7 tipc: remove pre-... |
804 805 |
l->peer_session = ANY_SESSION; l->session++; |
6e498158a tipc: move link s... |
806 |
l->mtu = l->advertised_mtu; |
6e498158a tipc: move link s... |
807 808 |
__skb_queue_purge(&l->transmq); __skb_queue_purge(&l->deferdq); |
23d8335d7 tipc: remove impl... |
809 |
skb_queue_splice_init(&l->wakeupq, l->inputq); |
2af5ae372 tipc: clean up un... |
810 811 812 813 814 815 |
__skb_queue_purge(&l->backlogq); l->backlog[TIPC_LOW_IMPORTANCE].len = 0; l->backlog[TIPC_MEDIUM_IMPORTANCE].len = 0; l->backlog[TIPC_HIGH_IMPORTANCE].len = 0; l->backlog[TIPC_CRITICAL_IMPORTANCE].len = 0; l->backlog[TIPC_SYSTEM_IMPORTANCE].len = 0; |
6e498158a tipc: move link s... |
816 817 818 819 820 821 822 |
kfree_skb(l->reasm_buf); kfree_skb(l->failover_reasm_skb); l->reasm_buf = NULL; l->failover_reasm_skb = NULL; l->rcv_unacked = 0; l->snd_nxt = 1; l->rcv_nxt = 1; |
c1ab3f1de tipc: make struct... |
823 |
l->acked = 0; |
6e498158a tipc: move link s... |
824 |
l->silent_intv_cnt = 0; |
88e8ac700 tipc: reduce tran... |
825 |
l->rst_cnt = 0; |
6e498158a tipc: move link s... |
826 |
l->stale_count = 0; |
526669866 tipc: let broadca... |
827 |
l->bc_peer_is_up = false; |
35c55c987 tipc: add neighbo... |
828 |
memset(&l->mon_state, 0, sizeof(l->mon_state)); |
38206d593 tipc: narrow down... |
829 |
tipc_link_reset_stats(l); |
b97bf3fd8 [TIPC] Initial merge |
830 |
} |
b97bf3fd8 [TIPC] Initial merge |
831 |
/** |
af9b028e2 tipc: make media ... |
832 833 834 835 836 |
* tipc_link_xmit(): enqueue buffer list according to queue situation * @link: link to use * @list: chain of buffers containing message * @xmitq: returned list of packets to be sent by caller * |
365ad353c tipc: reduce risk... |
837 |
* Consumes the buffer chain. |
af9b028e2 tipc: make media ... |
838 839 840 841 842 843 844 845 |
* Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted */ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list, struct sk_buff_head *xmitq) { struct tipc_msg *hdr = buf_msg(skb_peek(list)); unsigned int maxwin = l->window; |
365ad353c tipc: reduce risk... |
846 |
int imp = msg_importance(hdr); |
af9b028e2 tipc: make media ... |
847 848 849 |
unsigned int mtu = l->mtu; u16 ack = l->rcv_nxt - 1; u16 seqno = l->snd_nxt; |
526669866 tipc: let broadca... |
850 |
u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1; |
af9b028e2 tipc: make media ... |
851 852 853 |
struct sk_buff_head *transmq = &l->transmq; struct sk_buff_head *backlogq = &l->backlogq; struct sk_buff *skb, *_skb, *bskb; |
959011224 tipc: fix link st... |
854 |
int pkt_cnt = skb_queue_len(list); |
365ad353c tipc: reduce risk... |
855 |
int rc = 0; |
af9b028e2 tipc: make media ... |
856 |
|
4952cd3e7 tipc: refactor no... |
857 858 |
if (unlikely(msg_size(hdr) > mtu)) { skb_queue_purge(list); |
af9b028e2 tipc: make media ... |
859 |
return -EMSGSIZE; |
4952cd3e7 tipc: refactor no... |
860 |
} |
af9b028e2 tipc: make media ... |
861 |
|
365ad353c tipc: reduce risk... |
862 863 864 865 866 867 868 869 |
/* Allow oversubscription of one data msg per source at congestion */ if (unlikely(l->backlog[imp].len >= l->backlog[imp].limit)) { if (imp == TIPC_SYSTEM_IMPORTANCE) { pr_warn("%s<%s>, link overflow", link_rst_msg, l->name); return -ENOBUFS; } rc = link_schedule_user(l, hdr); } |
959011224 tipc: fix link st... |
870 871 872 873 |
if (pkt_cnt > 1) { l->stats.sent_fragmented++; l->stats.sent_fragments += pkt_cnt; } |
af9b028e2 tipc: make media ... |
874 875 876 877 878 879 |
/* Prepare each packet for sending, and add to relevant queue: */ while (skb_queue_len(list)) { skb = skb_peek(list); hdr = buf_msg(skb); msg_set_seqno(hdr, seqno); msg_set_ack(hdr, ack); |
526669866 tipc: let broadca... |
880 |
msg_set_bcast_ack(hdr, bc_ack); |
af9b028e2 tipc: make media ... |
881 882 883 |
if (likely(skb_queue_len(transmq) < maxwin)) { _skb = skb_clone(skb, GFP_ATOMIC); |
4952cd3e7 tipc: refactor no... |
884 885 |
if (!_skb) { skb_queue_purge(list); |
af9b028e2 tipc: make media ... |
886 |
return -ENOBUFS; |
4952cd3e7 tipc: refactor no... |
887 |
} |
af9b028e2 tipc: make media ... |
888 889 890 |
__skb_dequeue(list); __skb_queue_tail(transmq, skb); __skb_queue_tail(xmitq, _skb); |
c1ab3f1de tipc: make struct... |
891 |
TIPC_SKB_CB(skb)->ackers = l->ackers; |
af9b028e2 tipc: make media ... |
892 |
l->rcv_unacked = 0; |
959011224 tipc: fix link st... |
893 |
l->stats.sent_pkts++; |
af9b028e2 tipc: make media ... |
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 |
seqno++; continue; } if (tipc_msg_bundle(skb_peek_tail(backlogq), hdr, mtu)) { kfree_skb(__skb_dequeue(list)); l->stats.sent_bundled++; continue; } if (tipc_msg_make_bundle(&bskb, hdr, mtu, l->addr)) { kfree_skb(__skb_dequeue(list)); __skb_queue_tail(backlogq, bskb); l->backlog[msg_importance(buf_msg(bskb))].len++; l->stats.sent_bundled++; l->stats.sent_bundles++; continue; } l->backlog[imp].len += skb_queue_len(list); skb_queue_splice_tail_init(list, backlogq); } l->snd_nxt = seqno; |
365ad353c tipc: reduce risk... |
914 |
return rc; |
af9b028e2 tipc: make media ... |
915 |
} |
d999297c3 tipc: reduce lock... |
916 917 918 919 920 921 |
void tipc_link_advance_backlog(struct tipc_link *l, struct sk_buff_head *xmitq) { struct sk_buff *skb, *_skb; struct tipc_msg *hdr; u16 seqno = l->snd_nxt; u16 ack = l->rcv_nxt - 1; |
526669866 tipc: let broadca... |
922 |
u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1; |
d999297c3 tipc: reduce lock... |
923 924 925 926 927 928 929 930 931 932 933 934 935 |
while (skb_queue_len(&l->transmq) < l->window) { skb = skb_peek(&l->backlogq); if (!skb) break; _skb = skb_clone(skb, GFP_ATOMIC); if (!_skb) break; __skb_dequeue(&l->backlogq); hdr = buf_msg(skb); l->backlog[msg_importance(hdr)].len--; __skb_queue_tail(&l->transmq, skb); __skb_queue_tail(xmitq, _skb); |
c1ab3f1de tipc: make struct... |
936 |
TIPC_SKB_CB(skb)->ackers = l->ackers; |
d999297c3 tipc: reduce lock... |
937 |
msg_set_seqno(hdr, seqno); |
526669866 tipc: let broadca... |
938 939 |
msg_set_ack(hdr, ack); msg_set_bcast_ack(hdr, bc_ack); |
d999297c3 tipc: reduce lock... |
940 |
l->rcv_unacked = 0; |
959011224 tipc: fix link st... |
941 |
l->stats.sent_pkts++; |
d999297c3 tipc: reduce lock... |
942 943 944 945 |
seqno++; } l->snd_nxt = seqno; } |
526669866 tipc: let broadca... |
946 |
static void link_retransmit_failure(struct tipc_link *l, struct sk_buff *skb) |
d356eeba8 [TIPC]: Multicast... |
947 |
{ |
526669866 tipc: let broadca... |
948 949 950 951 |
struct tipc_msg *hdr = buf_msg(skb); pr_warn("Retransmission failure on link <%s> ", l->name); |
40501f90e tipc: don't reset... |
952 |
link_print(l, "State of link "); |
526669866 tipc: let broadca... |
953 954 955 956 957 958 |
pr_info("Failed msg: usr %u, typ %u, len %u, err %u ", msg_user(hdr), msg_type(hdr), msg_size(hdr), msg_errcode(hdr)); pr_info("sqno %u, prev: %x, src: %x ", msg_seqno(hdr), msg_prevnode(hdr), msg_orignode(hdr)); |
d356eeba8 [TIPC]: Multicast... |
959 |
} |
40501f90e tipc: don't reset... |
960 961 |
int tipc_link_retrans(struct tipc_link *l, struct tipc_link *nacker, u16 from, u16 to, struct sk_buff_head *xmitq) |
d999297c3 tipc: reduce lock... |
962 963 964 |
{ struct sk_buff *_skb, *skb = skb_peek(&l->transmq); struct tipc_msg *hdr; |
c1ab3f1de tipc: make struct... |
965 |
u16 ack = l->rcv_nxt - 1; |
526669866 tipc: let broadca... |
966 |
u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1; |
d999297c3 tipc: reduce lock... |
967 968 969 970 971 |
if (!skb) return 0; /* Detect repeated retransmit failures on same packet */ |
40501f90e tipc: don't reset... |
972 973 974 975 |
if (nacker->last_retransm != buf_seqno(skb)) { nacker->last_retransm = buf_seqno(skb); nacker->stale_count = 1; } else if (++nacker->stale_count > 100) { |
d999297c3 tipc: reduce lock... |
976 |
link_retransmit_failure(l, skb); |
40501f90e tipc: don't reset... |
977 978 979 |
nacker->stale_count = 0; if (link_is_bc_sndlink(l)) return TIPC_LINK_DOWN_EVT; |
662921cd0 tipc: merge link-... |
980 |
return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); |
d999297c3 tipc: reduce lock... |
981 |
} |
c1ab3f1de tipc: make struct... |
982 983 |
/* Move forward to where retransmission should start */ |
d999297c3 tipc: reduce lock... |
984 |
skb_queue_walk(&l->transmq, skb) { |
c1ab3f1de tipc: make struct... |
985 986 987 988 989 990 991 |
if (!less(buf_seqno(skb), from)) break; } skb_queue_walk_from(&l->transmq, skb) { if (more(buf_seqno(skb), to)) break; |
d999297c3 tipc: reduce lock... |
992 993 994 995 996 |
hdr = buf_msg(skb); _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC); if (!_skb) return 0; hdr = buf_msg(_skb); |
c1ab3f1de tipc: make struct... |
997 998 |
msg_set_ack(hdr, ack); msg_set_bcast_ack(hdr, bc_ack); |
d999297c3 tipc: reduce lock... |
999 1000 |
_skb->priority = TC_PRIO_CONTROL; __skb_queue_tail(xmitq, _skb); |
d999297c3 tipc: reduce lock... |
1001 1002 1003 1004 |
l->stats.retransmitted++; } return 0; } |
c637c1035 tipc: resolve rac... |
1005 |
/* tipc_data_input - deliver data and name distr msgs to upper layer |
7ae934beb tipc: refactor me... |
1006 |
* |
c637c1035 tipc: resolve rac... |
1007 |
* Consumes buffer if message is of right type |
7ae934beb tipc: refactor me... |
1008 1009 |
* Node lock must be held */ |
526669866 tipc: let broadca... |
1010 |
static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb, |
9073fb8be tipc: use tempora... |
1011 |
struct sk_buff_head *inputq) |
7ae934beb tipc: refactor me... |
1012 |
{ |
a853e4c6d tipc: introduce r... |
1013 1014 1015 |
struct tipc_msg *hdr = buf_msg(skb); switch (msg_user(hdr)) { |
c637c1035 tipc: resolve rac... |
1016 1017 1018 1019 |
case TIPC_LOW_IMPORTANCE: case TIPC_MEDIUM_IMPORTANCE: case TIPC_HIGH_IMPORTANCE: case TIPC_CRITICAL_IMPORTANCE: |
a853e4c6d tipc: introduce r... |
1020 1021 1022 1023 |
if (unlikely(msg_type(hdr) == TIPC_MCAST_MSG)) { skb_queue_tail(l->bc_rcvlink->inputq, skb); return true; } |
c637c1035 tipc: resolve rac... |
1024 |
case CONN_MANAGER: |
9945e8043 tipc: limit usage... |
1025 |
skb_queue_tail(inputq, skb); |
c637c1035 tipc: resolve rac... |
1026 |
return true; |
7ae934beb tipc: refactor me... |
1027 |
case NAME_DISTRIBUTOR: |
526669866 tipc: let broadca... |
1028 1029 |
l->bc_rcvlink->state = LINK_ESTABLISHED; skb_queue_tail(l->namedq, skb); |
c637c1035 tipc: resolve rac... |
1030 1031 |
return true; case MSG_BUNDLER: |
dff29b1a8 tipc: eliminate d... |
1032 |
case TUNNEL_PROTOCOL: |
c637c1035 tipc: resolve rac... |
1033 |
case MSG_FRAGMENTER: |
7ae934beb tipc: refactor me... |
1034 |
case BCAST_PROTOCOL: |
c637c1035 tipc: resolve rac... |
1035 |
return false; |
7ae934beb tipc: refactor me... |
1036 |
default: |
c637c1035 tipc: resolve rac... |
1037 1038 1039 1040 1041 |
pr_warn("Dropping received illegal msg type "); kfree_skb(skb); return false; }; |
7ae934beb tipc: refactor me... |
1042 |
} |
c637c1035 tipc: resolve rac... |
1043 1044 1045 1046 |
/* tipc_link_input - process packet that has passed link protocol check * * Consumes buffer |
7ae934beb tipc: refactor me... |
1047 |
*/ |
9073fb8be tipc: use tempora... |
1048 1049 |
static int tipc_link_input(struct tipc_link *l, struct sk_buff *skb, struct sk_buff_head *inputq) |
7ae934beb tipc: refactor me... |
1050 |
{ |
6e498158a tipc: move link s... |
1051 1052 |
struct tipc_msg *hdr = buf_msg(skb); struct sk_buff **reasm_skb = &l->reasm_buf; |
c637c1035 tipc: resolve rac... |
1053 |
struct sk_buff *iskb; |
9945e8043 tipc: limit usage... |
1054 |
struct sk_buff_head tmpq; |
6e498158a tipc: move link s... |
1055 |
int usr = msg_user(hdr); |
6144a996a tipc: move all li... |
1056 |
int rc = 0; |
6e498158a tipc: move link s... |
1057 1058 |
int pos = 0; int ipos = 0; |
c637c1035 tipc: resolve rac... |
1059 |
|
6e498158a tipc: move link s... |
1060 1061 1062 1063 |
if (unlikely(usr == TUNNEL_PROTOCOL)) { if (msg_type(hdr) == SYNCH_MSG) { __skb_queue_purge(&l->deferdq); goto drop; |
8b4ed8634 tipc: eliminate r... |
1064 |
} |
6e498158a tipc: move link s... |
1065 1066 1067 1068 1069 1070 1071 |
if (!tipc_msg_extract(skb, &iskb, &ipos)) return rc; kfree_skb(skb); skb = iskb; hdr = buf_msg(skb); if (less(msg_seqno(hdr), l->drop_point)) goto drop; |
9073fb8be tipc: use tempora... |
1072 |
if (tipc_data_input(l, skb, inputq)) |
6e498158a tipc: move link s... |
1073 1074 1075 1076 |
return rc; usr = msg_user(hdr); reasm_skb = &l->failover_reasm_skb; } |
c637c1035 tipc: resolve rac... |
1077 |
|
6e498158a tipc: move link s... |
1078 |
if (usr == MSG_BUNDLER) { |
9945e8043 tipc: limit usage... |
1079 |
skb_queue_head_init(&tmpq); |
6e498158a tipc: move link s... |
1080 1081 |
l->stats.recv_bundles++; l->stats.recv_bundled += msg_msgcnt(hdr); |
c637c1035 tipc: resolve rac... |
1082 |
while (tipc_msg_extract(skb, &iskb, &pos)) |
9945e8043 tipc: limit usage... |
1083 1084 |
tipc_data_input(l, iskb, &tmpq); tipc_skb_queue_splice_tail(&tmpq, inputq); |
662921cd0 tipc: merge link-... |
1085 |
return 0; |
6e498158a tipc: move link s... |
1086 1087 1088 1089 |
} else if (usr == MSG_FRAGMENTER) { l->stats.recv_fragments++; if (tipc_buf_append(reasm_skb, &skb)) { l->stats.recv_fragmented++; |
9073fb8be tipc: use tempora... |
1090 |
tipc_data_input(l, skb, inputq); |
526669866 tipc: let broadca... |
1091 1092 1093 |
} else if (!*reasm_skb && !link_is_bc_rcvlink(l)) { pr_warn_ratelimited("Unable to build fragment list "); |
662921cd0 tipc: merge link-... |
1094 |
return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); |
c637c1035 tipc: resolve rac... |
1095 |
} |
662921cd0 tipc: merge link-... |
1096 |
return 0; |
6e498158a tipc: move link s... |
1097 |
} else if (usr == BCAST_PROTOCOL) { |
c72fa872a tipc: eliminate l... |
1098 |
tipc_bcast_lock(l->net); |
526669866 tipc: let broadca... |
1099 |
tipc_link_bc_init_rcv(l->bc_rcvlink, hdr); |
c72fa872a tipc: eliminate l... |
1100 |
tipc_bcast_unlock(l->net); |
6e498158a tipc: move link s... |
1101 1102 1103 |
} drop: kfree_skb(skb); |
662921cd0 tipc: merge link-... |
1104 |
return 0; |
7ae934beb tipc: refactor me... |
1105 |
} |
d999297c3 tipc: reduce lock... |
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 |
static bool tipc_link_release_pkts(struct tipc_link *l, u16 acked) { bool released = false; struct sk_buff *skb, *tmp; skb_queue_walk_safe(&l->transmq, skb, tmp) { if (more(buf_seqno(skb), acked)) break; __skb_unlink(skb, &l->transmq); kfree_skb(skb); released = true; } return released; } |
34b9cd64c tipc: let first m... |
1120 |
/* tipc_link_build_state_msg: prepare link state message for transmission |
526669866 tipc: let broadca... |
1121 1122 1123 |
* * Note that sending of broadcast ack is coordinated among nodes, to reduce * risk of ack storms towards the sender |
f9aa358a8 tipc: simplify ti... |
1124 |
*/ |
34b9cd64c tipc: let first m... |
1125 |
int tipc_link_build_state_msg(struct tipc_link *l, struct sk_buff_head *xmitq) |
f9aa358a8 tipc: simplify ti... |
1126 |
{ |
526669866 tipc: let broadca... |
1127 1128 1129 1130 1131 |
if (!l) return 0; /* Broadcast ACK must be sent via a unicast link => defer to caller */ if (link_is_bc_rcvlink(l)) { |
e74a386d7 tipc: remove pre-... |
1132 |
if (((l->rcv_nxt ^ tipc_own_addr(l->net)) & 0xf) != 0xf) |
526669866 tipc: let broadca... |
1133 1134 |
return 0; l->rcv_unacked = 0; |
02d11ca20 tipc: transfer br... |
1135 1136 1137 1138 |
/* Use snd_nxt to store peer's snd_nxt in broadcast rcv link */ l->snd_nxt = l->rcv_nxt; return TIPC_LINK_SND_STATE; |
526669866 tipc: let broadca... |
1139 1140 1141 |
} /* Unicast ACK */ |
f9aa358a8 tipc: simplify ti... |
1142 1143 1144 |
l->rcv_unacked = 0; l->stats.sent_acks++; tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, xmitq); |
526669866 tipc: let broadca... |
1145 |
return 0; |
f9aa358a8 tipc: simplify ti... |
1146 |
} |
282b3a056 tipc: send out RE... |
1147 1148 1149 1150 1151 |
/* tipc_link_build_reset_msg: prepare link RESET or ACTIVATE message */ void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq) { int mtyp = RESET_MSG; |
634696b19 tipc: guarantee p... |
1152 |
struct sk_buff *skb; |
282b3a056 tipc: send out RE... |
1153 1154 1155 1156 1157 |
if (l->state == LINK_ESTABLISHING) mtyp = ACTIVATE_MSG; tipc_link_build_proto_msg(l, mtyp, 0, 0, 0, 0, xmitq); |
634696b19 tipc: guarantee p... |
1158 1159 1160 1161 1162 |
/* Inform peer that this endpoint is going down if applicable */ skb = skb_peek_tail(xmitq); if (skb && (l->state == LINK_RESET)) msg_set_peer_stopping(buf_msg(skb), 1); |
282b3a056 tipc: send out RE... |
1163 |
} |
f9aa358a8 tipc: simplify ti... |
1164 |
/* tipc_link_build_nack_msg: prepare link nack message for transmission |
e0a05ebe2 tipc: send broadc... |
1165 1166 |
* Note that sending of broadcast NACK is coordinated among nodes, to * reduce the risk of NACK storms towards the sender |
f9aa358a8 tipc: simplify ti... |
1167 |
*/ |
e0a05ebe2 tipc: send broadc... |
1168 1169 |
static int tipc_link_build_nack_msg(struct tipc_link *l, struct sk_buff_head *xmitq) |
f9aa358a8 tipc: simplify ti... |
1170 1171 |
{ u32 def_cnt = ++l->stats.deferred_recv; |
e0a05ebe2 tipc: send broadc... |
1172 |
int match1, match2; |
f9aa358a8 tipc: simplify ti... |
1173 |
|
e0a05ebe2 tipc: send broadc... |
1174 1175 1176 1177 1178 1179 1180 |
if (link_is_bc_rcvlink(l)) { match1 = def_cnt & 0xf; match2 = tipc_own_addr(l->net) & 0xf; if (match1 == match2) return TIPC_LINK_SND_STATE; return 0; } |
526669866 tipc: let broadca... |
1181 |
|
f9aa358a8 tipc: simplify ti... |
1182 1183 |
if ((skb_queue_len(&l->deferdq) == 1) || !(def_cnt % TIPC_NACK_INTV)) tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, xmitq); |
e0a05ebe2 tipc: send broadc... |
1184 |
return 0; |
f9aa358a8 tipc: simplify ti... |
1185 |
} |
d999297c3 tipc: reduce lock... |
1186 |
/* tipc_link_rcv - process TIPC packets/messages arriving from off-node |
f9aa358a8 tipc: simplify ti... |
1187 |
* @l: the link that should handle the message |
d999297c3 tipc: reduce lock... |
1188 1189 1190 1191 1192 1193 |
* @skb: TIPC packet * @xmitq: queue to place packets to be sent after this call */ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, struct sk_buff_head *xmitq) { |
f9aa358a8 tipc: simplify ti... |
1194 |
struct sk_buff_head *defq = &l->deferdq; |
d999297c3 tipc: reduce lock... |
1195 |
struct tipc_msg *hdr; |
81204c492 tipc: improve seq... |
1196 |
u16 seqno, rcv_nxt, win_lim; |
d999297c3 tipc: reduce lock... |
1197 |
int rc = 0; |
f9aa358a8 tipc: simplify ti... |
1198 |
do { |
d999297c3 tipc: reduce lock... |
1199 |
hdr = buf_msg(skb); |
f9aa358a8 tipc: simplify ti... |
1200 1201 |
seqno = msg_seqno(hdr); rcv_nxt = l->rcv_nxt; |
81204c492 tipc: improve seq... |
1202 |
win_lim = rcv_nxt + TIPC_MAX_LINK_WIN; |
d999297c3 tipc: reduce lock... |
1203 1204 |
/* Verify and update link state */ |
f9aa358a8 tipc: simplify ti... |
1205 1206 |
if (unlikely(msg_user(hdr) == LINK_PROTOCOL)) return tipc_link_proto_rcv(l, skb, xmitq); |
d999297c3 tipc: reduce lock... |
1207 |
|
662921cd0 tipc: merge link-... |
1208 |
if (unlikely(!link_is_up(l))) { |
73f646cec tipc: delay ESTAB... |
1209 1210 1211 |
if (l->state == LINK_ESTABLISHING) rc = TIPC_LINK_UP_EVT; goto drop; |
d999297c3 tipc: reduce lock... |
1212 |
} |
f9aa358a8 tipc: simplify ti... |
1213 |
/* Don't send probe at next timeout expiration */ |
d999297c3 tipc: reduce lock... |
1214 |
l->silent_intv_cnt = 0; |
81204c492 tipc: improve seq... |
1215 1216 1217 1218 1219 |
/* Drop if outside receive window */ if (unlikely(less(seqno, rcv_nxt) || more(seqno, win_lim))) { l->stats.duplicates++; goto drop; } |
d999297c3 tipc: reduce lock... |
1220 1221 1222 1223 1224 1225 |
/* Forward queues and wake up waiting users */ if (likely(tipc_link_release_pkts(l, msg_ack(hdr)))) { tipc_link_advance_backlog(l, xmitq); if (unlikely(!skb_queue_empty(&l->wakeupq))) link_prepare_wakeup(l); } |
81204c492 tipc: improve seq... |
1226 1227 |
/* Defer delivery if sequence gap */ if (unlikely(seqno != rcv_nxt)) { |
8306f99a5 tipc: disallow pa... |
1228 |
__tipc_skb_queue_sorted(defq, seqno, skb); |
e0a05ebe2 tipc: send broadc... |
1229 |
rc |= tipc_link_build_nack_msg(l, xmitq); |
f9aa358a8 tipc: simplify ti... |
1230 |
break; |
d999297c3 tipc: reduce lock... |
1231 |
} |
81204c492 tipc: improve seq... |
1232 |
/* Deliver packet */ |
d999297c3 tipc: reduce lock... |
1233 |
l->rcv_nxt++; |
959011224 tipc: fix link st... |
1234 |
l->stats.recv_pkts++; |
f9aa358a8 tipc: simplify ti... |
1235 |
if (!tipc_data_input(l, skb, l->inputq)) |
526669866 tipc: let broadca... |
1236 |
rc |= tipc_link_input(l, skb, l->inputq); |
f9aa358a8 tipc: simplify ti... |
1237 |
if (unlikely(++l->rcv_unacked >= TIPC_MIN_LINK_WIN)) |
34b9cd64c tipc: let first m... |
1238 |
rc |= tipc_link_build_state_msg(l, xmitq); |
02d11ca20 tipc: transfer br... |
1239 |
if (unlikely(rc & ~TIPC_LINK_SND_STATE)) |
526669866 tipc: let broadca... |
1240 |
break; |
f9aa358a8 tipc: simplify ti... |
1241 1242 1243 1244 1245 |
} while ((skb = __skb_dequeue(defq))); return rc; drop: kfree_skb(skb); |
d999297c3 tipc: reduce lock... |
1246 1247 |
return rc; } |
426cc2b86 tipc: introduce n... |
1248 1249 1250 1251 |
static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, u16 rcvgap, int tolerance, int priority, struct sk_buff_head *xmitq) { |
02d11ca20 tipc: transfer br... |
1252 |
struct tipc_link *bcl = l->bc_rcvlink; |
e74a386d7 tipc: remove pre-... |
1253 1254 1255 |
struct sk_buff *skb; struct tipc_msg *hdr; struct sk_buff_head *dfq = &l->deferdq; |
02d11ca20 tipc: transfer br... |
1256 |
bool node_up = link_is_up(bcl); |
35c55c987 tipc: add neighbo... |
1257 1258 1259 |
struct tipc_mon_state *mstate = &l->mon_state; int dlen = 0; void *data; |
426cc2b86 tipc: introduce n... |
1260 1261 |
/* Don't send protocol message during reset or link failover */ |
662921cd0 tipc: merge link-... |
1262 |
if (tipc_link_is_blocked(l)) |
426cc2b86 tipc: introduce n... |
1263 |
return; |
e74a386d7 tipc: remove pre-... |
1264 1265 1266 1267 1268 1269 1270 |
if (!tipc_link_is_up(l) && (mtyp == STATE_MSG)) return; if (!skb_queue_empty(dfq)) rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt; skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE, |
35c55c987 tipc: add neighbo... |
1271 |
tipc_max_domain_size, l->addr, |
e74a386d7 tipc: remove pre-... |
1272 1273 1274 1275 1276 |
tipc_own_addr(l->net), 0, 0, 0); if (!skb) return; hdr = buf_msg(skb); |
35c55c987 tipc: add neighbo... |
1277 |
data = msg_data(hdr); |
e74a386d7 tipc: remove pre-... |
1278 1279 |
msg_set_session(hdr, l->session); msg_set_bearer_id(hdr, l->bearer_id); |
426cc2b86 tipc: introduce n... |
1280 |
msg_set_net_plane(hdr, l->net_plane); |
526669866 tipc: let broadca... |
1281 1282 |
msg_set_next_sent(hdr, l->snd_nxt); msg_set_ack(hdr, l->rcv_nxt - 1); |
02d11ca20 tipc: transfer br... |
1283 |
msg_set_bcast_ack(hdr, bcl->rcv_nxt - 1); |
06bd2b1ed tipc: fix broadca... |
1284 |
msg_set_bc_ack_invalid(hdr, !node_up); |
526669866 tipc: let broadca... |
1285 |
msg_set_last_bcast(hdr, l->bc_sndlink->snd_nxt - 1); |
426cc2b86 tipc: introduce n... |
1286 1287 1288 1289 |
msg_set_link_tolerance(hdr, tolerance); msg_set_linkprio(hdr, priority); msg_set_redundant_link(hdr, node_up); msg_set_seq_gap(hdr, 0); |
526669866 tipc: let broadca... |
1290 |
msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2); |
426cc2b86 tipc: introduce n... |
1291 1292 |
if (mtyp == STATE_MSG) { |
e74a386d7 tipc: remove pre-... |
1293 |
msg_set_seq_gap(hdr, rcvgap); |
02d11ca20 tipc: transfer br... |
1294 |
msg_set_bc_gap(hdr, link_bc_rcv_gap(bcl)); |
426cc2b86 tipc: introduce n... |
1295 |
msg_set_probe(hdr, probe); |
35c55c987 tipc: add neighbo... |
1296 1297 1298 |
tipc_mon_prep(l->net, data, &dlen, mstate, l->bearer_id); msg_set_size(hdr, INT_H_SIZE + dlen); skb_trim(skb, INT_H_SIZE + dlen); |
426cc2b86 tipc: introduce n... |
1299 |
l->stats.sent_states++; |
526669866 tipc: let broadca... |
1300 |
l->rcv_unacked = 0; |
426cc2b86 tipc: introduce n... |
1301 1302 1303 |
} else { /* RESET_MSG or ACTIVATE_MSG */ msg_set_max_pkt(hdr, l->advertised_mtu); |
35c55c987 tipc: add neighbo... |
1304 1305 1306 |
strcpy(data, l->if_name); msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME); skb_trim(skb, INT_H_SIZE + TIPC_MAX_IF_NAME); |
426cc2b86 tipc: introduce n... |
1307 |
} |
e74a386d7 tipc: remove pre-... |
1308 1309 1310 1311 |
if (probe) l->stats.sent_probes++; if (rcvgap) l->stats.sent_nacks++; |
426cc2b86 tipc: introduce n... |
1312 |
skb->priority = TC_PRIO_CONTROL; |
6e498158a tipc: move link s... |
1313 |
__skb_queue_tail(xmitq, skb); |
b97bf3fd8 [TIPC] Initial merge |
1314 |
} |
6e498158a tipc: move link s... |
1315 |
/* tipc_link_tnl_prepare(): prepare and return a list of tunnel packets |
f9aa358a8 tipc: simplify ti... |
1316 |
* with contents of the link's transmit and backlog queues. |
b97bf3fd8 [TIPC] Initial merge |
1317 |
*/ |
6e498158a tipc: move link s... |
1318 1319 |
void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, int mtyp, struct sk_buff_head *xmitq) |
b97bf3fd8 [TIPC] Initial merge |
1320 |
{ |
6e498158a tipc: move link s... |
1321 1322 1323 1324 1325 |
struct sk_buff *skb, *tnlskb; struct tipc_msg *hdr, tnlhdr; struct sk_buff_head *queue = &l->transmq; struct sk_buff_head tmpxq, tnlq; u16 pktlen, pktcnt, seqno = l->snd_nxt; |
b97bf3fd8 [TIPC] Initial merge |
1326 |
|
6e498158a tipc: move link s... |
1327 |
if (!tnl) |
b97bf3fd8 [TIPC] Initial merge |
1328 |
return; |
6e498158a tipc: move link s... |
1329 1330 |
skb_queue_head_init(&tnlq); skb_queue_head_init(&tmpxq); |
dd3f9e70f tipc: add packet ... |
1331 |
|
6e498158a tipc: move link s... |
1332 1333 |
/* At least one packet required for safe algorithm => add dummy */ skb = tipc_msg_create(TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG, |
e74a386d7 tipc: remove pre-... |
1334 |
BASIC_H_SIZE, 0, l->addr, tipc_own_addr(l->net), |
6e498158a tipc: move link s... |
1335 1336 1337 1338 |
0, 0, TIPC_ERR_NO_PORT); if (!skb) { pr_warn("%sunable to create tunnel packet ", link_co_err); |
b97bf3fd8 [TIPC] Initial merge |
1339 1340 |
return; } |
6e498158a tipc: move link s... |
1341 1342 1343 1344 1345 |
skb_queue_tail(&tnlq, skb); tipc_link_xmit(l, &tnlq, &tmpxq); __skb_queue_purge(&tmpxq); /* Initialize reusable tunnel packet header */ |
e74a386d7 tipc: remove pre-... |
1346 |
tipc_msg_init(tipc_own_addr(l->net), &tnlhdr, TUNNEL_PROTOCOL, |
6e498158a tipc: move link s... |
1347 1348 1349 1350 1351 1352 |
mtyp, INT_H_SIZE, l->addr); pktcnt = skb_queue_len(&l->transmq) + skb_queue_len(&l->backlogq); msg_set_msgcnt(&tnlhdr, pktcnt); msg_set_bearer_id(&tnlhdr, l->peer_bearer_id); tnl: /* Wrap each packet into a tunnel packet */ |
05dcc5aa4 tipc: split link ... |
1353 |
skb_queue_walk(queue, skb) { |
6e498158a tipc: move link s... |
1354 1355 1356 1357 1358 |
hdr = buf_msg(skb); if (queue == &l->backlogq) msg_set_seqno(hdr, seqno++); pktlen = msg_size(hdr); msg_set_size(&tnlhdr, pktlen + INT_H_SIZE); |
57d5f64d8 tipc: allocate us... |
1359 |
tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE, GFP_ATOMIC); |
6e498158a tipc: move link s... |
1360 1361 1362 |
if (!tnlskb) { pr_warn("%sunable to send packet ", link_co_err); |
b97bf3fd8 [TIPC] Initial merge |
1363 1364 |
return; } |
6e498158a tipc: move link s... |
1365 1366 1367 |
skb_copy_to_linear_data(tnlskb, &tnlhdr, INT_H_SIZE); skb_copy_to_linear_data_offset(tnlskb, INT_H_SIZE, hdr, pktlen); __skb_queue_tail(&tnlq, tnlskb); |
b97bf3fd8 [TIPC] Initial merge |
1368 |
} |
6e498158a tipc: move link s... |
1369 1370 1371 |
if (queue != &l->backlogq) { queue = &l->backlogq; goto tnl; |
f006c9c70 tipc: change rece... |
1372 |
} |
1dab3d5ac tipc: change rece... |
1373 |
|
6e498158a tipc: move link s... |
1374 |
tipc_link_xmit(tnl, &tnlq, xmitq); |
b97bf3fd8 [TIPC] Initial merge |
1375 |
|
6e498158a tipc: move link s... |
1376 1377 1378 1379 |
if (mtyp == FAILOVER_MSG) { tnl->drop_point = l->rcv_nxt; tnl->failover_reasm_skb = l->reasm_buf; l->reasm_buf = NULL; |
2da714251 tipc: drop tunnel... |
1380 |
} |
b97bf3fd8 [TIPC] Initial merge |
1381 |
} |
d999297c3 tipc: reduce lock... |
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 |
/* tipc_link_proto_rcv(): receive link level protocol message : * Note that network plane id propagates through the network, and may * change at any time. The node with lowest numerical id determines * network plane */ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, struct sk_buff_head *xmitq) { struct tipc_msg *hdr = buf_msg(skb); u16 rcvgap = 0; |
c1ab3f1de tipc: make struct... |
1392 1393 |
u16 ack = msg_ack(hdr); u16 gap = msg_seq_gap(hdr); |
d999297c3 tipc: reduce lock... |
1394 1395 1396 |
u16 peers_snd_nxt = msg_next_sent(hdr); u16 peers_tol = msg_link_tolerance(hdr); u16 peers_prio = msg_linkprio(hdr); |
2be80c2d8 tipc: fix stale l... |
1397 |
u16 rcv_nxt = l->rcv_nxt; |
35c55c987 tipc: add neighbo... |
1398 |
u16 dlen = msg_data_sz(hdr); |
73f646cec tipc: delay ESTAB... |
1399 |
int mtyp = msg_type(hdr); |
35c55c987 tipc: add neighbo... |
1400 |
void *data; |
d999297c3 tipc: reduce lock... |
1401 1402 |
char *if_name; int rc = 0; |
526669866 tipc: let broadca... |
1403 |
if (tipc_link_is_blocked(l) || !xmitq) |
d999297c3 tipc: reduce lock... |
1404 |
goto exit; |
e74a386d7 tipc: remove pre-... |
1405 |
if (tipc_own_addr(l->net) > msg_prevnode(hdr)) |
d999297c3 tipc: reduce lock... |
1406 |
l->net_plane = msg_net_plane(hdr); |
35c55c987 tipc: add neighbo... |
1407 1408 1409 |
skb_linearize(skb); hdr = buf_msg(skb); data = msg_data(hdr); |
73f646cec tipc: delay ESTAB... |
1410 |
switch (mtyp) { |
d999297c3 tipc: reduce lock... |
1411 1412 1413 1414 |
case RESET_MSG: /* Ignore duplicate RESET with old session number */ if ((less_eq(msg_session(hdr), l->peer_session)) && |
e74a386d7 tipc: remove pre-... |
1415 |
(l->peer_session != ANY_SESSION)) |
d999297c3 tipc: reduce lock... |
1416 1417 |
break; /* fall thru' */ |
662921cd0 tipc: merge link-... |
1418 |
|
d999297c3 tipc: reduce lock... |
1419 1420 1421 1422 1423 1424 1425 1426 |
case ACTIVATE_MSG: /* Complete own link name with peer's interface name */ if_name = strrchr(l->name, ':') + 1; if (sizeof(l->name) - (if_name - l->name) <= TIPC_MAX_IF_NAME) break; if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME) break; |
35c55c987 tipc: add neighbo... |
1427 |
strncpy(if_name, data, TIPC_MAX_IF_NAME); |
d999297c3 tipc: reduce lock... |
1428 1429 1430 1431 1432 1433 1434 1435 |
/* Update own tolerance if peer indicates a non-zero value */ if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) l->tolerance = peers_tol; /* Update own priority if peer's priority is higher */ if (in_range(peers_prio, l->priority + 1, TIPC_MAX_LINK_PRI)) l->priority = peers_prio; |
73f646cec tipc: delay ESTAB... |
1436 |
/* ACTIVATE_MSG serves as PEER_RESET if link is already down */ |
634696b19 tipc: guarantee p... |
1437 1438 1439 |
if (msg_peer_stopping(hdr)) rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT); else if ((mtyp == RESET_MSG) || !link_is_up(l)) |
73f646cec tipc: delay ESTAB... |
1440 1441 1442 1443 1444 |
rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT); /* ACTIVATE_MSG takes up link if it was already locally reset */ if ((mtyp == ACTIVATE_MSG) && (l->state == LINK_ESTABLISHING)) rc = TIPC_LINK_UP_EVT; |
d999297c3 tipc: reduce lock... |
1445 1446 |
l->peer_session = msg_session(hdr); l->peer_bearer_id = msg_bearer_id(hdr); |
d999297c3 tipc: reduce lock... |
1447 1448 1449 |
if (l->mtu > msg_max_pkt(hdr)) l->mtu = msg_max_pkt(hdr); break; |
662921cd0 tipc: merge link-... |
1450 |
|
d999297c3 tipc: reduce lock... |
1451 |
case STATE_MSG: |
662921cd0 tipc: merge link-... |
1452 |
|
d999297c3 tipc: reduce lock... |
1453 1454 1455 |
/* Update own tolerance if peer indicates a non-zero value */ if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) l->tolerance = peers_tol; |
f79675563 tipc: fix compati... |
1456 1457 1458 |
/* Update own prio if peer indicates a different value */ if ((peers_prio != l->priority) && in_range(peers_prio, 1, TIPC_MAX_LINK_PRI)) { |
817298102 tipc: fix link pr... |
1459 1460 1461 |
l->priority = peers_prio; rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT); } |
d999297c3 tipc: reduce lock... |
1462 1463 1464 1465 |
l->silent_intv_cnt = 0; l->stats.recv_states++; if (msg_probe(hdr)) l->stats.recv_probes++; |
73f646cec tipc: delay ESTAB... |
1466 1467 1468 1469 |
if (!link_is_up(l)) { if (l->state == LINK_ESTABLISHING) rc = TIPC_LINK_UP_EVT; |
d999297c3 tipc: reduce lock... |
1470 |
break; |
73f646cec tipc: delay ESTAB... |
1471 |
} |
35c55c987 tipc: add neighbo... |
1472 1473 |
tipc_mon_rcv(l->net, data, dlen, l->addr, &l->mon_state, l->bearer_id); |
d999297c3 tipc: reduce lock... |
1474 |
|
662921cd0 tipc: merge link-... |
1475 |
/* Send NACK if peer has sent pkts we haven't received yet */ |
2be80c2d8 tipc: fix stale l... |
1476 |
if (more(peers_snd_nxt, rcv_nxt) && !tipc_link_is_synching(l)) |
d999297c3 tipc: reduce lock... |
1477 1478 1479 |
rcvgap = peers_snd_nxt - l->rcv_nxt; if (rcvgap || (msg_probe(hdr))) tipc_link_build_proto_msg(l, STATE_MSG, 0, rcvgap, |
16040894b tipc: fix compati... |
1480 |
0, 0, xmitq); |
c1ab3f1de tipc: make struct... |
1481 |
tipc_link_release_pkts(l, ack); |
d999297c3 tipc: reduce lock... |
1482 1483 |
/* If NACK, retransmit will now start at right position */ |
c1ab3f1de tipc: make struct... |
1484 |
if (gap) { |
40501f90e tipc: don't reset... |
1485 |
rc = tipc_link_retrans(l, l, ack + 1, ack + gap, xmitq); |
d999297c3 tipc: reduce lock... |
1486 1487 |
l->stats.recv_nacks++; } |
662921cd0 tipc: merge link-... |
1488 |
|
d999297c3 tipc: reduce lock... |
1489 1490 1491 1492 1493 1494 1495 1496 |
tipc_link_advance_backlog(l, xmitq); if (unlikely(!skb_queue_empty(&l->wakeupq))) link_prepare_wakeup(l); } exit: kfree_skb(skb); return rc; } |
526669866 tipc: let broadca... |
1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 |
/* tipc_link_build_bc_proto_msg() - create broadcast protocol message */ static bool tipc_link_build_bc_proto_msg(struct tipc_link *l, bool bcast, u16 peers_snd_nxt, struct sk_buff_head *xmitq) { struct sk_buff *skb; struct tipc_msg *hdr; struct sk_buff *dfrd_skb = skb_peek(&l->deferdq); u16 ack = l->rcv_nxt - 1; u16 gap_to = peers_snd_nxt - 1; skb = tipc_msg_create(BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, |
e74a386d7 tipc: remove pre-... |
1510 |
0, l->addr, tipc_own_addr(l->net), 0, 0, 0); |
526669866 tipc: let broadca... |
1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 |
if (!skb) return false; hdr = buf_msg(skb); msg_set_last_bcast(hdr, l->bc_sndlink->snd_nxt - 1); msg_set_bcast_ack(hdr, ack); msg_set_bcgap_after(hdr, ack); if (dfrd_skb) gap_to = buf_seqno(dfrd_skb) - 1; msg_set_bcgap_to(hdr, gap_to); msg_set_non_seq(hdr, bcast); __skb_queue_tail(xmitq, skb); return true; } /* tipc_link_build_bc_init_msg() - synchronize broadcast link endpoints. * * Give a newly added peer node the sequence number where it should * start receiving and acking broadcast packets. */ |
742e03833 tipc: link_is_bc_... |
1530 1531 |
static void tipc_link_build_bc_init_msg(struct tipc_link *l, struct sk_buff_head *xmitq) |
526669866 tipc: let broadca... |
1532 1533 1534 1535 1536 1537 |
{ struct sk_buff_head list; __skb_queue_head_init(&list); if (!tipc_link_build_bc_proto_msg(l->bc_rcvlink, false, 0, &list)) return; |
06bd2b1ed tipc: fix broadca... |
1538 |
msg_set_bc_ack_invalid(buf_msg(skb_peek(&list)), true); |
526669866 tipc: let broadca... |
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 |
tipc_link_xmit(l, &list, xmitq); } /* tipc_link_bc_init_rcv - receive initial broadcast synch data from peer */ void tipc_link_bc_init_rcv(struct tipc_link *l, struct tipc_msg *hdr) { int mtyp = msg_type(hdr); u16 peers_snd_nxt = msg_bc_snd_nxt(hdr); if (link_is_up(l)) return; if (msg_user(hdr) == BCAST_PROTOCOL) { l->rcv_nxt = peers_snd_nxt; l->state = LINK_ESTABLISHED; return; } if (l->peer_caps & TIPC_BCAST_SYNCH) return; if (msg_peer_node_is_up(hdr)) return; /* Compatibility: accept older, less safe initial synch data */ if ((mtyp == RESET_MSG) || (mtyp == ACTIVATE_MSG)) l->rcv_nxt = peers_snd_nxt; } |
7c4a54b96 tipc: rate limit ... |
1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 |
/* link_bc_retr eval()- check if the indicated range can be retransmitted now * - Adjust permitted range if there is overlap with previous retransmission */ static bool link_bc_retr_eval(struct tipc_link *l, u16 *from, u16 *to) { unsigned long elapsed = jiffies_to_msecs(jiffies - l->prev_retr); if (less(*to, *from)) return false; /* New retransmission request */ if ((elapsed > TIPC_BC_RETR_LIMIT) || less(*to, l->prev_from) || more(*from, l->prev_to)) { l->prev_from = *from; l->prev_to = *to; l->prev_retr = jiffies; return true; } /* Inside range of previous retransmit */ if (!less(*from, l->prev_from) && !more(*to, l->prev_to)) return false; /* Fully or partially outside previous range => exclude overlap */ if (less(*from, l->prev_from)) { *to = l->prev_from - 1; l->prev_from = *from; } if (more(*to, l->prev_to)) { *from = l->prev_to + 1; l->prev_to = *to; } l->prev_retr = jiffies; return true; } |
526669866 tipc: let broadca... |
1603 1604 |
/* tipc_link_bc_sync_rcv - update rcv link according to peer's send state */ |
02d11ca20 tipc: transfer br... |
1605 1606 |
int tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr, struct sk_buff_head *xmitq) |
526669866 tipc: let broadca... |
1607 |
{ |
7c4a54b96 tipc: rate limit ... |
1608 |
struct tipc_link *snd_l = l->bc_sndlink; |
526669866 tipc: let broadca... |
1609 |
u16 peers_snd_nxt = msg_bc_snd_nxt(hdr); |
02d11ca20 tipc: transfer br... |
1610 1611 1612 |
u16 from = msg_bcast_ack(hdr) + 1; u16 to = from + msg_bc_gap(hdr) - 1; int rc = 0; |
526669866 tipc: let broadca... |
1613 1614 |
if (!link_is_up(l)) |
02d11ca20 tipc: transfer br... |
1615 |
return rc; |
526669866 tipc: let broadca... |
1616 1617 |
if (!msg_peer_node_is_up(hdr)) |
02d11ca20 tipc: transfer br... |
1618 |
return rc; |
526669866 tipc: let broadca... |
1619 |
|
2d18ac4ba tipc: extend broa... |
1620 1621 1622 1623 1624 |
/* Open when peer ackowledges our bcast init msg (pkt #1) */ if (msg_ack(hdr)) l->bc_peer_is_up = true; if (!l->bc_peer_is_up) |
02d11ca20 tipc: transfer br... |
1625 |
return rc; |
526669866 tipc: let broadca... |
1626 |
|
7c4a54b96 tipc: rate limit ... |
1627 |
l->stats.recv_nacks++; |
526669866 tipc: let broadca... |
1628 1629 |
/* Ignore if peers_snd_nxt goes beyond receive window */ if (more(peers_snd_nxt, l->rcv_nxt + l->window)) |
02d11ca20 tipc: transfer br... |
1630 |
return rc; |
7c4a54b96 tipc: rate limit ... |
1631 |
if (link_bc_retr_eval(snd_l, &from, &to)) |
40501f90e tipc: don't reset... |
1632 |
rc = tipc_link_retrans(snd_l, l, from, to, xmitq); |
02d11ca20 tipc: transfer br... |
1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 |
l->snd_nxt = peers_snd_nxt; if (link_bc_rcv_gap(l)) rc |= TIPC_LINK_SND_STATE; /* Return now if sender supports nack via STATE messages */ if (l->peer_caps & TIPC_BCAST_STATE_NACK) return rc; /* Otherwise, be backwards compatible */ |
526669866 tipc: let broadca... |
1643 1644 1645 |
if (!more(peers_snd_nxt, l->rcv_nxt)) { l->nack_state = BC_NACK_SND_CONDITIONAL; |
02d11ca20 tipc: transfer br... |
1646 |
return 0; |
526669866 tipc: let broadca... |
1647 1648 1649 1650 1651 |
} /* Don't NACK if one was recently sent or peeked */ if (l->nack_state == BC_NACK_SND_SUPPRESS) { l->nack_state = BC_NACK_SND_UNCONDITIONAL; |
02d11ca20 tipc: transfer br... |
1652 |
return 0; |
526669866 tipc: let broadca... |
1653 1654 1655 1656 1657 1658 |
} /* Conditionally delay NACK sending until next synch rcv */ if (l->nack_state == BC_NACK_SND_CONDITIONAL) { l->nack_state = BC_NACK_SND_UNCONDITIONAL; if ((peers_snd_nxt - l->rcv_nxt) < TIPC_MIN_LINK_WIN) |
02d11ca20 tipc: transfer br... |
1659 |
return 0; |
526669866 tipc: let broadca... |
1660 1661 1662 1663 1664 |
} /* Send NACK now but suppress next one */ tipc_link_build_bc_proto_msg(l, true, peers_snd_nxt, xmitq); l->nack_state = BC_NACK_SND_SUPPRESS; |
02d11ca20 tipc: transfer br... |
1665 |
return 0; |
526669866 tipc: let broadca... |
1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 |
} void tipc_link_bc_ack_rcv(struct tipc_link *l, u16 acked, struct sk_buff_head *xmitq) { struct sk_buff *skb, *tmp; struct tipc_link *snd_l = l->bc_sndlink; if (!link_is_up(l) || !l->bc_peer_is_up) return; if (!more(acked, l->acked)) return; /* Skip over packets peer has already acked */ skb_queue_walk(&snd_l->transmq, skb) { if (more(buf_seqno(skb), l->acked)) break; } /* Update/release the packets peer is acking now */ skb_queue_walk_from_safe(&snd_l->transmq, skb, tmp) { if (more(buf_seqno(skb), acked)) break; if (!--TIPC_SKB_CB(skb)->ackers) { __skb_unlink(skb, &snd_l->transmq); kfree_skb(skb); } } l->acked = acked; tipc_link_advance_backlog(snd_l, xmitq); if (unlikely(!skb_queue_empty(&snd_l->wakeupq))) link_prepare_wakeup(snd_l); } /* tipc_link_bc_nack_rcv(): receive broadcast nack message |
02d11ca20 tipc: transfer br... |
1702 1703 |
* This function is here for backwards compatibility, since * no BCAST_PROTOCOL/STATE messages occur from TIPC v2.5. |
526669866 tipc: let broadca... |
1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 |
*/ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb, struct sk_buff_head *xmitq) { struct tipc_msg *hdr = buf_msg(skb); u32 dnode = msg_destnode(hdr); int mtyp = msg_type(hdr); u16 acked = msg_bcast_ack(hdr); u16 from = acked + 1; u16 to = msg_bcgap_to(hdr); u16 peers_snd_nxt = to + 1; int rc = 0; kfree_skb(skb); if (!tipc_link_is_up(l) || !l->bc_peer_is_up) return 0; if (mtyp != STATE_MSG) return 0; |
e74a386d7 tipc: remove pre-... |
1724 |
if (dnode == tipc_own_addr(l->net)) { |
526669866 tipc: let broadca... |
1725 |
tipc_link_bc_ack_rcv(l, acked, xmitq); |
40501f90e tipc: don't reset... |
1726 |
rc = tipc_link_retrans(l->bc_sndlink, l, from, to, xmitq); |
526669866 tipc: let broadca... |
1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 |
l->stats.recv_nacks++; return rc; } /* Msg for other node => suppress own NACK at next sync if applicable */ if (more(peers_snd_nxt, l->rcv_nxt) && !less(l->rcv_nxt, from)) l->nack_state = BC_NACK_SND_SUPPRESS; return 0; } |
e3eea1eb4 tipc: clean up ha... |
1737 |
void tipc_link_set_queue_limits(struct tipc_link *l, u32 win) |
b97bf3fd8 [TIPC] Initial merge |
1738 |
{ |
ed193ece2 tipc: simplify li... |
1739 |
int max_bulk = TIPC_MAX_PUBLICATIONS / (l->mtu / ITEM_SIZE); |
e3eea1eb4 tipc: clean up ha... |
1740 1741 |
l->window = win; |
5a0950c27 tipc: ensure that... |
1742 1743 1744 1745 |
l->backlog[TIPC_LOW_IMPORTANCE].limit = max_t(u16, 50, win); l->backlog[TIPC_MEDIUM_IMPORTANCE].limit = max_t(u16, 100, win * 2); l->backlog[TIPC_HIGH_IMPORTANCE].limit = max_t(u16, 150, win * 3); l->backlog[TIPC_CRITICAL_IMPORTANCE].limit = max_t(u16, 200, win * 4); |
1f66d161a tipc: introduce s... |
1746 |
l->backlog[TIPC_SYSTEM_IMPORTANCE].limit = max_bulk; |
b97bf3fd8 [TIPC] Initial merge |
1747 |
} |
5c216e1d2 tipc: Allow run-t... |
1748 |
/** |
38206d593 tipc: narrow down... |
1749 |
* link_reset_stats - reset link statistics |
1a90632da tipc: eliminate r... |
1750 |
* @l: pointer to link |
b97bf3fd8 [TIPC] Initial merge |
1751 |
*/ |
38206d593 tipc: narrow down... |
1752 |
void tipc_link_reset_stats(struct tipc_link *l) |
b97bf3fd8 [TIPC] Initial merge |
1753 |
{ |
38206d593 tipc: narrow down... |
1754 |
memset(&l->stats, 0, sizeof(l->stats)); |
b97bf3fd8 [TIPC] Initial merge |
1755 |
} |
1a20cc254 tipc: introduce n... |
1756 |
static void link_print(struct tipc_link *l, const char *str) |
b97bf3fd8 [TIPC] Initial merge |
1757 |
{ |
1a20cc254 tipc: introduce n... |
1758 |
struct sk_buff *hskb = skb_peek(&l->transmq); |
c1ab3f1de tipc: make struct... |
1759 |
u16 head = hskb ? msg_seqno(buf_msg(hskb)) : l->snd_nxt - 1; |
1a20cc254 tipc: introduce n... |
1760 |
u16 tail = l->snd_nxt - 1; |
7a2f7d18e tipc: decouple th... |
1761 |
|
662921cd0 tipc: merge link-... |
1762 1763 |
pr_info("%s Link <%s> state %x ", str, l->name, l->state); |
1a20cc254 tipc: introduce n... |
1764 1765 1766 1767 |
pr_info("XMTQ: %u [%u-%u], BKLGQ: %u, SNDNX: %u, RCVNX: %u ", skb_queue_len(&l->transmq), head, tail, skb_queue_len(&l->backlogq), l->snd_nxt, l->rcv_nxt); |
b97bf3fd8 [TIPC] Initial merge |
1768 |
} |
0655f6a86 tipc: add bearer ... |
1769 1770 1771 1772 1773 1774 1775 1776 |
/* Parse and validate nested (link) properties valid for media, bearer and link */ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]) { int err; err = nla_parse_nested(props, TIPC_NLA_PROP_MAX, prop, |
fceb6435e netlink: pass ext... |
1777 |
tipc_nl_prop_policy, NULL); |
0655f6a86 tipc: add bearer ... |
1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 |
if (err) return err; if (props[TIPC_NLA_PROP_PRIO]) { u32 prio; prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); if (prio > TIPC_MAX_LINK_PRI) return -EINVAL; } if (props[TIPC_NLA_PROP_TOL]) { u32 tol; tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]); if ((tol < TIPC_MIN_LINK_TOL) || (tol > TIPC_MAX_LINK_TOL)) return -EINVAL; } if (props[TIPC_NLA_PROP_WIN]) { u32 win; win = nla_get_u32(props[TIPC_NLA_PROP_WIN]); if ((win < TIPC_MIN_LINK_WIN) || (win > TIPC_MAX_LINK_WIN)) return -EINVAL; } return 0; } |
7be57fc69 tipc: add link ge... |
1807 |
|
d8182804c tipc: fix sparse ... |
1808 |
static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s) |
7be57fc69 tipc: add link ge... |
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 |
{ int i; struct nlattr *stats; struct nla_map { u32 key; u32 val; }; struct nla_map map[] = { |
959011224 tipc: fix link st... |
1819 |
{TIPC_NLA_STATS_RX_INFO, 0}, |
7be57fc69 tipc: add link ge... |
1820 1821 1822 1823 |
{TIPC_NLA_STATS_RX_FRAGMENTS, s->recv_fragments}, {TIPC_NLA_STATS_RX_FRAGMENTED, s->recv_fragmented}, {TIPC_NLA_STATS_RX_BUNDLES, s->recv_bundles}, {TIPC_NLA_STATS_RX_BUNDLED, s->recv_bundled}, |
959011224 tipc: fix link st... |
1824 |
{TIPC_NLA_STATS_TX_INFO, 0}, |
7be57fc69 tipc: add link ge... |
1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 |
{TIPC_NLA_STATS_TX_FRAGMENTS, s->sent_fragments}, {TIPC_NLA_STATS_TX_FRAGMENTED, s->sent_fragmented}, {TIPC_NLA_STATS_TX_BUNDLES, s->sent_bundles}, {TIPC_NLA_STATS_TX_BUNDLED, s->sent_bundled}, {TIPC_NLA_STATS_MSG_PROF_TOT, (s->msg_length_counts) ? s->msg_length_counts : 1}, {TIPC_NLA_STATS_MSG_LEN_CNT, s->msg_length_counts}, {TIPC_NLA_STATS_MSG_LEN_TOT, s->msg_lengths_total}, {TIPC_NLA_STATS_MSG_LEN_P0, s->msg_length_profile[0]}, {TIPC_NLA_STATS_MSG_LEN_P1, s->msg_length_profile[1]}, {TIPC_NLA_STATS_MSG_LEN_P2, s->msg_length_profile[2]}, {TIPC_NLA_STATS_MSG_LEN_P3, s->msg_length_profile[3]}, {TIPC_NLA_STATS_MSG_LEN_P4, s->msg_length_profile[4]}, {TIPC_NLA_STATS_MSG_LEN_P5, s->msg_length_profile[5]}, {TIPC_NLA_STATS_MSG_LEN_P6, s->msg_length_profile[6]}, {TIPC_NLA_STATS_RX_STATES, s->recv_states}, {TIPC_NLA_STATS_RX_PROBES, s->recv_probes}, {TIPC_NLA_STATS_RX_NACKS, s->recv_nacks}, {TIPC_NLA_STATS_RX_DEFERRED, s->deferred_recv}, {TIPC_NLA_STATS_TX_STATES, s->sent_states}, {TIPC_NLA_STATS_TX_PROBES, s->sent_probes}, {TIPC_NLA_STATS_TX_NACKS, s->sent_nacks}, {TIPC_NLA_STATS_TX_ACKS, s->sent_acks}, {TIPC_NLA_STATS_RETRANSMITTED, s->retransmitted}, {TIPC_NLA_STATS_DUPLICATES, s->duplicates}, {TIPC_NLA_STATS_LINK_CONGS, s->link_congs}, {TIPC_NLA_STATS_MAX_QUEUE, s->max_queue_sz}, {TIPC_NLA_STATS_AVG_QUEUE, s->queue_sz_counts ? (s->accu_queue_sz / s->queue_sz_counts) : 0} }; stats = nla_nest_start(skb, TIPC_NLA_LINK_STATS); if (!stats) return -EMSGSIZE; for (i = 0; i < ARRAY_SIZE(map); i++) if (nla_put_u32(skb, map[i].key, map[i].val)) goto msg_full; nla_nest_end(skb, stats); return 0; msg_full: nla_nest_cancel(skb, stats); return -EMSGSIZE; } /* Caller should hold appropriate locks to protect the link */ |
5be9c0867 tipc: narrow down... |
1874 1875 |
int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg, struct tipc_link *link, int nlflags) |
7be57fc69 tipc: add link ge... |
1876 1877 1878 1879 1880 |
{ int err; void *hdr; struct nlattr *attrs; struct nlattr *prop; |
347475395 tipc: make tipc n... |
1881 |
struct tipc_net *tn = net_generic(net, tipc_net_id); |
7be57fc69 tipc: add link ge... |
1882 |
|
bfb3e5dd8 tipc: move and re... |
1883 |
hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
f2f67390a tipc: remove wron... |
1884 |
nlflags, TIPC_NL_LINK_GET); |
7be57fc69 tipc: add link ge... |
1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 |
if (!hdr) return -EMSGSIZE; attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK); if (!attrs) goto msg_full; if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, link->name)) goto attr_msg_full; if (nla_put_u32(msg->skb, TIPC_NLA_LINK_DEST, |
347475395 tipc: make tipc n... |
1895 |
tipc_cluster_mask(tn->own_addr))) |
7be57fc69 tipc: add link ge... |
1896 |
goto attr_msg_full; |
ed193ece2 tipc: simplify li... |
1897 |
if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->mtu)) |
7be57fc69 tipc: add link ge... |
1898 |
goto attr_msg_full; |
959011224 tipc: fix link st... |
1899 |
if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->stats.recv_pkts)) |
7be57fc69 tipc: add link ge... |
1900 |
goto attr_msg_full; |
959011224 tipc: fix link st... |
1901 |
if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->stats.sent_pkts)) |
7be57fc69 tipc: add link ge... |
1902 1903 1904 1905 1906 |
goto attr_msg_full; if (tipc_link_is_up(link)) if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP)) goto attr_msg_full; |
c72fa872a tipc: eliminate l... |
1907 |
if (link->active) |
7be57fc69 tipc: add link ge... |
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 |
if (nla_put_flag(msg->skb, TIPC_NLA_LINK_ACTIVE)) goto attr_msg_full; prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP); if (!prop) goto attr_msg_full; if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority)) goto prop_msg_full; if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, link->tolerance)) goto prop_msg_full; if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, |
1f66d161a tipc: introduce s... |
1919 |
link->window)) |
7be57fc69 tipc: add link ge... |
1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 |
goto prop_msg_full; if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority)) goto prop_msg_full; nla_nest_end(msg->skb, prop); err = __tipc_nl_add_stats(msg->skb, &link->stats); if (err) goto attr_msg_full; nla_nest_end(msg->skb, attrs); genlmsg_end(msg->skb, hdr); return 0; prop_msg_full: nla_nest_cancel(msg->skb, prop); attr_msg_full: nla_nest_cancel(msg->skb, attrs); msg_full: genlmsg_cancel(msg->skb, hdr); return -EMSGSIZE; } |
38206d593 tipc: narrow down... |
1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 |
static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb, struct tipc_stats *stats) { int i; struct nlattr *nest; struct nla_map { __u32 key; __u32 val; }; struct nla_map map[] = { |
959011224 tipc: fix link st... |
1956 |
{TIPC_NLA_STATS_RX_INFO, stats->recv_pkts}, |
38206d593 tipc: narrow down... |
1957 1958 1959 1960 |
{TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments}, {TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented}, {TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles}, {TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled}, |
959011224 tipc: fix link st... |
1961 |
{TIPC_NLA_STATS_TX_INFO, stats->sent_pkts}, |
38206d593 tipc: narrow down... |
1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 |
{TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments}, {TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented}, {TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles}, {TIPC_NLA_STATS_TX_BUNDLED, stats->sent_bundled}, {TIPC_NLA_STATS_RX_NACKS, stats->recv_nacks}, {TIPC_NLA_STATS_RX_DEFERRED, stats->deferred_recv}, {TIPC_NLA_STATS_TX_NACKS, stats->sent_nacks}, {TIPC_NLA_STATS_TX_ACKS, stats->sent_acks}, {TIPC_NLA_STATS_RETRANSMITTED, stats->retransmitted}, {TIPC_NLA_STATS_DUPLICATES, stats->duplicates}, {TIPC_NLA_STATS_LINK_CONGS, stats->link_congs}, {TIPC_NLA_STATS_MAX_QUEUE, stats->max_queue_sz}, {TIPC_NLA_STATS_AVG_QUEUE, stats->queue_sz_counts ? (stats->accu_queue_sz / stats->queue_sz_counts) : 0} }; nest = nla_nest_start(skb, TIPC_NLA_LINK_STATS); if (!nest) return -EMSGSIZE; for (i = 0; i < ARRAY_SIZE(map); i++) if (nla_put_u32(skb, map[i].key, map[i].val)) goto msg_full; nla_nest_end(skb, nest); return 0; msg_full: nla_nest_cancel(skb, nest); return -EMSGSIZE; } int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg) { int err; void *hdr; struct nlattr *attrs; struct nlattr *prop; struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_link *bcl = tn->bcl; if (!bcl) return 0; tipc_bcast_lock(net); hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_LINK_GET); |
b53ce3e7d tipc: unlock in e... |
2011 2012 |
if (!hdr) { tipc_bcast_unlock(net); |
38206d593 tipc: narrow down... |
2013 |
return -EMSGSIZE; |
b53ce3e7d tipc: unlock in e... |
2014 |
} |
38206d593 tipc: narrow down... |
2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 |
attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK); if (!attrs) goto msg_full; /* The broadcast link is always up */ if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP)) goto attr_msg_full; if (nla_put_flag(msg->skb, TIPC_NLA_LINK_BROADCAST)) goto attr_msg_full; if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name)) goto attr_msg_full; |
959011224 tipc: fix link st... |
2028 |
if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, 0)) |
38206d593 tipc: narrow down... |
2029 |
goto attr_msg_full; |
959011224 tipc: fix link st... |
2030 |
if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, 0)) |
38206d593 tipc: narrow down... |
2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 |
goto attr_msg_full; prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP); if (!prop) goto attr_msg_full; if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->window)) goto prop_msg_full; nla_nest_end(msg->skb, prop); err = __tipc_nl_add_bc_link_stat(msg->skb, &bcl->stats); if (err) goto attr_msg_full; tipc_bcast_unlock(net); nla_nest_end(msg->skb, attrs); genlmsg_end(msg->skb, hdr); return 0; prop_msg_full: nla_nest_cancel(msg->skb, prop); attr_msg_full: nla_nest_cancel(msg->skb, attrs); msg_full: tipc_bcast_unlock(net); genlmsg_cancel(msg->skb, hdr); return -EMSGSIZE; } |
d01332f1a tipc: fix link at... |
2060 2061 |
void tipc_link_set_tolerance(struct tipc_link *l, u32 tol, struct sk_buff_head *xmitq) |
38206d593 tipc: narrow down... |
2062 2063 |
{ l->tolerance = tol; |
d01332f1a tipc: fix link at... |
2064 |
tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, tol, 0, xmitq); |
38206d593 tipc: narrow down... |
2065 |
} |
d01332f1a tipc: fix link at... |
2066 2067 |
void tipc_link_set_prio(struct tipc_link *l, u32 prio, struct sk_buff_head *xmitq) |
38206d593 tipc: narrow down... |
2068 2069 |
{ l->priority = prio; |
d01332f1a tipc: fix link at... |
2070 |
tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, prio, xmitq); |
38206d593 tipc: narrow down... |
2071 2072 2073 2074 2075 2076 |
} void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit) { l->abort_limit = limit; } |