Skip to content

Commit 9012de5

Browse files
Jon Maloydavem330
authored andcommitted
tipc: add sequence number check for link STATE messages
Some switch infrastructures produce huge amounts of packet duplicates. This becomes a problem if those messages are STATE/NACK protocol messages, causing unnecessary retransmissions of already accepted packets. We now introduce a unique sequence number per STATE protocol message so that duplicates can be identified and ignored. This will also be useful when tracing such cases, and to avert replay attacks when TIPC is encrypted. For compatibility reasons we have to introduce a new capability flag TIPC_LINK_PROTO_SEQNO to handle this new feature. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent e32f55f commit 9012de5

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

net/tipc/link.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ struct tipc_link {
130130
/* Management and link supervision data */
131131
u32 peer_session;
132132
u32 session;
133+
u16 snd_nxt_state;
134+
u16 rcv_nxt_state;
133135
u32 peer_bearer_id;
134136
u32 bearer_id;
135137
u32 tolerance;
@@ -339,6 +341,11 @@ char tipc_link_plane(struct tipc_link *l)
339341
return l->net_plane;
340342
}
341343

344+
void tipc_link_update_caps(struct tipc_link *l, u16 capabilities)
345+
{
346+
l->peer_caps = capabilities;
347+
}
348+
342349
void tipc_link_add_bc_peer(struct tipc_link *snd_l,
343350
struct tipc_link *uc_l,
344351
struct sk_buff_head *xmitq)
@@ -859,6 +866,8 @@ void tipc_link_reset(struct tipc_link *l)
859866
l->rcv_unacked = 0;
860867
l->snd_nxt = 1;
861868
l->rcv_nxt = 1;
869+
l->snd_nxt_state = 1;
870+
l->rcv_nxt_state = 1;
862871
l->acked = 0;
863872
l->silent_intv_cnt = 0;
864873
l->rst_cnt = 0;
@@ -1353,6 +1362,8 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
13531362
msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2);
13541363

13551364
if (mtyp == STATE_MSG) {
1365+
if (l->peer_caps & TIPC_LINK_PROTO_SEQNO)
1366+
msg_set_seqno(hdr, l->snd_nxt_state++);
13561367
msg_set_seq_gap(hdr, rcvgap);
13571368
msg_set_bc_gap(hdr, link_bc_rcv_gap(bcl));
13581369
msg_set_probe(hdr, probe);
@@ -1522,6 +1533,11 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
15221533

15231534
case STATE_MSG:
15241535

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+
15251541
/* Update own tolerance if peer indicates a non-zero value */
15261542
if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL))
15271543
l->tolerance = peers_tol;

net/tipc/link.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ char *tipc_link_name(struct tipc_link *l);
110110
char tipc_link_plane(struct tipc_link *l);
111111
int tipc_link_prio(struct tipc_link *l);
112112
int tipc_link_window(struct tipc_link *l);
113+
void tipc_link_update_caps(struct tipc_link *l, u16 capabilities);
113114
unsigned long tipc_link_tolerance(struct tipc_link *l);
114115
void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
115116
struct sk_buff_head *xmitq);

net/tipc/node.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,20 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
363363
{
364364
struct tipc_net *tn = net_generic(net, tipc_net_id);
365365
struct tipc_node *n, *temp_node;
366+
struct tipc_link *l;
367+
int bearer_id;
366368
int i;
367369

368370
spin_lock_bh(&tn->node_list_lock);
369371
n = tipc_node_find(net, addr);
370372
if (n) {
371373
/* Same node may come back with new capabilities */
372374
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+
}
373380
goto exit;
374381
}
375382
n = kzalloc(sizeof(*n), GFP_ATOMIC);

net/tipc/node.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,16 @@ enum {
4949
TIPC_BCAST_STATE_NACK = (1 << 2),
5050
TIPC_BLOCK_FLOWCTL = (1 << 3),
5151
TIPC_BCAST_RCAST = (1 << 4),
52-
TIPC_NODE_ID128 = (1 << 5)
52+
TIPC_NODE_ID128 = (1 << 5),
53+
TIPC_LINK_PROTO_SEQNO = (1 << 6)
5354
};
5455

55-
#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
56-
TIPC_BCAST_STATE_NACK | \
57-
TIPC_BCAST_RCAST | \
58-
TIPC_BLOCK_FLOWCTL | \
59-
TIPC_NODE_ID128)
56+
#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
57+
TIPC_BCAST_STATE_NACK | \
58+
TIPC_BCAST_RCAST | \
59+
TIPC_BLOCK_FLOWCTL | \
60+
TIPC_NODE_ID128 | \
61+
TIPC_LINK_PROTO_SEQNO)
6062
#define INVALID_BEARER_ID -1
6163

6264
void tipc_node_stop(struct net *net);

0 commit comments

Comments
 (0)