summaryrefslogtreecommitdiff
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorJon Maloy <jon.maloy@ericsson.com>2018-07-10 02:07:35 +0300
committerDavid S. Miller <davem@davemloft.net>2018-07-12 09:06:14 +0300
commit9012de5089560136b849b920ad038b96160ed8f6 (patch)
tree20261a0c6e074ca936878835b64a04294ca3af52 /net/tipc/link.c
parente32f55f373217001187ff171e75c5dfbb251f633 (diff)
downloadlinux-9012de5089560136b849b920ad038b96160ed8f6.tar.xz
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>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c16
1 files changed, 16 insertions, 0 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 {
/* Management and link supervision data */
u32 peer_session;
u32 session;
+ u16 snd_nxt_state;
+ u16 rcv_nxt_state;
u32 peer_bearer_id;
u32 bearer_id;
u32 tolerance;
@@ -339,6 +341,11 @@ char tipc_link_plane(struct tipc_link *l)
return l->net_plane;
}
+void tipc_link_update_caps(struct tipc_link *l, u16 capabilities)
+{
+ l->peer_caps = capabilities;
+}
+
void tipc_link_add_bc_peer(struct tipc_link *snd_l,
struct tipc_link *uc_l,
struct sk_buff_head *xmitq)
@@ -859,6 +866,8 @@ void tipc_link_reset(struct tipc_link *l)
l->rcv_unacked = 0;
l->snd_nxt = 1;
l->rcv_nxt = 1;
+ l->snd_nxt_state = 1;
+ l->rcv_nxt_state = 1;
l->acked = 0;
l->silent_intv_cnt = 0;
l->rst_cnt = 0;
@@ -1353,6 +1362,8 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2);
if (mtyp == STATE_MSG) {
+ if (l->peer_caps & TIPC_LINK_PROTO_SEQNO)
+ msg_set_seqno(hdr, l->snd_nxt_state++);
msg_set_seq_gap(hdr, rcvgap);
msg_set_bc_gap(hdr, link_bc_rcv_gap(bcl));
msg_set_probe(hdr, probe);
@@ -1522,6 +1533,11 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
case STATE_MSG:
+ if (l->peer_caps & TIPC_LINK_PROTO_SEQNO &&
+ less(msg_seqno(hdr), l->rcv_nxt_state))
+ break;
+ l->rcv_nxt_state = msg_seqno(hdr) + 1;
+
/* 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;