aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c126
-rw-r--r--net/tipc/link.c346
-rw-r--r--net/tipc/link.h170
-rw-r--r--net/tipc/netlink.c2
-rw-r--r--net/tipc/netlink_compat.c4
-rw-r--r--net/tipc/node.c108
-rw-r--r--net/tipc/node.h4
7 files changed, 415 insertions, 345 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 9dc239dfe192..e401108360a2 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -332,131 +332,15 @@ void tipc_bcast_remove_peer(struct net *net, struct tipc_link *rcv_l)
332 tipc_sk_rcv(net, inputq); 332 tipc_sk_rcv(net, inputq);
333} 333}
334 334
335static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb,
336 struct tipc_stats *stats)
337{
338 int i;
339 struct nlattr *nest;
340
341 struct nla_map {
342 __u32 key;
343 __u32 val;
344 };
345
346 struct nla_map map[] = {
347 {TIPC_NLA_STATS_RX_INFO, stats->recv_info},
348 {TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments},
349 {TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented},
350 {TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles},
351 {TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled},
352 {TIPC_NLA_STATS_TX_INFO, stats->sent_info},
353 {TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments},
354 {TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented},
355 {TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles},
356 {TIPC_NLA_STATS_TX_BUNDLED, stats->sent_bundled},
357 {TIPC_NLA_STATS_RX_NACKS, stats->recv_nacks},
358 {TIPC_NLA_STATS_RX_DEFERRED, stats->deferred_recv},
359 {TIPC_NLA_STATS_TX_NACKS, stats->sent_nacks},
360 {TIPC_NLA_STATS_TX_ACKS, stats->sent_acks},
361 {TIPC_NLA_STATS_RETRANSMITTED, stats->retransmitted},
362 {TIPC_NLA_STATS_DUPLICATES, stats->duplicates},
363 {TIPC_NLA_STATS_LINK_CONGS, stats->link_congs},
364 {TIPC_NLA_STATS_MAX_QUEUE, stats->max_queue_sz},
365 {TIPC_NLA_STATS_AVG_QUEUE, stats->queue_sz_counts ?
366 (stats->accu_queue_sz / stats->queue_sz_counts) : 0}
367 };
368
369 nest = nla_nest_start(skb, TIPC_NLA_LINK_STATS);
370 if (!nest)
371 return -EMSGSIZE;
372
373 for (i = 0; i < ARRAY_SIZE(map); i++)
374 if (nla_put_u32(skb, map[i].key, map[i].val))
375 goto msg_full;
376
377 nla_nest_end(skb, nest);
378
379 return 0;
380msg_full:
381 nla_nest_cancel(skb, nest);
382
383 return -EMSGSIZE;
384}
385
386int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg)
387{
388 int err;
389 void *hdr;
390 struct nlattr *attrs;
391 struct nlattr *prop;
392 struct tipc_net *tn = net_generic(net, tipc_net_id);
393 struct tipc_link *bcl = tn->bcl;
394
395 if (!bcl)
396 return 0;
397
398 tipc_bcast_lock(net);
399
400 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
401 NLM_F_MULTI, TIPC_NL_LINK_GET);
402 if (!hdr)
403 return -EMSGSIZE;
404
405 attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK);
406 if (!attrs)
407 goto msg_full;
408
409 /* The broadcast link is always up */
410 if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
411 goto attr_msg_full;
412
413 if (nla_put_flag(msg->skb, TIPC_NLA_LINK_BROADCAST))
414 goto attr_msg_full;
415 if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name))
416 goto attr_msg_full;
417 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->rcv_nxt))
418 goto attr_msg_full;
419 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->snd_nxt))
420 goto attr_msg_full;
421
422 prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
423 if (!prop)
424 goto attr_msg_full;
425 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->window))
426 goto prop_msg_full;
427 nla_nest_end(msg->skb, prop);
428
429 err = __tipc_nl_add_bc_link_stat(msg->skb, &bcl->stats);
430 if (err)
431 goto attr_msg_full;
432
433 tipc_bcast_unlock(net);
434 nla_nest_end(msg->skb, attrs);
435 genlmsg_end(msg->skb, hdr);
436
437 return 0;
438
439prop_msg_full:
440 nla_nest_cancel(msg->skb, prop);
441attr_msg_full:
442 nla_nest_cancel(msg->skb, attrs);
443msg_full:
444 tipc_bcast_unlock(net);
445 genlmsg_cancel(msg->skb, hdr);
446
447 return -EMSGSIZE;
448}
449
450int tipc_bclink_reset_stats(struct net *net) 335int tipc_bclink_reset_stats(struct net *net)
451{ 336{
452 struct tipc_net *tn = net_generic(net, tipc_net_id); 337 struct tipc_link *l = tipc_bc_sndlink(net);
453 struct tipc_link *bcl = tn->bcl;
454 338
455 if (!bcl) 339 if (!l)
456 return -ENOPROTOOPT; 340 return -ENOPROTOOPT;
457 341
458 tipc_bcast_lock(net); 342 tipc_bcast_lock(net);
459 memset(&bcl->stats, 0, sizeof(bcl->stats)); 343 tipc_link_reset_stats(l);
460 tipc_bcast_unlock(net); 344 tipc_bcast_unlock(net);
461 return 0; 345 return 0;
462} 346}
@@ -530,9 +414,7 @@ enomem:
530 414
531void tipc_bcast_reinit(struct net *net) 415void tipc_bcast_reinit(struct net *net)
532{ 416{
533 struct tipc_bc_base *b = tipc_bc_base(net); 417 tipc_link_reinit(tipc_bc_sndlink(net), tipc_own_addr(net));
534
535 msg_set_prevnode(b->link->pmsg, tipc_own_addr(net));
536} 418}
537 419
538void tipc_bcast_stop(struct net *net) 420void tipc_bcast_stop(struct net *net)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index c513a807b3a1..4380eb119796 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -45,6 +45,151 @@
45 45
46#include <linux/pkt_sched.h> 46#include <linux/pkt_sched.h>
47 47
48struct tipc_stats {
49 u32 sent_info; /* used in counting # sent packets */
50 u32 recv_info; /* used in counting # recv'd packets */
51 u32 sent_states;
52 u32 recv_states;
53 u32 sent_probes;
54 u32 recv_probes;
55 u32 sent_nacks;
56 u32 recv_nacks;
57 u32 sent_acks;
58 u32 sent_bundled;
59 u32 sent_bundles;
60 u32 recv_bundled;
61 u32 recv_bundles;
62 u32 retransmitted;
63 u32 sent_fragmented;
64 u32 sent_fragments;
65 u32 recv_fragmented;
66 u32 recv_fragments;
67 u32 link_congs; /* # port sends blocked by congestion */
68 u32 deferred_recv;
69 u32 duplicates;
70 u32 max_queue_sz; /* send queue size high water mark */
71 u32 accu_queue_sz; /* used for send queue size profiling */
72 u32 queue_sz_counts; /* used for send queue size profiling */
73 u32 msg_length_counts; /* used for message length profiling */
74 u32 msg_lengths_total; /* used for message length profiling */
75 u32 msg_length_profile[7]; /* used for msg. length profiling */
76};
77
78/**
79 * struct tipc_link - TIPC link data structure
80 * @addr: network address of link's peer node
81 * @name: link name character string
82 * @media_addr: media address to use when sending messages over link
83 * @timer: link timer
84 * @net: pointer to namespace struct
85 * @refcnt: reference counter for permanent references (owner node & timer)
86 * @peer_session: link session # being used by peer end of link
87 * @peer_bearer_id: bearer id used by link's peer endpoint
88 * @bearer_id: local bearer id used by link
89 * @tolerance: minimum link continuity loss needed to reset link [in ms]
90 * @keepalive_intv: link keepalive timer interval
91 * @abort_limit: # of unacknowledged continuity probes needed to reset link
92 * @state: current state of link FSM
93 * @peer_caps: bitmap describing capabilities of peer node
94 * @silent_intv_cnt: # of timer intervals without any reception from peer
95 * @proto_msg: template for control messages generated by link
96 * @pmsg: convenience pointer to "proto_msg" field
97 * @priority: current link priority
98 * @net_plane: current link network plane ('A' through 'H')
99 * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
100 * @exp_msg_count: # of tunnelled messages expected during link changeover
101 * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset
102 * @mtu: current maximum packet size for this link
103 * @advertised_mtu: advertised own mtu when link is being established
104 * @transmitq: queue for sent, non-acked messages
105 * @backlogq: queue for messages waiting to be sent
106 * @snt_nxt: next sequence number to use for outbound messages
107 * @last_retransmitted: sequence number of most recently retransmitted message
108 * @stale_count: # of identical retransmit requests made by peer
109 * @ackers: # of peers that needs to ack each packet before it can be released
110 * @acked: # last packet acked by a certain peer. Used for broadcast.
111 * @rcv_nxt: next sequence number to expect for inbound messages
112 * @deferred_queue: deferred queue saved OOS b'cast message received from node
113 * @unacked_window: # of inbound messages rx'd without ack'ing back to peer
114 * @inputq: buffer queue for messages to be delivered upwards
115 * @namedq: buffer queue for name table messages to be delivered upwards
116 * @next_out: ptr to first unsent outbound message in queue
117 * @wakeupq: linked list of wakeup msgs waiting for link congestion to abate
118 * @long_msg_seq_no: next identifier to use for outbound fragmented messages
119 * @reasm_buf: head of partially reassembled inbound message fragments
120 * @bc_rcvr: marks that this is a broadcast receiver link
121 * @stats: collects statistics regarding link activity
122 */
123struct tipc_link {
124 u32 addr;
125 char name[TIPC_MAX_LINK_NAME];
126 struct tipc_media_addr *media_addr;
127 struct net *net;
128
129 /* Management and link supervision data */
130 u32 peer_session;
131 u32 peer_bearer_id;
132 u32 bearer_id;
133 u32 tolerance;
134 unsigned long keepalive_intv;
135 u32 abort_limit;
136 u32 state;
137 u16 peer_caps;
138 bool active;
139 u32 silent_intv_cnt;
140 struct {
141 unchar hdr[INT_H_SIZE];
142 unchar body[TIPC_MAX_IF_NAME];
143 } proto_msg;
144 struct tipc_msg *pmsg;
145 u32 priority;
146 char net_plane;
147
148 /* Failover/synch */
149 u16 drop_point;
150 struct sk_buff *failover_reasm_skb;
151
152 /* Max packet negotiation */
153 u16 mtu;
154 u16 advertised_mtu;
155
156 /* Sending */
157 struct sk_buff_head transmq;
158 struct sk_buff_head backlogq;
159 struct {
160 u16 len;
161 u16 limit;
162 } backlog[5];
163 u16 snd_nxt;
164 u16 last_retransm;
165 u16 window;
166 u32 stale_count;
167
168 /* Reception */
169 u16 rcv_nxt;
170 u32 rcv_unacked;
171 struct sk_buff_head deferdq;
172 struct sk_buff_head *inputq;
173 struct sk_buff_head *namedq;
174
175 /* Congestion handling */
176 struct sk_buff_head wakeupq;
177
178 /* Fragmentation/reassembly */
179 struct sk_buff *reasm_buf;
180
181 /* Broadcast */
182 u16 ackers;
183 u16 acked;
184 struct tipc_link *bc_rcvlink;
185 struct tipc_link *bc_sndlink;
186 int nack_state;
187 bool bc_peer_is_up;
188
189 /* Statistics */
190 struct tipc_stats stats;
191};
192
48/* 193/*
49 * Error message prefixes 194 * Error message prefixes
50 */ 195 */
@@ -165,6 +310,36 @@ void tipc_link_set_active(struct tipc_link *l, bool active)
165 l->active = active; 310 l->active = active;
166} 311}
167 312
313u32 tipc_link_id(struct tipc_link *l)
314{
315 return l->peer_bearer_id << 16 | l->bearer_id;
316}
317
318int tipc_link_window(struct tipc_link *l)
319{
320 return l->window;
321}
322
323int tipc_link_prio(struct tipc_link *l)
324{
325 return l->priority;
326}
327
328unsigned long tipc_link_tolerance(struct tipc_link *l)
329{
330 return l->tolerance;
331}
332
333struct sk_buff_head *tipc_link_inputq(struct tipc_link *l)
334{
335 return l->inputq;
336}
337
338char tipc_link_plane(struct tipc_link *l)
339{
340 return l->net_plane;
341}
342
168void tipc_link_add_bc_peer(struct tipc_link *snd_l, 343void tipc_link_add_bc_peer(struct tipc_link *snd_l,
169 struct tipc_link *uc_l, 344 struct tipc_link *uc_l,
170 struct sk_buff_head *xmitq) 345 struct sk_buff_head *xmitq)
@@ -207,11 +382,31 @@ int tipc_link_mtu(struct tipc_link *l)
207 return l->mtu; 382 return l->mtu;
208} 383}
209 384
385u16 tipc_link_rcv_nxt(struct tipc_link *l)
386{
387 return l->rcv_nxt;
388}
389
390u16 tipc_link_acked(struct tipc_link *l)
391{
392 return l->acked;
393}
394
395char *tipc_link_name(struct tipc_link *l)
396{
397 return l->name;
398}
399
210static u32 link_own_addr(struct tipc_link *l) 400static u32 link_own_addr(struct tipc_link *l)
211{ 401{
212 return msg_prevnode(l->pmsg); 402 return msg_prevnode(l->pmsg);
213} 403}
214 404
405void tipc_link_reinit(struct tipc_link *l, u32 addr)
406{
407 msg_set_prevnode(l->pmsg, addr);
408}
409
215/** 410/**
216 * tipc_link_create - create a new link 411 * tipc_link_create - create a new link
217 * @n: pointer to associated node 412 * @n: pointer to associated node
@@ -674,7 +869,7 @@ void tipc_link_reset(struct tipc_link *l)
674 l->stats.recv_info = 0; 869 l->stats.recv_info = 0;
675 l->stale_count = 0; 870 l->stale_count = 0;
676 l->bc_peer_is_up = false; 871 l->bc_peer_is_up = false;
677 link_reset_statistics(l); 872 tipc_link_reset_stats(l);
678} 873}
679 874
680/** 875/**
@@ -1067,8 +1262,9 @@ drop:
1067/* 1262/*
1068 * Send protocol message to the other endpoint. 1263 * Send protocol message to the other endpoint.
1069 */ 1264 */
1070void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ, int probe_msg, 1265static void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ,
1071 u32 gap, u32 tolerance, u32 priority) 1266 int probe_msg, u32 gap, u32 tolerance,
1267 u32 priority)
1072{ 1268{
1073 struct sk_buff *skb = NULL; 1269 struct sk_buff *skb = NULL;
1074 struct sk_buff_head xmitq; 1270 struct sk_buff_head xmitq;
@@ -1510,14 +1706,16 @@ void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
1510} 1706}
1511 1707
1512/** 1708/**
1513 * link_reset_statistics - reset link statistics 1709 * link_reset_stats - reset link statistics
1514 * @l_ptr: pointer to link 1710 * @l_ptr: pointer to link
1515 */ 1711 */
1516void link_reset_statistics(struct tipc_link *l_ptr) 1712void tipc_link_reset_stats(struct tipc_link *l)
1517{ 1713{
1518 memset(&l_ptr->stats, 0, sizeof(l_ptr->stats)); 1714 memset(&l->stats, 0, sizeof(l->stats));
1519 l_ptr->stats.sent_info = l_ptr->snd_nxt; 1715 if (!link_is_bc_sndlink(l)) {
1520 l_ptr->stats.recv_info = l_ptr->rcv_nxt; 1716 l->stats.sent_info = l->snd_nxt;
1717 l->stats.recv_info = l->rcv_nxt;
1718 }
1521} 1719}
1522 1720
1523static void link_print(struct tipc_link *l, const char *str) 1721static void link_print(struct tipc_link *l, const char *str)
@@ -1705,3 +1903,135 @@ msg_full:
1705 1903
1706 return -EMSGSIZE; 1904 return -EMSGSIZE;
1707} 1905}
1906
1907static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb,
1908 struct tipc_stats *stats)
1909{
1910 int i;
1911 struct nlattr *nest;
1912
1913 struct nla_map {
1914 __u32 key;
1915 __u32 val;
1916 };
1917
1918 struct nla_map map[] = {
1919 {TIPC_NLA_STATS_RX_INFO, stats->recv_info},
1920 {TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments},
1921 {TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented},
1922 {TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles},
1923 {TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled},
1924 {TIPC_NLA_STATS_TX_INFO, stats->sent_info},
1925 {TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments},
1926 {TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented},
1927 {TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles},
1928 {TIPC_NLA_STATS_TX_BUNDLED, stats->sent_bundled},
1929 {TIPC_NLA_STATS_RX_NACKS, stats->recv_nacks},
1930 {TIPC_NLA_STATS_RX_DEFERRED, stats->deferred_recv},
1931 {TIPC_NLA_STATS_TX_NACKS, stats->sent_nacks},
1932 {TIPC_NLA_STATS_TX_ACKS, stats->sent_acks},
1933 {TIPC_NLA_STATS_RETRANSMITTED, stats->retransmitted},
1934 {TIPC_NLA_STATS_DUPLICATES, stats->duplicates},
1935 {TIPC_NLA_STATS_LINK_CONGS, stats->link_congs},
1936 {TIPC_NLA_STATS_MAX_QUEUE, stats->max_queue_sz},
1937 {TIPC_NLA_STATS_AVG_QUEUE, stats->queue_sz_counts ?
1938 (stats->accu_queue_sz / stats->queue_sz_counts) : 0}
1939 };
1940
1941 nest = nla_nest_start(skb, TIPC_NLA_LINK_STATS);
1942 if (!nest)
1943 return -EMSGSIZE;
1944
1945 for (i = 0; i < ARRAY_SIZE(map); i++)
1946 if (nla_put_u32(skb, map[i].key, map[i].val))
1947 goto msg_full;
1948
1949 nla_nest_end(skb, nest);
1950
1951 return 0;
1952msg_full:
1953 nla_nest_cancel(skb, nest);
1954
1955 return -EMSGSIZE;
1956}
1957
1958int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg)
1959{
1960 int err;
1961 void *hdr;
1962 struct nlattr *attrs;
1963 struct nlattr *prop;
1964 struct tipc_net *tn = net_generic(net, tipc_net_id);
1965 struct tipc_link *bcl = tn->bcl;
1966
1967 if (!bcl)
1968 return 0;
1969
1970 tipc_bcast_lock(net);
1971
1972 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
1973 NLM_F_MULTI, TIPC_NL_LINK_GET);
1974 if (!hdr)
1975 return -EMSGSIZE;
1976
1977 attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK);
1978 if (!attrs)
1979 goto msg_full;
1980
1981 /* The broadcast link is always up */
1982 if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
1983 goto attr_msg_full;
1984
1985 if (nla_put_flag(msg->skb, TIPC_NLA_LINK_BROADCAST))
1986 goto attr_msg_full;
1987 if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name))
1988 goto attr_msg_full;
1989 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, bcl->rcv_nxt))
1990 goto attr_msg_full;
1991 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, bcl->snd_nxt))
1992 goto attr_msg_full;
1993
1994 prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
1995 if (!prop)
1996 goto attr_msg_full;
1997 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->window))
1998 goto prop_msg_full;
1999 nla_nest_end(msg->skb, prop);
2000
2001 err = __tipc_nl_add_bc_link_stat(msg->skb, &bcl->stats);
2002 if (err)
2003 goto attr_msg_full;
2004
2005 tipc_bcast_unlock(net);
2006 nla_nest_end(msg->skb, attrs);
2007 genlmsg_end(msg->skb, hdr);
2008
2009 return 0;
2010
2011prop_msg_full:
2012 nla_nest_cancel(msg->skb, prop);
2013attr_msg_full:
2014 nla_nest_cancel(msg->skb, attrs);
2015msg_full:
2016 tipc_bcast_unlock(net);
2017 genlmsg_cancel(msg->skb, hdr);
2018
2019 return -EMSGSIZE;
2020}
2021
2022void tipc_link_set_tolerance(struct tipc_link *l, u32 tol)
2023{
2024 l->tolerance = tol;
2025 tipc_link_proto_xmit(l, STATE_MSG, 0, 0, tol, 0);
2026}
2027
2028void tipc_link_set_prio(struct tipc_link *l, u32 prio)
2029{
2030 l->priority = prio;
2031 tipc_link_proto_xmit(l, STATE_MSG, 0, 0, 0, prio);
2032}
2033
2034void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit)
2035{
2036 l->abort_limit = limit;
2037}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index a7ee806e1ee4..616fc808f23a 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -45,10 +45,6 @@
45*/ 45*/
46#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */ 46#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
47 47
48/* Out-of-range value for link sequence numbers
49 */
50#define INVALID_LINK_SEQ 0x10000
51
52/* Link FSM events: 48/* Link FSM events:
53 */ 49 */
54enum { 50enum {
@@ -75,151 +71,6 @@ enum {
75 */ 71 */
76#define MAX_PKT_DEFAULT 1500 72#define MAX_PKT_DEFAULT 1500
77 73
78struct tipc_stats {
79 u32 sent_info; /* used in counting # sent packets */
80 u32 recv_info; /* used in counting # recv'd packets */
81 u32 sent_states;
82 u32 recv_states;
83 u32 sent_probes;
84 u32 recv_probes;
85 u32 sent_nacks;
86 u32 recv_nacks;
87 u32 sent_acks;
88 u32 sent_bundled;
89 u32 sent_bundles;
90 u32 recv_bundled;
91 u32 recv_bundles;
92 u32 retransmitted;
93 u32 sent_fragmented;
94 u32 sent_fragments;
95 u32 recv_fragmented;
96 u32 recv_fragments;
97 u32 link_congs; /* # port sends blocked by congestion */
98 u32 deferred_recv;
99 u32 duplicates;
100 u32 max_queue_sz; /* send queue size high water mark */
101 u32 accu_queue_sz; /* used for send queue size profiling */
102 u32 queue_sz_counts; /* used for send queue size profiling */
103 u32 msg_length_counts; /* used for message length profiling */
104 u32 msg_lengths_total; /* used for message length profiling */
105 u32 msg_length_profile[7]; /* used for msg. length profiling */
106};
107
108/**
109 * struct tipc_link - TIPC link data structure
110 * @addr: network address of link's peer node
111 * @name: link name character string
112 * @media_addr: media address to use when sending messages over link
113 * @timer: link timer
114 * @net: pointer to namespace struct
115 * @refcnt: reference counter for permanent references (owner node & timer)
116 * @peer_session: link session # being used by peer end of link
117 * @peer_bearer_id: bearer id used by link's peer endpoint
118 * @bearer_id: local bearer id used by link
119 * @tolerance: minimum link continuity loss needed to reset link [in ms]
120 * @keepalive_intv: link keepalive timer interval
121 * @abort_limit: # of unacknowledged continuity probes needed to reset link
122 * @state: current state of link FSM
123 * @peer_caps: bitmap describing capabilities of peer node
124 * @silent_intv_cnt: # of timer intervals without any reception from peer
125 * @proto_msg: template for control messages generated by link
126 * @pmsg: convenience pointer to "proto_msg" field
127 * @priority: current link priority
128 * @net_plane: current link network plane ('A' through 'H')
129 * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
130 * @exp_msg_count: # of tunnelled messages expected during link changeover
131 * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset
132 * @mtu: current maximum packet size for this link
133 * @advertised_mtu: advertised own mtu when link is being established
134 * @transmitq: queue for sent, non-acked messages
135 * @backlogq: queue for messages waiting to be sent
136 * @snt_nxt: next sequence number to use for outbound messages
137 * @last_retransmitted: sequence number of most recently retransmitted message
138 * @stale_count: # of identical retransmit requests made by peer
139 * @ackers: # of peers that needs to ack each packet before it can be released
140 * @acked: # last packet acked by a certain peer. Used for broadcast.
141 * @rcv_nxt: next sequence number to expect for inbound messages
142 * @deferred_queue: deferred queue saved OOS b'cast message received from node
143 * @unacked_window: # of inbound messages rx'd without ack'ing back to peer
144 * @inputq: buffer queue for messages to be delivered upwards
145 * @namedq: buffer queue for name table messages to be delivered upwards
146 * @next_out: ptr to first unsent outbound message in queue
147 * @wakeupq: linked list of wakeup msgs waiting for link congestion to abate
148 * @long_msg_seq_no: next identifier to use for outbound fragmented messages
149 * @reasm_buf: head of partially reassembled inbound message fragments
150 * @bc_rcvr: marks that this is a broadcast receiver link
151 * @stats: collects statistics regarding link activity
152 */
153struct tipc_link {
154 u32 addr;
155 char name[TIPC_MAX_LINK_NAME];
156 struct tipc_media_addr *media_addr;
157 struct net *net;
158
159 /* Management and link supervision data */
160 u32 peer_session;
161 u32 peer_bearer_id;
162 u32 bearer_id;
163 u32 tolerance;
164 unsigned long keepalive_intv;
165 u32 abort_limit;
166 u32 state;
167 u16 peer_caps;
168 bool active;
169 u32 silent_intv_cnt;
170 struct {
171 unchar hdr[INT_H_SIZE];
172 unchar body[TIPC_MAX_IF_NAME];
173 } proto_msg;
174 struct tipc_msg *pmsg;
175 u32 priority;
176 char net_plane;
177
178 /* Failover/synch */
179 u16 drop_point;
180 struct sk_buff *failover_reasm_skb;
181
182 /* Max packet negotiation */
183 u16 mtu;
184 u16 advertised_mtu;
185
186 /* Sending */
187 struct sk_buff_head transmq;
188 struct sk_buff_head backlogq;
189 struct {
190 u16 len;
191 u16 limit;
192 } backlog[5];
193 u16 snd_nxt;
194 u16 last_retransm;
195 u16 window;
196 u32 stale_count;
197
198 /* Reception */
199 u16 rcv_nxt;
200 u32 rcv_unacked;
201 struct sk_buff_head deferdq;
202 struct sk_buff_head *inputq;
203 struct sk_buff_head *namedq;
204
205 /* Congestion handling */
206 struct sk_buff_head wakeupq;
207
208 /* Fragmentation/reassembly */
209 struct sk_buff *reasm_buf;
210
211 /* Broadcast */
212 u16 ackers;
213 u16 acked;
214 struct tipc_link *bc_rcvlink;
215 struct tipc_link *bc_sndlink;
216 int nack_state;
217 bool bc_peer_is_up;
218
219 /* Statistics */
220 struct tipc_stats stats;
221};
222
223bool tipc_link_create(struct net *net, char *if_name, int bearer_id, 74bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
224 int tolerance, char net_plane, u32 mtu, int priority, 75 int tolerance, char net_plane, u32 mtu, int priority,
225 int window, u32 session, u32 ownnode, u32 peer, 76 int window, u32 session, u32 ownnode, u32 peer,
@@ -235,11 +86,11 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
235 struct sk_buff_head *namedq, 86 struct sk_buff_head *namedq,
236 struct tipc_link *bc_sndlink, 87 struct tipc_link *bc_sndlink,
237 struct tipc_link **link); 88 struct tipc_link **link);
89void tipc_link_reinit(struct tipc_link *l, u32 addr);
238void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, 90void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
239 int mtyp, struct sk_buff_head *xmitq); 91 int mtyp, struct sk_buff_head *xmitq);
240void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq); 92void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq);
241int tipc_link_fsm_evt(struct tipc_link *l, int evt); 93int tipc_link_fsm_evt(struct tipc_link *l, int evt);
242void tipc_link_reset_fragments(struct tipc_link *l_ptr);
243bool tipc_link_is_up(struct tipc_link *l); 94bool tipc_link_is_up(struct tipc_link *l);
244bool tipc_link_peer_is_down(struct tipc_link *l); 95bool tipc_link_peer_is_down(struct tipc_link *l);
245bool tipc_link_is_reset(struct tipc_link *l); 96bool tipc_link_is_reset(struct tipc_link *l);
@@ -249,15 +100,24 @@ bool tipc_link_is_failingover(struct tipc_link *l);
249bool tipc_link_is_blocked(struct tipc_link *l); 100bool tipc_link_is_blocked(struct tipc_link *l);
250void tipc_link_set_active(struct tipc_link *l, bool active); 101void tipc_link_set_active(struct tipc_link *l, bool active);
251void tipc_link_reset(struct tipc_link *l_ptr); 102void tipc_link_reset(struct tipc_link *l_ptr);
252void link_reset_statistics(struct tipc_link *l); 103void tipc_link_reset_stats(struct tipc_link *l);
253int tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list, 104int tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list,
254 struct sk_buff_head *xmitq); 105 struct sk_buff_head *xmitq);
255void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ, int probe_msg, 106struct sk_buff_head *tipc_link_inputq(struct tipc_link *l);
256 u32 gap, u32 tolerance, u32 priority); 107u16 tipc_link_rcv_nxt(struct tipc_link *l);
108u16 tipc_link_acked(struct tipc_link *l);
109u32 tipc_link_id(struct tipc_link *l);
110char *tipc_link_name(struct tipc_link *l);
111char tipc_link_plane(struct tipc_link *l);
112int tipc_link_prio(struct tipc_link *l);
113int tipc_link_window(struct tipc_link *l);
114unsigned long tipc_link_tolerance(struct tipc_link *l);
115void tipc_link_set_tolerance(struct tipc_link *l, u32 tol);
116void tipc_link_set_prio(struct tipc_link *l, u32 prio);
117void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit);
257void tipc_link_set_queue_limits(struct tipc_link *l, u32 window); 118void tipc_link_set_queue_limits(struct tipc_link *l, u32 window);
258int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg, 119int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
259 struct tipc_link *link, int nlflags); 120 struct tipc_link *link, int nlflags);
260int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb);
261int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); 121int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
262int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq); 122int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq);
263int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb, 123int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 29dfcc94b6a5..8975b0135b76 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -102,7 +102,7 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
102 { 102 {
103 .cmd = TIPC_NL_LINK_GET, 103 .cmd = TIPC_NL_LINK_GET,
104 .doit = tipc_nl_node_get_link, 104 .doit = tipc_nl_node_get_link,
105 .dumpit = tipc_nl_link_dump, 105 .dumpit = tipc_nl_node_dump_link,
106 .policy = tipc_nl_policy, 106 .policy = tipc_nl_policy,
107 }, 107 },
108 { 108 {
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index acda1ce57151..2c016fdefe97 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -1023,13 +1023,13 @@ static int tipc_nl_compat_handle(struct tipc_nl_compat_msg *msg)
1023 msg->req_type = TIPC_TLV_LINK_NAME; 1023 msg->req_type = TIPC_TLV_LINK_NAME;
1024 msg->rep_size = ULTRA_STRING_MAX_LEN; 1024 msg->rep_size = ULTRA_STRING_MAX_LEN;
1025 msg->rep_type = TIPC_TLV_ULTRA_STRING; 1025 msg->rep_type = TIPC_TLV_ULTRA_STRING;
1026 dump.dumpit = tipc_nl_link_dump; 1026 dump.dumpit = tipc_nl_node_dump_link;
1027 dump.format = tipc_nl_compat_link_stat_dump; 1027 dump.format = tipc_nl_compat_link_stat_dump;
1028 return tipc_nl_compat_dumpit(&dump, msg); 1028 return tipc_nl_compat_dumpit(&dump, msg);
1029 case TIPC_CMD_GET_LINKS: 1029 case TIPC_CMD_GET_LINKS:
1030 msg->req_type = TIPC_TLV_NET_ADDR; 1030 msg->req_type = TIPC_TLV_NET_ADDR;
1031 msg->rep_size = ULTRA_STRING_MAX_LEN; 1031 msg->rep_size = ULTRA_STRING_MAX_LEN;
1032 dump.dumpit = tipc_nl_link_dump; 1032 dump.dumpit = tipc_nl_node_dump_link;
1033 dump.format = tipc_nl_compat_link_dump; 1033 dump.format = tipc_nl_compat_link_dump;
1034 return tipc_nl_compat_dumpit(&dump, msg); 1034 return tipc_nl_compat_dumpit(&dump, msg);
1035 case TIPC_CMD_SET_LINK_TOL: 1035 case TIPC_CMD_SET_LINK_TOL:
diff --git a/net/tipc/node.c b/net/tipc/node.c
index e110ba67422e..82c05e9dd0ee 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -42,11 +42,8 @@
42#include "bcast.h" 42#include "bcast.h"
43#include "discover.h" 43#include "discover.h"
44 44
45/* Out-of-range value for node signature */
46#define INVALID_NODE_SIG 0x10000 45#define INVALID_NODE_SIG 0x10000
47 46
48#define INVALID_BEARER_ID -1
49
50/* Flags used to take different actions according to flag type 47/* Flags used to take different actions according to flag type
51 * TIPC_NOTIFY_NODE_DOWN: notify node is down 48 * TIPC_NOTIFY_NODE_DOWN: notify node is down
52 * TIPC_NOTIFY_NODE_UP: notify node is up 49 * TIPC_NOTIFY_NODE_UP: notify node is up
@@ -360,7 +357,8 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
360 n_ptr->active_links[0] = INVALID_BEARER_ID; 357 n_ptr->active_links[0] = INVALID_BEARER_ID;
361 n_ptr->active_links[1] = INVALID_BEARER_ID; 358 n_ptr->active_links[1] = INVALID_BEARER_ID;
362 if (!tipc_link_bc_create(net, tipc_own_addr(net), n_ptr->addr, 359 if (!tipc_link_bc_create(net, tipc_own_addr(net), n_ptr->addr,
363 U16_MAX, tipc_bc_sndlink(net)->window, 360 U16_MAX,
361 tipc_link_window(tipc_bc_sndlink(net)),
364 n_ptr->capabilities, 362 n_ptr->capabilities,
365 &n_ptr->bc_entry.inputq1, 363 &n_ptr->bc_entry.inputq1,
366 &n_ptr->bc_entry.namedq, 364 &n_ptr->bc_entry.namedq,
@@ -381,7 +379,7 @@ exit:
381 379
382static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l) 380static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
383{ 381{
384 unsigned long tol = l->tolerance; 382 unsigned long tol = tipc_link_tolerance(l);
385 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4; 383 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
386 unsigned long keepalive_intv = msecs_to_jiffies(intv); 384 unsigned long keepalive_intv = msecs_to_jiffies(intv);
387 385
@@ -390,7 +388,7 @@ static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
390 n->keepalive_intv = keepalive_intv; 388 n->keepalive_intv = keepalive_intv;
391 389
392 /* Ensure link's abort limit corresponds to current interval */ 390 /* Ensure link's abort limit corresponds to current interval */
393 l->abort_limit = l->tolerance / jiffies_to_msecs(n->keepalive_intv); 391 tipc_link_set_abort_limit(l, tol / jiffies_to_msecs(n->keepalive_intv));
394} 392}
395 393
396static void tipc_node_delete(struct tipc_node *node) 394static void tipc_node_delete(struct tipc_node *node)
@@ -559,16 +557,16 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
559 557
560 n->working_links++; 558 n->working_links++;
561 n->action_flags |= TIPC_NOTIFY_LINK_UP; 559 n->action_flags |= TIPC_NOTIFY_LINK_UP;
562 n->link_id = nl->peer_bearer_id << 16 | bearer_id; 560 n->link_id = tipc_link_id(nl);
563 561
564 /* Leave room for tunnel header when returning 'mtu' to users: */ 562 /* Leave room for tunnel header when returning 'mtu' to users: */
565 n->links[bearer_id].mtu = nl->mtu - INT_H_SIZE; 563 n->links[bearer_id].mtu = tipc_link_mtu(nl) - INT_H_SIZE;
566 564
567 tipc_bearer_add_dest(n->net, bearer_id, n->addr); 565 tipc_bearer_add_dest(n->net, bearer_id, n->addr);
568 tipc_bcast_inc_bearer_dst_cnt(n->net, bearer_id); 566 tipc_bcast_inc_bearer_dst_cnt(n->net, bearer_id);
569 567
570 pr_debug("Established link <%s> on network plane %c\n", 568 pr_debug("Established link <%s> on network plane %c\n",
571 nl->name, nl->net_plane); 569 tipc_link_name(nl), tipc_link_plane(nl));
572 570
573 /* First link? => give it both slots */ 571 /* First link? => give it both slots */
574 if (!ol) { 572 if (!ol) {
@@ -581,17 +579,17 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
581 } 579 }
582 580
583 /* Second link => redistribute slots */ 581 /* Second link => redistribute slots */
584 if (nl->priority > ol->priority) { 582 if (tipc_link_prio(nl) > tipc_link_prio(ol)) {
585 pr_debug("Old link <%s> becomes standby\n", ol->name); 583 pr_debug("Old link <%s> becomes standby\n", tipc_link_name(ol));
586 *slot0 = bearer_id; 584 *slot0 = bearer_id;
587 *slot1 = bearer_id; 585 *slot1 = bearer_id;
588 tipc_link_set_active(nl, true); 586 tipc_link_set_active(nl, true);
589 tipc_link_set_active(ol, false); 587 tipc_link_set_active(ol, false);
590 } else if (nl->priority == ol->priority) { 588 } else if (tipc_link_prio(nl) == tipc_link_prio(ol)) {
591 tipc_link_set_active(nl, true); 589 tipc_link_set_active(nl, true);
592 *slot1 = bearer_id; 590 *slot1 = bearer_id;
593 } else { 591 } else {
594 pr_debug("New link <%s> is standby\n", nl->name); 592 pr_debug("New link <%s> is standby\n", tipc_link_name(nl));
595 } 593 }
596 594
597 /* Prepare synchronization with first link */ 595 /* Prepare synchronization with first link */
@@ -621,7 +619,7 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
621 struct tipc_link_entry *le = &n->links[*bearer_id]; 619 struct tipc_link_entry *le = &n->links[*bearer_id];
622 int *slot0 = &n->active_links[0]; 620 int *slot0 = &n->active_links[0];
623 int *slot1 = &n->active_links[1]; 621 int *slot1 = &n->active_links[1];
624 int i, highest = 0; 622 int i, highest = 0, prio;
625 struct tipc_link *l, *_l, *tnl; 623 struct tipc_link *l, *_l, *tnl;
626 624
627 l = n->links[*bearer_id].link; 625 l = n->links[*bearer_id].link;
@@ -630,12 +628,12 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
630 628
631 n->working_links--; 629 n->working_links--;
632 n->action_flags |= TIPC_NOTIFY_LINK_DOWN; 630 n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
633 n->link_id = l->peer_bearer_id << 16 | *bearer_id; 631 n->link_id = tipc_link_id(l);
634 632
635 tipc_bearer_remove_dest(n->net, *bearer_id, n->addr); 633 tipc_bearer_remove_dest(n->net, *bearer_id, n->addr);
636 634
637 pr_debug("Lost link <%s> on network plane %c\n", 635 pr_debug("Lost link <%s> on network plane %c\n",
638 l->name, l->net_plane); 636 tipc_link_name(l), tipc_link_plane(l));
639 637
640 /* Select new active link if any available */ 638 /* Select new active link if any available */
641 *slot0 = INVALID_BEARER_ID; 639 *slot0 = INVALID_BEARER_ID;
@@ -646,10 +644,11 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
646 continue; 644 continue;
647 if (_l == l) 645 if (_l == l)
648 continue; 646 continue;
649 if (_l->priority < highest) 647 prio = tipc_link_prio(_l);
648 if (prio < highest)
650 continue; 649 continue;
651 if (_l->priority > highest) { 650 if (prio > highest) {
652 highest = _l->priority; 651 highest = prio;
653 *slot0 = i; 652 *slot0 = i;
654 *slot1 = i; 653 *slot1 = i;
655 continue; 654 continue;
@@ -672,17 +671,17 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
672 tipc_bcast_dec_bearer_dst_cnt(n->net, *bearer_id); 671 tipc_bcast_dec_bearer_dst_cnt(n->net, *bearer_id);
673 672
674 /* There is still a working link => initiate failover */ 673 /* There is still a working link => initiate failover */
675 tnl = node_active_link(n, 0); 674 *bearer_id = n->active_links[0];
675 tnl = n->links[*bearer_id].link;
676 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT); 676 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT);
677 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT); 677 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
678 n->sync_point = tnl->rcv_nxt + (U16_MAX / 2 - 1); 678 n->sync_point = tipc_link_rcv_nxt(tnl) + (U16_MAX / 2 - 1);
679 tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq); 679 tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq);
680 tipc_link_reset(l); 680 tipc_link_reset(l);
681 tipc_link_fsm_evt(l, LINK_RESET_EVT); 681 tipc_link_fsm_evt(l, LINK_RESET_EVT);
682 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT); 682 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
683 tipc_node_fsm_evt(n, NODE_FAILOVER_BEGIN_EVT); 683 tipc_node_fsm_evt(n, NODE_FAILOVER_BEGIN_EVT);
684 *maddr = &n->links[tnl->bearer_id].maddr; 684 *maddr = &n->links[*bearer_id].maddr;
685 *bearer_id = tnl->bearer_id;
686} 685}
687 686
688static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) 687static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete)
@@ -1117,7 +1116,7 @@ int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
1117 tipc_node_read_lock(node); 1116 tipc_node_read_lock(node);
1118 link = node->links[bearer_id].link; 1117 link = node->links[bearer_id].link;
1119 if (link) { 1118 if (link) {
1120 strncpy(linkname, link->name, len); 1119 strncpy(linkname, tipc_link_name(link), len);
1121 err = 0; 1120 err = 0;
1122 } 1121 }
1123exit: 1122exit:
@@ -1328,25 +1327,25 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
1328 u16 oseqno = msg_seqno(hdr); 1327 u16 oseqno = msg_seqno(hdr);
1329 u16 iseqno = msg_seqno(msg_get_wrapped(hdr)); 1328 u16 iseqno = msg_seqno(msg_get_wrapped(hdr));
1330 u16 exp_pkts = msg_msgcnt(hdr); 1329 u16 exp_pkts = msg_msgcnt(hdr);
1331 u16 rcv_nxt, syncpt, dlv_nxt; 1330 u16 rcv_nxt, syncpt, dlv_nxt, inputq_len;
1332 int state = n->state; 1331 int state = n->state;
1333 struct tipc_link *l, *tnl, *pl = NULL; 1332 struct tipc_link *l, *tnl, *pl = NULL;
1334 struct tipc_media_addr *maddr; 1333 struct tipc_media_addr *maddr;
1335 int i, pb_id; 1334 int pb_id;
1336 1335
1337 l = n->links[bearer_id].link; 1336 l = n->links[bearer_id].link;
1338 if (!l) 1337 if (!l)
1339 return false; 1338 return false;
1340 rcv_nxt = l->rcv_nxt; 1339 rcv_nxt = tipc_link_rcv_nxt(l);
1341 1340
1342 1341
1343 if (likely((state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) 1342 if (likely((state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL)))
1344 return true; 1343 return true;
1345 1344
1346 /* Find parallel link, if any */ 1345 /* Find parallel link, if any */
1347 for (i = 0; i < MAX_BEARERS; i++) { 1346 for (pb_id = 0; pb_id < MAX_BEARERS; pb_id++) {
1348 if ((i != bearer_id) && n->links[i].link) { 1347 if ((pb_id != bearer_id) && n->links[pb_id].link) {
1349 pl = n->links[i].link; 1348 pl = n->links[pb_id].link;
1350 break; 1349 break;
1351 } 1350 }
1352 } 1351 }
@@ -1378,9 +1377,9 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
1378 if ((usr == TUNNEL_PROTOCOL) && (mtyp == FAILOVER_MSG)) { 1377 if ((usr == TUNNEL_PROTOCOL) && (mtyp == FAILOVER_MSG)) {
1379 syncpt = oseqno + exp_pkts - 1; 1378 syncpt = oseqno + exp_pkts - 1;
1380 if (pl && tipc_link_is_up(pl)) { 1379 if (pl && tipc_link_is_up(pl)) {
1381 pb_id = pl->bearer_id;
1382 __tipc_node_link_down(n, &pb_id, xmitq, &maddr); 1380 __tipc_node_link_down(n, &pb_id, xmitq, &maddr);
1383 tipc_skb_queue_splice_tail_init(pl->inputq, l->inputq); 1381 tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl),
1382 tipc_link_inputq(l));
1384 } 1383 }
1385 /* If pkts arrive out of order, use lowest calculated syncpt */ 1384 /* If pkts arrive out of order, use lowest calculated syncpt */
1386 if (less(syncpt, n->sync_point)) 1385 if (less(syncpt, n->sync_point))
@@ -1423,7 +1422,8 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
1423 tnl = pl; 1422 tnl = pl;
1424 pl = l; 1423 pl = l;
1425 } 1424 }
1426 dlv_nxt = pl->rcv_nxt - mod(skb_queue_len(pl->inputq)); 1425 inputq_len = skb_queue_len(tipc_link_inputq(pl));
1426 dlv_nxt = tipc_link_rcv_nxt(pl) - inputq_len;
1427 if (more(dlv_nxt, n->sync_point)) { 1427 if (more(dlv_nxt, n->sync_point)) {
1428 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT); 1428 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT);
1429 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT); 1429 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
@@ -1483,7 +1483,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
1483 /* Ensure broadcast reception is in synch with peer's send state */ 1483 /* Ensure broadcast reception is in synch with peer's send state */
1484 if (unlikely(usr == LINK_PROTOCOL)) 1484 if (unlikely(usr == LINK_PROTOCOL))
1485 tipc_bcast_sync_rcv(net, n->bc_entry.link, hdr); 1485 tipc_bcast_sync_rcv(net, n->bc_entry.link, hdr);
1486 else if (unlikely(n->bc_entry.link->acked != bc_ack)) 1486 else if (unlikely(tipc_link_acked(n->bc_entry.link) != bc_ack))
1487 tipc_bcast_ack_rcv(net, n->bc_entry.link, bc_ack); 1487 tipc_bcast_ack_rcv(net, n->bc_entry.link, bc_ack);
1488 1488
1489 /* Receive packet directly if conditions permit */ 1489 /* Receive packet directly if conditions permit */
@@ -1592,36 +1592,36 @@ out:
1592 return skb->len; 1592 return skb->len;
1593} 1593}
1594 1594
1595/* tipc_link_find_owner - locate owner node of link by link's name 1595/* tipc_node_find_by_name - locate owner node of link by link's name
1596 * @net: the applicable net namespace 1596 * @net: the applicable net namespace
1597 * @name: pointer to link name string 1597 * @name: pointer to link name string
1598 * @bearer_id: pointer to index in 'node->links' array where the link was found. 1598 * @bearer_id: pointer to index in 'node->links' array where the link was found.
1599 * 1599 *
1600 * Returns pointer to node owning the link, or 0 if no matching link is found. 1600 * Returns pointer to node owning the link, or 0 if no matching link is found.
1601 */ 1601 */
1602static struct tipc_node *tipc_link_find_owner(struct net *net, 1602static struct tipc_node *tipc_node_find_by_name(struct net *net,
1603 const char *link_name, 1603 const char *link_name,
1604 unsigned int *bearer_id) 1604 unsigned int *bearer_id)
1605{ 1605{
1606 struct tipc_net *tn = net_generic(net, tipc_net_id); 1606 struct tipc_net *tn = net_generic(net, tipc_net_id);
1607 struct tipc_link *l_ptr; 1607 struct tipc_link *l;
1608 struct tipc_node *n_ptr; 1608 struct tipc_node *n;
1609 struct tipc_node *found_node = NULL; 1609 struct tipc_node *found_node = NULL;
1610 int i; 1610 int i;
1611 1611
1612 *bearer_id = 0; 1612 *bearer_id = 0;
1613 rcu_read_lock(); 1613 rcu_read_lock();
1614 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) { 1614 list_for_each_entry_rcu(n, &tn->node_list, list) {
1615 tipc_node_read_lock(n_ptr); 1615 tipc_node_read_lock(n);
1616 for (i = 0; i < MAX_BEARERS; i++) { 1616 for (i = 0; i < MAX_BEARERS; i++) {
1617 l_ptr = n_ptr->links[i].link; 1617 l = n->links[i].link;
1618 if (l_ptr && !strcmp(l_ptr->name, link_name)) { 1618 if (l && !strcmp(tipc_link_name(l), link_name)) {
1619 *bearer_id = i; 1619 *bearer_id = i;
1620 found_node = n_ptr; 1620 found_node = n;
1621 break; 1621 break;
1622 } 1622 }
1623 } 1623 }
1624 tipc_node_read_unlock(n_ptr); 1624 tipc_node_read_unlock(n);
1625 if (found_node) 1625 if (found_node)
1626 break; 1626 break;
1627 } 1627 }
@@ -1658,7 +1658,7 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1658 if (strcmp(name, tipc_bclink_name) == 0) 1658 if (strcmp(name, tipc_bclink_name) == 0)
1659 return tipc_nl_bc_link_set(net, attrs); 1659 return tipc_nl_bc_link_set(net, attrs);
1660 1660
1661 node = tipc_link_find_owner(net, name, &bearer_id); 1661 node = tipc_node_find_by_name(net, name, &bearer_id);
1662 if (!node) 1662 if (!node)
1663 return -EINVAL; 1663 return -EINVAL;
1664 1664
@@ -1684,15 +1684,13 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1684 u32 tol; 1684 u32 tol;
1685 1685
1686 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]); 1686 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1687 link->tolerance = tol; 1687 tipc_link_set_tolerance(link, tol);
1688 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0);
1689 } 1688 }
1690 if (props[TIPC_NLA_PROP_PRIO]) { 1689 if (props[TIPC_NLA_PROP_PRIO]) {
1691 u32 prio; 1690 u32 prio;
1692 1691
1693 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]); 1692 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
1694 link->priority = prio; 1693 tipc_link_set_prio(link, prio);
1695 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, 0, prio);
1696 } 1694 }
1697 if (props[TIPC_NLA_PROP_WIN]) { 1695 if (props[TIPC_NLA_PROP_WIN]) {
1698 u32 win; 1696 u32 win;
@@ -1737,7 +1735,7 @@ int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info)
1737 struct tipc_node *node; 1735 struct tipc_node *node;
1738 struct tipc_link *link; 1736 struct tipc_link *link;
1739 1737
1740 node = tipc_link_find_owner(net, name, &bearer_id); 1738 node = tipc_node_find_by_name(net, name, &bearer_id);
1741 if (!node) 1739 if (!node)
1742 return -EINVAL; 1740 return -EINVAL;
1743 1741
@@ -1792,7 +1790,7 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
1792 return 0; 1790 return 0;
1793 } 1791 }
1794 1792
1795 node = tipc_link_find_owner(net, link_name, &bearer_id); 1793 node = tipc_node_find_by_name(net, link_name, &bearer_id);
1796 if (!node) 1794 if (!node)
1797 return -EINVAL; 1795 return -EINVAL;
1798 1796
@@ -1805,7 +1803,7 @@ int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
1805 tipc_node_read_unlock(node); 1803 tipc_node_read_unlock(node);
1806 return -EINVAL; 1804 return -EINVAL;
1807 } 1805 }
1808 link_reset_statistics(link); 1806 tipc_link_reset_stats(link);
1809 spin_unlock_bh(&le->lock); 1807 spin_unlock_bh(&le->lock);
1810 tipc_node_read_unlock(node); 1808 tipc_node_read_unlock(node);
1811 return 0; 1809 return 0;
@@ -1834,7 +1832,7 @@ static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
1834 return 0; 1832 return 0;
1835} 1833}
1836 1834
1837int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb) 1835int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb)
1838{ 1836{
1839 struct net *net = sock_net(skb->sk); 1837 struct net *net = sock_net(skb->sk);
1840 struct tipc_net *tn = net_generic(net, tipc_net_id); 1838 struct tipc_net *tn = net_generic(net, tipc_net_id);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 1fbed29d9a25..f39d9d06e8bb 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -42,8 +42,6 @@
42#include "bearer.h" 42#include "bearer.h"
43#include "msg.h" 43#include "msg.h"
44 44
45#define INVALID_BEARER_ID -1
46
47/* Optional capabilities supported by this code version 45/* Optional capabilities supported by this code version
48 */ 46 */
49enum { 47enum {
@@ -51,6 +49,7 @@ enum {
51}; 49};
52 50
53#define TIPC_NODE_CAPABILITIES TIPC_BCAST_SYNCH 51#define TIPC_NODE_CAPABILITIES TIPC_BCAST_SYNCH
52#define INVALID_BEARER_ID -1
54 53
55void tipc_node_stop(struct net *net); 54void tipc_node_stop(struct net *net);
56void tipc_node_check_dest(struct net *net, u32 onode, 55void tipc_node_check_dest(struct net *net, u32 onode,
@@ -72,6 +71,7 @@ int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port);
72void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port); 71void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port);
73int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel); 72int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel);
74int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb); 73int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb);
74int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb);
75int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info); 75int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info);
76int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info); 76int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info);
77int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info); 77int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info);