aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-11-19 14:30:46 -0500
committerDavid S. Miller <davem@davemloft.net>2015-11-20 14:06:10 -0500
commit38206d5939068415c413ac253be6f364d06e672f (patch)
tree0325222bc72ed1ae0039ccb3f7d8300342b6dff9 /net/tipc
parent5be9c086715c10fb9ae3ffc0ef580dc3a165f98a (diff)
tipc: narrow down interface towards struct tipc_link
We move the definition of struct tipc_link from link.h to link.c in order to minimize its exposure to the rest of the code. When needed, we define new functions to make it possible for external entities to access and set data in the link. Apart from the above, there are no functional changes. Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
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);