aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c493
1 files changed, 170 insertions, 323 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0cc3d9015c5d..69cd9bf3f561 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,48 @@ 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 (*head &&
2362 skb_try_coalesce(*head, frag, &headstolen, &delta)) {
2363 kfree_skb_partial(frag, headstolen);
2364 } else {
2365 if (!*head)
2366 goto out_free;
2367 if (!skb_has_frag_list(*head))
2368 skb_shinfo(*head)->frag_list = frag;
2369 else
2370 (*tail)->next = frag;
2371 *tail = frag;
2372 (*head)->truesize += frag->truesize;
2373 }
2374 if (fragid == LAST_FRAGMENT) {
2375 *fbuf = *head;
2376 *tail = *head = NULL;
2377 return LINK_REASM_COMPLETE;
2540 } 2378 }
2541 kfree_skb(fbuf);
2542 return 0; 2379 return 0;
2380out_free:
2381 pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
2382 kfree_skb(*fbuf);
2383 return LINK_REASM_ERROR;
2543} 2384}
2544 2385
2545static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance) 2386static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance)
@@ -2585,25 +2426,21 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
2585static struct tipc_link *link_find_link(const char *name, 2426static struct tipc_link *link_find_link(const char *name,
2586 struct tipc_node **node) 2427 struct tipc_node **node)
2587{ 2428{
2588 struct tipc_link_name link_name_parts;
2589 struct tipc_bearer *b_ptr;
2590 struct tipc_link *l_ptr; 2429 struct tipc_link *l_ptr;
2430 struct tipc_node *n_ptr;
2431 int i;
2591 2432
2592 if (!link_name_validate(name, &link_name_parts)) 2433 list_for_each_entry(n_ptr, &tipc_node_list, list) {
2593 return NULL; 2434 for (i = 0; i < MAX_BEARERS; i++) {
2594 2435 l_ptr = n_ptr->links[i];
2595 b_ptr = tipc_bearer_find_interface(link_name_parts.if_local); 2436 if (l_ptr && !strcmp(l_ptr->name, name))
2596 if (!b_ptr) 2437 goto found;
2597 return NULL; 2438 }
2598 2439 }
2599 *node = tipc_node_find(link_name_parts.addr_peer); 2440 l_ptr = NULL;
2600 if (!*node) 2441 n_ptr = NULL;
2601 return NULL; 2442found:
2602 2443 *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; 2444 return l_ptr;
2608} 2445}
2609 2446
@@ -2646,6 +2483,7 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2646 struct tipc_link *l_ptr; 2483 struct tipc_link *l_ptr;
2647 struct tipc_bearer *b_ptr; 2484 struct tipc_bearer *b_ptr;
2648 struct tipc_media *m_ptr; 2485 struct tipc_media *m_ptr;
2486 int res = 0;
2649 2487
2650 l_ptr = link_find_link(name, &node); 2488 l_ptr = link_find_link(name, &node);
2651 if (l_ptr) { 2489 if (l_ptr) {
@@ -2668,9 +2506,12 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2668 case TIPC_CMD_SET_LINK_WINDOW: 2506 case TIPC_CMD_SET_LINK_WINDOW:
2669 tipc_link_set_queue_limits(l_ptr, new_value); 2507 tipc_link_set_queue_limits(l_ptr, new_value);
2670 break; 2508 break;
2509 default:
2510 res = -EINVAL;
2511 break;
2671 } 2512 }
2672 tipc_node_unlock(node); 2513 tipc_node_unlock(node);
2673 return 0; 2514 return res;
2674 } 2515 }
2675 2516
2676 b_ptr = tipc_bearer_find(name); 2517 b_ptr = tipc_bearer_find(name);
@@ -2678,15 +2519,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2678 switch (cmd) { 2519 switch (cmd) {
2679 case TIPC_CMD_SET_LINK_TOL: 2520 case TIPC_CMD_SET_LINK_TOL:
2680 b_ptr->tolerance = new_value; 2521 b_ptr->tolerance = new_value;
2681 return 0; 2522 break;
2682 case TIPC_CMD_SET_LINK_PRI: 2523 case TIPC_CMD_SET_LINK_PRI:
2683 b_ptr->priority = new_value; 2524 b_ptr->priority = new_value;
2684 return 0; 2525 break;
2685 case TIPC_CMD_SET_LINK_WINDOW: 2526 case TIPC_CMD_SET_LINK_WINDOW:
2686 b_ptr->window = new_value; 2527 b_ptr->window = new_value;
2687 return 0; 2528 break;
2529 default:
2530 res = -EINVAL;
2531 break;
2688 } 2532 }
2689 return -EINVAL; 2533 return res;
2690 } 2534 }
2691 2535
2692 m_ptr = tipc_media_find(name); 2536 m_ptr = tipc_media_find(name);
@@ -2695,15 +2539,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
2695 switch (cmd) { 2539 switch (cmd) {
2696 case TIPC_CMD_SET_LINK_TOL: 2540 case TIPC_CMD_SET_LINK_TOL:
2697 m_ptr->tolerance = new_value; 2541 m_ptr->tolerance = new_value;
2698 return 0; 2542 break;
2699 case TIPC_CMD_SET_LINK_PRI: 2543 case TIPC_CMD_SET_LINK_PRI:
2700 m_ptr->priority = new_value; 2544 m_ptr->priority = new_value;
2701 return 0; 2545 break;
2702 case TIPC_CMD_SET_LINK_WINDOW: 2546 case TIPC_CMD_SET_LINK_WINDOW:
2703 m_ptr->window = new_value; 2547 m_ptr->window = new_value;
2704 return 0; 2548 break;
2549 default:
2550 res = -EINVAL;
2551 break;
2705 } 2552 }
2706 return -EINVAL; 2553 return res;
2707} 2554}
2708 2555
2709struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, 2556struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space,