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 ---