@@ -120,11 +120,21 @@ bool tipc_link_is_up(struct tipc_link *l)
120
120
return link_is_up (l );
121
121
}
122
122
123
+ bool tipc_link_peer_is_down (struct tipc_link * l )
124
+ {
125
+ return l -> state == LINK_PEER_RESET ;
126
+ }
127
+
123
128
bool tipc_link_is_reset (struct tipc_link * l )
124
129
{
125
130
return l -> state & (LINK_RESET | LINK_FAILINGOVER | LINK_ESTABLISHING );
126
131
}
127
132
133
+ bool tipc_link_is_establishing (struct tipc_link * l )
134
+ {
135
+ return l -> state == LINK_ESTABLISHING ;
136
+ }
137
+
128
138
bool tipc_link_is_synching (struct tipc_link * l )
129
139
{
130
140
return l -> state == LINK_SYNCHING ;
@@ -321,14 +331,15 @@ int tipc_link_fsm_evt(struct tipc_link *l, int evt)
321
331
switch (evt ) {
322
332
case LINK_ESTABLISH_EVT :
323
333
l -> state = LINK_ESTABLISHED ;
324
- rc |= TIPC_LINK_UP_EVT ;
325
334
break ;
326
335
case LINK_FAILOVER_BEGIN_EVT :
327
336
l -> state = LINK_FAILINGOVER ;
328
337
break ;
329
- case LINK_PEER_RESET_EVT :
330
338
case LINK_RESET_EVT :
339
+ l -> state = LINK_RESET ;
340
+ break ;
331
341
case LINK_FAILURE_EVT :
342
+ case LINK_PEER_RESET_EVT :
332
343
case LINK_SYNCH_BEGIN_EVT :
333
344
case LINK_FAILOVER_END_EVT :
334
345
break ;
@@ -578,8 +589,6 @@ void tipc_link_purge_queues(struct tipc_link *l_ptr)
578
589
579
590
void tipc_link_reset (struct tipc_link * l )
580
591
{
581
- tipc_link_fsm_evt (l , LINK_RESET_EVT );
582
-
583
592
/* Link is down, accept any session */
584
593
l -> peer_session = WILDCARD_SESSION ;
585
594
@@ -953,7 +962,7 @@ static bool tipc_data_input(struct tipc_link *link, struct sk_buff *skb,
953
962
case TIPC_HIGH_IMPORTANCE :
954
963
case TIPC_CRITICAL_IMPORTANCE :
955
964
case CONN_MANAGER :
956
- __skb_queue_tail (inputq , skb );
965
+ skb_queue_tail (inputq , skb );
957
966
return true;
958
967
case NAME_DISTRIBUTOR :
959
968
node -> bclink .recv_permitted = true;
@@ -982,6 +991,7 @@ static int tipc_link_input(struct tipc_link *l, struct sk_buff *skb,
982
991
struct tipc_msg * hdr = buf_msg (skb );
983
992
struct sk_buff * * reasm_skb = & l -> reasm_buf ;
984
993
struct sk_buff * iskb ;
994
+ struct sk_buff_head tmpq ;
985
995
int usr = msg_user (hdr );
986
996
int rc = 0 ;
987
997
int pos = 0 ;
@@ -1006,10 +1016,12 @@ static int tipc_link_input(struct tipc_link *l, struct sk_buff *skb,
1006
1016
}
1007
1017
1008
1018
if (usr == MSG_BUNDLER ) {
1019
+ skb_queue_head_init (& tmpq );
1009
1020
l -> stats .recv_bundles ++ ;
1010
1021
l -> stats .recv_bundled += msg_msgcnt (hdr );
1011
1022
while (tipc_msg_extract (skb , & iskb , & pos ))
1012
- tipc_data_input (l , iskb , inputq );
1023
+ tipc_data_input (l , iskb , & tmpq );
1024
+ tipc_skb_queue_splice_tail (& tmpq , inputq );
1013
1025
return 0 ;
1014
1026
} else if (usr == MSG_FRAGMENTER ) {
1015
1027
l -> stats .recv_fragments ++ ;
@@ -1044,89 +1056,105 @@ static bool tipc_link_release_pkts(struct tipc_link *l, u16 acked)
1044
1056
return released ;
1045
1057
}
1046
1058
1059
+ /* tipc_link_build_ack_msg: prepare link acknowledge message for transmission
1060
+ */
1061
+ void tipc_link_build_ack_msg (struct tipc_link * l , struct sk_buff_head * xmitq )
1062
+ {
1063
+ l -> rcv_unacked = 0 ;
1064
+ l -> stats .sent_acks ++ ;
1065
+ tipc_link_build_proto_msg (l , STATE_MSG , 0 , 0 , 0 , 0 , xmitq );
1066
+ }
1067
+
1068
+ /* tipc_link_build_reset_msg: prepare link RESET or ACTIVATE message
1069
+ */
1070
+ void tipc_link_build_reset_msg (struct tipc_link * l , struct sk_buff_head * xmitq )
1071
+ {
1072
+ int mtyp = RESET_MSG ;
1073
+
1074
+ if (l -> state == LINK_ESTABLISHING )
1075
+ mtyp = ACTIVATE_MSG ;
1076
+
1077
+ tipc_link_build_proto_msg (l , mtyp , 0 , 0 , 0 , 0 , xmitq );
1078
+ }
1079
+
1080
+ /* tipc_link_build_nack_msg: prepare link nack message for transmission
1081
+ */
1082
+ static void tipc_link_build_nack_msg (struct tipc_link * l ,
1083
+ struct sk_buff_head * xmitq )
1084
+ {
1085
+ u32 def_cnt = ++ l -> stats .deferred_recv ;
1086
+
1087
+ if ((skb_queue_len (& l -> deferdq ) == 1 ) || !(def_cnt % TIPC_NACK_INTV ))
1088
+ tipc_link_build_proto_msg (l , STATE_MSG , 0 , 0 , 0 , 0 , xmitq );
1089
+ }
1090
+
1047
1091
/* tipc_link_rcv - process TIPC packets/messages arriving from off-node
1048
- * @link : the link that should handle the message
1092
+ * @l : the link that should handle the message
1049
1093
* @skb: TIPC packet
1050
1094
* @xmitq: queue to place packets to be sent after this call
1051
1095
*/
1052
1096
int tipc_link_rcv (struct tipc_link * l , struct sk_buff * skb ,
1053
1097
struct sk_buff_head * xmitq )
1054
1098
{
1055
- struct sk_buff_head * arrvq = & l -> deferdq ;
1056
- struct sk_buff_head tmpq ;
1099
+ struct sk_buff_head * defq = & l -> deferdq ;
1057
1100
struct tipc_msg * hdr ;
1058
- u16 seqno , rcv_nxt ;
1101
+ u16 seqno , rcv_nxt , win_lim ;
1059
1102
int rc = 0 ;
1060
1103
1061
- __skb_queue_head_init (& tmpq );
1062
-
1063
- if (unlikely (!__tipc_skb_queue_sorted (arrvq , skb ))) {
1064
- if (!(skb_queue_len (arrvq ) % TIPC_NACK_INTV ))
1065
- tipc_link_build_proto_msg (l , STATE_MSG , 0 ,
1066
- 0 , 0 , 0 , xmitq );
1067
- return rc ;
1068
- }
1069
-
1070
- while ((skb = skb_peek (arrvq ))) {
1104
+ do {
1071
1105
hdr = buf_msg (skb );
1106
+ seqno = msg_seqno (hdr );
1107
+ rcv_nxt = l -> rcv_nxt ;
1108
+ win_lim = rcv_nxt + TIPC_MAX_LINK_WIN ;
1072
1109
1073
1110
/* Verify and update link state */
1074
- if (unlikely (msg_user (hdr ) == LINK_PROTOCOL )) {
1075
- __skb_dequeue (arrvq );
1076
- rc = tipc_link_proto_rcv (l , skb , xmitq );
1077
- continue ;
1078
- }
1111
+ if (unlikely (msg_user (hdr ) == LINK_PROTOCOL ))
1112
+ return tipc_link_proto_rcv (l , skb , xmitq );
1079
1113
1080
1114
if (unlikely (!link_is_up (l ))) {
1081
- rc = tipc_link_fsm_evt (l , LINK_ESTABLISH_EVT );
1082
- if (!link_is_up (l )) {
1083
- kfree_skb (__skb_dequeue (arrvq ));
1084
- goto exit ;
1085
- }
1115
+ if (l -> state == LINK_ESTABLISHING )
1116
+ rc = TIPC_LINK_UP_EVT ;
1117
+ goto drop ;
1086
1118
}
1087
1119
1120
+ /* Don't send probe at next timeout expiration */
1088
1121
l -> silent_intv_cnt = 0 ;
1089
1122
1123
+ /* Drop if outside receive window */
1124
+ if (unlikely (less (seqno , rcv_nxt ) || more (seqno , win_lim ))) {
1125
+ l -> stats .duplicates ++ ;
1126
+ goto drop ;
1127
+ }
1128
+
1090
1129
/* Forward queues and wake up waiting users */
1091
1130
if (likely (tipc_link_release_pkts (l , msg_ack (hdr )))) {
1092
1131
tipc_link_advance_backlog (l , xmitq );
1093
1132
if (unlikely (!skb_queue_empty (& l -> wakeupq )))
1094
1133
link_prepare_wakeup (l );
1095
1134
}
1096
1135
1097
- /* Defer reception if there is a gap in the sequence */
1098
- seqno = msg_seqno (hdr );
1099
- rcv_nxt = l -> rcv_nxt ;
1100
- if (unlikely (less (rcv_nxt , seqno ))) {
1101
- l -> stats .deferred_recv ++ ;
1102
- goto exit ;
1103
- }
1104
-
1105
- __skb_dequeue (arrvq );
1106
-
1107
- /* Drop if packet already received */
1108
- if (unlikely (more (rcv_nxt , seqno ))) {
1109
- l -> stats .duplicates ++ ;
1110
- kfree_skb (skb );
1111
- goto exit ;
1136
+ /* Defer delivery if sequence gap */
1137
+ if (unlikely (seqno != rcv_nxt )) {
1138
+ __tipc_skb_queue_sorted (defq , seqno , skb );
1139
+ tipc_link_build_nack_msg (l , xmitq );
1140
+ break ;
1112
1141
}
1113
1142
1114
- /* Packet can be delivered */
1143
+ /* Deliver packet */
1115
1144
l -> rcv_nxt ++ ;
1116
1145
l -> stats .recv_info ++ ;
1117
- if (unlikely (!tipc_data_input (l , skb , & tmpq )))
1118
- rc = tipc_link_input (l , skb , & tmpq );
1146
+ if (!tipc_data_input (l , skb , l -> inputq ))
1147
+ rc = tipc_link_input (l , skb , l -> inputq );
1148
+ if (unlikely (rc ))
1149
+ break ;
1150
+ if (unlikely (++ l -> rcv_unacked >= TIPC_MIN_LINK_WIN ))
1151
+ tipc_link_build_ack_msg (l , xmitq );
1152
+
1153
+ } while ((skb = __skb_dequeue (defq )));
1119
1154
1120
- /* Ack at regular intervals */
1121
- if (unlikely (++ l -> rcv_unacked >= TIPC_MIN_LINK_WIN )) {
1122
- l -> rcv_unacked = 0 ;
1123
- l -> stats .sent_acks ++ ;
1124
- tipc_link_build_proto_msg (l , STATE_MSG ,
1125
- 0 , 0 , 0 , 0 , xmitq );
1126
- }
1127
- }
1128
- exit :
1129
- tipc_skb_queue_splice_tail (& tmpq , l -> inputq );
1155
+ return rc ;
1156
+ drop :
1157
+ kfree_skb (skb );
1130
1158
return rc ;
1131
1159
}
1132
1160
@@ -1250,7 +1278,7 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1250
1278
}
1251
1279
1252
1280
/* tipc_link_tnl_prepare(): prepare and return a list of tunnel packets
1253
- * with contents of the link's tranmsit and backlog queues.
1281
+ * with contents of the link's transmit and backlog queues.
1254
1282
*/
1255
1283
void tipc_link_tnl_prepare (struct tipc_link * l , struct tipc_link * tnl ,
1256
1284
int mtyp , struct sk_buff_head * xmitq )
@@ -1331,6 +1359,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1331
1359
u16 peers_tol = msg_link_tolerance (hdr );
1332
1360
u16 peers_prio = msg_linkprio (hdr );
1333
1361
u16 rcv_nxt = l -> rcv_nxt ;
1362
+ int mtyp = msg_type (hdr );
1334
1363
char * if_name ;
1335
1364
int rc = 0 ;
1336
1365
@@ -1340,7 +1369,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1340
1369
if (link_own_addr (l ) > msg_prevnode (hdr ))
1341
1370
l -> net_plane = msg_net_plane (hdr );
1342
1371
1343
- switch (msg_type ( hdr ) ) {
1372
+ switch (mtyp ) {
1344
1373
case RESET_MSG :
1345
1374
1346
1375
/* Ignore duplicate RESET with old session number */
@@ -1367,12 +1396,14 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1367
1396
if (in_range (peers_prio , l -> priority + 1 , TIPC_MAX_LINK_PRI ))
1368
1397
l -> priority = peers_prio ;
1369
1398
1370
- if (msg_type (hdr ) == RESET_MSG ) {
1371
- rc |= tipc_link_fsm_evt (l , LINK_PEER_RESET_EVT );
1372
- } else if (!link_is_up (l )) {
1373
- tipc_link_fsm_evt (l , LINK_PEER_RESET_EVT );
1374
- rc |= tipc_link_fsm_evt (l , LINK_ESTABLISH_EVT );
1375
- }
1399
+ /* ACTIVATE_MSG serves as PEER_RESET if link is already down */
1400
+ if ((mtyp == RESET_MSG ) || !link_is_up (l ))
1401
+ rc = tipc_link_fsm_evt (l , LINK_PEER_RESET_EVT );
1402
+
1403
+ /* ACTIVATE_MSG takes up link if it was already locally reset */
1404
+ if ((mtyp == ACTIVATE_MSG ) && (l -> state == LINK_ESTABLISHING ))
1405
+ rc = TIPC_LINK_UP_EVT ;
1406
+
1376
1407
l -> peer_session = msg_session (hdr );
1377
1408
l -> peer_bearer_id = msg_bearer_id (hdr );
1378
1409
if (l -> mtu > msg_max_pkt (hdr ))
@@ -1389,9 +1420,12 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1389
1420
l -> stats .recv_states ++ ;
1390
1421
if (msg_probe (hdr ))
1391
1422
l -> stats .recv_probes ++ ;
1392
- rc = tipc_link_fsm_evt (l , LINK_ESTABLISH_EVT );
1393
- if (!link_is_up (l ))
1423
+
1424
+ if (!link_is_up (l )) {
1425
+ if (l -> state == LINK_ESTABLISHING )
1426
+ rc = TIPC_LINK_UP_EVT ;
1394
1427
break ;
1428
+ }
1395
1429
1396
1430
/* Send NACK if peer has sent pkts we haven't received yet */
1397
1431
if (more (peers_snd_nxt , rcv_nxt ) && !tipc_link_is_synching (l ))
0 commit comments