diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a904ccd5a93a..03f8bdf70d8f 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 | ||
@@ -95,6 +96,7 @@ struct tipc_stats { | |||
95 | * @pmsg: convenience pointer to "proto_msg" field | 96 | * @pmsg: convenience pointer to "proto_msg" field |
96 | * @priority: current link priority | 97 | * @priority: current link priority |
97 | * @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 | ||
98 | * @backlog_limit: backlog queue congestion thresholds (indexed by importance) | 100 | * @backlog_limit: backlog queue congestion thresholds (indexed by importance) |
99 | * @exp_msg_count: # of tunnelled messages expected during link changeover | 101 | * @exp_msg_count: # of tunnelled messages expected during link changeover |
100 | * @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 |
@@ -138,6 +140,7 @@ struct tipc_link { | |||
138 | char if_name[TIPC_MAX_IF_NAME]; | 140 | char if_name[TIPC_MAX_IF_NAME]; |
139 | u32 priority; | 141 | u32 priority; |
140 | char net_plane; | 142 | char net_plane; |
143 | struct tipc_mon_state mon_state; | ||
141 | u16 rst_cnt; | 144 | u16 rst_cnt; |
142 | 145 | ||
143 | /* Failover/synch */ | 146 | /* Failover/synch */ |
@@ -708,18 +711,25 @@ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) | |||
708 | bool setup = false; | 711 | bool setup = false; |
709 | u16 bc_snt = l->bc_sndlink->snd_nxt - 1; | 712 | u16 bc_snt = l->bc_sndlink->snd_nxt - 1; |
710 | u16 bc_acked = l->bc_rcvlink->acked; | 713 | u16 bc_acked = l->bc_rcvlink->acked; |
711 | 714 | struct tipc_mon_state *mstate = &l->mon_state; | |
712 | link_profile_stats(l); | ||
713 | 715 | ||
714 | switch (l->state) { | 716 | switch (l->state) { |
715 | case LINK_ESTABLISHED: | 717 | case LINK_ESTABLISHED: |
716 | case LINK_SYNCHING: | 718 | case LINK_SYNCHING: |
717 | if (l->silent_intv_cnt > l->abort_limit) | ||
718 | return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); | ||
719 | mtyp = STATE_MSG; | 719 | mtyp = STATE_MSG; |
720 | link_profile_stats(l); | ||
721 | tipc_mon_get_state(l->net, l->addr, mstate, l->bearer_id); | ||
722 | if (mstate->reset || (l->silent_intv_cnt > l->abort_limit)) | ||
723 | return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); | ||
720 | state = bc_acked != bc_snt; | 724 | state = bc_acked != bc_snt; |
721 | probe = l->silent_intv_cnt; | 725 | state |= l->bc_rcvlink->rcv_unacked; |
722 | l->silent_intv_cnt++; | 726 | state |= l->rcv_unacked; |
727 | state |= !skb_queue_empty(&l->transmq); | ||
728 | state |= !skb_queue_empty(&l->deferdq); | ||
729 | probe = mstate->probing; | ||
730 | probe |= l->silent_intv_cnt; | ||
731 | if (probe || mstate->monitoring) | ||
732 | l->silent_intv_cnt++; | ||
723 | break; | 733 | break; |
724 | case LINK_RESET: | 734 | case LINK_RESET: |
725 | setup = l->rst_cnt++ <= 4; | 735 | setup = l->rst_cnt++ <= 4; |
@@ -830,6 +840,7 @@ void tipc_link_reset(struct tipc_link *l) | |||
830 | l->stats.recv_info = 0; | 840 | l->stats.recv_info = 0; |
831 | l->stale_count = 0; | 841 | l->stale_count = 0; |
832 | l->bc_peer_is_up = false; | 842 | l->bc_peer_is_up = false; |
843 | memset(&l->mon_state, 0, sizeof(l->mon_state)); | ||
833 | tipc_link_reset_stats(l); | 844 | tipc_link_reset_stats(l); |
834 | } | 845 | } |
835 | 846 | ||
@@ -1238,6 +1249,9 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, | |||
1238 | struct tipc_msg *hdr; | 1249 | struct tipc_msg *hdr; |
1239 | struct sk_buff_head *dfq = &l->deferdq; | 1250 | struct sk_buff_head *dfq = &l->deferdq; |
1240 | bool node_up = link_is_up(l->bc_rcvlink); | 1251 | bool node_up = link_is_up(l->bc_rcvlink); |
1252 | struct tipc_mon_state *mstate = &l->mon_state; | ||
1253 | int dlen = 0; | ||
1254 | void *data; | ||
1241 | 1255 | ||
1242 | /* Don't send protocol message during reset or link failover */ | 1256 | /* Don't send protocol message during reset or link failover */ |
1243 | if (tipc_link_is_blocked(l)) | 1257 | if (tipc_link_is_blocked(l)) |
@@ -1250,12 +1264,13 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, | |||
1250 | rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt; | 1264 | rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt; |
1251 | 1265 | ||
1252 | skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE, | 1266 | skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE, |
1253 | TIPC_MAX_IF_NAME, l->addr, | 1267 | tipc_max_domain_size, l->addr, |
1254 | tipc_own_addr(l->net), 0, 0, 0); | 1268 | tipc_own_addr(l->net), 0, 0, 0); |
1255 | if (!skb) | 1269 | if (!skb) |
1256 | return; | 1270 | return; |
1257 | 1271 | ||
1258 | hdr = buf_msg(skb); | 1272 | hdr = buf_msg(skb); |
1273 | data = msg_data(hdr); | ||
1259 | msg_set_session(hdr, l->session); | 1274 | msg_set_session(hdr, l->session); |
1260 | msg_set_bearer_id(hdr, l->bearer_id); | 1275 | msg_set_bearer_id(hdr, l->bearer_id); |
1261 | msg_set_net_plane(hdr, l->net_plane); | 1276 | msg_set_net_plane(hdr, l->net_plane); |
@@ -1271,14 +1286,18 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, | |||
1271 | 1286 | ||
1272 | if (mtyp == STATE_MSG) { | 1287 | if (mtyp == STATE_MSG) { |
1273 | msg_set_seq_gap(hdr, rcvgap); | 1288 | msg_set_seq_gap(hdr, rcvgap); |
1274 | msg_set_size(hdr, INT_H_SIZE); | ||
1275 | msg_set_probe(hdr, probe); | 1289 | msg_set_probe(hdr, probe); |
1290 | tipc_mon_prep(l->net, data, &dlen, mstate, l->bearer_id); | ||
1291 | msg_set_size(hdr, INT_H_SIZE + dlen); | ||
1292 | skb_trim(skb, INT_H_SIZE + dlen); | ||
1276 | l->stats.sent_states++; | 1293 | l->stats.sent_states++; |
1277 | l->rcv_unacked = 0; | 1294 | l->rcv_unacked = 0; |
1278 | } else { | 1295 | } else { |
1279 | /* RESET_MSG or ACTIVATE_MSG */ | 1296 | /* RESET_MSG or ACTIVATE_MSG */ |
1280 | msg_set_max_pkt(hdr, l->advertised_mtu); | 1297 | msg_set_max_pkt(hdr, l->advertised_mtu); |
1281 | strcpy(msg_data(hdr), l->if_name); | 1298 | strcpy(data, l->if_name); |
1299 | msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME); | ||
1300 | skb_trim(skb, INT_H_SIZE + TIPC_MAX_IF_NAME); | ||
1282 | } | 1301 | } |
1283 | if (probe) | 1302 | if (probe) |
1284 | l->stats.sent_probes++; | 1303 | l->stats.sent_probes++; |
@@ -1371,7 +1390,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1371 | u16 peers_tol = msg_link_tolerance(hdr); | 1390 | u16 peers_tol = msg_link_tolerance(hdr); |
1372 | u16 peers_prio = msg_linkprio(hdr); | 1391 | u16 peers_prio = msg_linkprio(hdr); |
1373 | u16 rcv_nxt = l->rcv_nxt; | 1392 | u16 rcv_nxt = l->rcv_nxt; |
1393 | u16 dlen = msg_data_sz(hdr); | ||
1374 | int mtyp = msg_type(hdr); | 1394 | int mtyp = msg_type(hdr); |
1395 | void *data; | ||
1375 | char *if_name; | 1396 | char *if_name; |
1376 | int rc = 0; | 1397 | int rc = 0; |
1377 | 1398 | ||
@@ -1381,6 +1402,10 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1381 | if (tipc_own_addr(l->net) > msg_prevnode(hdr)) | 1402 | if (tipc_own_addr(l->net) > msg_prevnode(hdr)) |
1382 | l->net_plane = msg_net_plane(hdr); | 1403 | l->net_plane = msg_net_plane(hdr); |
1383 | 1404 | ||
1405 | skb_linearize(skb); | ||
1406 | hdr = buf_msg(skb); | ||
1407 | data = msg_data(hdr); | ||
1408 | |||
1384 | switch (mtyp) { | 1409 | switch (mtyp) { |
1385 | case RESET_MSG: | 1410 | case RESET_MSG: |
1386 | 1411 | ||
@@ -1391,8 +1416,6 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1391 | /* fall thru' */ | 1416 | /* fall thru' */ |
1392 | 1417 | ||
1393 | case ACTIVATE_MSG: | 1418 | case ACTIVATE_MSG: |
1394 | skb_linearize(skb); | ||
1395 | hdr = buf_msg(skb); | ||
1396 | 1419 | ||
1397 | /* Complete own link name with peer's interface name */ | 1420 | /* Complete own link name with peer's interface name */ |
1398 | if_name = strrchr(l->name, ':') + 1; | 1421 | if_name = strrchr(l->name, ':') + 1; |
@@ -1400,7 +1423,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1400 | break; | 1423 | break; |
1401 | if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME) | 1424 | if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME) |
1402 | break; | 1425 | break; |
1403 | strncpy(if_name, msg_data(hdr), TIPC_MAX_IF_NAME); | 1426 | strncpy(if_name, data, TIPC_MAX_IF_NAME); |
1404 | 1427 | ||
1405 | /* Update own tolerance if peer indicates a non-zero value */ | 1428 | /* Update own tolerance if peer indicates a non-zero value */ |
1406 | if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) | 1429 | if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) |
@@ -1448,6 +1471,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1448 | rc = TIPC_LINK_UP_EVT; | 1471 | rc = TIPC_LINK_UP_EVT; |
1449 | break; | 1472 | break; |
1450 | } | 1473 | } |
1474 | tipc_mon_rcv(l->net, data, dlen, l->addr, | ||
1475 | &l->mon_state, l->bearer_id); | ||
1451 | 1476 | ||
1452 | /* Send NACK if peer has sent pkts we haven't received yet */ | 1477 | /* Send NACK if peer has sent pkts we haven't received yet */ |
1453 | if (more(peers_snd_nxt, rcv_nxt) && !tipc_link_is_synching(l)) | 1478 | if (more(peers_snd_nxt, rcv_nxt) && !tipc_link_is_synching(l)) |