link.c (6278e03dc667b611cc9ebbd8f455d859f18f8e11) | link.c (35c55c9877f8de0ab129fa1a309271d0ecc868b9) |
---|---|
1/* 2 * net/tipc/link.c: TIPC link code 3 * 4 * Copyright (c) 1996-2007, 2012-2016, Ericsson AB 5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 28 unchanged lines hidden (view full) --- 37#include "core.h" 38#include "subscr.h" 39#include "link.h" 40#include "bcast.h" 41#include "socket.h" 42#include "name_distr.h" 43#include "discover.h" 44#include "netlink.h" | 1/* 2 * net/tipc/link.c: TIPC link code 3 * 4 * Copyright (c) 1996-2007, 2012-2016, Ericsson AB 5 * Copyright (c) 2004-2007, 2010-2013, Wind River Systems 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 28 unchanged lines hidden (view full) --- 37#include "core.h" 38#include "subscr.h" 39#include "link.h" 40#include "bcast.h" 41#include "socket.h" 42#include "name_distr.h" 43#include "discover.h" 44#include "netlink.h" |
45#include "monitor.h" |
|
45 46#include <linux/pkt_sched.h> 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; --- 37 unchanged lines hidden (view full) --- 90 * @abort_limit: # of unacknowledged continuity probes needed to reset link 91 * @state: current state of link FSM 92 * @peer_caps: bitmap describing capabilities of peer node 93 * @silent_intv_cnt: # of timer intervals without any reception from peer 94 * @proto_msg: template for control messages generated by link 95 * @pmsg: convenience pointer to "proto_msg" field 96 * @priority: current link priority 97 * @net_plane: current link network plane ('A' through 'H') | 46 47#include <linux/pkt_sched.h> 48 49struct tipc_stats { 50 u32 sent_info; /* used in counting # sent packets */ 51 u32 recv_info; /* used in counting # recv'd packets */ 52 u32 sent_states; 53 u32 recv_states; --- 37 unchanged lines hidden (view full) --- 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 * @mon_state: cookie with information needed by link monitor |
|
98 * @backlog_limit: backlog queue congestion thresholds (indexed by importance) 99 * @exp_msg_count: # of tunnelled messages expected during link changeover 100 * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset 101 * @mtu: current maximum packet size for this link 102 * @advertised_mtu: advertised own mtu when link is being established 103 * @transmitq: queue for sent, non-acked messages 104 * @backlogq: queue for messages waiting to be sent 105 * @snt_nxt: next sequence number to use for outbound messages --- 27 unchanged lines hidden (view full) --- 133 u32 abort_limit; 134 u32 state; 135 u16 peer_caps; 136 bool active; 137 u32 silent_intv_cnt; 138 char if_name[TIPC_MAX_IF_NAME]; 139 u32 priority; 140 char net_plane; | 100 * @backlog_limit: backlog queue congestion thresholds (indexed by importance) 101 * @exp_msg_count: # of tunnelled messages expected during link changeover 102 * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset 103 * @mtu: current maximum packet size for this link 104 * @advertised_mtu: advertised own mtu when link is being established 105 * @transmitq: queue for sent, non-acked messages 106 * @backlogq: queue for messages waiting to be sent 107 * @snt_nxt: next sequence number to use for outbound messages --- 27 unchanged lines hidden (view full) --- 135 u32 abort_limit; 136 u32 state; 137 u16 peer_caps; 138 bool active; 139 u32 silent_intv_cnt; 140 char if_name[TIPC_MAX_IF_NAME]; 141 u32 priority; 142 char net_plane; |
143 struct tipc_mon_state mon_state; |
|
141 u16 rst_cnt; 142 143 /* Failover/synch */ 144 u16 drop_point; 145 struct sk_buff *failover_reasm_skb; 146 147 /* Max packet negotiation */ 148 u16 mtu; --- 554 unchanged lines hidden (view full) --- 703int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) 704{ 705 int mtyp, rc = 0; 706 bool state = false; 707 bool probe = false; 708 bool setup = false; 709 u16 bc_snt = l->bc_sndlink->snd_nxt - 1; 710 u16 bc_acked = l->bc_rcvlink->acked; | 144 u16 rst_cnt; 145 146 /* Failover/synch */ 147 u16 drop_point; 148 struct sk_buff *failover_reasm_skb; 149 150 /* Max packet negotiation */ 151 u16 mtu; --- 554 unchanged lines hidden (view full) --- 706int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq) 707{ 708 int mtyp, rc = 0; 709 bool state = false; 710 bool probe = false; 711 bool setup = false; 712 u16 bc_snt = l->bc_sndlink->snd_nxt - 1; 713 u16 bc_acked = l->bc_rcvlink->acked; |
714 struct tipc_mon_state *mstate = &l->mon_state; |
|
711 | 715 |
712 link_profile_stats(l); 713 | |
714 switch (l->state) { 715 case LINK_ESTABLISHED: 716 case LINK_SYNCHING: | 716 switch (l->state) { 717 case LINK_ESTABLISHED: 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; 722 l->silent_intv_cnt++; | 725 state |= l->bc_rcvlink->rcv_unacked; 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; 724 case LINK_RESET: 725 setup = l->rst_cnt++ <= 4; 726 setup |= !(l->rst_cnt % 16); 727 mtyp = RESET_MSG; 728 break; 729 case LINK_ESTABLISHING: 730 setup = true; --- 94 unchanged lines hidden (view full) --- 825 l->snd_nxt = 1; 826 l->rcv_nxt = 1; 827 l->acked = 0; 828 l->silent_intv_cnt = 0; 829 l->rst_cnt = 0; 830 l->stats.recv_info = 0; 831 l->stale_count = 0; 832 l->bc_peer_is_up = false; | 733 break; 734 case LINK_RESET: 735 setup = l->rst_cnt++ <= 4; 736 setup |= !(l->rst_cnt % 16); 737 mtyp = RESET_MSG; 738 break; 739 case LINK_ESTABLISHING: 740 setup = true; --- 94 unchanged lines hidden (view full) --- 835 l->snd_nxt = 1; 836 l->rcv_nxt = 1; 837 l->acked = 0; 838 l->silent_intv_cnt = 0; 839 l->rst_cnt = 0; 840 l->stats.recv_info = 0; 841 l->stale_count = 0; 842 l->bc_peer_is_up = false; |
843 memset(&l->mon_state, 0, sizeof(l->mon_state)); |
|
833 tipc_link_reset_stats(l); 834} 835 836/** 837 * tipc_link_xmit(): enqueue buffer list according to queue situation 838 * @link: link to use 839 * @list: chain of buffers containing message 840 * @xmitq: returned list of packets to be sent by caller --- 392 unchanged lines hidden (view full) --- 1233static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, 1234 u16 rcvgap, int tolerance, int priority, 1235 struct sk_buff_head *xmitq) 1236{ 1237 struct sk_buff *skb; 1238 struct tipc_msg *hdr; 1239 struct sk_buff_head *dfq = &l->deferdq; 1240 bool node_up = link_is_up(l->bc_rcvlink); | 844 tipc_link_reset_stats(l); 845} 846 847/** 848 * tipc_link_xmit(): enqueue buffer list according to queue situation 849 * @link: link to use 850 * @list: chain of buffers containing message 851 * @xmitq: returned list of packets to be sent by caller --- 392 unchanged lines hidden (view full) --- 1244static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, 1245 u16 rcvgap, int tolerance, int priority, 1246 struct sk_buff_head *xmitq) 1247{ 1248 struct sk_buff *skb; 1249 struct tipc_msg *hdr; 1250 struct sk_buff_head *dfq = &l->deferdq; 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 1242 /* Don't send protocol message during reset or link failover */ 1243 if (tipc_link_is_blocked(l)) 1244 return; 1245 1246 if (!tipc_link_is_up(l) && (mtyp == STATE_MSG)) 1247 return; 1248 1249 if (!skb_queue_empty(dfq)) 1250 rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt; 1251 1252 skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE, | 1255 1256 /* Don't send protocol message during reset or link failover */ 1257 if (tipc_link_is_blocked(l)) 1258 return; 1259 1260 if (!tipc_link_is_up(l) && (mtyp == STATE_MSG)) 1261 return; 1262 1263 if (!skb_queue_empty(dfq)) 1264 rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt; 1265 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); 1255 if (!skb) 1256 return; 1257 1258 hdr = buf_msg(skb); | 1268 tipc_own_addr(l->net), 0, 0, 0); 1269 if (!skb) 1270 return; 1271 1272 hdr = buf_msg(skb); |
1273 data = msg_data(hdr); |
|
1259 msg_set_session(hdr, l->session); 1260 msg_set_bearer_id(hdr, l->bearer_id); 1261 msg_set_net_plane(hdr, l->net_plane); 1262 msg_set_next_sent(hdr, l->snd_nxt); 1263 msg_set_ack(hdr, l->rcv_nxt - 1); 1264 msg_set_bcast_ack(hdr, l->bc_rcvlink->rcv_nxt - 1); 1265 msg_set_last_bcast(hdr, l->bc_sndlink->snd_nxt - 1); 1266 msg_set_link_tolerance(hdr, tolerance); 1267 msg_set_linkprio(hdr, priority); 1268 msg_set_redundant_link(hdr, node_up); 1269 msg_set_seq_gap(hdr, 0); 1270 msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2); 1271 1272 if (mtyp == STATE_MSG) { 1273 msg_set_seq_gap(hdr, rcvgap); | 1274 msg_set_session(hdr, l->session); 1275 msg_set_bearer_id(hdr, l->bearer_id); 1276 msg_set_net_plane(hdr, l->net_plane); 1277 msg_set_next_sent(hdr, l->snd_nxt); 1278 msg_set_ack(hdr, l->rcv_nxt - 1); 1279 msg_set_bcast_ack(hdr, l->bc_rcvlink->rcv_nxt - 1); 1280 msg_set_last_bcast(hdr, l->bc_sndlink->snd_nxt - 1); 1281 msg_set_link_tolerance(hdr, tolerance); 1282 msg_set_linkprio(hdr, priority); 1283 msg_set_redundant_link(hdr, node_up); 1284 msg_set_seq_gap(hdr, 0); 1285 msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2); 1286 1287 if (mtyp == STATE_MSG) { 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++; 1277 l->rcv_unacked = 0; 1278 } else { 1279 /* RESET_MSG or ACTIVATE_MSG */ 1280 msg_set_max_pkt(hdr, l->advertised_mtu); | 1293 l->stats.sent_states++; 1294 l->rcv_unacked = 0; 1295 } else { 1296 /* RESET_MSG or ACTIVATE_MSG */ 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 } 1283 if (probe) 1284 l->stats.sent_probes++; 1285 if (rcvgap) 1286 l->stats.sent_nacks++; 1287 skb->priority = TC_PRIO_CONTROL; 1288 __skb_queue_tail(xmitq, skb); 1289} --- 76 unchanged lines hidden (view full) --- 1366 struct tipc_msg *hdr = buf_msg(skb); 1367 u16 rcvgap = 0; 1368 u16 ack = msg_ack(hdr); 1369 u16 gap = msg_seq_gap(hdr); 1370 u16 peers_snd_nxt = msg_next_sent(hdr); 1371 u16 peers_tol = msg_link_tolerance(hdr); 1372 u16 peers_prio = msg_linkprio(hdr); 1373 u16 rcv_nxt = l->rcv_nxt; | 1301 } 1302 if (probe) 1303 l->stats.sent_probes++; 1304 if (rcvgap) 1305 l->stats.sent_nacks++; 1306 skb->priority = TC_PRIO_CONTROL; 1307 __skb_queue_tail(xmitq, skb); 1308} --- 76 unchanged lines hidden (view full) --- 1385 struct tipc_msg *hdr = buf_msg(skb); 1386 u16 rcvgap = 0; 1387 u16 ack = msg_ack(hdr); 1388 u16 gap = msg_seq_gap(hdr); 1389 u16 peers_snd_nxt = msg_next_sent(hdr); 1390 u16 peers_tol = msg_link_tolerance(hdr); 1391 u16 peers_prio = msg_linkprio(hdr); 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; 1376 int rc = 0; 1377 1378 if (tipc_link_is_blocked(l) || !xmitq) 1379 goto exit; 1380 1381 if (tipc_own_addr(l->net) > msg_prevnode(hdr)) 1382 l->net_plane = msg_net_plane(hdr); 1383 | 1396 char *if_name; 1397 int rc = 0; 1398 1399 if (tipc_link_is_blocked(l) || !xmitq) 1400 goto exit; 1401 1402 if (tipc_own_addr(l->net) > msg_prevnode(hdr)) 1403 l->net_plane = msg_net_plane(hdr); 1404 |
1405 skb_linearize(skb); 1406 hdr = buf_msg(skb); 1407 data = msg_data(hdr); 1408 |
|
1384 switch (mtyp) { 1385 case RESET_MSG: 1386 1387 /* Ignore duplicate RESET with old session number */ 1388 if ((less_eq(msg_session(hdr), l->peer_session)) && 1389 (l->peer_session != ANY_SESSION)) 1390 break; 1391 /* fall thru' */ 1392 1393 case ACTIVATE_MSG: | 1409 switch (mtyp) { 1410 case RESET_MSG: 1411 1412 /* Ignore duplicate RESET with old session number */ 1413 if ((less_eq(msg_session(hdr), l->peer_session)) && 1414 (l->peer_session != ANY_SESSION)) 1415 break; 1416 /* fall thru' */ 1417 1418 case ACTIVATE_MSG: |
1394 skb_linearize(skb); 1395 hdr = buf_msg(skb); | |
1396 1397 /* Complete own link name with peer's interface name */ 1398 if_name = strrchr(l->name, ':') + 1; 1399 if (sizeof(l->name) - (if_name - l->name) <= TIPC_MAX_IF_NAME) 1400 break; 1401 if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME) 1402 break; | 1419 1420 /* Complete own link name with peer's interface name */ 1421 if_name = strrchr(l->name, ':') + 1; 1422 if (sizeof(l->name) - (if_name - l->name) <= TIPC_MAX_IF_NAME) 1423 break; 1424 if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME) 1425 break; |
1403 strncpy(if_name, msg_data(hdr), TIPC_MAX_IF_NAME); | 1426 strncpy(if_name, data, TIPC_MAX_IF_NAME); |
1404 1405 /* Update own tolerance if peer indicates a non-zero value */ 1406 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) 1407 l->tolerance = peers_tol; 1408 1409 /* Update own priority if peer's priority is higher */ 1410 if (in_range(peers_prio, l->priority + 1, TIPC_MAX_LINK_PRI)) 1411 l->priority = peers_prio; --- 31 unchanged lines hidden (view full) --- 1443 if (msg_probe(hdr)) 1444 l->stats.recv_probes++; 1445 1446 if (!link_is_up(l)) { 1447 if (l->state == LINK_ESTABLISHING) 1448 rc = TIPC_LINK_UP_EVT; 1449 break; 1450 } | 1427 1428 /* Update own tolerance if peer indicates a non-zero value */ 1429 if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) 1430 l->tolerance = peers_tol; 1431 1432 /* Update own priority if peer's priority is higher */ 1433 if (in_range(peers_prio, l->priority + 1, TIPC_MAX_LINK_PRI)) 1434 l->priority = peers_prio; --- 31 unchanged lines hidden (view full) --- 1466 if (msg_probe(hdr)) 1467 l->stats.recv_probes++; 1468 1469 if (!link_is_up(l)) { 1470 if (l->state == LINK_ESTABLISHING) 1471 rc = TIPC_LINK_UP_EVT; 1472 break; 1473 } |
1474 tipc_mon_rcv(l->net, data, dlen, l->addr, 1475 &l->mon_state, l->bearer_id); |
|
1451 1452 /* 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)) 1454 rcvgap = peers_snd_nxt - l->rcv_nxt; 1455 if (rcvgap || (msg_probe(hdr))) 1456 tipc_link_build_proto_msg(l, STATE_MSG, 0, rcvgap, 1457 0, 0, xmitq); 1458 tipc_link_release_pkts(l, ack); --- 544 unchanged lines hidden --- | 1476 1477 /* Send NACK if peer has sent pkts we haven't received yet */ 1478 if (more(peers_snd_nxt, rcv_nxt) && !tipc_link_is_synching(l)) 1479 rcvgap = peers_snd_nxt - l->rcv_nxt; 1480 if (rcvgap || (msg_probe(hdr))) 1481 tipc_link_build_proto_msg(l, STATE_MSG, 0, rcvgap, 1482 0, 0, xmitq); 1483 tipc_link_release_pkts(l, ack); --- 544 unchanged lines hidden --- |