diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 51 |
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)) |