aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/link.c16
-rw-r--r--net/tipc/link.h1
-rw-r--r--net/tipc/node.c7
-rw-r--r--net/tipc/node.h14
4 files changed, 32 insertions, 6 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index ec4d28328652..065e9e67da5d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -130,6 +130,8 @@ struct tipc_link {
130 /* Management and link supervision data */ 130 /* Management and link supervision data */
131 u32 peer_session; 131 u32 peer_session;
132 u32 session; 132 u32 session;
133 u16 snd_nxt_state;
134 u16 rcv_nxt_state;
133 u32 peer_bearer_id; 135 u32 peer_bearer_id;
134 u32 bearer_id; 136 u32 bearer_id;
135 u32 tolerance; 137 u32 tolerance;
@@ -339,6 +341,11 @@ char tipc_link_plane(struct tipc_link *l)
339 return l->net_plane; 341 return l->net_plane;
340} 342}
341 343
344void tipc_link_update_caps(struct tipc_link *l, u16 capabilities)
345{
346 l->peer_caps = capabilities;
347}
348
342void tipc_link_add_bc_peer(struct tipc_link *snd_l, 349void tipc_link_add_bc_peer(struct tipc_link *snd_l,
343 struct tipc_link *uc_l, 350 struct tipc_link *uc_l,
344 struct sk_buff_head *xmitq) 351 struct sk_buff_head *xmitq)
@@ -859,6 +866,8 @@ void tipc_link_reset(struct tipc_link *l)
859 l->rcv_unacked = 0; 866 l->rcv_unacked = 0;
860 l->snd_nxt = 1; 867 l->snd_nxt = 1;
861 l->rcv_nxt = 1; 868 l->rcv_nxt = 1;
869 l->snd_nxt_state = 1;
870 l->rcv_nxt_state = 1;
862 l->acked = 0; 871 l->acked = 0;
863 l->silent_intv_cnt = 0; 872 l->silent_intv_cnt = 0;
864 l->rst_cnt = 0; 873 l->rst_cnt = 0;
@@ -1353,6 +1362,8 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1353 msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2); 1362 msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2);
1354 1363
1355 if (mtyp == STATE_MSG) { 1364 if (mtyp == STATE_MSG) {
1365 if (l->peer_caps & TIPC_LINK_PROTO_SEQNO)
1366 msg_set_seqno(hdr, l->snd_nxt_state++);
1356 msg_set_seq_gap(hdr, rcvgap); 1367 msg_set_seq_gap(hdr, rcvgap);
1357 msg_set_bc_gap(hdr, link_bc_rcv_gap(bcl)); 1368 msg_set_bc_gap(hdr, link_bc_rcv_gap(bcl));
1358 msg_set_probe(hdr, probe); 1369 msg_set_probe(hdr, probe);
@@ -1522,6 +1533,11 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1522 1533
1523 case STATE_MSG: 1534 case STATE_MSG:
1524 1535
1536 if (l->peer_caps & TIPC_LINK_PROTO_SEQNO &&
1537 less(msg_seqno(hdr), l->rcv_nxt_state))
1538 break;
1539 l->rcv_nxt_state = msg_seqno(hdr) + 1;
1540
1525 /* Update own tolerance if peer indicates a non-zero value */ 1541 /* Update own tolerance if peer indicates a non-zero value */
1526 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) 1542 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL))
1527 l->tolerance = peers_tol; 1543 l->tolerance = peers_tol;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index ec59348a81e8..d56f9c9e5000 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -110,6 +110,7 @@ char *tipc_link_name(struct tipc_link *l);
110char tipc_link_plane(struct tipc_link *l); 110char tipc_link_plane(struct tipc_link *l);
111int tipc_link_prio(struct tipc_link *l); 111int tipc_link_prio(struct tipc_link *l);
112int tipc_link_window(struct tipc_link *l); 112int tipc_link_window(struct tipc_link *l);
113void tipc_link_update_caps(struct tipc_link *l, u16 capabilities);
113unsigned long tipc_link_tolerance(struct tipc_link *l); 114unsigned long tipc_link_tolerance(struct tipc_link *l);
114void tipc_link_set_tolerance(struct tipc_link *l, u32 tol, 115void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
115 struct sk_buff_head *xmitq); 116 struct sk_buff_head *xmitq);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index cfdbaf479fd1..1cdb176798f7 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -363,6 +363,8 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
363{ 363{
364 struct tipc_net *tn = net_generic(net, tipc_net_id); 364 struct tipc_net *tn = net_generic(net, tipc_net_id);
365 struct tipc_node *n, *temp_node; 365 struct tipc_node *n, *temp_node;
366 struct tipc_link *l;
367 int bearer_id;
366 int i; 368 int i;
367 369
368 spin_lock_bh(&tn->node_list_lock); 370 spin_lock_bh(&tn->node_list_lock);
@@ -370,6 +372,11 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
370 if (n) { 372 if (n) {
371 /* Same node may come back with new capabilities */ 373 /* Same node may come back with new capabilities */
372 n->capabilities = capabilities; 374 n->capabilities = capabilities;
375 for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
376 l = n->links[bearer_id].link;
377 if (l)
378 tipc_link_update_caps(l, capabilities);
379 }
373 goto exit; 380 goto exit;
374 } 381 }
375 n = kzalloc(sizeof(*n), GFP_ATOMIC); 382 n = kzalloc(sizeof(*n), GFP_ATOMIC);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 846c8f240872..48b3298a248d 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -49,14 +49,16 @@ enum {
49 TIPC_BCAST_STATE_NACK = (1 << 2), 49 TIPC_BCAST_STATE_NACK = (1 << 2),
50 TIPC_BLOCK_FLOWCTL = (1 << 3), 50 TIPC_BLOCK_FLOWCTL = (1 << 3),
51 TIPC_BCAST_RCAST = (1 << 4), 51 TIPC_BCAST_RCAST = (1 << 4),
52 TIPC_NODE_ID128 = (1 << 5) 52 TIPC_NODE_ID128 = (1 << 5),
53 TIPC_LINK_PROTO_SEQNO = (1 << 6)
53}; 54};
54 55
55#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \ 56#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
56 TIPC_BCAST_STATE_NACK | \ 57 TIPC_BCAST_STATE_NACK | \
57 TIPC_BCAST_RCAST | \ 58 TIPC_BCAST_RCAST | \
58 TIPC_BLOCK_FLOWCTL | \ 59 TIPC_BLOCK_FLOWCTL | \
59 TIPC_NODE_ID128) 60 TIPC_NODE_ID128 | \
61 TIPC_LINK_PROTO_SEQNO)
60#define INVALID_BEARER_ID -1 62#define INVALID_BEARER_ID -1
61 63
62void tipc_node_stop(struct net *net); 64void tipc_node_stop(struct net *net);