diff options
Diffstat (limited to 'net/rxrpc/input.c')
-rw-r--r-- | net/rxrpc/input.c | 90 |
1 files changed, 64 insertions, 26 deletions
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index cfdc199c6351..800f5b8a1baa 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
@@ -622,13 +622,14 @@ static void rxrpc_input_requested_ack(struct rxrpc_call *call, | |||
622 | if (!skb) | 622 | if (!skb) |
623 | continue; | 623 | continue; |
624 | 624 | ||
625 | sent_at = skb->tstamp; | ||
626 | smp_rmb(); /* Read timestamp before serial. */ | ||
625 | sp = rxrpc_skb(skb); | 627 | sp = rxrpc_skb(skb); |
626 | if (sp->hdr.serial != orig_serial) | 628 | if (sp->hdr.serial != orig_serial) |
627 | continue; | 629 | continue; |
628 | smp_rmb(); | ||
629 | sent_at = skb->tstamp; | ||
630 | goto found; | 630 | goto found; |
631 | } | 631 | } |
632 | |||
632 | return; | 633 | return; |
633 | 634 | ||
634 | found: | 635 | found: |
@@ -1124,12 +1125,14 @@ void rxrpc_data_ready(struct sock *udp_sk) | |||
1124 | { | 1125 | { |
1125 | struct rxrpc_connection *conn; | 1126 | struct rxrpc_connection *conn; |
1126 | struct rxrpc_channel *chan; | 1127 | struct rxrpc_channel *chan; |
1127 | struct rxrpc_call *call; | 1128 | struct rxrpc_call *call = NULL; |
1128 | struct rxrpc_skb_priv *sp; | 1129 | struct rxrpc_skb_priv *sp; |
1129 | struct rxrpc_local *local = udp_sk->sk_user_data; | 1130 | struct rxrpc_local *local = udp_sk->sk_user_data; |
1131 | struct rxrpc_peer *peer = NULL; | ||
1132 | struct rxrpc_sock *rx = NULL; | ||
1130 | struct sk_buff *skb; | 1133 | struct sk_buff *skb; |
1131 | unsigned int channel; | 1134 | unsigned int channel; |
1132 | int ret, skew; | 1135 | int ret, skew = 0; |
1133 | 1136 | ||
1134 | _enter("%p", udp_sk); | 1137 | _enter("%p", udp_sk); |
1135 | 1138 | ||
@@ -1143,6 +1146,9 @@ void rxrpc_data_ready(struct sock *udp_sk) | |||
1143 | return; | 1146 | return; |
1144 | } | 1147 | } |
1145 | 1148 | ||
1149 | if (skb->tstamp == 0) | ||
1150 | skb->tstamp = ktime_get_real(); | ||
1151 | |||
1146 | rxrpc_new_skb(skb, rxrpc_skb_rx_received); | 1152 | rxrpc_new_skb(skb, rxrpc_skb_rx_received); |
1147 | 1153 | ||
1148 | _net("recv skb %p", skb); | 1154 | _net("recv skb %p", skb); |
@@ -1177,46 +1183,75 @@ void rxrpc_data_ready(struct sock *udp_sk) | |||
1177 | 1183 | ||
1178 | trace_rxrpc_rx_packet(sp); | 1184 | trace_rxrpc_rx_packet(sp); |
1179 | 1185 | ||
1180 | _net("Rx RxRPC %s ep=%x call=%x:%x", | ||
1181 | sp->hdr.flags & RXRPC_CLIENT_INITIATED ? "ToServer" : "ToClient", | ||
1182 | sp->hdr.epoch, sp->hdr.cid, sp->hdr.callNumber); | ||
1183 | |||
1184 | if (sp->hdr.type >= RXRPC_N_PACKET_TYPES || | ||
1185 | !((RXRPC_SUPPORTED_PACKET_TYPES >> sp->hdr.type) & 1)) { | ||
1186 | _proto("Rx Bad Packet Type %u", sp->hdr.type); | ||
1187 | goto bad_message; | ||
1188 | } | ||
1189 | |||
1190 | switch (sp->hdr.type) { | 1186 | switch (sp->hdr.type) { |
1191 | case RXRPC_PACKET_TYPE_VERSION: | 1187 | case RXRPC_PACKET_TYPE_VERSION: |
1192 | if (!(sp->hdr.flags & RXRPC_CLIENT_INITIATED)) | 1188 | if (rxrpc_to_client(sp)) |
1193 | goto discard; | 1189 | goto discard; |
1194 | rxrpc_post_packet_to_local(local, skb); | 1190 | rxrpc_post_packet_to_local(local, skb); |
1195 | goto out; | 1191 | goto out; |
1196 | 1192 | ||
1197 | case RXRPC_PACKET_TYPE_BUSY: | 1193 | case RXRPC_PACKET_TYPE_BUSY: |
1198 | if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) | 1194 | if (rxrpc_to_server(sp)) |
1199 | goto discard; | 1195 | goto discard; |
1200 | /* Fall through */ | 1196 | /* Fall through */ |
1197 | case RXRPC_PACKET_TYPE_ACK: | ||
1198 | case RXRPC_PACKET_TYPE_ACKALL: | ||
1199 | if (sp->hdr.callNumber == 0) | ||
1200 | goto bad_message; | ||
1201 | /* Fall through */ | ||
1202 | case RXRPC_PACKET_TYPE_ABORT: | ||
1203 | break; | ||
1201 | 1204 | ||
1202 | case RXRPC_PACKET_TYPE_DATA: | 1205 | case RXRPC_PACKET_TYPE_DATA: |
1203 | if (sp->hdr.callNumber == 0) | 1206 | if (sp->hdr.callNumber == 0 || |
1207 | sp->hdr.seq == 0) | ||
1204 | goto bad_message; | 1208 | goto bad_message; |
1205 | if (sp->hdr.flags & RXRPC_JUMBO_PACKET && | 1209 | if (sp->hdr.flags & RXRPC_JUMBO_PACKET && |
1206 | !rxrpc_validate_jumbo(skb)) | 1210 | !rxrpc_validate_jumbo(skb)) |
1207 | goto bad_message; | 1211 | goto bad_message; |
1208 | break; | 1212 | break; |
1209 | 1213 | ||
1214 | case RXRPC_PACKET_TYPE_CHALLENGE: | ||
1215 | if (rxrpc_to_server(sp)) | ||
1216 | goto discard; | ||
1217 | break; | ||
1218 | case RXRPC_PACKET_TYPE_RESPONSE: | ||
1219 | if (rxrpc_to_client(sp)) | ||
1220 | goto discard; | ||
1221 | break; | ||
1222 | |||
1210 | /* Packet types 9-11 should just be ignored. */ | 1223 | /* Packet types 9-11 should just be ignored. */ |
1211 | case RXRPC_PACKET_TYPE_PARAMS: | 1224 | case RXRPC_PACKET_TYPE_PARAMS: |
1212 | case RXRPC_PACKET_TYPE_10: | 1225 | case RXRPC_PACKET_TYPE_10: |
1213 | case RXRPC_PACKET_TYPE_11: | 1226 | case RXRPC_PACKET_TYPE_11: |
1214 | goto discard; | 1227 | goto discard; |
1228 | |||
1229 | default: | ||
1230 | _proto("Rx Bad Packet Type %u", sp->hdr.type); | ||
1231 | goto bad_message; | ||
1215 | } | 1232 | } |
1216 | 1233 | ||
1234 | if (sp->hdr.serviceId == 0) | ||
1235 | goto bad_message; | ||
1236 | |||
1217 | rcu_read_lock(); | 1237 | rcu_read_lock(); |
1218 | 1238 | ||
1219 | conn = rxrpc_find_connection_rcu(local, skb); | 1239 | if (rxrpc_to_server(sp)) { |
1240 | /* Weed out packets to services we're not offering. Packets | ||
1241 | * that would begin a call are explicitly rejected and the rest | ||
1242 | * are just discarded. | ||
1243 | */ | ||
1244 | rx = rcu_dereference(local->service); | ||
1245 | if (!rx || (sp->hdr.serviceId != rx->srx.srx_service && | ||
1246 | sp->hdr.serviceId != rx->second_service)) { | ||
1247 | if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA && | ||
1248 | sp->hdr.seq == 1) | ||
1249 | goto unsupported_service; | ||
1250 | goto discard_unlock; | ||
1251 | } | ||
1252 | } | ||
1253 | |||
1254 | conn = rxrpc_find_connection_rcu(local, skb, &peer); | ||
1220 | if (conn) { | 1255 | if (conn) { |
1221 | if (sp->hdr.securityIndex != conn->security_ix) | 1256 | if (sp->hdr.securityIndex != conn->security_ix) |
1222 | goto wrong_security; | 1257 | goto wrong_security; |
@@ -1280,7 +1315,7 @@ void rxrpc_data_ready(struct sock *udp_sk) | |||
1280 | call = rcu_dereference(chan->call); | 1315 | call = rcu_dereference(chan->call); |
1281 | 1316 | ||
1282 | if (sp->hdr.callNumber > chan->call_id) { | 1317 | if (sp->hdr.callNumber > chan->call_id) { |
1283 | if (!(sp->hdr.flags & RXRPC_CLIENT_INITIATED)) { | 1318 | if (rxrpc_to_client(sp)) { |
1284 | rcu_read_unlock(); | 1319 | rcu_read_unlock(); |
1285 | goto reject_packet; | 1320 | goto reject_packet; |
1286 | } | 1321 | } |
@@ -1297,19 +1332,15 @@ void rxrpc_data_ready(struct sock *udp_sk) | |||
1297 | if (!test_bit(RXRPC_CALL_RX_HEARD, &call->flags)) | 1332 | if (!test_bit(RXRPC_CALL_RX_HEARD, &call->flags)) |
1298 | set_bit(RXRPC_CALL_RX_HEARD, &call->flags); | 1333 | set_bit(RXRPC_CALL_RX_HEARD, &call->flags); |
1299 | } | 1334 | } |
1300 | } else { | ||
1301 | skew = 0; | ||
1302 | call = NULL; | ||
1303 | } | 1335 | } |
1304 | 1336 | ||
1305 | if (!call || atomic_read(&call->usage) == 0) { | 1337 | if (!call || atomic_read(&call->usage) == 0) { |
1306 | if (!(sp->hdr.type & RXRPC_CLIENT_INITIATED) || | 1338 | if (rxrpc_to_client(sp) || |
1307 | sp->hdr.callNumber == 0 || | ||
1308 | sp->hdr.type != RXRPC_PACKET_TYPE_DATA) | 1339 | sp->hdr.type != RXRPC_PACKET_TYPE_DATA) |
1309 | goto bad_message_unlock; | 1340 | goto bad_message_unlock; |
1310 | if (sp->hdr.seq != 1) | 1341 | if (sp->hdr.seq != 1) |
1311 | goto discard_unlock; | 1342 | goto discard_unlock; |
1312 | call = rxrpc_new_incoming_call(local, conn, skb); | 1343 | call = rxrpc_new_incoming_call(local, rx, peer, conn, skb); |
1313 | if (!call) { | 1344 | if (!call) { |
1314 | rcu_read_unlock(); | 1345 | rcu_read_unlock(); |
1315 | goto reject_packet; | 1346 | goto reject_packet; |
@@ -1340,6 +1371,13 @@ wrong_security: | |||
1340 | skb->priority = RXKADINCONSISTENCY; | 1371 | skb->priority = RXKADINCONSISTENCY; |
1341 | goto post_abort; | 1372 | goto post_abort; |
1342 | 1373 | ||
1374 | unsupported_service: | ||
1375 | rcu_read_unlock(); | ||
1376 | trace_rxrpc_abort(0, "INV", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, | ||
1377 | RX_INVALID_OPERATION, EOPNOTSUPP); | ||
1378 | skb->priority = RX_INVALID_OPERATION; | ||
1379 | goto post_abort; | ||
1380 | |||
1343 | reupgrade: | 1381 | reupgrade: |
1344 | rcu_read_unlock(); | 1382 | rcu_read_unlock(); |
1345 | trace_rxrpc_abort(0, "UPG", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, | 1383 | trace_rxrpc_abort(0, "UPG", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq, |
@@ -1354,7 +1392,7 @@ bad_message: | |||
1354 | protocol_error: | 1392 | protocol_error: |
1355 | skb->priority = RX_PROTOCOL_ERROR; | 1393 | skb->priority = RX_PROTOCOL_ERROR; |
1356 | post_abort: | 1394 | post_abort: |
1357 | skb->mark = RXRPC_SKB_MARK_LOCAL_ABORT; | 1395 | skb->mark = RXRPC_SKB_MARK_REJECT_ABORT; |
1358 | reject_packet: | 1396 | reject_packet: |
1359 | trace_rxrpc_rx_done(skb->mark, skb->priority); | 1397 | trace_rxrpc_rx_done(skb->mark, skb->priority); |
1360 | rxrpc_reject_packet(local, skb); | 1398 | rxrpc_reject_packet(local, skb); |