aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 03:40:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 03:40:34 -0500
commit42a2d923cc349583ebf6fdd52a7d35e1c2f7e6bd (patch)
tree2b2b0c03b5389c1301800119333967efafd994ca /net/tipc/link.c
parent5cbb3d216e2041700231bcfc383ee5f8b7fc8b74 (diff)
parent75ecab1df14d90e86cebef9ec5c76befde46e65f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) The addition of nftables. No longer will we need protocol aware firewall filtering modules, it can all live in userspace. At the core of nftables is a, for lack of a better term, virtual machine that executes byte codes to inspect packet or metadata (arriving interface index, etc.) and make verdict decisions. Besides support for loading packet contents and comparing them, the interpreter supports lookups in various datastructures as fundamental operations. For example sets are supports, and therefore one could create a set of whitelist IP address entries which have ACCEPT verdicts attached to them, and use the appropriate byte codes to do such lookups. Since the interpreted code is composed in userspace, userspace can do things like optimize things before giving it to the kernel. Another major improvement is the capability of atomically updating portions of the ruleset. In the existing netfilter implementation, one has to update the entire rule set in order to make a change and this is very expensive. Userspace tools exist to create nftables rules using existing netfilter rule sets, but both kernel implementations will need to co-exist for quite some time as we transition from the old to the new stuff. Kudos to Patrick McHardy, Pablo Neira Ayuso, and others who have worked so hard on this. 2) Daniel Borkmann and Hannes Frederic Sowa made several improvements to our pseudo-random number generator, mostly used for things like UDP port randomization and netfitler, amongst other things. In particular the taus88 generater is updated to taus113, and test cases are added. 3) Support 64-bit rates in HTB and TBF schedulers, from Eric Dumazet and Yang Yingliang. 4) Add support for new 577xx tigon3 chips to tg3 driver, from Nithin Sujir. 5) Fix two fatal flaws in TCP dynamic right sizing, from Eric Dumazet, Neal Cardwell, and Yuchung Cheng. 6) Allow IP_TOS and IP_TTL to be specified in sendmsg() ancillary control message data, much like other socket option attributes. From Francesco Fusco. 7) Allow applications to specify a cap on the rate computed automatically by the kernel for pacing flows, via a new SO_MAX_PACING_RATE socket option. From Eric Dumazet. 8) Make the initial autotuned send buffer sizing in TCP more closely reflect actual needs, from Eric Dumazet. 9) Currently early socket demux only happens for TCP sockets, but we can do it for connected UDP sockets too. Implementation from Shawn Bohrer. 10) Refactor inet socket demux with the goal of improving hash demux performance for listening sockets. With the main goals being able to use RCU lookups on even request sockets, and eliminating the listening lock contention. From Eric Dumazet. 11) The bonding layer has many demuxes in it's fast path, and an RCU conversion was started back in 3.11, several changes here extend the RCU usage to even more locations. From Ding Tianhong and Wang Yufen, based upon suggestions by Nikolay Aleksandrov and Veaceslav Falico. 12) Allow stackability of segmentation offloads to, in particular, allow segmentation offloading over tunnels. From Eric Dumazet. 13) Significantly improve the handling of secret keys we input into the various hash functions in the inet hashtables, TCP fast open, as well as syncookies. From Hannes Frederic Sowa. The key fundamental operation is "net_get_random_once()" which uses static keys. Hannes even extended this to ipv4/ipv6 fragmentation handling and our generic flow dissector. 14) The generic driver layer takes care now to set the driver data to NULL on device removal, so it's no longer necessary for drivers to explicitly set it to NULL any more. Many drivers have been cleaned up in this way, from Jingoo Han. 15) Add a BPF based packet scheduler classifier, from Daniel Borkmann. 16) Improve CRC32 interfaces and generic SKB checksum iterators so that SCTP's checksumming can more cleanly be handled. Also from Daniel Borkmann. 17) Add a new PMTU discovery mode, IP_PMTUDISC_INTERFACE, which forces using the interface MTU value. This helps avoid PMTU attacks, particularly on DNS servers. From Hannes Frederic Sowa. 18) Use generic XPS for transmit queue steering rather than internal (re-)implementation in virtio-net. From Jason Wang. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1622 commits) random32: add test cases for taus113 implementation random32: upgrade taus88 generator to taus113 from errata paper random32: move rnd_state to linux/random.h random32: add prandom_reseed_late() and call when nonblocking pool becomes initialized random32: add periodic reseeding random32: fix off-by-one in seeding requirement PHY: Add RTL8201CP phy_driver to realtek xtsonic: add missing platform_set_drvdata() in xtsonic_probe() macmace: add missing platform_set_drvdata() in mace_probe() ethernet/arc/arc_emac: add missing platform_set_drvdata() in arc_emac_probe() ipv6: protect for_each_sk_fl_rcu in mem_check with rcu_read_lock_bh vlan: Implement vlan_dev_get_egress_qos_mask as an inline. ixgbe: add warning when max_vfs is out of range. igb: Update link modes display in ethtool netfilter: push reasm skb through instead of original frag skbs ip6_output: fragment outgoing reassembled skb properly MAINTAINERS: mv643xx_eth: take over maintainership from Lennart net_sched: tbf: support of 64bit rates ixgbe: deleting dfwd stations out of order can cause null ptr deref ixgbe: fix build err, num_rx_queues is only available with CONFIG_RPS ...
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c492
1 files changed, 169 insertions, 323 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0cc3d9015c5d..cf465d66ccde 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -75,20 +75,6 @@ static const char *link_unk_evt = "Unknown link event ";
75 */ 75 */
76#define START_CHANGEOVER 100000u 76#define START_CHANGEOVER 100000u
77 77
78/**
79 * struct tipc_link_name - deconstructed link name
80 * @addr_local: network address of node at this end
81 * @if_local: name of interface at this end
82 * @addr_peer: network address of node at far end
83 * @if_peer: name of interface at far end
84 */
85struct tipc_link_name {
86 u32 addr_local;
87 char if_local[TIPC_MAX_IF_NAME];
88 u32 addr_peer;
89 char if_peer[TIPC_MAX_IF_NAME];
90};
91
92static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, 78static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
93 struct sk_buff *buf); 79 struct sk_buff *buf);
94static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf); 80static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
@@ -97,8 +83,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
97static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance); 83static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
98static int link_send_sections_long(struct tipc_port *sender, 84static int link_send_sections_long(struct tipc_port *sender,
99 struct iovec const *msg_sect, 85 struct iovec const *msg_sect,
100 u32 num_sect, unsigned int total_len, 86 unsigned int len, u32 destnode);
101 u32 destnode);
102static void link_state_event(struct tipc_link *l_ptr, u32 event); 87static void link_state_event(struct tipc_link *l_ptr, u32 event);
103static void link_reset_statistics(struct tipc_link *l_ptr); 88static void link_reset_statistics(struct tipc_link *l_ptr);
104static void link_print(struct tipc_link *l_ptr, const char *str); 89static void link_print(struct tipc_link *l_ptr, const char *str);
@@ -161,72 +146,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
161} 146}
162 147
163/** 148/**
164 * link_name_validate - validate & (optionally) deconstruct tipc_link name
165 * @name: ptr to link name string
166 * @name_parts: ptr to area for link name components (or NULL if not needed)
167 *
168 * Returns 1 if link name is valid, otherwise 0.
169 */
170static int link_name_validate(const char *name,
171 struct tipc_link_name *name_parts)
172{
173 char name_copy[TIPC_MAX_LINK_NAME];
174 char *addr_local;
175 char *if_local;
176 char *addr_peer;
177 char *if_peer;
178 char dummy;
179 u32 z_local, c_local, n_local;
180 u32 z_peer, c_peer, n_peer;
181 u32 if_local_len;
182 u32 if_peer_len;
183
184 /* copy link name & ensure length is OK */
185 name_copy[TIPC_MAX_LINK_NAME - 1] = 0;
186 /* need above in case non-Posix strncpy() doesn't pad with nulls */
187 strncpy(name_copy, name, TIPC_MAX_LINK_NAME);
188 if (name_copy[TIPC_MAX_LINK_NAME - 1] != 0)
189 return 0;
190
191 /* ensure all component parts of link name are present */
192 addr_local = name_copy;
193 if_local = strchr(addr_local, ':');
194 if (if_local == NULL)
195 return 0;
196 *(if_local++) = 0;
197 addr_peer = strchr(if_local, '-');
198 if (addr_peer == NULL)
199 return 0;
200 *(addr_peer++) = 0;
201 if_local_len = addr_peer - if_local;
202 if_peer = strchr(addr_peer, ':');
203 if (if_peer == NULL)
204 return 0;
205 *(if_peer++) = 0;
206 if_peer_len = strlen(if_peer) + 1;
207
208 /* validate component parts of link name */
209 if ((sscanf(addr_local, "%u.%u.%u%c",
210 &z_local, &c_local, &n_local, &dummy) != 3) ||
211 (sscanf(addr_peer, "%u.%u.%u%c",
212 &z_peer, &c_peer, &n_peer, &dummy) != 3) ||
213 (z_local > 255) || (c_local > 4095) || (n_local > 4095) ||
214 (z_peer > 255) || (c_peer > 4095) || (n_peer > 4095) ||
215 (if_local_len <= 1) || (if_local_len > TIPC_MAX_IF_NAME) ||
216 (if_peer_len <= 1) || (if_peer_len > TIPC_MAX_IF_NAME))
217 return 0;
218
219 /* return link name components, if necessary */
220 if (name_parts) {
221 name_parts->addr_local = tipc_addr(z_local, c_local, n_local);
222 strcpy(name_parts->if_local, if_local);
223 name_parts->addr_peer = tipc_addr(z_peer, c_peer, n_peer);
224 strcpy(name_parts->if_peer, if_peer);
225 }
226 return 1;
227}
228
229/**
230 * link_timeout - handle expiration of link timer 149 * link_timeout - handle expiration of link timer
231 * @l_ptr: pointer to link 150 * @l_ptr: pointer to link
232 * 151 *
@@ -485,15 +404,9 @@ static void link_release_outqueue(struct tipc_link *l_ptr)
485 */ 404 */
486void tipc_link_reset_fragments(struct tipc_link *l_ptr) 405void tipc_link_reset_fragments(struct tipc_link *l_ptr)
487{ 406{
488 struct sk_buff *buf = l_ptr->defragm_buf; 407 kfree_skb(l_ptr->reasm_head);
489 struct sk_buff *next; 408 l_ptr->reasm_head = NULL;
490 409 l_ptr->reasm_tail = NULL;
491 while (buf) {
492 next = buf->next;
493 kfree_skb(buf);
494 buf = next;
495 }
496 l_ptr->defragm_buf = NULL;
497} 410}
498 411
499/** 412/**
@@ -1065,8 +978,7 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
1065 */ 978 */
1066int tipc_link_send_sections_fast(struct tipc_port *sender, 979int tipc_link_send_sections_fast(struct tipc_port *sender,
1067 struct iovec const *msg_sect, 980 struct iovec const *msg_sect,
1068 const u32 num_sect, unsigned int total_len, 981 unsigned int len, u32 destaddr)
1069 u32 destaddr)
1070{ 982{
1071 struct tipc_msg *hdr = &sender->phdr; 983 struct tipc_msg *hdr = &sender->phdr;
1072 struct tipc_link *l_ptr; 984 struct tipc_link *l_ptr;
@@ -1080,8 +992,7 @@ again:
1080 * Try building message using port's max_pkt hint. 992 * Try building message using port's max_pkt hint.
1081 * (Must not hold any locks while building message.) 993 * (Must not hold any locks while building message.)
1082 */ 994 */
1083 res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, 995 res = tipc_msg_build(hdr, msg_sect, len, sender->max_pkt, &buf);
1084 sender->max_pkt, &buf);
1085 /* Exit if build request was invalid */ 996 /* Exit if build request was invalid */
1086 if (unlikely(res < 0)) 997 if (unlikely(res < 0))
1087 return res; 998 return res;
@@ -1121,8 +1032,7 @@ exit:
1121 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt) 1032 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
1122 goto again; 1033 goto again;
1123 1034
1124 return link_send_sections_long(sender, msg_sect, 1035 return link_send_sections_long(sender, msg_sect, len,
1125 num_sect, total_len,
1126 destaddr); 1036 destaddr);
1127 } 1037 }
1128 tipc_node_unlock(node); 1038 tipc_node_unlock(node);
@@ -1133,8 +1043,8 @@ exit:
1133 if (buf) 1043 if (buf)
1134 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); 1044 return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
1135 if (res >= 0) 1045 if (res >= 0)
1136 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1046 return tipc_port_reject_sections(sender, hdr, msg_sect,
1137 total_len, TIPC_ERR_NO_NODE); 1047 len, TIPC_ERR_NO_NODE);
1138 return res; 1048 return res;
1139} 1049}
1140 1050
@@ -1154,18 +1064,17 @@ exit:
1154 */ 1064 */
1155static int link_send_sections_long(struct tipc_port *sender, 1065static int link_send_sections_long(struct tipc_port *sender,
1156 struct iovec const *msg_sect, 1066 struct iovec const *msg_sect,
1157 u32 num_sect, unsigned int total_len, 1067 unsigned int len, u32 destaddr)
1158 u32 destaddr)
1159{ 1068{
1160 struct tipc_link *l_ptr; 1069 struct tipc_link *l_ptr;
1161 struct tipc_node *node; 1070 struct tipc_node *node;
1162 struct tipc_msg *hdr = &sender->phdr; 1071 struct tipc_msg *hdr = &sender->phdr;
1163 u32 dsz = total_len; 1072 u32 dsz = len;
1164 u32 max_pkt, fragm_sz, rest; 1073 u32 max_pkt, fragm_sz, rest;
1165 struct tipc_msg fragm_hdr; 1074 struct tipc_msg fragm_hdr;
1166 struct sk_buff *buf, *buf_chain, *prev; 1075 struct sk_buff *buf, *buf_chain, *prev;
1167 u32 fragm_crs, fragm_rest, hsz, sect_rest; 1076 u32 fragm_crs, fragm_rest, hsz, sect_rest;
1168 const unchar *sect_crs; 1077 const unchar __user *sect_crs;
1169 int curr_sect; 1078 int curr_sect;
1170 u32 fragm_no; 1079 u32 fragm_no;
1171 int res = 0; 1080 int res = 0;
@@ -1207,7 +1116,7 @@ again:
1207 1116
1208 if (!sect_rest) { 1117 if (!sect_rest) {
1209 sect_rest = msg_sect[++curr_sect].iov_len; 1118 sect_rest = msg_sect[++curr_sect].iov_len;
1210 sect_crs = (const unchar *)msg_sect[curr_sect].iov_base; 1119 sect_crs = msg_sect[curr_sect].iov_base;
1211 } 1120 }
1212 1121
1213 if (sect_rest < fragm_rest) 1122 if (sect_rest < fragm_rest)
@@ -1283,8 +1192,8 @@ reject:
1283 buf = buf_chain->next; 1192 buf = buf_chain->next;
1284 kfree_skb(buf_chain); 1193 kfree_skb(buf_chain);
1285 } 1194 }
1286 return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, 1195 return tipc_port_reject_sections(sender, hdr, msg_sect,
1287 total_len, TIPC_ERR_NO_NODE); 1196 len, TIPC_ERR_NO_NODE);
1288 } 1197 }
1289 1198
1290 /* Append chain of fragments to send queue & send them */ 1199 /* Append chain of fragments to send queue & send them */
@@ -1592,15 +1501,15 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1592 1501
1593 /* Ensure bearer is still enabled */ 1502 /* Ensure bearer is still enabled */
1594 if (unlikely(!b_ptr->active)) 1503 if (unlikely(!b_ptr->active))
1595 goto cont; 1504 goto discard;
1596 1505
1597 /* Ensure message is well-formed */ 1506 /* Ensure message is well-formed */
1598 if (unlikely(!link_recv_buf_validate(buf))) 1507 if (unlikely(!link_recv_buf_validate(buf)))
1599 goto cont; 1508 goto discard;
1600 1509
1601 /* Ensure message data is a single contiguous unit */ 1510 /* Ensure message data is a single contiguous unit */
1602 if (unlikely(skb_linearize(buf))) 1511 if (unlikely(skb_linearize(buf)))
1603 goto cont; 1512 goto discard;
1604 1513
1605 /* Handle arrival of a non-unicast link message */ 1514 /* Handle arrival of a non-unicast link message */
1606 msg = buf_msg(buf); 1515 msg = buf_msg(buf);
@@ -1616,20 +1525,18 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1616 /* Discard unicast link messages destined for another node */ 1525 /* Discard unicast link messages destined for another node */
1617 if (unlikely(!msg_short(msg) && 1526 if (unlikely(!msg_short(msg) &&
1618 (msg_destnode(msg) != tipc_own_addr))) 1527 (msg_destnode(msg) != tipc_own_addr)))
1619 goto cont; 1528 goto discard;
1620 1529
1621 /* Locate neighboring node that sent message */ 1530 /* Locate neighboring node that sent message */
1622 n_ptr = tipc_node_find(msg_prevnode(msg)); 1531 n_ptr = tipc_node_find(msg_prevnode(msg));
1623 if (unlikely(!n_ptr)) 1532 if (unlikely(!n_ptr))
1624 goto cont; 1533 goto discard;
1625 tipc_node_lock(n_ptr); 1534 tipc_node_lock(n_ptr);
1626 1535
1627 /* Locate unicast link endpoint that should handle message */ 1536 /* Locate unicast link endpoint that should handle message */
1628 l_ptr = n_ptr->links[b_ptr->identity]; 1537 l_ptr = n_ptr->links[b_ptr->identity];
1629 if (unlikely(!l_ptr)) { 1538 if (unlikely(!l_ptr))
1630 tipc_node_unlock(n_ptr); 1539 goto unlock_discard;
1631 goto cont;
1632 }
1633 1540
1634 /* Verify that communication with node is currently allowed */ 1541 /* Verify that communication with node is currently allowed */
1635 if ((n_ptr->block_setup & WAIT_PEER_DOWN) && 1542 if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&
@@ -1639,10 +1546,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1639 !msg_redundant_link(msg)) 1546 !msg_redundant_link(msg))
1640 n_ptr->block_setup &= ~WAIT_PEER_DOWN; 1547 n_ptr->block_setup &= ~WAIT_PEER_DOWN;
1641 1548
1642 if (n_ptr->block_setup) { 1549 if (n_ptr->block_setup)
1643 tipc_node_unlock(n_ptr); 1550 goto unlock_discard;
1644 goto cont;
1645 }
1646 1551
1647 /* Validate message sequence number info */ 1552 /* Validate message sequence number info */
1648 seq_no = msg_seqno(msg); 1553 seq_no = msg_seqno(msg);
@@ -1678,98 +1583,100 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
1678 1583
1679 /* Now (finally!) process the incoming message */ 1584 /* Now (finally!) process the incoming message */
1680protocol_check: 1585protocol_check:
1681 if (likely(link_working_working(l_ptr))) { 1586 if (unlikely(!link_working_working(l_ptr))) {
1682 if (likely(seq_no == mod(l_ptr->next_in_no))) { 1587 if (msg_user(msg) == LINK_PROTOCOL) {
1683 l_ptr->next_in_no++; 1588 link_recv_proto_msg(l_ptr, buf);
1684 if (unlikely(l_ptr->oldest_deferred_in)) 1589 head = link_insert_deferred_queue(l_ptr, head);
1685 head = link_insert_deferred_queue(l_ptr, 1590 tipc_node_unlock(n_ptr);
1686 head); 1591 continue;
1687deliver: 1592 }
1688 if (likely(msg_isdata(msg))) { 1593
1689 tipc_node_unlock(n_ptr); 1594 /* Traffic message. Conditionally activate link */
1690 tipc_port_recv_msg(buf); 1595 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
1691 continue; 1596
1692 } 1597 if (link_working_working(l_ptr)) {
1693 switch (msg_user(msg)) { 1598 /* Re-insert buffer in front of queue */
1694 int ret; 1599 buf->next = head;
1695 case MSG_BUNDLER: 1600 head = buf;
1696 l_ptr->stats.recv_bundles++;
1697 l_ptr->stats.recv_bundled +=
1698 msg_msgcnt(msg);
1699 tipc_node_unlock(n_ptr);
1700 tipc_link_recv_bundle(buf);
1701 continue;
1702 case NAME_DISTRIBUTOR:
1703 n_ptr->bclink.recv_permitted = true;
1704 tipc_node_unlock(n_ptr);
1705 tipc_named_recv(buf);
1706 continue;
1707 case BCAST_PROTOCOL:
1708 tipc_link_recv_sync(n_ptr, buf);
1709 tipc_node_unlock(n_ptr);
1710 continue;
1711 case CONN_MANAGER:
1712 tipc_node_unlock(n_ptr);
1713 tipc_port_recv_proto_msg(buf);
1714 continue;
1715 case MSG_FRAGMENTER:
1716 l_ptr->stats.recv_fragments++;
1717 ret = tipc_link_recv_fragment(
1718 &l_ptr->defragm_buf,
1719 &buf, &msg);
1720 if (ret == 1) {
1721 l_ptr->stats.recv_fragmented++;
1722 goto deliver;
1723 }
1724 if (ret == -1)
1725 l_ptr->next_in_no--;
1726 break;
1727 case CHANGEOVER_PROTOCOL:
1728 type = msg_type(msg);
1729 if (link_recv_changeover_msg(&l_ptr,
1730 &buf)) {
1731 msg = buf_msg(buf);
1732 seq_no = msg_seqno(msg);
1733 if (type == ORIGINAL_MSG)
1734 goto deliver;
1735 goto protocol_check;
1736 }
1737 break;
1738 default:
1739 kfree_skb(buf);
1740 buf = NULL;
1741 break;
1742 }
1743 tipc_node_unlock(n_ptr); 1601 tipc_node_unlock(n_ptr);
1744 tipc_net_route_msg(buf);
1745 continue; 1602 continue;
1746 } 1603 }
1604 goto unlock_discard;
1605 }
1606
1607 /* Link is now in state WORKING_WORKING */
1608 if (unlikely(seq_no != mod(l_ptr->next_in_no))) {
1747 link_handle_out_of_seq_msg(l_ptr, buf); 1609 link_handle_out_of_seq_msg(l_ptr, buf);
1748 head = link_insert_deferred_queue(l_ptr, head); 1610 head = link_insert_deferred_queue(l_ptr, head);
1749 tipc_node_unlock(n_ptr); 1611 tipc_node_unlock(n_ptr);
1750 continue; 1612 continue;
1751 } 1613 }
1752 1614 l_ptr->next_in_no++;
1753 /* Link is not in state WORKING_WORKING */ 1615 if (unlikely(l_ptr->oldest_deferred_in))
1754 if (msg_user(msg) == LINK_PROTOCOL) {
1755 link_recv_proto_msg(l_ptr, buf);
1756 head = link_insert_deferred_queue(l_ptr, head); 1616 head = link_insert_deferred_queue(l_ptr, head);
1617deliver:
1618 if (likely(msg_isdata(msg))) {
1757 tipc_node_unlock(n_ptr); 1619 tipc_node_unlock(n_ptr);
1620 tipc_port_recv_msg(buf);
1758 continue; 1621 continue;
1759 } 1622 }
1760 1623 switch (msg_user(msg)) {
1761 /* Traffic message. Conditionally activate link */ 1624 int ret;
1762 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1625 case MSG_BUNDLER:
1763 1626 l_ptr->stats.recv_bundles++;
1764 if (link_working_working(l_ptr)) { 1627 l_ptr->stats.recv_bundled += msg_msgcnt(msg);
1765 /* Re-insert buffer in front of queue */ 1628 tipc_node_unlock(n_ptr);
1766 buf->next = head; 1629 tipc_link_recv_bundle(buf);
1767 head = buf; 1630 continue;
1631 case NAME_DISTRIBUTOR:
1632 n_ptr->bclink.recv_permitted = true;
1633 tipc_node_unlock(n_ptr);
1634 tipc_named_recv(buf);
1635 continue;
1636 case BCAST_PROTOCOL:
1637 tipc_link_recv_sync(n_ptr, buf);
1638 tipc_node_unlock(n_ptr);
1639 continue;
1640 case CONN_MANAGER:
1641 tipc_node_unlock(n_ptr);
1642 tipc_port_recv_proto_msg(buf);
1643 continue;
1644 case MSG_FRAGMENTER:
1645 l_ptr->stats.recv_fragments++;
1646 ret = tipc_link_recv_fragment(&l_ptr->reasm_head,
1647 &l_ptr->reasm_tail,
1648 &buf);
1649 if (ret == LINK_REASM_COMPLETE) {
1650 l_ptr->stats.recv_fragmented++;
1651 msg = buf_msg(buf);
1652 goto deliver;
1653 }
1654 if (ret == LINK_REASM_ERROR)
1655 tipc_link_reset(l_ptr);
1768 tipc_node_unlock(n_ptr); 1656 tipc_node_unlock(n_ptr);
1769 continue; 1657 continue;
1658 case CHANGEOVER_PROTOCOL:
1659 type = msg_type(msg);
1660 if (link_recv_changeover_msg(&l_ptr, &buf)) {
1661 msg = buf_msg(buf);
1662 seq_no = msg_seqno(msg);
1663 if (type == ORIGINAL_MSG)
1664 goto deliver;
1665 goto protocol_check;
1666 }
1667 break;
1668 default:
1669 kfree_skb(buf);
1670 buf = NULL;
1671 break;
1770 } 1672 }
1771 tipc_node_unlock(n_ptr); 1673 tipc_node_unlock(n_ptr);
1772cont: 1674 tipc_net_route_msg(buf);
1675 continue;
1676unlock_discard:
1677
1678 tipc_node_unlock(n_ptr);
1679discard:
1773 kfree_skb(buf); 1680 kfree_skb(buf);
1774 } 1681 }
1775 read_unlock_bh(&tipc_net_lock); 1682 read_unlock_bh(&tipc_net_lock);
@@ -2432,114 +2339,47 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
2432} 2339}
2433 2340
2434/* 2341/*
2435 * A pending message being re-assembled must store certain values
2436 * to handle subsequent fragments correctly. The following functions
2437 * help storing these values in unused, available fields in the
2438 * pending message. This makes dynamic memory allocation unnecessary.
2439 */
2440static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno)
2441{
2442 msg_set_seqno(buf_msg(buf), seqno);
2443}
2444
2445static u32 get_fragm_size(struct sk_buff *buf)
2446{
2447 return msg_ack(buf_msg(buf));
2448}
2449
2450static void set_fragm_size(struct sk_buff *buf, u32 sz)
2451{
2452 msg_set_ack(buf_msg(buf), sz);
2453}
2454
2455static u32 get_expected_frags(struct sk_buff *buf)
2456{
2457 return msg_bcast_ack(buf_msg(buf));
2458}
2459
2460static void set_expected_frags(struct sk_buff *buf, u32 exp)
2461{
2462 msg_set_bcast_ack(buf_msg(buf), exp);
2463}
2464
2465/*
2466 * tipc_link_recv_fragment(): Called with node lock on. Returns 2342 * tipc_link_recv_fragment(): Called with node lock on. Returns
2467 * the reassembled buffer if message is complete. 2343 * the reassembled buffer if message is complete.
2468 */ 2344 */
2469int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, 2345int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
2470 struct tipc_msg **m) 2346 struct sk_buff **fbuf)
2471{ 2347{
2472 struct sk_buff *prev = NULL; 2348 struct sk_buff *frag = *fbuf;
2473 struct sk_buff *fbuf = *fb; 2349 struct tipc_msg *msg = buf_msg(frag);
2474 struct tipc_msg *fragm = buf_msg(fbuf); 2350 u32 fragid = msg_type(msg);
2475 struct sk_buff *pbuf = *pending; 2351 bool headstolen;
2476 u32 long_msg_seq_no = msg_long_msgno(fragm); 2352 int delta;
2477 2353
2478 *fb = NULL; 2354 skb_pull(frag, msg_hdr_sz(msg));
2479 2355 if (fragid == FIRST_FRAGMENT) {
2480 /* Is there an incomplete message waiting for this fragment? */ 2356 if (*head || skb_unclone(frag, GFP_ATOMIC))
2481 while (pbuf && ((buf_seqno(pbuf) != long_msg_seq_no) || 2357 goto out_free;
2482 (msg_orignode(fragm) != msg_orignode(buf_msg(pbuf))))) { 2358 *head = frag;
2483 prev = pbuf; 2359 skb_frag_list_init(*head);
2484 pbuf = pbuf->next;
2485 }
2486
2487 if (!pbuf && (msg_type(fragm) == FIRST_FRAGMENT)) {
2488 struct tipc_msg *imsg = (struct tipc_msg *)msg_data(fragm);
2489 u32 msg_sz = msg_size(imsg);
2490 u32 fragm_sz = msg_data_sz(fragm);
2491 u32 exp_fragm_cnt;
2492 u32 max = TIPC_MAX_USER_MSG_SIZE + NAMED_H_SIZE;
2493
2494 if (msg_type(imsg) == TIPC_MCAST_MSG)
2495 max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
2496 if (fragm_sz == 0 || msg_size(imsg) > max) {
2497 kfree_skb(fbuf);
2498 return 0;
2499 }
2500 exp_fragm_cnt = msg_sz / fragm_sz + !!(msg_sz % fragm_sz);
2501 pbuf = tipc_buf_acquire(msg_size(imsg));
2502 if (pbuf != NULL) {
2503 pbuf->next = *pending;
2504 *pending = pbuf;
2505 skb_copy_to_linear_data(pbuf, imsg,
2506 msg_data_sz(fragm));
2507 /* Prepare buffer for subsequent fragments. */
2508 set_long_msg_seqno(pbuf, long_msg_seq_no);
2509 set_fragm_size(pbuf, fragm_sz);
2510 set_expected_frags(pbuf, exp_fragm_cnt - 1);
2511 } else {
2512 pr_debug("Link unable to reassemble fragmented message\n");
2513 kfree_skb(fbuf);
2514 return -1;
2515 }
2516 kfree_skb(fbuf);
2517 return 0;
2518 } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) {
2519 u32 dsz = msg_data_sz(fragm);
2520 u32 fsz = get_fragm_size(pbuf);
2521 u32 crs = ((msg_fragm_no(fragm) - 1) * fsz);
2522 u32 exp_frags = get_expected_frags(pbuf) - 1;
2523 skb_copy_to_linear_data_offset(pbuf, crs,
2524 msg_data(fragm), dsz);
2525 kfree_skb(fbuf);
2526
2527 /* Is message complete? */
2528 if (exp_frags == 0) {
2529 if (prev)
2530 prev->next = pbuf->next;
2531 else
2532 *pending = pbuf->next;
2533 msg_reset_reroute_cnt(buf_msg(pbuf));
2534 *fb = pbuf;
2535 *m = buf_msg(pbuf);
2536 return 1;
2537 }
2538 set_expected_frags(pbuf, exp_frags);
2539 return 0; 2360 return 0;
2361 } else if (skb_try_coalesce(*head, frag, &headstolen, &delta)) {
2362 kfree_skb_partial(frag, headstolen);
2363 } else {
2364 if (!*head)
2365 goto out_free;
2366 if (!skb_has_frag_list(*head))
2367 skb_shinfo(*head)->frag_list = frag;
2368 else
2369 (*tail)->next = frag;
2370 *tail = frag;
2371 (*head)->truesize += frag->truesize;
2372 }
2373 if (fragid == LAST_FRAGMENT) {
2374 *fbuf = *head;
2375 *tail = *head = NULL;
2376 return LINK_REASM_COMPLETE;
2540 } 2377 }
2541 kfree_skb(fbuf);
2542 return 0; 2378 return 0;
2379out_free:
2380 pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
2381 kfree_skb(*fbuf);
2382 return LINK_REASM_ERROR;
2543} 2383}
2544 2384
2545static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance) 2385static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance)
@@ -2585,25 +2425,21 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
2585static struct tipc_link *link_find_link(const char *name, 2425static struct tipc_link *link_find_link(const char *name,
2586 struct tipc_node **node) 2426 struct tipc_node **node)
2587{ 2427{
2588 struct tipc_link_name link_name_parts;
2589 struct tipc_bearer *b_ptr;
2590 struct tipc_link *l_ptr; 2428 struct tipc_link *l_ptr;
2429 struct tipc_node *n_ptr;
2430 int i;
2591 2431
2592 if (!link_name_validate(name, &link_name_parts)) 2432 list_for_each_entry(n_ptr, &tipc_node_list, list) {
2593 return NULL; 2433 for (i = 0; i < MAX_BEARERS; i++) {
2594 2434 l_ptr = n_ptr->links[i];
2595 b_ptr = tipc_bearer_find_interface(link_name_parts.if_local); 2435 if (l_ptr && !strcmp(l_ptr->name, name))
2596 if (!b_ptr) 2436 goto found;
2597 return NULL; 2437 }
2598 2438 }
2599 *node = tipc_node_find(link_name_parts.addr_peer); 2439 l_ptr = NULL;
2600 if (!*node) 2440 n_ptr = NULL;
2601 return NULL; 2441found:
2602 2442 *node = n_ptr;
2603 l_ptr = (*node)->links[b_ptr->identity];
2604 if (!l_ptr || strcmp(l_ptr->name, name))
2605 return NULL;
2606
2607 return l_ptr; 2443 return l_ptr;
2608} 2444}
2609 2445
@@ -2646,6 +2482,7 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2646 struct tipc_link *l_ptr; 2482 struct tipc_link *l_ptr;
2647 struct tipc_bearer *b_ptr; 2483 struct tipc_bearer *b_ptr;
2648 struct tipc_media *m_ptr; 2484 struct tipc_media *m_ptr;
2485 int res = 0;
2649 2486
2650 l_ptr = link_find_link(name, &node); 2487 l_ptr = link_find_link(name, &node);
2651 if (l_ptr) { 2488 if (l_ptr) {
@@ -2668,9 +2505,12 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2668 case TIPC_CMD_SET_LINK_WINDOW: 2505 case TIPC_CMD_SET_LINK_WINDOW:
2669 tipc_link_set_queue_limits(l_ptr, new_value); 2506 tipc_link_set_queue_limits(l_ptr, new_value);
2670 break; 2507 break;
2508 default:
2509 res = -EINVAL;
2510 break;
2671 } 2511 }
2672 tipc_node_unlock(node); 2512 tipc_node_unlock(node);
2673 return 0; 2513 return res;
2674 } 2514 }
2675 2515
2676 b_ptr = tipc_bearer_find(name); 2516 b_ptr = tipc_bearer_find(name);
@@ -2678,15 +2518,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2678 switch (cmd) { 2518 switch (cmd) {
2679 case TIPC_CMD_SET_LINK_TOL: 2519 case TIPC_CMD_SET_LINK_TOL:
2680 b_ptr->tolerance = new_value; 2520 b_ptr->tolerance = new_value;
2681 return 0; 2521 break;
2682 case TIPC_CMD_SET_LINK_PRI: 2522 case TIPC_CMD_SET_LINK_PRI:
2683 b_ptr->priority = new_value; 2523 b_ptr->priority = new_value;
2684 return 0; 2524 break;
2685 case TIPC_CMD_SET_LINK_WINDOW: 2525 case TIPC_CMD_SET_LINK_WINDOW:
2686 b_ptr->window = new_value; 2526 b_ptr->window = new_value;
2687 return 0; 2527 break;
2528 default:
2529 res = -EINVAL;
2530 break;
2688 } 2531 }
2689 return -EINVAL; 2532 return res;
2690 } 2533 }
2691 2534
2692 m_ptr = tipc_media_find(name); 2535 m_ptr = tipc_media_find(name);
@@ -2695,15 +2538,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2695 switch (cmd) { 2538 switch (cmd) {
2696 case TIPC_CMD_SET_LINK_TOL: 2539 case TIPC_CMD_SET_LINK_TOL:
2697 m_ptr->tolerance = new_value; 2540 m_ptr->tolerance = new_value;
2698 return 0; 2541 break;
2699 case TIPC_CMD_SET_LINK_PRI: 2542 case TIPC_CMD_SET_LINK_PRI:
2700 m_ptr->priority = new_value; 2543 m_ptr->priority = new_value;
2701 return 0; 2544 break;
2702 case TIPC_CMD_SET_LINK_WINDOW: 2545 case TIPC_CMD_SET_LINK_WINDOW:
2703 m_ptr->window = new_value; 2546 m_ptr->window = new_value;
2704 return 0; 2547 break;
2548 default:
2549 res = -EINVAL;
2550 break;
2705 } 2551 }
2706 return -EINVAL; 2552 return res;
2707} 2553}
2708 2554
2709struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, 2555struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space,