aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 67b6ab9f4c8d..c1df33f878b2 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -42,6 +42,7 @@
42#include "name_distr.h" 42#include "name_distr.h"
43#include "discover.h" 43#include "discover.h"
44#include "netlink.h" 44#include "netlink.h"
45#include "monitor.h"
45 46
46#include <linux/pkt_sched.h> 47#include <linux/pkt_sched.h>
47 48
@@ -87,7 +88,6 @@ struct tipc_stats {
87 * @peer_bearer_id: bearer id used by link's peer endpoint 88 * @peer_bearer_id: bearer id used by link's peer endpoint
88 * @bearer_id: local bearer id used by link 89 * @bearer_id: local bearer id used by link
89 * @tolerance: minimum link continuity loss needed to reset link [in ms] 90 * @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 91 * @abort_limit: # of unacknowledged continuity probes needed to reset link
92 * @state: current state of link FSM 92 * @state: current state of link FSM
93 * @peer_caps: bitmap describing capabilities of peer node 93 * @peer_caps: bitmap describing capabilities of peer node
@@ -96,6 +96,7 @@ struct tipc_stats {
96 * @pmsg: convenience pointer to "proto_msg" field 96 * @pmsg: convenience pointer to "proto_msg" field
97 * @priority: current link priority 97 * @priority: current link priority
98 * @net_plane: current link network plane ('A' through 'H') 98 * @net_plane: current link network plane ('A' through 'H')
99 * @mon_state: cookie with information needed by link monitor
99 * @backlog_limit: backlog queue congestion thresholds (indexed by importance) 100 * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
100 * @exp_msg_count: # of tunnelled messages expected during link changeover 101 * @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 * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset
@@ -131,7 +132,6 @@ struct tipc_link {
131 u32 peer_bearer_id; 132 u32 peer_bearer_id;
132 u32 bearer_id; 133 u32 bearer_id;
133 u32 tolerance; 134 u32 tolerance;
134 unsigned long keepalive_intv;
135 u32 abort_limit; 135 u32 abort_limit;
136 u32 state; 136 u32 state;
137 u16 peer_caps; 137 u16 peer_caps;
@@ -140,6 +140,7 @@ struct tipc_link {
140 char if_name[TIPC_MAX_IF_NAME]; 140 char if_name[TIPC_MAX_IF_NAME];
141 u32 priority; 141 u32 priority;
142 char net_plane; 142 char net_plane;
143 struct tipc_mon_state mon_state;
143 u16 rst_cnt; 144 u16 rst_cnt;
144 145
145 /* Failover/synch */ 146 /* Failover/synch */
@@ -711,18 +712,25 @@ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
711 bool setup = false; 712 bool setup = false;
712 u16 bc_snt = l->bc_sndlink->snd_nxt - 1; 713 u16 bc_snt = l->bc_sndlink->snd_nxt - 1;
713 u16 bc_acked = l->bc_rcvlink->acked; 714 u16 bc_acked = l->bc_rcvlink->acked;
714 715 struct tipc_mon_state *mstate = &l->mon_state;
715 link_profile_stats(l);
716 716
717 switch (l->state) { 717 switch (l->state) {
718 case LINK_ESTABLISHED: 718 case LINK_ESTABLISHED:
719 case LINK_SYNCHING: 719 case LINK_SYNCHING:
720 if (l->silent_intv_cnt > l->abort_limit)
721 return tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
722 mtyp = STATE_MSG; 720 mtyp = STATE_MSG;
721 link_profile_stats(l);
722 tipc_mon_get_state(l->net, l->addr, mstate, l->bearer_id);
723 if (mstate->reset || (l->silent_intv_cnt > l->abort_limit))
724 return tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
723 state = bc_acked != bc_snt; 725 state = bc_acked != bc_snt;
724 probe = l->silent_intv_cnt; 726 state |= l->bc_rcvlink->rcv_unacked;
725 l->silent_intv_cnt++; 727 state |= l->rcv_unacked;
728 state |= !skb_queue_empty(&l->transmq);
729 state |= !skb_queue_empty(&l->deferdq);
730 probe = mstate->probing;
731 probe |= l->silent_intv_cnt;
732 if (probe || mstate->monitoring)
733 l->silent_intv_cnt++;
726 break; 734 break;
727 case LINK_RESET: 735 case LINK_RESET:
728 setup = l->rst_cnt++ <= 4; 736 setup = l->rst_cnt++ <= 4;
@@ -833,6 +841,7 @@ void tipc_link_reset(struct tipc_link *l)
833 l->stats.recv_info = 0; 841 l->stats.recv_info = 0;
834 l->stale_count = 0; 842 l->stale_count = 0;
835 l->bc_peer_is_up = false; 843 l->bc_peer_is_up = false;
844 memset(&l->mon_state, 0, sizeof(l->mon_state));
836 tipc_link_reset_stats(l); 845 tipc_link_reset_stats(l);
837} 846}
838 847
@@ -1241,6 +1250,9 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1241 struct tipc_msg *hdr; 1250 struct tipc_msg *hdr;
1242 struct sk_buff_head *dfq = &l->deferdq; 1251 struct sk_buff_head *dfq = &l->deferdq;
1243 bool node_up = link_is_up(l->bc_rcvlink); 1252 bool node_up = link_is_up(l->bc_rcvlink);
1253 struct tipc_mon_state *mstate = &l->mon_state;
1254 int dlen = 0;
1255 void *data;
1244 1256
1245 /* Don't send protocol message during reset or link failover */ 1257 /* Don't send protocol message during reset or link failover */
1246 if (tipc_link_is_blocked(l)) 1258 if (tipc_link_is_blocked(l))
@@ -1253,12 +1265,13 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1253 rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt; 1265 rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt;
1254 1266
1255 skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE, 1267 skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE,
1256 TIPC_MAX_IF_NAME, l->addr, 1268 tipc_max_domain_size, l->addr,
1257 tipc_own_addr(l->net), 0, 0, 0); 1269 tipc_own_addr(l->net), 0, 0, 0);
1258 if (!skb) 1270 if (!skb)
1259 return; 1271 return;
1260 1272
1261 hdr = buf_msg(skb); 1273 hdr = buf_msg(skb);
1274 data = msg_data(hdr);
1262 msg_set_session(hdr, l->session); 1275 msg_set_session(hdr, l->session);
1263 msg_set_bearer_id(hdr, l->bearer_id); 1276 msg_set_bearer_id(hdr, l->bearer_id);
1264 msg_set_net_plane(hdr, l->net_plane); 1277 msg_set_net_plane(hdr, l->net_plane);
@@ -1274,14 +1287,18 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
1274 1287
1275 if (mtyp == STATE_MSG) { 1288 if (mtyp == STATE_MSG) {
1276 msg_set_seq_gap(hdr, rcvgap); 1289 msg_set_seq_gap(hdr, rcvgap);
1277 msg_set_size(hdr, INT_H_SIZE);
1278 msg_set_probe(hdr, probe); 1290 msg_set_probe(hdr, probe);
1291 tipc_mon_prep(l->net, data, &dlen, mstate, l->bearer_id);
1292 msg_set_size(hdr, INT_H_SIZE + dlen);
1293 skb_trim(skb, INT_H_SIZE + dlen);
1279 l->stats.sent_states++; 1294 l->stats.sent_states++;
1280 l->rcv_unacked = 0; 1295 l->rcv_unacked = 0;
1281 } else { 1296 } else {
1282 /* RESET_MSG or ACTIVATE_MSG */ 1297 /* RESET_MSG or ACTIVATE_MSG */
1283 msg_set_max_pkt(hdr, l->advertised_mtu); 1298 msg_set_max_pkt(hdr, l->advertised_mtu);
1284 strcpy(msg_data(hdr), l->if_name); 1299 strcpy(data, l->if_name);
1300 msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME);
1301 skb_trim(skb, INT_H_SIZE + TIPC_MAX_IF_NAME);
1285 } 1302 }
1286 if (probe) 1303 if (probe)
1287 l->stats.sent_probes++; 1304 l->stats.sent_probes++;
@@ -1374,7 +1391,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1374 u16 peers_tol = msg_link_tolerance(hdr); 1391 u16 peers_tol = msg_link_tolerance(hdr);
1375 u16 peers_prio = msg_linkprio(hdr); 1392 u16 peers_prio = msg_linkprio(hdr);
1376 u16 rcv_nxt = l->rcv_nxt; 1393 u16 rcv_nxt = l->rcv_nxt;
1394 u16 dlen = msg_data_sz(hdr);
1377 int mtyp = msg_type(hdr); 1395 int mtyp = msg_type(hdr);
1396 void *data;
1378 char *if_name; 1397 char *if_name;
1379 int rc = 0; 1398 int rc = 0;
1380 1399
@@ -1384,6 +1403,10 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1384 if (tipc_own_addr(l->net) > msg_prevnode(hdr)) 1403 if (tipc_own_addr(l->net) > msg_prevnode(hdr))
1385 l->net_plane = msg_net_plane(hdr); 1404 l->net_plane = msg_net_plane(hdr);
1386 1405
1406 skb_linearize(skb);
1407 hdr = buf_msg(skb);
1408 data = msg_data(hdr);
1409
1387 switch (mtyp) { 1410 switch (mtyp) {
1388 case RESET_MSG: 1411 case RESET_MSG:
1389 1412
@@ -1394,8 +1417,6 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1394 /* fall thru' */ 1417 /* fall thru' */
1395 1418
1396 case ACTIVATE_MSG: 1419 case ACTIVATE_MSG:
1397 skb_linearize(skb);
1398 hdr = buf_msg(skb);
1399 1420
1400 /* Complete own link name with peer's interface name */ 1421 /* Complete own link name with peer's interface name */
1401 if_name = strrchr(l->name, ':') + 1; 1422 if_name = strrchr(l->name, ':') + 1;
@@ -1403,7 +1424,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1403 break; 1424 break;
1404 if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME) 1425 if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME)
1405 break; 1426 break;
1406 strncpy(if_name, msg_data(hdr), TIPC_MAX_IF_NAME); 1427 strncpy(if_name, data, TIPC_MAX_IF_NAME);
1407 1428
1408 /* Update own tolerance if peer indicates a non-zero value */ 1429 /* Update own tolerance if peer indicates a non-zero value */
1409 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) 1430 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL))
@@ -1451,6 +1472,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
1451 rc = TIPC_LINK_UP_EVT; 1472 rc = TIPC_LINK_UP_EVT;
1452 break; 1473 break;
1453 } 1474 }
1475 tipc_mon_rcv(l->net, data, dlen, l->addr,
1476 &l->mon_state, l->bearer_id);
1454 1477
1455 /* Send NACK if peer has sent pkts we haven't received yet */ 1478 /* Send NACK if peer has sent pkts we haven't received yet */
1456 if (more(peers_snd_nxt, rcv_nxt) && !tipc_link_is_synching(l)) 1479 if (more(peers_snd_nxt, rcv_nxt) && !tipc_link_is_synching(l))