diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 88 |
1 files changed, 26 insertions, 62 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a80feee5197a..0cc3d9015c5d 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/link.c: TIPC link code | 2 | * net/tipc/link.c: TIPC link code |
3 | * | 3 | * |
4 | * Copyright (c) 1996-2007, 2012, Ericsson AB | 4 | * Copyright (c) 1996-2007, 2012, Ericsson AB |
5 | * Copyright (c) 2004-2007, 2010-2011, Wind River Systems | 5 | * Copyright (c) 2004-2007, 2010-2013, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -41,6 +41,8 @@ | |||
41 | #include "discover.h" | 41 | #include "discover.h" |
42 | #include "config.h" | 42 | #include "config.h" |
43 | 43 | ||
44 | #include <linux/pkt_sched.h> | ||
45 | |||
44 | /* | 46 | /* |
45 | * Error message prefixes | 47 | * Error message prefixes |
46 | */ | 48 | */ |
@@ -771,8 +773,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) | |||
771 | * link_bundle_buf(): Append contents of a buffer to | 773 | * link_bundle_buf(): Append contents of a buffer to |
772 | * the tail of an existing one. | 774 | * the tail of an existing one. |
773 | */ | 775 | */ |
774 | static int link_bundle_buf(struct tipc_link *l_ptr, | 776 | static int link_bundle_buf(struct tipc_link *l_ptr, struct sk_buff *bundler, |
775 | struct sk_buff *bundler, | ||
776 | struct sk_buff *buf) | 777 | struct sk_buff *buf) |
777 | { | 778 | { |
778 | struct tipc_msg *bundler_msg = buf_msg(bundler); | 779 | struct tipc_msg *bundler_msg = buf_msg(bundler); |
@@ -1057,40 +1058,6 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
1057 | } | 1058 | } |
1058 | 1059 | ||
1059 | /* | 1060 | /* |
1060 | * tipc_send_buf_fast: Entry for data messages where the | ||
1061 | * destination node is known and the header is complete, | ||
1062 | * inclusive total message length. | ||
1063 | * Returns user data length. | ||
1064 | */ | ||
1065 | int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) | ||
1066 | { | ||
1067 | struct tipc_link *l_ptr; | ||
1068 | struct tipc_node *n_ptr; | ||
1069 | int res; | ||
1070 | u32 selector = msg_origport(buf_msg(buf)) & 1; | ||
1071 | u32 dummy; | ||
1072 | |||
1073 | read_lock_bh(&tipc_net_lock); | ||
1074 | n_ptr = tipc_node_find(destnode); | ||
1075 | if (likely(n_ptr)) { | ||
1076 | tipc_node_lock(n_ptr); | ||
1077 | l_ptr = n_ptr->active_links[selector]; | ||
1078 | if (likely(l_ptr)) { | ||
1079 | res = link_send_buf_fast(l_ptr, buf, &dummy); | ||
1080 | tipc_node_unlock(n_ptr); | ||
1081 | read_unlock_bh(&tipc_net_lock); | ||
1082 | return res; | ||
1083 | } | ||
1084 | tipc_node_unlock(n_ptr); | ||
1085 | } | ||
1086 | read_unlock_bh(&tipc_net_lock); | ||
1087 | res = msg_data_sz(buf_msg(buf)); | ||
1088 | tipc_reject_msg(buf, TIPC_ERR_NO_NODE); | ||
1089 | return res; | ||
1090 | } | ||
1091 | |||
1092 | |||
1093 | /* | ||
1094 | * tipc_link_send_sections_fast: Entry for messages where the | 1061 | * tipc_link_send_sections_fast: Entry for messages where the |
1095 | * destination processor is known and the header is complete, | 1062 | * destination processor is known and the header is complete, |
1096 | * except for total message length. | 1063 | * except for total message length. |
@@ -1098,8 +1065,7 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) | |||
1098 | */ | 1065 | */ |
1099 | int tipc_link_send_sections_fast(struct tipc_port *sender, | 1066 | int tipc_link_send_sections_fast(struct tipc_port *sender, |
1100 | struct iovec const *msg_sect, | 1067 | struct iovec const *msg_sect, |
1101 | const u32 num_sect, | 1068 | const u32 num_sect, unsigned int total_len, |
1102 | unsigned int total_len, | ||
1103 | u32 destaddr) | 1069 | u32 destaddr) |
1104 | { | 1070 | { |
1105 | struct tipc_msg *hdr = &sender->phdr; | 1071 | struct tipc_msg *hdr = &sender->phdr; |
@@ -1115,7 +1081,10 @@ again: | |||
1115 | * (Must not hold any locks while building message.) | 1081 | * (Must not hold any locks while building message.) |
1116 | */ | 1082 | */ |
1117 | res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, | 1083 | res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, |
1118 | sender->max_pkt, !sender->user_port, &buf); | 1084 | sender->max_pkt, &buf); |
1085 | /* Exit if build request was invalid */ | ||
1086 | if (unlikely(res < 0)) | ||
1087 | return res; | ||
1119 | 1088 | ||
1120 | read_lock_bh(&tipc_net_lock); | 1089 | read_lock_bh(&tipc_net_lock); |
1121 | node = tipc_node_find(destaddr); | 1090 | node = tipc_node_find(destaddr); |
@@ -1132,10 +1101,6 @@ exit: | |||
1132 | return res; | 1101 | return res; |
1133 | } | 1102 | } |
1134 | 1103 | ||
1135 | /* Exit if build request was invalid */ | ||
1136 | if (unlikely(res < 0)) | ||
1137 | goto exit; | ||
1138 | |||
1139 | /* Exit if link (or bearer) is congested */ | 1104 | /* Exit if link (or bearer) is congested */ |
1140 | if (link_congested(l_ptr) || | 1105 | if (link_congested(l_ptr) || |
1141 | tipc_bearer_blocked(l_ptr->b_ptr)) { | 1106 | tipc_bearer_blocked(l_ptr->b_ptr)) { |
@@ -1189,8 +1154,7 @@ exit: | |||
1189 | */ | 1154 | */ |
1190 | static int link_send_sections_long(struct tipc_port *sender, | 1155 | static int link_send_sections_long(struct tipc_port *sender, |
1191 | struct iovec const *msg_sect, | 1156 | struct iovec const *msg_sect, |
1192 | u32 num_sect, | 1157 | u32 num_sect, unsigned int total_len, |
1193 | unsigned int total_len, | ||
1194 | u32 destaddr) | 1158 | u32 destaddr) |
1195 | { | 1159 | { |
1196 | struct tipc_link *l_ptr; | 1160 | struct tipc_link *l_ptr; |
@@ -1204,6 +1168,7 @@ static int link_send_sections_long(struct tipc_port *sender, | |||
1204 | const unchar *sect_crs; | 1168 | const unchar *sect_crs; |
1205 | int curr_sect; | 1169 | int curr_sect; |
1206 | u32 fragm_no; | 1170 | u32 fragm_no; |
1171 | int res = 0; | ||
1207 | 1172 | ||
1208 | again: | 1173 | again: |
1209 | fragm_no = 1; | 1174 | fragm_no = 1; |
@@ -1250,18 +1215,15 @@ again: | |||
1250 | else | 1215 | else |
1251 | sz = fragm_rest; | 1216 | sz = fragm_rest; |
1252 | 1217 | ||
1253 | if (likely(!sender->user_port)) { | 1218 | if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) { |
1254 | if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) { | 1219 | res = -EFAULT; |
1255 | error: | 1220 | error: |
1256 | for (; buf_chain; buf_chain = buf) { | 1221 | for (; buf_chain; buf_chain = buf) { |
1257 | buf = buf_chain->next; | 1222 | buf = buf_chain->next; |
1258 | kfree_skb(buf_chain); | 1223 | kfree_skb(buf_chain); |
1259 | } | ||
1260 | return -EFAULT; | ||
1261 | } | 1224 | } |
1262 | } else | 1225 | return res; |
1263 | skb_copy_to_linear_data_offset(buf, fragm_crs, | 1226 | } |
1264 | sect_crs, sz); | ||
1265 | sect_crs += sz; | 1227 | sect_crs += sz; |
1266 | sect_rest -= sz; | 1228 | sect_rest -= sz; |
1267 | fragm_crs += sz; | 1229 | fragm_crs += sz; |
@@ -1281,8 +1243,10 @@ error: | |||
1281 | msg_set_fragm_no(&fragm_hdr, ++fragm_no); | 1243 | msg_set_fragm_no(&fragm_hdr, ++fragm_no); |
1282 | prev = buf; | 1244 | prev = buf; |
1283 | buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE); | 1245 | buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE); |
1284 | if (!buf) | 1246 | if (!buf) { |
1247 | res = -ENOMEM; | ||
1285 | goto error; | 1248 | goto error; |
1249 | } | ||
1286 | 1250 | ||
1287 | buf->next = NULL; | 1251 | buf->next = NULL; |
1288 | prev->next = buf; | 1252 | prev->next = buf; |
@@ -1446,7 +1410,7 @@ static void link_reset_all(unsigned long addr) | |||
1446 | } | 1410 | } |
1447 | 1411 | ||
1448 | static void link_retransmit_failure(struct tipc_link *l_ptr, | 1412 | static void link_retransmit_failure(struct tipc_link *l_ptr, |
1449 | struct sk_buff *buf) | 1413 | struct sk_buff *buf) |
1450 | { | 1414 | { |
1451 | struct tipc_msg *msg = buf_msg(buf); | 1415 | struct tipc_msg *msg = buf_msg(buf); |
1452 | 1416 | ||
@@ -1901,8 +1865,8 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, | |||
1901 | * Send protocol message to the other endpoint. | 1865 | * Send protocol message to the other endpoint. |
1902 | */ | 1866 | */ |
1903 | void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | 1867 | void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, |
1904 | int probe_msg, u32 gap, u32 tolerance, | 1868 | int probe_msg, u32 gap, u32 tolerance, |
1905 | u32 priority, u32 ack_mtu) | 1869 | u32 priority, u32 ack_mtu) |
1906 | { | 1870 | { |
1907 | struct sk_buff *buf = NULL; | 1871 | struct sk_buff *buf = NULL; |
1908 | struct tipc_msg *msg = l_ptr->pmsg; | 1872 | struct tipc_msg *msg = l_ptr->pmsg; |
@@ -1988,6 +1952,7 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
1988 | return; | 1952 | return; |
1989 | 1953 | ||
1990 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | 1954 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); |
1955 | buf->priority = TC_PRIO_CONTROL; | ||
1991 | 1956 | ||
1992 | /* Defer message if bearer is already blocked */ | 1957 | /* Defer message if bearer is already blocked */ |
1993 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { | 1958 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { |
@@ -2145,8 +2110,7 @@ exit: | |||
2145 | * another bearer. Owner node is locked. | 2110 | * another bearer. Owner node is locked. |
2146 | */ | 2111 | */ |
2147 | static void tipc_link_tunnel(struct tipc_link *l_ptr, | 2112 | static void tipc_link_tunnel(struct tipc_link *l_ptr, |
2148 | struct tipc_msg *tunnel_hdr, | 2113 | struct tipc_msg *tunnel_hdr, struct tipc_msg *msg, |
2149 | struct tipc_msg *msg, | ||
2150 | u32 selector) | 2114 | u32 selector) |
2151 | { | 2115 | { |
2152 | struct tipc_link *tunnel; | 2116 | struct tipc_link *tunnel; |