RxRPC rewrite
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUAVtmzofSw1s6N8H32AQIgGw/5AUW61fVAiCWsv1jvLmcTm0eDDBivKY4i HfX1vhtxns63NeQ+0P9SiLg5Kc6bNaBr2W+VDcSkHtuoEIrgDReTgizcb/uUOFtI ihsE46jpQJci9h0V9Qa8pQ1w4Ac09vP++d72mD0PyD0sYwqhL1jBp1iROcmzRPCp AC7QalPAOiyep9vdrlUFVxdR60PNe2DlJnXntYgHVmkXmVMDwvcH93CqWML0xubI Qr5rjZrxJA8otwaNyWzGI5+CzVM2x6VaDV2AahFmxMNwbCO8vPEwGsdI4NiHhGHQ 8eUiIYrJdwTFgzMo2BzGq0r6NXxlev/PTOj3swYT4B0AU3vaVsRo+C/vZ1g2c+nA FdN/zS4WfZ1bgfTHcub3WCksXvLnwA9g6kCMreu8Q6t7xd4W6B1gDc1pyZfuB4zi MOg+EOzy+CtwLz70nr5xS8GjjSvoAc3pW4gvPYfhIB/6z/6z3UGLbWa8M+MMd6vQ HDXFKlLqXgTTJHBui3gYrajZaYWh5pxOj0VvrKkWTlHDfz6FfxsCaIMfC3xFOhH3 wYDgnlflKfgJOq0eo5QsNahNi+VZlZNC00h3gCUhYVHUkcFDdvBQxqiEUmTZoa+r UdKW9lxsAMgAx/cW1X0KCh1XtT0theHfdgrBRKpxlJjKfo7UcWoK/sZwzj+P8rl7 pDKOJj3Y2FU= =9CQy -----END PGP SIGNATURE----- Merge tag 'rxrpc-rewrite-20160304' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs David Howells says: ==================== RxRPC: Rewrite part 1 Here's the first set of patches from my RxRPC rewrite, aimed at net-next. These do some clean ups and bug fixes. Most of the changes are small, but there are a couple of bigger changes: (*) Convert call flag numbers and event numbers into enums. Then rename the event numbers to all have _EV_ in their name to stop confusion. Fix one instance of an event bit being used instead of a flag bit. (*) A copy of the Rx protocol header is kept in the sk_buff private data. Keep this in host byte order rather than network byte order as it makes more sense. A number of other fields then get converted into host byte order too. Conversion between host and network byte order is then done at the packet reception/generation stage. This is based on net-next/master ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
94f7153e41
|
@ -22,7 +22,7 @@ typedef __be32 rxrpc_serial_net_t; /* on-the-wire Rx message serial number */
|
|||
* on-the-wire Rx packet header
|
||||
* - all multibyte fields should be in network byte order
|
||||
*/
|
||||
struct rxrpc_header {
|
||||
struct rxrpc_wire_header {
|
||||
__be32 epoch; /* client boot timestamp */
|
||||
|
||||
__be32 cid; /* connection and channel ID */
|
||||
|
@ -68,10 +68,19 @@ struct rxrpc_header {
|
|||
|
||||
} __packed;
|
||||
|
||||
#define __rxrpc_header_off(X) offsetof(struct rxrpc_header,X)
|
||||
|
||||
extern const char *rxrpc_pkts[];
|
||||
|
||||
#define RXRPC_SUPPORTED_PACKET_TYPES ( \
|
||||
(1 << RXRPC_PACKET_TYPE_DATA) | \
|
||||
(1 << RXRPC_PACKET_TYPE_ACK) | \
|
||||
(1 << RXRPC_PACKET_TYPE_BUSY) | \
|
||||
(1 << RXRPC_PACKET_TYPE_ABORT) | \
|
||||
(1 << RXRPC_PACKET_TYPE_ACKALL) | \
|
||||
(1 << RXRPC_PACKET_TYPE_CHALLENGE) | \
|
||||
(1 << RXRPC_PACKET_TYPE_RESPONSE) | \
|
||||
/*(1 << RXRPC_PACKET_TYPE_DEBUG) | */ \
|
||||
(1 << RXRPC_PACKET_TYPE_VERSION))
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* jumbo packet secondary header
|
||||
|
|
|
@ -37,7 +37,7 @@ static struct proto rxrpc_proto;
|
|||
static const struct proto_ops rxrpc_rpc_ops;
|
||||
|
||||
/* local epoch for detecting local-end reset */
|
||||
__be32 rxrpc_epoch;
|
||||
u32 rxrpc_epoch;
|
||||
|
||||
/* current debugging ID */
|
||||
atomic_t rxrpc_debug_id;
|
||||
|
@ -81,6 +81,8 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
|
|||
struct sockaddr_rxrpc *srx,
|
||||
int len)
|
||||
{
|
||||
unsigned tail;
|
||||
|
||||
if (len < sizeof(struct sockaddr_rxrpc))
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -103,9 +105,7 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
|
|||
_debug("INET: %x @ %pI4",
|
||||
ntohs(srx->transport.sin.sin_port),
|
||||
&srx->transport.sin.sin_addr);
|
||||
if (srx->transport_len > 8)
|
||||
memset((void *)&srx->transport + 8, 0,
|
||||
srx->transport_len - 8);
|
||||
tail = offsetof(struct sockaddr_rxrpc, transport.sin.__pad);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
|
@ -113,6 +113,8 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
|
|||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
if (tail < len)
|
||||
memset((void *)srx + tail, 0, len - tail);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -121,11 +123,10 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
|
|||
*/
|
||||
static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
|
||||
{
|
||||
struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *) saddr;
|
||||
struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr;
|
||||
struct sock *sk = sock->sk;
|
||||
struct rxrpc_local *local;
|
||||
struct rxrpc_sock *rx = rxrpc_sk(sk), *prx;
|
||||
__be16 service_id;
|
||||
int ret;
|
||||
|
||||
_enter("%p,%p,%d", rx, saddr, len);
|
||||
|
@ -143,7 +144,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
|
|||
|
||||
memcpy(&rx->srx, srx, sizeof(rx->srx));
|
||||
|
||||
/* find a local transport endpoint if we don't have one already */
|
||||
/* Find or create a local transport endpoint to use */
|
||||
local = rxrpc_lookup_local(&rx->srx);
|
||||
if (IS_ERR(local)) {
|
||||
ret = PTR_ERR(local);
|
||||
|
@ -152,14 +153,12 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
|
|||
|
||||
rx->local = local;
|
||||
if (srx->srx_service) {
|
||||
service_id = htons(srx->srx_service);
|
||||
write_lock_bh(&local->services_lock);
|
||||
list_for_each_entry(prx, &local->services, listen_link) {
|
||||
if (prx->service_id == service_id)
|
||||
if (prx->srx.srx_service == srx->srx_service)
|
||||
goto service_in_use;
|
||||
}
|
||||
|
||||
rx->service_id = service_id;
|
||||
list_add_tail(&rx->listen_link, &local->services);
|
||||
write_unlock_bh(&local->services_lock);
|
||||
|
||||
|
@ -276,7 +275,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
|
|||
struct rxrpc_transport *trans;
|
||||
struct rxrpc_call *call;
|
||||
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
|
||||
__be16 service_id;
|
||||
|
||||
_enter(",,%x,%lx", key_serial(key), user_call_ID);
|
||||
|
||||
|
@ -299,16 +297,14 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
|
|||
atomic_inc(&trans->usage);
|
||||
}
|
||||
|
||||
service_id = rx->service_id;
|
||||
if (srx)
|
||||
service_id = htons(srx->srx_service);
|
||||
|
||||
if (!srx)
|
||||
srx = &rx->srx;
|
||||
if (!key)
|
||||
key = rx->key;
|
||||
if (key && !key->payload.data[0])
|
||||
key = NULL; /* a no-security key */
|
||||
|
||||
bundle = rxrpc_get_bundle(rx, trans, key, service_id, gfp);
|
||||
bundle = rxrpc_get_bundle(rx, trans, key, srx->srx_service, gfp);
|
||||
if (IS_ERR(bundle)) {
|
||||
call = ERR_CAST(bundle);
|
||||
goto out;
|
||||
|
@ -324,7 +320,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
|
|||
_leave(" = %p", call);
|
||||
return call;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(rxrpc_kernel_begin_call);
|
||||
|
||||
/**
|
||||
|
@ -340,7 +335,6 @@ void rxrpc_kernel_end_call(struct rxrpc_call *call)
|
|||
rxrpc_remove_user_ID(call->socket, call);
|
||||
rxrpc_put_call(call);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(rxrpc_kernel_end_call);
|
||||
|
||||
/**
|
||||
|
@ -425,7 +419,6 @@ static int rxrpc_connect(struct socket *sock, struct sockaddr *addr,
|
|||
}
|
||||
|
||||
rx->trans = trans;
|
||||
rx->service_id = htons(srx->srx_service);
|
||||
rx->sk.sk_state = RXRPC_CLIENT_CONNECTED;
|
||||
|
||||
release_sock(&rx->sk);
|
||||
|
@ -622,7 +615,7 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
|
|||
if (!net_eq(net, &init_net))
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
/* we support transport protocol UDP only */
|
||||
/* we support transport protocol UDP/UDP6 only */
|
||||
if (protocol != PF_INET)
|
||||
return -EPROTONOSUPPORT;
|
||||
|
||||
|
@ -754,7 +747,7 @@ static int rxrpc_release(struct socket *sock)
|
|||
* RxRPC network protocol
|
||||
*/
|
||||
static const struct proto_ops rxrpc_rpc_ops = {
|
||||
.family = PF_UNIX,
|
||||
.family = PF_RXRPC,
|
||||
.owner = THIS_MODULE,
|
||||
.release = rxrpc_release,
|
||||
.bind = rxrpc_bind,
|
||||
|
@ -778,7 +771,7 @@ static struct proto rxrpc_proto = {
|
|||
.name = "RXRPC",
|
||||
.owner = THIS_MODULE,
|
||||
.obj_size = sizeof(struct rxrpc_sock),
|
||||
.max_header = sizeof(struct rxrpc_header),
|
||||
.max_header = sizeof(struct rxrpc_wire_header),
|
||||
};
|
||||
|
||||
static const struct net_proto_family rxrpc_family_ops = {
|
||||
|
@ -796,7 +789,7 @@ static int __init af_rxrpc_init(void)
|
|||
|
||||
BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > FIELD_SIZEOF(struct sk_buff, cb));
|
||||
|
||||
rxrpc_epoch = htonl(get_seconds());
|
||||
rxrpc_epoch = get_seconds();
|
||||
|
||||
ret = -ENOMEM;
|
||||
rxrpc_call_jar = kmem_cache_create(
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
* generate a connection-level abort
|
||||
*/
|
||||
static int rxrpc_busy(struct rxrpc_local *local, struct sockaddr_rxrpc *srx,
|
||||
struct rxrpc_header *hdr)
|
||||
struct rxrpc_wire_header *whdr)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct kvec iov[1];
|
||||
|
@ -36,25 +36,21 @@ static int rxrpc_busy(struct rxrpc_local *local, struct sockaddr_rxrpc *srx,
|
|||
|
||||
_enter("%d,,", local->debug_id);
|
||||
|
||||
whdr->type = RXRPC_PACKET_TYPE_BUSY;
|
||||
whdr->serial = htonl(1);
|
||||
|
||||
msg.msg_name = &srx->transport.sin;
|
||||
msg.msg_namelen = sizeof(srx->transport.sin);
|
||||
msg.msg_control = NULL;
|
||||
msg.msg_controllen = 0;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
hdr->seq = 0;
|
||||
hdr->type = RXRPC_PACKET_TYPE_BUSY;
|
||||
hdr->flags = 0;
|
||||
hdr->userStatus = 0;
|
||||
hdr->_rsvd = 0;
|
||||
|
||||
iov[0].iov_base = hdr;
|
||||
iov[0].iov_len = sizeof(*hdr);
|
||||
iov[0].iov_base = whdr;
|
||||
iov[0].iov_len = sizeof(*whdr);
|
||||
|
||||
len = iov[0].iov_len;
|
||||
|
||||
hdr->serial = htonl(1);
|
||||
_proto("Tx BUSY %%%u", ntohl(hdr->serial));
|
||||
_proto("Tx BUSY %%1");
|
||||
|
||||
ret = kernel_sendmsg(local->socket, &msg, iov, 1, len);
|
||||
if (ret < 0) {
|
||||
|
@ -185,8 +181,8 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local,
|
|||
read_unlock_bh(&local->services_lock);
|
||||
|
||||
read_lock_bh(&call->state_lock);
|
||||
if (!test_bit(RXRPC_CALL_RELEASE, &call->flags) &&
|
||||
!test_and_set_bit(RXRPC_CALL_RELEASE, &call->events)) {
|
||||
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
|
||||
!test_and_set_bit(RXRPC_CALL_EV_RELEASE, &call->events)) {
|
||||
rxrpc_get_call(call);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
|
@ -211,8 +207,8 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
|
|||
struct rxrpc_skb_priv *sp;
|
||||
struct sockaddr_rxrpc srx;
|
||||
struct rxrpc_sock *rx;
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct sk_buff *skb;
|
||||
__be16 service_id;
|
||||
int ret;
|
||||
|
||||
_enter("%d", local->debug_id);
|
||||
|
@ -240,6 +236,19 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
|
|||
|
||||
sp = rxrpc_skb(skb);
|
||||
|
||||
/* Set up a response packet header in case we need it */
|
||||
whdr.epoch = htonl(sp->hdr.epoch);
|
||||
whdr.cid = htonl(sp->hdr.cid);
|
||||
whdr.callNumber = htonl(sp->hdr.callNumber);
|
||||
whdr.seq = htonl(sp->hdr.seq);
|
||||
whdr.serial = 0;
|
||||
whdr.flags = 0;
|
||||
whdr.type = 0;
|
||||
whdr.userStatus = 0;
|
||||
whdr.securityIndex = sp->hdr.securityIndex;
|
||||
whdr._rsvd = 0;
|
||||
whdr.serviceId = htons(sp->hdr.serviceId);
|
||||
|
||||
/* determine the remote address */
|
||||
memset(&srx, 0, sizeof(srx));
|
||||
srx.srx_family = AF_RXRPC;
|
||||
|
@ -256,10 +265,9 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
|
|||
}
|
||||
|
||||
/* get the socket providing the service */
|
||||
service_id = sp->hdr.serviceId;
|
||||
read_lock_bh(&local->services_lock);
|
||||
list_for_each_entry(rx, &local->services, listen_link) {
|
||||
if (rx->service_id == service_id &&
|
||||
if (rx->srx.srx_service == sp->hdr.serviceId &&
|
||||
rx->sk.sk_state != RXRPC_CLOSE)
|
||||
goto found_service;
|
||||
}
|
||||
|
@ -267,7 +275,7 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
|
|||
goto invalid_service;
|
||||
|
||||
found_service:
|
||||
_debug("found service %hd", ntohs(rx->service_id));
|
||||
_debug("found service %hd", rx->srx.srx_service);
|
||||
if (sk_acceptq_is_full(&rx->sk))
|
||||
goto backlog_full;
|
||||
sk_acceptq_added(&rx->sk);
|
||||
|
@ -296,7 +304,7 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
|
|||
backlog_full:
|
||||
read_unlock_bh(&local->services_lock);
|
||||
busy:
|
||||
rxrpc_busy(local, &srx, &sp->hdr);
|
||||
rxrpc_busy(local, &srx, &whdr);
|
||||
rxrpc_free_skb(skb);
|
||||
goto process_next_packet;
|
||||
|
||||
|
@ -379,7 +387,7 @@ struct rxrpc_call *rxrpc_accept_call(struct rxrpc_sock *rx,
|
|||
rb_insert_color(&call->sock_node, &rx->calls);
|
||||
if (test_and_set_bit(RXRPC_CALL_HAS_USERID, &call->flags))
|
||||
BUG();
|
||||
if (test_and_set_bit(RXRPC_CALL_ACCEPTED, &call->events))
|
||||
if (test_and_set_bit(RXRPC_CALL_EV_ACCEPTED, &call->events))
|
||||
BUG();
|
||||
rxrpc_queue_call(call);
|
||||
|
||||
|
@ -395,7 +403,7 @@ struct rxrpc_call *rxrpc_accept_call(struct rxrpc_sock *rx,
|
|||
out_release:
|
||||
_debug("release %p", call);
|
||||
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
|
||||
!test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_RELEASE, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
out_discard:
|
||||
write_unlock_bh(&call->state_lock);
|
||||
|
@ -407,7 +415,7 @@ struct rxrpc_call *rxrpc_accept_call(struct rxrpc_sock *rx,
|
|||
}
|
||||
|
||||
/*
|
||||
* handle rejectance of a call by userspace
|
||||
* Handle rejection of a call by userspace
|
||||
* - reject the call at the front of the queue
|
||||
*/
|
||||
int rxrpc_reject_call(struct rxrpc_sock *rx)
|
||||
|
@ -434,7 +442,7 @@ int rxrpc_reject_call(struct rxrpc_sock *rx)
|
|||
switch (call->state) {
|
||||
case RXRPC_CALL_SERVER_ACCEPTING:
|
||||
call->state = RXRPC_CALL_SERVER_BUSY;
|
||||
if (test_and_set_bit(RXRPC_CALL_REJECT_BUSY, &call->events))
|
||||
if (test_and_set_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
ret = 0;
|
||||
goto out_release;
|
||||
|
@ -458,7 +466,7 @@ int rxrpc_reject_call(struct rxrpc_sock *rx)
|
|||
out_release:
|
||||
_debug("release %p", call);
|
||||
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
|
||||
!test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_RELEASE, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
out_discard:
|
||||
write_unlock_bh(&call->state_lock);
|
||||
|
@ -487,7 +495,6 @@ struct rxrpc_call *rxrpc_kernel_accept_call(struct socket *sock,
|
|||
_leave(" = %p", call);
|
||||
return call;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(rxrpc_kernel_accept_call);
|
||||
|
||||
/**
|
||||
|
@ -506,5 +513,4 @@ int rxrpc_kernel_reject_call(struct socket *sock)
|
|||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(rxrpc_kernel_reject_call);
|
||||
|
|
|
@ -91,7 +91,7 @@ static const s8 rxrpc_ack_priority[] = {
|
|||
* propose an ACK be sent
|
||||
*/
|
||||
void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
|
||||
__be32 serial, bool immediate)
|
||||
u32 serial, bool immediate)
|
||||
{
|
||||
unsigned long expiry;
|
||||
s8 prior = rxrpc_ack_priority[ack_reason];
|
||||
|
@ -99,8 +99,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
|
|||
ASSERTCMP(prior, >, 0);
|
||||
|
||||
_enter("{%d},%s,%%%x,%u",
|
||||
call->debug_id, rxrpc_acks(ack_reason), ntohl(serial),
|
||||
immediate);
|
||||
call->debug_id, rxrpc_acks(ack_reason), serial, immediate);
|
||||
|
||||
if (prior < rxrpc_ack_priority[call->ackr_reason]) {
|
||||
if (immediate)
|
||||
|
@ -139,7 +138,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
|
|||
expiry = rxrpc_requested_ack_delay;
|
||||
if (!expiry)
|
||||
goto cancel_timer;
|
||||
if (!immediate || serial == cpu_to_be32(1)) {
|
||||
if (!immediate || serial == 1) {
|
||||
_debug("run defer timer");
|
||||
goto run_timer;
|
||||
}
|
||||
|
@ -157,11 +156,11 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
|
|||
return;
|
||||
|
||||
cancel_timer:
|
||||
_debug("cancel timer %%%u", ntohl(serial));
|
||||
_debug("cancel timer %%%u", serial);
|
||||
try_to_del_timer_sync(&call->ack_timer);
|
||||
read_lock_bh(&call->state_lock);
|
||||
if (call->state <= RXRPC_CALL_COMPLETE &&
|
||||
!test_and_set_bit(RXRPC_CALL_ACK, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_ACK, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
read_unlock_bh(&call->state_lock);
|
||||
}
|
||||
|
@ -170,7 +169,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
|
|||
* propose an ACK be sent, locking the call structure
|
||||
*/
|
||||
void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
|
||||
__be32 serial, bool immediate)
|
||||
u32 serial, bool immediate)
|
||||
{
|
||||
s8 prior = rxrpc_ack_priority[ack_reason];
|
||||
|
||||
|
@ -193,7 +192,7 @@ static void rxrpc_set_resend(struct rxrpc_call *call, u8 resend,
|
|||
|
||||
if (resend & 1) {
|
||||
_debug("SET RESEND");
|
||||
set_bit(RXRPC_CALL_RESEND, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_RESEND, &call->events);
|
||||
}
|
||||
|
||||
if (resend & 2) {
|
||||
|
@ -203,7 +202,7 @@ static void rxrpc_set_resend(struct rxrpc_call *call, u8 resend,
|
|||
} else {
|
||||
_debug("KILL RESEND TIMER");
|
||||
del_timer_sync(&call->resend_timer);
|
||||
clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
|
||||
}
|
||||
read_unlock_bh(&call->state_lock);
|
||||
|
@ -214,8 +213,8 @@ static void rxrpc_set_resend(struct rxrpc_call *call, u8 resend,
|
|||
*/
|
||||
static void rxrpc_resend(struct rxrpc_call *call)
|
||||
{
|
||||
struct rxrpc_wire_header *whdr;
|
||||
struct rxrpc_skb_priv *sp;
|
||||
struct rxrpc_header *hdr;
|
||||
struct sk_buff *txb;
|
||||
unsigned long *p_txb, resend_at;
|
||||
bool stop;
|
||||
|
@ -247,14 +246,13 @@ static void rxrpc_resend(struct rxrpc_call *call)
|
|||
sp->need_resend = false;
|
||||
|
||||
/* each Tx packet has a new serial number */
|
||||
sp->hdr.serial =
|
||||
htonl(atomic_inc_return(&call->conn->serial));
|
||||
sp->hdr.serial = atomic_inc_return(&call->conn->serial);
|
||||
|
||||
hdr = (struct rxrpc_header *) txb->head;
|
||||
hdr->serial = sp->hdr.serial;
|
||||
whdr = (struct rxrpc_wire_header *)txb->head;
|
||||
whdr->serial = htonl(sp->hdr.serial);
|
||||
|
||||
_proto("Tx DATA %%%u { #%d }",
|
||||
ntohl(sp->hdr.serial), ntohl(sp->hdr.seq));
|
||||
sp->hdr.serial, sp->hdr.seq);
|
||||
if (rxrpc_send_packet(call->conn->trans, txb) < 0) {
|
||||
stop = true;
|
||||
sp->resend_at = jiffies + 3;
|
||||
|
@ -428,7 +426,7 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, u32 hard)
|
|||
int tail = call->acks_tail, old_tail;
|
||||
int win = CIRC_CNT(call->acks_head, tail, call->acks_winsz);
|
||||
|
||||
_enter("{%u,%u},%u", call->acks_hard, win, hard);
|
||||
kenter("{%u,%u},%u", call->acks_hard, win, hard);
|
||||
|
||||
ASSERTCMP(hard - call->acks_hard, <=, win);
|
||||
|
||||
|
@ -478,11 +476,11 @@ static int rxrpc_drain_rx_oos_queue(struct rxrpc_call *call)
|
|||
sp = rxrpc_skb(skb);
|
||||
|
||||
_debug("drain OOS packet %d [%d]",
|
||||
ntohl(sp->hdr.seq), call->rx_first_oos);
|
||||
sp->hdr.seq, call->rx_first_oos);
|
||||
|
||||
if (ntohl(sp->hdr.seq) != call->rx_first_oos) {
|
||||
if (sp->hdr.seq != call->rx_first_oos) {
|
||||
skb_queue_head(&call->rx_oos_queue, skb);
|
||||
call->rx_first_oos = ntohl(rxrpc_skb(skb)->hdr.seq);
|
||||
call->rx_first_oos = rxrpc_skb(skb)->hdr.seq;
|
||||
_debug("requeue %p {%u}", skb, call->rx_first_oos);
|
||||
} else {
|
||||
skb->mark = RXRPC_SKB_MARK_DATA;
|
||||
|
@ -496,8 +494,7 @@ static int rxrpc_drain_rx_oos_queue(struct rxrpc_call *call)
|
|||
/* find out what the next packet is */
|
||||
skb = skb_peek(&call->rx_oos_queue);
|
||||
if (skb)
|
||||
call->rx_first_oos =
|
||||
ntohl(rxrpc_skb(skb)->hdr.seq);
|
||||
call->rx_first_oos = rxrpc_skb(skb)->hdr.seq;
|
||||
else
|
||||
call->rx_first_oos = 0;
|
||||
_debug("peek %p {%u}", skb, call->rx_first_oos);
|
||||
|
@ -522,7 +519,7 @@ static void rxrpc_insert_oos_packet(struct rxrpc_call *call,
|
|||
u32 seq;
|
||||
|
||||
sp = rxrpc_skb(skb);
|
||||
seq = ntohl(sp->hdr.seq);
|
||||
seq = sp->hdr.seq;
|
||||
_enter(",,{%u}", seq);
|
||||
|
||||
skb->destructor = rxrpc_packet_destructor;
|
||||
|
@ -535,9 +532,8 @@ static void rxrpc_insert_oos_packet(struct rxrpc_call *call,
|
|||
|
||||
skb_queue_walk(&call->rx_oos_queue, p) {
|
||||
psp = rxrpc_skb(p);
|
||||
if (ntohl(psp->hdr.seq) > seq) {
|
||||
_debug("insert oos #%u before #%u",
|
||||
seq, ntohl(psp->hdr.seq));
|
||||
if (psp->hdr.seq > seq) {
|
||||
_debug("insert oos #%u before #%u", seq, psp->hdr.seq);
|
||||
skb_insert(p, skb, &call->rx_oos_queue);
|
||||
goto inserted;
|
||||
}
|
||||
|
@ -555,7 +551,7 @@ static void rxrpc_insert_oos_packet(struct rxrpc_call *call,
|
|||
if (call->state < RXRPC_CALL_COMPLETE &&
|
||||
call->rx_data_post == call->rx_first_oos) {
|
||||
_debug("drain rx oos now");
|
||||
set_bit(RXRPC_CALL_DRAIN_RX_OOS, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_DRAIN_RX_OOS, &call->events);
|
||||
}
|
||||
read_unlock(&call->state_lock);
|
||||
|
||||
|
@ -586,7 +582,7 @@ static void rxrpc_zap_tx_window(struct rxrpc_call *call)
|
|||
|
||||
skb = (struct sk_buff *) _skb;
|
||||
sp = rxrpc_skb(skb);
|
||||
_debug("+++ clear Tx %u", ntohl(sp->hdr.seq));
|
||||
_debug("+++ clear Tx %u", sp->hdr.seq);
|
||||
rxrpc_free_skb(skb);
|
||||
}
|
||||
|
||||
|
@ -657,8 +653,7 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
|
|||
/* data packets that wind up here have been received out of
|
||||
* order, need security processing or are jumbo packets */
|
||||
case RXRPC_PACKET_TYPE_DATA:
|
||||
_proto("OOSQ DATA %%%u { #%u }",
|
||||
ntohl(sp->hdr.serial), ntohl(sp->hdr.seq));
|
||||
_proto("OOSQ DATA %%%u { #%u }", sp->hdr.serial, sp->hdr.seq);
|
||||
|
||||
/* secured packets must be verified and possibly decrypted */
|
||||
if (rxrpc_verify_packet(call, skb, _abort_code) < 0)
|
||||
|
@ -676,7 +671,7 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
|
|||
if (!skb_pull(skb, sizeof(ack)))
|
||||
BUG();
|
||||
|
||||
latest = ntohl(sp->hdr.serial);
|
||||
latest = sp->hdr.serial;
|
||||
hard = ntohl(ack.firstPacket);
|
||||
tx = atomic_read(&call->sequence);
|
||||
|
||||
|
@ -793,7 +788,7 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
|
|||
|
||||
del_timer_sync(&call->resend_timer);
|
||||
clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
|
||||
clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events);
|
||||
|
||||
if (call->acks_window)
|
||||
rxrpc_zap_tx_window(call);
|
||||
|
@ -881,16 +876,17 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
{
|
||||
struct rxrpc_call *call =
|
||||
container_of(work, struct rxrpc_call, processor);
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct rxrpc_ackpacket ack;
|
||||
struct rxrpc_ackinfo ackinfo;
|
||||
struct rxrpc_header hdr;
|
||||
struct msghdr msg;
|
||||
struct kvec iov[5];
|
||||
enum rxrpc_call_event genbit;
|
||||
unsigned long bits;
|
||||
__be32 data, pad;
|
||||
size_t len;
|
||||
int genbit, loop, nbit, ioc, ret, mtu;
|
||||
u32 abort_code = RX_PROTOCOL_ERROR;
|
||||
int loop, nbit, ioc, ret, mtu;
|
||||
u32 serial, abort_code = RX_PROTOCOL_ERROR;
|
||||
u8 *acks = NULL;
|
||||
|
||||
//printk("\n--------------------\n");
|
||||
|
@ -911,33 +907,33 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
msg.msg_controllen = 0;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
hdr.epoch = call->conn->epoch;
|
||||
hdr.cid = call->cid;
|
||||
hdr.callNumber = call->call_id;
|
||||
hdr.seq = 0;
|
||||
hdr.type = RXRPC_PACKET_TYPE_ACK;
|
||||
hdr.flags = call->conn->out_clientflag;
|
||||
hdr.userStatus = 0;
|
||||
hdr.securityIndex = call->conn->security_ix;
|
||||
hdr._rsvd = 0;
|
||||
hdr.serviceId = call->conn->service_id;
|
||||
whdr.epoch = htonl(call->conn->epoch);
|
||||
whdr.cid = htonl(call->cid);
|
||||
whdr.callNumber = htonl(call->call_id);
|
||||
whdr.seq = 0;
|
||||
whdr.type = RXRPC_PACKET_TYPE_ACK;
|
||||
whdr.flags = call->conn->out_clientflag;
|
||||
whdr.userStatus = 0;
|
||||
whdr.securityIndex = call->conn->security_ix;
|
||||
whdr._rsvd = 0;
|
||||
whdr.serviceId = htons(call->service_id);
|
||||
|
||||
memset(iov, 0, sizeof(iov));
|
||||
iov[0].iov_base = &hdr;
|
||||
iov[0].iov_len = sizeof(hdr);
|
||||
iov[0].iov_base = &whdr;
|
||||
iov[0].iov_len = sizeof(whdr);
|
||||
|
||||
/* deal with events of a final nature */
|
||||
if (test_bit(RXRPC_CALL_RELEASE, &call->events)) {
|
||||
if (test_bit(RXRPC_CALL_EV_RELEASE, &call->events)) {
|
||||
rxrpc_release_call(call);
|
||||
clear_bit(RXRPC_CALL_RELEASE, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RELEASE, &call->events);
|
||||
}
|
||||
|
||||
if (test_bit(RXRPC_CALL_RCVD_ERROR, &call->events)) {
|
||||
if (test_bit(RXRPC_CALL_EV_RCVD_ERROR, &call->events)) {
|
||||
int error;
|
||||
|
||||
clear_bit(RXRPC_CALL_CONN_ABORT, &call->events);
|
||||
clear_bit(RXRPC_CALL_REJECT_BUSY, &call->events);
|
||||
clear_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
|
||||
error = call->conn->trans->peer->net_error;
|
||||
_debug("post net error %d", error);
|
||||
|
@ -945,47 +941,47 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
if (rxrpc_post_message(call, RXRPC_SKB_MARK_NET_ERROR,
|
||||
error, true) < 0)
|
||||
goto no_mem;
|
||||
clear_bit(RXRPC_CALL_RCVD_ERROR, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RCVD_ERROR, &call->events);
|
||||
goto kill_ACKs;
|
||||
}
|
||||
|
||||
if (test_bit(RXRPC_CALL_CONN_ABORT, &call->events)) {
|
||||
if (test_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events)) {
|
||||
ASSERTCMP(call->state, >, RXRPC_CALL_COMPLETE);
|
||||
|
||||
clear_bit(RXRPC_CALL_REJECT_BUSY, &call->events);
|
||||
clear_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
|
||||
_debug("post conn abort");
|
||||
|
||||
if (rxrpc_post_message(call, RXRPC_SKB_MARK_LOCAL_ERROR,
|
||||
call->conn->error, true) < 0)
|
||||
goto no_mem;
|
||||
clear_bit(RXRPC_CALL_CONN_ABORT, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events);
|
||||
goto kill_ACKs;
|
||||
}
|
||||
|
||||
if (test_bit(RXRPC_CALL_REJECT_BUSY, &call->events)) {
|
||||
hdr.type = RXRPC_PACKET_TYPE_BUSY;
|
||||
genbit = RXRPC_CALL_REJECT_BUSY;
|
||||
if (test_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events)) {
|
||||
whdr.type = RXRPC_PACKET_TYPE_BUSY;
|
||||
genbit = RXRPC_CALL_EV_REJECT_BUSY;
|
||||
goto send_message;
|
||||
}
|
||||
|
||||
if (test_bit(RXRPC_CALL_ABORT, &call->events)) {
|
||||
if (test_bit(RXRPC_CALL_EV_ABORT, &call->events)) {
|
||||
ASSERTCMP(call->state, >, RXRPC_CALL_COMPLETE);
|
||||
|
||||
if (rxrpc_post_message(call, RXRPC_SKB_MARK_LOCAL_ERROR,
|
||||
ECONNABORTED, true) < 0)
|
||||
goto no_mem;
|
||||
hdr.type = RXRPC_PACKET_TYPE_ABORT;
|
||||
whdr.type = RXRPC_PACKET_TYPE_ABORT;
|
||||
data = htonl(call->abort_code);
|
||||
iov[1].iov_base = &data;
|
||||
iov[1].iov_len = sizeof(data);
|
||||
genbit = RXRPC_CALL_ABORT;
|
||||
genbit = RXRPC_CALL_EV_ABORT;
|
||||
goto send_message;
|
||||
}
|
||||
|
||||
if (test_bit(RXRPC_CALL_ACK_FINAL, &call->events)) {
|
||||
genbit = RXRPC_CALL_ACK_FINAL;
|
||||
if (test_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events)) {
|
||||
genbit = RXRPC_CALL_EV_ACK_FINAL;
|
||||
|
||||
ack.bufferSpace = htons(8);
|
||||
ack.maxSkew = 0;
|
||||
|
@ -995,9 +991,9 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
call->ackr_reason = 0;
|
||||
|
||||
spin_lock_bh(&call->lock);
|
||||
ack.serial = call->ackr_serial;
|
||||
ack.previousPacket = call->ackr_prev_seq;
|
||||
ack.firstPacket = htonl(call->rx_data_eaten + 1);
|
||||
ack.serial = htonl(call->ackr_serial);
|
||||
ack.previousPacket = htonl(call->ackr_prev_seq);
|
||||
ack.firstPacket = htonl(call->rx_data_eaten + 1);
|
||||
spin_unlock_bh(&call->lock);
|
||||
|
||||
pad = 0;
|
||||
|
@ -1011,12 +1007,12 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
goto send_ACK;
|
||||
}
|
||||
|
||||
if (call->events & ((1 << RXRPC_CALL_RCVD_BUSY) |
|
||||
(1 << RXRPC_CALL_RCVD_ABORT))
|
||||
if (call->events & ((1 << RXRPC_CALL_EV_RCVD_BUSY) |
|
||||
(1 << RXRPC_CALL_EV_RCVD_ABORT))
|
||||
) {
|
||||
u32 mark;
|
||||
|
||||
if (test_bit(RXRPC_CALL_RCVD_ABORT, &call->events))
|
||||
if (test_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events))
|
||||
mark = RXRPC_SKB_MARK_REMOTE_ABORT;
|
||||
else
|
||||
mark = RXRPC_SKB_MARK_BUSY;
|
||||
|
@ -1026,22 +1022,22 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
if (rxrpc_post_message(call, mark, ECONNABORTED, true) < 0)
|
||||
goto no_mem;
|
||||
|
||||
clear_bit(RXRPC_CALL_RCVD_BUSY, &call->events);
|
||||
clear_bit(RXRPC_CALL_RCVD_ABORT, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RCVD_BUSY, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
|
||||
goto kill_ACKs;
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(RXRPC_CALL_RCVD_ACKALL, &call->events)) {
|
||||
if (test_and_clear_bit(RXRPC_CALL_EV_RCVD_ACKALL, &call->events)) {
|
||||
_debug("do implicit ackall");
|
||||
rxrpc_clear_tx_window(call);
|
||||
}
|
||||
|
||||
if (test_bit(RXRPC_CALL_LIFE_TIMER, &call->events)) {
|
||||
if (test_bit(RXRPC_CALL_EV_LIFE_TIMER, &call->events)) {
|
||||
write_lock_bh(&call->state_lock);
|
||||
if (call->state <= RXRPC_CALL_COMPLETE) {
|
||||
call->state = RXRPC_CALL_LOCALLY_ABORTED;
|
||||
call->abort_code = RX_CALL_TIMEOUT;
|
||||
set_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
}
|
||||
write_unlock_bh(&call->state_lock);
|
||||
|
||||
|
@ -1050,7 +1046,7 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
ETIME, true) < 0)
|
||||
goto no_mem;
|
||||
|
||||
clear_bit(RXRPC_CALL_LIFE_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_LIFE_TIMER, &call->events);
|
||||
goto kill_ACKs;
|
||||
}
|
||||
|
||||
|
@ -1071,13 +1067,13 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
}
|
||||
|
||||
/* handle resending */
|
||||
if (test_and_clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events))
|
||||
if (test_and_clear_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events))
|
||||
rxrpc_resend_timer(call);
|
||||
if (test_and_clear_bit(RXRPC_CALL_RESEND, &call->events))
|
||||
if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events))
|
||||
rxrpc_resend(call);
|
||||
|
||||
/* consider sending an ordinary ACK */
|
||||
if (test_bit(RXRPC_CALL_ACK, &call->events)) {
|
||||
if (test_bit(RXRPC_CALL_EV_ACK, &call->events)) {
|
||||
_debug("send ACK: window: %d - %d { %lx }",
|
||||
call->rx_data_eaten, call->ackr_win_top,
|
||||
call->ackr_window[0]);
|
||||
|
@ -1085,11 +1081,11 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
if (call->state > RXRPC_CALL_SERVER_ACK_REQUEST &&
|
||||
call->ackr_reason != RXRPC_ACK_PING_RESPONSE) {
|
||||
/* ACK by sending reply DATA packet in this state */
|
||||
clear_bit(RXRPC_CALL_ACK, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_ACK, &call->events);
|
||||
goto maybe_reschedule;
|
||||
}
|
||||
|
||||
genbit = RXRPC_CALL_ACK;
|
||||
genbit = RXRPC_CALL_EV_ACK;
|
||||
|
||||
acks = kzalloc(call->ackr_win_top - call->rx_data_eaten,
|
||||
GFP_NOFS);
|
||||
|
@ -1099,13 +1095,11 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
//hdr.flags = RXRPC_SLOW_START_OK;
|
||||
ack.bufferSpace = htons(8);
|
||||
ack.maxSkew = 0;
|
||||
ack.serial = 0;
|
||||
ack.reason = 0;
|
||||
|
||||
spin_lock_bh(&call->lock);
|
||||
ack.reason = call->ackr_reason;
|
||||
ack.serial = call->ackr_serial;
|
||||
ack.previousPacket = call->ackr_prev_seq;
|
||||
ack.reason = call->ackr_reason;
|
||||
ack.serial = htonl(call->ackr_serial);
|
||||
ack.previousPacket = htonl(call->ackr_prev_seq);
|
||||
ack.firstPacket = htonl(call->rx_data_eaten + 1);
|
||||
|
||||
ack.nAcks = 0;
|
||||
|
@ -1152,7 +1146,7 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
|
||||
/* handle completion of security negotiations on an incoming
|
||||
* connection */
|
||||
if (test_and_clear_bit(RXRPC_CALL_SECURED, &call->events)) {
|
||||
if (test_and_clear_bit(RXRPC_CALL_EV_SECURED, &call->events)) {
|
||||
_debug("secured");
|
||||
spin_lock_bh(&call->lock);
|
||||
|
||||
|
@ -1160,7 +1154,7 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
_debug("securing");
|
||||
write_lock(&call->conn->lock);
|
||||
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
|
||||
!test_bit(RXRPC_CALL_RELEASE, &call->events)) {
|
||||
!test_bit(RXRPC_CALL_EV_RELEASE, &call->events)) {
|
||||
_debug("not released");
|
||||
call->state = RXRPC_CALL_SERVER_ACCEPTING;
|
||||
list_move_tail(&call->accept_link,
|
||||
|
@ -1169,39 +1163,39 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
write_unlock(&call->conn->lock);
|
||||
read_lock(&call->state_lock);
|
||||
if (call->state < RXRPC_CALL_COMPLETE)
|
||||
set_bit(RXRPC_CALL_POST_ACCEPT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_POST_ACCEPT, &call->events);
|
||||
read_unlock(&call->state_lock);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&call->lock);
|
||||
if (!test_bit(RXRPC_CALL_POST_ACCEPT, &call->events))
|
||||
if (!test_bit(RXRPC_CALL_EV_POST_ACCEPT, &call->events))
|
||||
goto maybe_reschedule;
|
||||
}
|
||||
|
||||
/* post a notification of an acceptable connection to the app */
|
||||
if (test_bit(RXRPC_CALL_POST_ACCEPT, &call->events)) {
|
||||
if (test_bit(RXRPC_CALL_EV_POST_ACCEPT, &call->events)) {
|
||||
_debug("post accept");
|
||||
if (rxrpc_post_message(call, RXRPC_SKB_MARK_NEW_CALL,
|
||||
0, false) < 0)
|
||||
goto no_mem;
|
||||
clear_bit(RXRPC_CALL_POST_ACCEPT, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_POST_ACCEPT, &call->events);
|
||||
goto maybe_reschedule;
|
||||
}
|
||||
|
||||
/* handle incoming call acceptance */
|
||||
if (test_and_clear_bit(RXRPC_CALL_ACCEPTED, &call->events)) {
|
||||
if (test_and_clear_bit(RXRPC_CALL_EV_ACCEPTED, &call->events)) {
|
||||
_debug("accepted");
|
||||
ASSERTCMP(call->rx_data_post, ==, 0);
|
||||
call->rx_data_post = 1;
|
||||
read_lock_bh(&call->state_lock);
|
||||
if (call->state < RXRPC_CALL_COMPLETE)
|
||||
set_bit(RXRPC_CALL_DRAIN_RX_OOS, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_DRAIN_RX_OOS, &call->events);
|
||||
read_unlock_bh(&call->state_lock);
|
||||
}
|
||||
|
||||
/* drain the out of sequence received packet queue into the packet Rx
|
||||
* queue */
|
||||
if (test_and_clear_bit(RXRPC_CALL_DRAIN_RX_OOS, &call->events)) {
|
||||
if (test_and_clear_bit(RXRPC_CALL_EV_DRAIN_RX_OOS, &call->events)) {
|
||||
while (call->rx_data_post == call->rx_first_oos)
|
||||
if (rxrpc_drain_rx_oos_queue(call) < 0)
|
||||
break;
|
||||
|
@ -1224,9 +1218,10 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
ackinfo.rxMTU = htonl(rxrpc_rx_mtu);
|
||||
ackinfo.jumbo_max = htonl(rxrpc_rx_jumbo_max);
|
||||
|
||||
hdr.serial = htonl(atomic_inc_return(&call->conn->serial));
|
||||
serial = atomic_inc_return(&call->conn->serial);
|
||||
whdr.serial = htonl(serial);
|
||||
_proto("Tx ACK %%%u { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
|
||||
ntohl(hdr.serial),
|
||||
serial,
|
||||
ntohs(ack.maxSkew),
|
||||
ntohl(ack.firstPacket),
|
||||
ntohl(ack.previousPacket),
|
||||
|
@ -1242,8 +1237,9 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
send_message:
|
||||
_debug("send message");
|
||||
|
||||
hdr.serial = htonl(atomic_inc_return(&call->conn->serial));
|
||||
_proto("Tx %s %%%u", rxrpc_pkts[hdr.type], ntohl(hdr.serial));
|
||||
serial = atomic_inc_return(&call->conn->serial);
|
||||
whdr.serial = htonl(serial);
|
||||
_proto("Tx %s %%%u", rxrpc_pkts[whdr.type], serial);
|
||||
send_message_2:
|
||||
|
||||
len = iov[0].iov_len;
|
||||
|
@ -1280,12 +1276,12 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
}
|
||||
|
||||
switch (genbit) {
|
||||
case RXRPC_CALL_ABORT:
|
||||
case RXRPC_CALL_EV_ABORT:
|
||||
clear_bit(genbit, &call->events);
|
||||
clear_bit(RXRPC_CALL_RCVD_ABORT, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
|
||||
goto kill_ACKs;
|
||||
|
||||
case RXRPC_CALL_ACK_FINAL:
|
||||
case RXRPC_CALL_EV_ACK_FINAL:
|
||||
write_lock_bh(&call->state_lock);
|
||||
if (call->state == RXRPC_CALL_CLIENT_FINAL_ACK)
|
||||
call->state = RXRPC_CALL_COMPLETE;
|
||||
|
@ -1310,9 +1306,9 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
|
||||
kill_ACKs:
|
||||
del_timer_sync(&call->ack_timer);
|
||||
if (test_and_clear_bit(RXRPC_CALL_ACK_FINAL, &call->events))
|
||||
if (test_and_clear_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events))
|
||||
rxrpc_put_call(call);
|
||||
clear_bit(RXRPC_CALL_ACK, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_ACK, &call->events);
|
||||
|
||||
maybe_reschedule:
|
||||
if (call->events || !skb_queue_empty(&call->rx_queue)) {
|
||||
|
@ -1326,12 +1322,11 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
if (call->state >= RXRPC_CALL_COMPLETE &&
|
||||
!list_empty(&call->accept_link)) {
|
||||
_debug("X unlinking once-pending call %p { e=%lx f=%lx c=%x }",
|
||||
call, call->events, call->flags,
|
||||
ntohl(call->conn->cid));
|
||||
call, call->events, call->flags, call->conn->cid);
|
||||
|
||||
read_lock_bh(&call->state_lock);
|
||||
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
|
||||
!test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_RELEASE, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
read_unlock_bh(&call->state_lock);
|
||||
}
|
||||
|
@ -1345,7 +1340,7 @@ void rxrpc_process_call(struct work_struct *work)
|
|||
* this means there's a race between clearing the flag and setting the
|
||||
* work pending bit and the work item being processed again */
|
||||
if (call->events && !work_pending(&call->processor)) {
|
||||
_debug("jumpstart %x", ntohl(call->conn->cid));
|
||||
_debug("jumpstart %x", call->conn->cid);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ unsigned rxrpc_max_call_lifetime = 60 * HZ;
|
|||
*/
|
||||
unsigned rxrpc_dead_call_expiry = 2 * HZ;
|
||||
|
||||
const char *const rxrpc_call_states[] = {
|
||||
const char *const rxrpc_call_states[NR__RXRPC_CALL_STATES] = {
|
||||
[RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq",
|
||||
[RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl",
|
||||
[RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl",
|
||||
|
@ -64,11 +64,11 @@ static DEFINE_HASHTABLE(rxrpc_call_hash, 10);
|
|||
* Hash function for rxrpc_call_hash
|
||||
*/
|
||||
static unsigned long rxrpc_call_hashfunc(
|
||||
u8 clientflag,
|
||||
__be32 cid,
|
||||
__be32 call_id,
|
||||
__be32 epoch,
|
||||
__be16 service_id,
|
||||
u8 in_clientflag,
|
||||
u32 cid,
|
||||
u32 call_id,
|
||||
u32 epoch,
|
||||
u16 service_id,
|
||||
sa_family_t proto,
|
||||
void *localptr,
|
||||
unsigned int addr_size,
|
||||
|
@ -77,7 +77,6 @@ static unsigned long rxrpc_call_hashfunc(
|
|||
const u16 *p;
|
||||
unsigned int i;
|
||||
unsigned long key;
|
||||
u32 hcid = ntohl(cid);
|
||||
|
||||
_enter("");
|
||||
|
||||
|
@ -85,12 +84,12 @@ static unsigned long rxrpc_call_hashfunc(
|
|||
/* We just want to add up the __be32 values, so forcing the
|
||||
* cast should be okay.
|
||||
*/
|
||||
key += (__force u32)epoch;
|
||||
key += (__force u16)service_id;
|
||||
key += (__force u32)call_id;
|
||||
key += (hcid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
|
||||
key += hcid & RXRPC_CHANNELMASK;
|
||||
key += clientflag;
|
||||
key += epoch;
|
||||
key += service_id;
|
||||
key += call_id;
|
||||
key += (cid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
|
||||
key += cid & RXRPC_CHANNELMASK;
|
||||
key += in_clientflag;
|
||||
key += proto;
|
||||
/* Step through the peer address in 16-bit portions for speed */
|
||||
for (i = 0, p = (const u16 *)peer_addr; i < addr_size >> 1; i++, p++)
|
||||
|
@ -148,19 +147,16 @@ static void rxrpc_call_hash_del(struct rxrpc_call *call)
|
|||
* isn't there.
|
||||
*/
|
||||
struct rxrpc_call *rxrpc_find_call_hash(
|
||||
u8 clientflag,
|
||||
__be32 cid,
|
||||
__be32 call_id,
|
||||
__be32 epoch,
|
||||
__be16 service_id,
|
||||
struct rxrpc_host_header *hdr,
|
||||
void *localptr,
|
||||
sa_family_t proto,
|
||||
const u8 *peer_addr)
|
||||
const void *peer_addr)
|
||||
{
|
||||
unsigned long key;
|
||||
unsigned int addr_size = 0;
|
||||
struct rxrpc_call *call = NULL;
|
||||
struct rxrpc_call *ret = NULL;
|
||||
u8 in_clientflag = hdr->flags & RXRPC_CLIENT_INITIATED;
|
||||
|
||||
_enter("");
|
||||
switch (proto) {
|
||||
|
@ -174,20 +170,21 @@ struct rxrpc_call *rxrpc_find_call_hash(
|
|||
break;
|
||||
}
|
||||
|
||||
key = rxrpc_call_hashfunc(clientflag, cid, call_id, epoch,
|
||||
service_id, proto, localptr, addr_size,
|
||||
key = rxrpc_call_hashfunc(in_clientflag, hdr->cid, hdr->callNumber,
|
||||
hdr->epoch, hdr->serviceId,
|
||||
proto, localptr, addr_size,
|
||||
peer_addr);
|
||||
hash_for_each_possible_rcu(rxrpc_call_hash, call, hash_node, key) {
|
||||
if (call->hash_key == key &&
|
||||
call->call_id == call_id &&
|
||||
call->cid == cid &&
|
||||
call->in_clientflag == clientflag &&
|
||||
call->service_id == service_id &&
|
||||
call->call_id == hdr->callNumber &&
|
||||
call->cid == hdr->cid &&
|
||||
call->in_clientflag == in_clientflag &&
|
||||
call->service_id == hdr->serviceId &&
|
||||
call->proto == proto &&
|
||||
call->local == localptr &&
|
||||
memcmp(call->peer_ip.ipv6_addr, peer_addr,
|
||||
addr_size) == 0 &&
|
||||
call->epoch == epoch) {
|
||||
addr_size) == 0 &&
|
||||
call->epoch == hdr->epoch) {
|
||||
ret = call;
|
||||
break;
|
||||
}
|
||||
|
@ -414,12 +411,12 @@ struct rxrpc_call *rxrpc_get_client_call(struct rxrpc_sock *rx,
|
|||
*/
|
||||
struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
|
||||
struct rxrpc_connection *conn,
|
||||
struct rxrpc_header *hdr,
|
||||
struct rxrpc_host_header *hdr,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct rxrpc_call *call, *candidate;
|
||||
struct rb_node **p, *parent;
|
||||
__be32 call_id;
|
||||
u32 call_id;
|
||||
|
||||
_enter(",%d,,%x", conn->debug_id, gfp);
|
||||
|
||||
|
@ -433,7 +430,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
|
|||
candidate->conn = conn;
|
||||
candidate->cid = hdr->cid;
|
||||
candidate->call_id = hdr->callNumber;
|
||||
candidate->channel = ntohl(hdr->cid) & RXRPC_CHANNELMASK;
|
||||
candidate->channel = hdr->cid & RXRPC_CHANNELMASK;
|
||||
candidate->rx_data_post = 0;
|
||||
candidate->state = RXRPC_CALL_SERVER_ACCEPTING;
|
||||
if (conn->security_ix > 0)
|
||||
|
@ -452,7 +449,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
|
|||
read_lock(&call->state_lock);
|
||||
switch (call->state) {
|
||||
case RXRPC_CALL_LOCALLY_ABORTED:
|
||||
if (!test_and_set_bit(RXRPC_CALL_ABORT, &call->events))
|
||||
if (!test_and_set_bit(RXRPC_CALL_EV_ABORT, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
case RXRPC_CALL_REMOTELY_ABORTED:
|
||||
read_unlock(&call->state_lock);
|
||||
|
@ -492,9 +489,9 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
|
|||
/* The tree is sorted in order of the __be32 value without
|
||||
* turning it into host order.
|
||||
*/
|
||||
if ((__force u32)call_id < (__force u32)call->call_id)
|
||||
if (call_id < call->call_id)
|
||||
p = &(*p)->rb_left;
|
||||
else if ((__force u32)call_id > (__force u32)call->call_id)
|
||||
else if (call_id > call->call_id)
|
||||
p = &(*p)->rb_right;
|
||||
else
|
||||
goto old_call;
|
||||
|
@ -686,7 +683,7 @@ void rxrpc_release_call(struct rxrpc_call *call)
|
|||
_debug("+++ ABORTING STATE %d +++\n", call->state);
|
||||
call->state = RXRPC_CALL_LOCALLY_ABORTED;
|
||||
call->abort_code = RX_CALL_DEAD;
|
||||
set_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
write_unlock(&call->state_lock);
|
||||
|
@ -714,8 +711,7 @@ void rxrpc_release_call(struct rxrpc_call *call)
|
|||
|
||||
_debug("- zap %s %%%u #%u",
|
||||
rxrpc_pkts[sp->hdr.type],
|
||||
ntohl(sp->hdr.serial),
|
||||
ntohl(sp->hdr.seq));
|
||||
sp->hdr.serial, sp->hdr.seq);
|
||||
rxrpc_free_skb(skb);
|
||||
spin_lock_bh(&call->lock);
|
||||
}
|
||||
|
@ -763,10 +759,10 @@ static void rxrpc_mark_call_released(struct rxrpc_call *call)
|
|||
_debug("abort call %p", call);
|
||||
call->state = RXRPC_CALL_LOCALLY_ABORTED;
|
||||
call->abort_code = RX_CALL_DEAD;
|
||||
if (!test_and_set_bit(RXRPC_CALL_ABORT, &call->events))
|
||||
if (!test_and_set_bit(RXRPC_CALL_EV_ABORT, &call->events))
|
||||
sched = true;
|
||||
}
|
||||
if (!test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
|
||||
if (!test_and_set_bit(RXRPC_CALL_EV_RELEASE, &call->events))
|
||||
sched = true;
|
||||
if (sched)
|
||||
rxrpc_queue_call(call);
|
||||
|
@ -873,9 +869,9 @@ static void rxrpc_cleanup_call(struct rxrpc_call *call)
|
|||
unsigned long _skb;
|
||||
|
||||
_skb = call->acks_window[call->acks_tail] & ~1;
|
||||
sp = rxrpc_skb((struct sk_buff *) _skb);
|
||||
_debug("+++ clear Tx %u", ntohl(sp->hdr.seq));
|
||||
rxrpc_free_skb((struct sk_buff *) _skb);
|
||||
sp = rxrpc_skb((struct sk_buff *)_skb);
|
||||
_debug("+++ clear Tx %u", sp->hdr.seq);
|
||||
rxrpc_free_skb((struct sk_buff *)_skb);
|
||||
call->acks_tail =
|
||||
(call->acks_tail + 1) & (call->acks_winsz - 1);
|
||||
}
|
||||
|
@ -975,7 +971,7 @@ static void rxrpc_call_life_expired(unsigned long _call)
|
|||
_enter("{%d}", call->debug_id);
|
||||
read_lock_bh(&call->state_lock);
|
||||
if (call->state < RXRPC_CALL_COMPLETE) {
|
||||
set_bit(RXRPC_CALL_LIFE_TIMER, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_LIFE_TIMER, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
read_unlock_bh(&call->state_lock);
|
||||
|
@ -995,7 +991,7 @@ static void rxrpc_resend_time_expired(unsigned long _call)
|
|||
return;
|
||||
|
||||
clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
|
||||
if (!test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events))
|
||||
if (!test_and_set_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
|
||||
|
@ -1013,7 +1009,7 @@ static void rxrpc_ack_time_expired(unsigned long _call)
|
|||
|
||||
read_lock_bh(&call->state_lock);
|
||||
if (call->state < RXRPC_CALL_COMPLETE &&
|
||||
!test_and_set_bit(RXRPC_CALL_ACK, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_ACK, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
read_unlock_bh(&call->state_lock);
|
||||
}
|
||||
|
|
|
@ -57,10 +57,10 @@ static struct rxrpc_conn_bundle *rxrpc_alloc_bundle(gfp_t gfp)
|
|||
*/
|
||||
static inline
|
||||
int rxrpc_cmp_bundle(const struct rxrpc_conn_bundle *bundle,
|
||||
struct key *key, __be16 service_id)
|
||||
struct key *key, u16 service_id)
|
||||
{
|
||||
return (bundle->service_id - service_id) ?:
|
||||
((unsigned long) bundle->key - (unsigned long) key);
|
||||
((unsigned long)bundle->key - (unsigned long)key);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -69,14 +69,14 @@ int rxrpc_cmp_bundle(const struct rxrpc_conn_bundle *bundle,
|
|||
struct rxrpc_conn_bundle *rxrpc_get_bundle(struct rxrpc_sock *rx,
|
||||
struct rxrpc_transport *trans,
|
||||
struct key *key,
|
||||
__be16 service_id,
|
||||
u16 service_id,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct rxrpc_conn_bundle *bundle, *candidate;
|
||||
struct rb_node *p, *parent, **pp;
|
||||
|
||||
_enter("%p{%x},%x,%hx,",
|
||||
rx, key_serial(key), trans->debug_id, ntohs(service_id));
|
||||
rx, key_serial(key), trans->debug_id, service_id);
|
||||
|
||||
if (rx->trans == trans && rx->bundle) {
|
||||
atomic_inc(&rx->bundle->usage);
|
||||
|
@ -213,7 +213,7 @@ static struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
|
|||
conn->debug_id = atomic_inc_return(&rxrpc_debug_id);
|
||||
conn->avail_calls = RXRPC_MAXCALLS;
|
||||
conn->size_align = 4;
|
||||
conn->header_size = sizeof(struct rxrpc_header);
|
||||
conn->header_size = sizeof(struct rxrpc_wire_header);
|
||||
}
|
||||
|
||||
_leave(" = %p{%d}", conn, conn ? conn->debug_id : 0);
|
||||
|
@ -230,7 +230,7 @@ static void rxrpc_assign_connection_id(struct rxrpc_connection *conn)
|
|||
struct rxrpc_connection *xconn;
|
||||
struct rb_node *parent, **p;
|
||||
__be32 epoch;
|
||||
u32 real_conn_id;
|
||||
u32 cid;
|
||||
|
||||
_enter("");
|
||||
|
||||
|
@ -241,7 +241,7 @@ static void rxrpc_assign_connection_id(struct rxrpc_connection *conn)
|
|||
conn->trans->conn_idcounter += RXRPC_CID_INC;
|
||||
if (conn->trans->conn_idcounter < RXRPC_CID_INC)
|
||||
conn->trans->conn_idcounter = RXRPC_CID_INC;
|
||||
real_conn_id = conn->trans->conn_idcounter;
|
||||
cid = conn->trans->conn_idcounter;
|
||||
|
||||
attempt_insertion:
|
||||
parent = NULL;
|
||||
|
@ -255,9 +255,9 @@ static void rxrpc_assign_connection_id(struct rxrpc_connection *conn)
|
|||
p = &(*p)->rb_left;
|
||||
else if (epoch > xconn->epoch)
|
||||
p = &(*p)->rb_right;
|
||||
else if (real_conn_id < xconn->real_conn_id)
|
||||
else if (cid < xconn->cid)
|
||||
p = &(*p)->rb_left;
|
||||
else if (real_conn_id > xconn->real_conn_id)
|
||||
else if (cid > xconn->cid)
|
||||
p = &(*p)->rb_right;
|
||||
else
|
||||
goto id_exists;
|
||||
|
@ -268,20 +268,19 @@ static void rxrpc_assign_connection_id(struct rxrpc_connection *conn)
|
|||
rb_link_node(&conn->node, parent, p);
|
||||
rb_insert_color(&conn->node, &conn->trans->client_conns);
|
||||
|
||||
conn->real_conn_id = real_conn_id;
|
||||
conn->cid = htonl(real_conn_id);
|
||||
conn->cid = cid;
|
||||
write_unlock_bh(&conn->trans->conn_lock);
|
||||
_leave(" [CONNID %x CID %x]", real_conn_id, ntohl(conn->cid));
|
||||
_leave(" [CID %x]", cid);
|
||||
return;
|
||||
|
||||
/* we found a connection with the proposed ID - walk the tree from that
|
||||
* point looking for the next unused ID */
|
||||
id_exists:
|
||||
for (;;) {
|
||||
real_conn_id += RXRPC_CID_INC;
|
||||
if (real_conn_id < RXRPC_CID_INC) {
|
||||
real_conn_id = RXRPC_CID_INC;
|
||||
conn->trans->conn_idcounter = real_conn_id;
|
||||
cid += RXRPC_CID_INC;
|
||||
if (cid < RXRPC_CID_INC) {
|
||||
cid = RXRPC_CID_INC;
|
||||
conn->trans->conn_idcounter = cid;
|
||||
goto attempt_insertion;
|
||||
}
|
||||
|
||||
|
@ -291,7 +290,7 @@ static void rxrpc_assign_connection_id(struct rxrpc_connection *conn)
|
|||
|
||||
xconn = rb_entry(parent, struct rxrpc_connection, node);
|
||||
if (epoch < xconn->epoch ||
|
||||
real_conn_id < xconn->real_conn_id)
|
||||
cid < xconn->cid)
|
||||
goto attempt_insertion;
|
||||
}
|
||||
}
|
||||
|
@ -334,7 +333,7 @@ static void rxrpc_add_call_ID_to_conn(struct rxrpc_connection *conn,
|
|||
*/
|
||||
static int rxrpc_connect_exclusive(struct rxrpc_sock *rx,
|
||||
struct rxrpc_transport *trans,
|
||||
__be16 service_id,
|
||||
u16 service_id,
|
||||
struct rxrpc_call *call,
|
||||
gfp_t gfp)
|
||||
{
|
||||
|
@ -404,11 +403,11 @@ static int rxrpc_connect_exclusive(struct rxrpc_sock *rx,
|
|||
conn->channels[chan] = call;
|
||||
call->conn = conn;
|
||||
call->channel = chan;
|
||||
call->cid = conn->cid | htonl(chan);
|
||||
call->call_id = htonl(++conn->call_counter);
|
||||
call->cid = conn->cid | chan;
|
||||
call->call_id = ++conn->call_counter;
|
||||
|
||||
_net("CONNECT client on conn %d chan %d as call %x",
|
||||
conn->debug_id, chan, ntohl(call->call_id));
|
||||
conn->debug_id, chan, call->call_id);
|
||||
|
||||
spin_unlock(&trans->client_lock);
|
||||
|
||||
|
@ -593,11 +592,11 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
|
|||
conn->channels[chan] = call;
|
||||
call->conn = conn;
|
||||
call->channel = chan;
|
||||
call->cid = conn->cid | htonl(chan);
|
||||
call->call_id = htonl(++conn->call_counter);
|
||||
call->cid = conn->cid | chan;
|
||||
call->call_id = ++conn->call_counter;
|
||||
|
||||
_net("CONNECT client on conn %d chan %d as call %x",
|
||||
conn->debug_id, chan, ntohl(call->call_id));
|
||||
conn->debug_id, chan, call->call_id);
|
||||
|
||||
ASSERTCMP(conn->avail_calls, <, RXRPC_MAXCALLS);
|
||||
spin_unlock(&trans->client_lock);
|
||||
|
@ -620,21 +619,21 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
|
|||
*/
|
||||
struct rxrpc_connection *
|
||||
rxrpc_incoming_connection(struct rxrpc_transport *trans,
|
||||
struct rxrpc_header *hdr,
|
||||
struct rxrpc_host_header *hdr,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct rxrpc_connection *conn, *candidate = NULL;
|
||||
struct rb_node *p, **pp;
|
||||
const char *new = "old";
|
||||
__be32 epoch;
|
||||
u32 conn_id;
|
||||
u32 cid;
|
||||
|
||||
_enter("");
|
||||
|
||||
ASSERT(hdr->flags & RXRPC_CLIENT_INITIATED);
|
||||
|
||||
epoch = hdr->epoch;
|
||||
conn_id = ntohl(hdr->cid) & RXRPC_CIDMASK;
|
||||
cid = hdr->cid & RXRPC_CIDMASK;
|
||||
|
||||
/* search the connection list first */
|
||||
read_lock_bh(&trans->conn_lock);
|
||||
|
@ -643,15 +642,15 @@ rxrpc_incoming_connection(struct rxrpc_transport *trans,
|
|||
while (p) {
|
||||
conn = rb_entry(p, struct rxrpc_connection, node);
|
||||
|
||||
_debug("maybe %x", conn->real_conn_id);
|
||||
_debug("maybe %x", conn->cid);
|
||||
|
||||
if (epoch < conn->epoch)
|
||||
p = p->rb_left;
|
||||
else if (epoch > conn->epoch)
|
||||
p = p->rb_right;
|
||||
else if (conn_id < conn->real_conn_id)
|
||||
else if (cid < conn->cid)
|
||||
p = p->rb_left;
|
||||
else if (conn_id > conn->real_conn_id)
|
||||
else if (cid > conn->cid)
|
||||
p = p->rb_right;
|
||||
else
|
||||
goto found_extant_connection;
|
||||
|
@ -668,12 +667,11 @@ rxrpc_incoming_connection(struct rxrpc_transport *trans,
|
|||
|
||||
candidate->trans = trans;
|
||||
candidate->epoch = hdr->epoch;
|
||||
candidate->cid = hdr->cid & cpu_to_be32(RXRPC_CIDMASK);
|
||||
candidate->cid = hdr->cid & RXRPC_CIDMASK;
|
||||
candidate->service_id = hdr->serviceId;
|
||||
candidate->security_ix = hdr->securityIndex;
|
||||
candidate->in_clientflag = RXRPC_CLIENT_INITIATED;
|
||||
candidate->out_clientflag = 0;
|
||||
candidate->real_conn_id = conn_id;
|
||||
candidate->state = RXRPC_CONN_SERVER;
|
||||
if (candidate->service_id)
|
||||
candidate->state = RXRPC_CONN_SERVER_UNSECURED;
|
||||
|
@ -690,9 +688,9 @@ rxrpc_incoming_connection(struct rxrpc_transport *trans,
|
|||
pp = &(*pp)->rb_left;
|
||||
else if (epoch > conn->epoch)
|
||||
pp = &(*pp)->rb_right;
|
||||
else if (conn_id < conn->real_conn_id)
|
||||
else if (cid < conn->cid)
|
||||
pp = &(*pp)->rb_left;
|
||||
else if (conn_id > conn->real_conn_id)
|
||||
else if (cid > conn->cid)
|
||||
pp = &(*pp)->rb_right;
|
||||
else
|
||||
goto found_extant_second;
|
||||
|
@ -714,7 +712,7 @@ rxrpc_incoming_connection(struct rxrpc_transport *trans,
|
|||
new = "new";
|
||||
|
||||
success:
|
||||
_net("CONNECTION %s %d {%x}", new, conn->debug_id, conn->real_conn_id);
|
||||
_net("CONNECTION %s %d {%x}", new, conn->debug_id, conn->cid);
|
||||
|
||||
_leave(" = %p {u=%d}", conn, atomic_read(&conn->usage));
|
||||
return conn;
|
||||
|
@ -751,18 +749,17 @@ rxrpc_incoming_connection(struct rxrpc_transport *trans,
|
|||
* packet
|
||||
*/
|
||||
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *trans,
|
||||
struct rxrpc_header *hdr)
|
||||
struct rxrpc_host_header *hdr)
|
||||
{
|
||||
struct rxrpc_connection *conn;
|
||||
struct rb_node *p;
|
||||
__be32 epoch;
|
||||
u32 conn_id;
|
||||
u32 epoch, cid;
|
||||
|
||||
_enter(",{%x,%x}", ntohl(hdr->cid), hdr->flags);
|
||||
_enter(",{%x,%x}", hdr->cid, hdr->flags);
|
||||
|
||||
read_lock_bh(&trans->conn_lock);
|
||||
|
||||
conn_id = ntohl(hdr->cid) & RXRPC_CIDMASK;
|
||||
cid = hdr->cid & RXRPC_CIDMASK;
|
||||
epoch = hdr->epoch;
|
||||
|
||||
if (hdr->flags & RXRPC_CLIENT_INITIATED)
|
||||
|
@ -773,15 +770,15 @@ struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *trans,
|
|||
while (p) {
|
||||
conn = rb_entry(p, struct rxrpc_connection, node);
|
||||
|
||||
_debug("maybe %x", conn->real_conn_id);
|
||||
_debug("maybe %x", conn->cid);
|
||||
|
||||
if (epoch < conn->epoch)
|
||||
p = p->rb_left;
|
||||
else if (epoch > conn->epoch)
|
||||
p = p->rb_right;
|
||||
else if (conn_id < conn->real_conn_id)
|
||||
else if (cid < conn->cid)
|
||||
p = p->rb_left;
|
||||
else if (conn_id > conn->real_conn_id)
|
||||
else if (cid > conn->cid)
|
||||
p = p->rb_right;
|
||||
else
|
||||
goto found;
|
||||
|
|
|
@ -42,9 +42,9 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state,
|
|||
call->state = state;
|
||||
call->abort_code = abort_code;
|
||||
if (state == RXRPC_CALL_LOCALLY_ABORTED)
|
||||
set_bit(RXRPC_CALL_CONN_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_CONN_ABORT, &call->events);
|
||||
else
|
||||
set_bit(RXRPC_CALL_RCVD_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
write_unlock(&call->state_lock);
|
||||
|
@ -60,11 +60,12 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, int state,
|
|||
static int rxrpc_abort_connection(struct rxrpc_connection *conn,
|
||||
u32 error, u32 abort_code)
|
||||
{
|
||||
struct rxrpc_header hdr;
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct msghdr msg;
|
||||
struct kvec iov[2];
|
||||
__be32 word;
|
||||
size_t len;
|
||||
u32 serial;
|
||||
int ret;
|
||||
|
||||
_enter("%d,,%u,%u", conn->debug_id, error, abort_code);
|
||||
|
@ -89,28 +90,29 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn,
|
|||
msg.msg_controllen = 0;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
hdr.epoch = conn->epoch;
|
||||
hdr.cid = conn->cid;
|
||||
hdr.callNumber = 0;
|
||||
hdr.seq = 0;
|
||||
hdr.type = RXRPC_PACKET_TYPE_ABORT;
|
||||
hdr.flags = conn->out_clientflag;
|
||||
hdr.userStatus = 0;
|
||||
hdr.securityIndex = conn->security_ix;
|
||||
hdr._rsvd = 0;
|
||||
hdr.serviceId = conn->service_id;
|
||||
whdr.epoch = htonl(conn->epoch);
|
||||
whdr.cid = htonl(conn->cid);
|
||||
whdr.callNumber = 0;
|
||||
whdr.seq = 0;
|
||||
whdr.type = RXRPC_PACKET_TYPE_ABORT;
|
||||
whdr.flags = conn->out_clientflag;
|
||||
whdr.userStatus = 0;
|
||||
whdr.securityIndex = conn->security_ix;
|
||||
whdr._rsvd = 0;
|
||||
whdr.serviceId = htons(conn->service_id);
|
||||
|
||||
word = htonl(abort_code);
|
||||
|
||||
iov[0].iov_base = &hdr;
|
||||
iov[0].iov_len = sizeof(hdr);
|
||||
iov[0].iov_base = &whdr;
|
||||
iov[0].iov_len = sizeof(whdr);
|
||||
iov[1].iov_base = &word;
|
||||
iov[1].iov_len = sizeof(word);
|
||||
|
||||
len = iov[0].iov_len + iov[1].iov_len;
|
||||
|
||||
hdr.serial = htonl(atomic_inc_return(&conn->serial));
|
||||
_proto("Tx CONN ABORT %%%u { %d }", ntohl(hdr.serial), abort_code);
|
||||
serial = atomic_inc_return(&conn->serial);
|
||||
whdr.serial = htonl(serial);
|
||||
_proto("Tx CONN ABORT %%%u { %d }", serial, abort_code);
|
||||
|
||||
ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 2, len);
|
||||
if (ret < 0) {
|
||||
|
@ -132,7 +134,7 @@ static void rxrpc_call_is_secure(struct rxrpc_call *call)
|
|||
if (call) {
|
||||
read_lock(&call->state_lock);
|
||||
if (call->state < RXRPC_CALL_COMPLETE &&
|
||||
!test_and_set_bit(RXRPC_CALL_SECURED, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_SECURED, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
read_unlock(&call->state_lock);
|
||||
}
|
||||
|
@ -146,8 +148,8 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
|
|||
u32 *_abort_code)
|
||||
{
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
__be32 tmp;
|
||||
u32 serial;
|
||||
__be32 wtmp;
|
||||
u32 abort_code;
|
||||
int loop, ret;
|
||||
|
||||
if (conn->state >= RXRPC_CONN_REMOTELY_ABORTED) {
|
||||
|
@ -155,19 +157,18 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
|
|||
return -ECONNABORTED;
|
||||
}
|
||||
|
||||
serial = ntohl(sp->hdr.serial);
|
||||
|
||||
_enter("{%d},{%u,%%%u},", conn->debug_id, sp->hdr.type, serial);
|
||||
_enter("{%d},{%u,%%%u},", conn->debug_id, sp->hdr.type, sp->hdr.serial);
|
||||
|
||||
switch (sp->hdr.type) {
|
||||
case RXRPC_PACKET_TYPE_ABORT:
|
||||
if (skb_copy_bits(skb, 0, &tmp, sizeof(tmp)) < 0)
|
||||
if (skb_copy_bits(skb, 0, &wtmp, sizeof(wtmp)) < 0)
|
||||
return -EPROTO;
|
||||
_proto("Rx ABORT %%%u { ac=%d }", serial, ntohl(tmp));
|
||||
abort_code = ntohl(wtmp);
|
||||
_proto("Rx ABORT %%%u { ac=%d }", sp->hdr.serial, abort_code);
|
||||
|
||||
conn->state = RXRPC_CONN_REMOTELY_ABORTED;
|
||||
rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED,
|
||||
ntohl(tmp));
|
||||
abort_code);
|
||||
return -ECONNABORTED;
|
||||
|
||||
case RXRPC_PACKET_TYPE_CHALLENGE:
|
||||
|
@ -335,7 +336,7 @@ void rxrpc_reject_packets(struct work_struct *work)
|
|||
struct sockaddr_in sin;
|
||||
} sa;
|
||||
struct rxrpc_skb_priv *sp;
|
||||
struct rxrpc_header hdr;
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct rxrpc_local *local;
|
||||
struct sk_buff *skb;
|
||||
struct msghdr msg;
|
||||
|
@ -348,11 +349,11 @@ void rxrpc_reject_packets(struct work_struct *work)
|
|||
|
||||
_enter("%d", local->debug_id);
|
||||
|
||||
iov[0].iov_base = &hdr;
|
||||
iov[0].iov_len = sizeof(hdr);
|
||||
iov[0].iov_base = &whdr;
|
||||
iov[0].iov_len = sizeof(whdr);
|
||||
iov[1].iov_base = &code;
|
||||
iov[1].iov_len = sizeof(code);
|
||||
size = sizeof(hdr) + sizeof(code);
|
||||
size = sizeof(whdr) + sizeof(code);
|
||||
|
||||
msg.msg_name = &sa;
|
||||
msg.msg_control = NULL;
|
||||
|
@ -370,8 +371,8 @@ void rxrpc_reject_packets(struct work_struct *work)
|
|||
break;
|
||||
}
|
||||
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
hdr.type = RXRPC_PACKET_TYPE_ABORT;
|
||||
memset(&whdr, 0, sizeof(whdr));
|
||||
whdr.type = RXRPC_PACKET_TYPE_ABORT;
|
||||
|
||||
while ((skb = skb_dequeue(&local->reject_queue))) {
|
||||
sp = rxrpc_skb(skb);
|
||||
|
@ -381,13 +382,13 @@ void rxrpc_reject_packets(struct work_struct *work)
|
|||
sa.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
|
||||
code = htonl(skb->priority);
|
||||
|
||||
hdr.epoch = sp->hdr.epoch;
|
||||
hdr.cid = sp->hdr.cid;
|
||||
hdr.callNumber = sp->hdr.callNumber;
|
||||
hdr.serviceId = sp->hdr.serviceId;
|
||||
hdr.flags = sp->hdr.flags;
|
||||
hdr.flags ^= RXRPC_CLIENT_INITIATED;
|
||||
hdr.flags &= RXRPC_CLIENT_INITIATED;
|
||||
whdr.epoch = htonl(sp->hdr.epoch);
|
||||
whdr.cid = htonl(sp->hdr.cid);
|
||||
whdr.callNumber = htonl(sp->hdr.callNumber);
|
||||
whdr.serviceId = htons(sp->hdr.serviceId);
|
||||
whdr.flags = sp->hdr.flags;
|
||||
whdr.flags ^= RXRPC_CLIENT_INITIATED;
|
||||
whdr.flags &= RXRPC_CLIENT_INITIATED;
|
||||
|
||||
kernel_sendmsg(local->socket, &msg, iov, 2, size);
|
||||
break;
|
||||
|
|
|
@ -115,7 +115,6 @@ void rxrpc_UDP_error_report(struct sock *sk)
|
|||
/* pass the transport ref to error_handler to release */
|
||||
skb_queue_tail(&trans->error_queue, skb);
|
||||
rxrpc_queue_work(&trans->error_handler);
|
||||
|
||||
_leave("");
|
||||
}
|
||||
|
||||
|
@ -152,28 +151,18 @@ void rxrpc_UDP_error_handler(struct work_struct *work)
|
|||
switch (ee->ee_code) {
|
||||
case ICMP_NET_UNREACH:
|
||||
_net("Rx Received ICMP Network Unreachable");
|
||||
err = ENETUNREACH;
|
||||
break;
|
||||
case ICMP_HOST_UNREACH:
|
||||
_net("Rx Received ICMP Host Unreachable");
|
||||
err = EHOSTUNREACH;
|
||||
break;
|
||||
case ICMP_PORT_UNREACH:
|
||||
_net("Rx Received ICMP Port Unreachable");
|
||||
err = ECONNREFUSED;
|
||||
break;
|
||||
case ICMP_FRAG_NEEDED:
|
||||
_net("Rx Received ICMP Fragmentation Needed (%d)",
|
||||
ee->ee_info);
|
||||
err = 0; /* dealt with elsewhere */
|
||||
break;
|
||||
case ICMP_NET_UNKNOWN:
|
||||
_net("Rx Received ICMP Unknown Network");
|
||||
err = ENETUNREACH;
|
||||
break;
|
||||
case ICMP_HOST_UNKNOWN:
|
||||
_net("Rx Received ICMP Unknown Host");
|
||||
err = EHOSTUNREACH;
|
||||
break;
|
||||
default:
|
||||
_net("Rx Received ICMP DestUnreach code=%u",
|
||||
|
@ -222,7 +211,7 @@ void rxrpc_UDP_error_handler(struct work_struct *work)
|
|||
if (call->state != RXRPC_CALL_COMPLETE &&
|
||||
call->state < RXRPC_CALL_NETWORK_ERROR) {
|
||||
call->state = RXRPC_CALL_NETWORK_ERROR;
|
||||
set_bit(RXRPC_CALL_RCVD_ERROR, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_RCVD_ERROR, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
write_unlock(&call->state_lock);
|
||||
|
|
|
@ -231,7 +231,7 @@ static int rxrpc_fast_process_data(struct rxrpc_call *call,
|
|||
_debug("drain rx oos now");
|
||||
read_lock(&call->state_lock);
|
||||
if (call->state < RXRPC_CALL_COMPLETE &&
|
||||
!test_and_set_bit(RXRPC_CALL_DRAIN_RX_OOS, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_DRAIN_RX_OOS, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
read_unlock(&call->state_lock);
|
||||
}
|
||||
|
@ -287,12 +287,12 @@ static void rxrpc_assume_implicit_ackall(struct rxrpc_call *call, u32 serial)
|
|||
call->acks_latest = serial;
|
||||
|
||||
_debug("implicit ACKALL %%%u", call->acks_latest);
|
||||
set_bit(RXRPC_CALL_RCVD_ACKALL, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_RCVD_ACKALL, &call->events);
|
||||
write_unlock_bh(&call->state_lock);
|
||||
|
||||
if (try_to_del_timer_sync(&call->resend_timer) >= 0) {
|
||||
clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_RESEND, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RESEND, &call->events);
|
||||
clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
|
||||
}
|
||||
break;
|
||||
|
@ -310,8 +310,8 @@ static void rxrpc_assume_implicit_ackall(struct rxrpc_call *call, u32 serial)
|
|||
void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
{
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
__be32 _abort_code;
|
||||
u32 serial, hi_serial, seq, abort_code;
|
||||
__be32 wtmp;
|
||||
u32 hi_serial, abort_code;
|
||||
|
||||
_enter("%p,%p", call, skb);
|
||||
|
||||
|
@ -330,16 +330,15 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
|
|||
|
||||
/* track the latest serial number on this connection for ACK packet
|
||||
* information */
|
||||
serial = ntohl(sp->hdr.serial);
|
||||
hi_serial = atomic_read(&call->conn->hi_serial);
|
||||
while (serial > hi_serial)
|
||||
while (sp->hdr.serial > hi_serial)
|
||||
hi_serial = atomic_cmpxchg(&call->conn->hi_serial, hi_serial,
|
||||
serial);
|
||||
sp->hdr.serial);
|
||||
|
||||
/* request ACK generation for any ACK or DATA packet that requests
|
||||
* it */
|
||||
if (sp->hdr.flags & RXRPC_REQUEST_ACK) {
|
||||
_proto("ACK Requested on %%%u", serial);
|
||||
_proto("ACK Requested on %%%u", sp->hdr.serial);
|
||||
rxrpc_propose_ACK(call, RXRPC_ACK_REQUESTED, sp->hdr.serial, false);
|
||||
}
|
||||
|
||||
|
@ -347,24 +346,23 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
|
|||
case RXRPC_PACKET_TYPE_ABORT:
|
||||
_debug("abort");
|
||||
|
||||
if (skb_copy_bits(skb, 0, &_abort_code,
|
||||
sizeof(_abort_code)) < 0)
|
||||
if (skb_copy_bits(skb, 0, &wtmp, sizeof(wtmp)) < 0)
|
||||
goto protocol_error;
|
||||
|
||||
abort_code = ntohl(_abort_code);
|
||||
_proto("Rx ABORT %%%u { %x }", serial, abort_code);
|
||||
abort_code = ntohl(wtmp);
|
||||
_proto("Rx ABORT %%%u { %x }", sp->hdr.serial, abort_code);
|
||||
|
||||
write_lock_bh(&call->state_lock);
|
||||
if (call->state < RXRPC_CALL_COMPLETE) {
|
||||
call->state = RXRPC_CALL_REMOTELY_ABORTED;
|
||||
call->abort_code = abort_code;
|
||||
set_bit(RXRPC_CALL_RCVD_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_RCVD_ABORT, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
goto free_packet_unlock;
|
||||
|
||||
case RXRPC_PACKET_TYPE_BUSY:
|
||||
_proto("Rx BUSY %%%u", serial);
|
||||
_proto("Rx BUSY %%%u", sp->hdr.serial);
|
||||
|
||||
if (call->conn->out_clientflag)
|
||||
goto protocol_error;
|
||||
|
@ -373,7 +371,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
|
|||
switch (call->state) {
|
||||
case RXRPC_CALL_CLIENT_SEND_REQUEST:
|
||||
call->state = RXRPC_CALL_SERVER_BUSY;
|
||||
set_bit(RXRPC_CALL_RCVD_BUSY, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_RCVD_BUSY, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
case RXRPC_CALL_SERVER_BUSY:
|
||||
goto free_packet_unlock;
|
||||
|
@ -382,15 +380,13 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
default:
|
||||
_proto("Rx %s %%%u", rxrpc_pkts[sp->hdr.type], serial);
|
||||
_proto("Rx %s %%%u", rxrpc_pkts[sp->hdr.type], sp->hdr.serial);
|
||||
goto protocol_error;
|
||||
|
||||
case RXRPC_PACKET_TYPE_DATA:
|
||||
seq = ntohl(sp->hdr.seq);
|
||||
_proto("Rx DATA %%%u { #%u }", sp->hdr.serial, sp->hdr.seq);
|
||||
|
||||
_proto("Rx DATA %%%u { #%u }", serial, seq);
|
||||
|
||||
if (seq == 0)
|
||||
if (sp->hdr.seq == 0)
|
||||
goto protocol_error;
|
||||
|
||||
call->ackr_prev_seq = sp->hdr.seq;
|
||||
|
@ -398,9 +394,9 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
|
|||
/* received data implicitly ACKs all of the request packets we
|
||||
* sent when we're acting as a client */
|
||||
if (call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY)
|
||||
rxrpc_assume_implicit_ackall(call, serial);
|
||||
rxrpc_assume_implicit_ackall(call, sp->hdr.serial);
|
||||
|
||||
switch (rxrpc_fast_process_data(call, skb, seq)) {
|
||||
switch (rxrpc_fast_process_data(call, skb, sp->hdr.seq)) {
|
||||
case 0:
|
||||
skb = NULL;
|
||||
goto done;
|
||||
|
@ -433,7 +429,7 @@ void rxrpc_fast_process_packet(struct rxrpc_call *call, struct sk_buff *skb)
|
|||
if (call->state <= RXRPC_CALL_COMPLETE) {
|
||||
call->state = RXRPC_CALL_LOCALLY_ABORTED;
|
||||
call->abort_code = RX_PROTOCOL_ERROR;
|
||||
set_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
free_packet_unlock:
|
||||
|
@ -481,12 +477,12 @@ static void rxrpc_process_jumbo_packet(struct rxrpc_call *call,
|
|||
if (!pskb_pull(jumbo, sizeof(jhdr)))
|
||||
BUG();
|
||||
|
||||
sp->hdr.seq = htonl(ntohl(sp->hdr.seq) + 1);
|
||||
sp->hdr.serial = htonl(ntohl(sp->hdr.serial) + 1);
|
||||
sp->hdr.seq += 1;
|
||||
sp->hdr.serial += 1;
|
||||
sp->hdr.flags = jhdr.flags;
|
||||
sp->hdr._rsvd = jhdr._rsvd;
|
||||
|
||||
_proto("Rx DATA Jumbo %%%u", ntohl(sp->hdr.serial) - 1);
|
||||
_proto("Rx DATA Jumbo %%%u", sp->hdr.serial - 1);
|
||||
|
||||
rxrpc_fast_process_packet(call, part);
|
||||
part = NULL;
|
||||
|
@ -505,7 +501,7 @@ static void rxrpc_process_jumbo_packet(struct rxrpc_call *call,
|
|||
if (call->state <= RXRPC_CALL_COMPLETE) {
|
||||
call->state = RXRPC_CALL_LOCALLY_ABORTED;
|
||||
call->abort_code = RX_PROTOCOL_ERROR;
|
||||
set_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
write_unlock_bh(&call->state_lock);
|
||||
|
@ -530,7 +526,7 @@ static void rxrpc_post_packet_to_call(struct rxrpc_call *call,
|
|||
read_lock(&call->state_lock);
|
||||
switch (call->state) {
|
||||
case RXRPC_CALL_LOCALLY_ABORTED:
|
||||
if (!test_and_set_bit(RXRPC_CALL_ABORT, &call->events)) {
|
||||
if (!test_and_set_bit(RXRPC_CALL_EV_ABORT, &call->events)) {
|
||||
rxrpc_queue_call(call);
|
||||
goto free_unlock;
|
||||
}
|
||||
|
@ -546,7 +542,7 @@ static void rxrpc_post_packet_to_call(struct rxrpc_call *call,
|
|||
/* resend last packet of a completed call */
|
||||
_debug("final ack again");
|
||||
rxrpc_get_call(call);
|
||||
set_bit(RXRPC_CALL_ACK_FINAL, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events);
|
||||
rxrpc_queue_call(call);
|
||||
goto free_unlock;
|
||||
default:
|
||||
|
@ -607,6 +603,35 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local,
|
|||
rxrpc_queue_work(&local->event_processor);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the wire header from a packet and translate the byte order.
|
||||
*/
|
||||
static noinline
|
||||
int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
|
||||
{
|
||||
struct rxrpc_wire_header whdr;
|
||||
|
||||
/* dig out the RxRPC connection details */
|
||||
if (skb_copy_bits(skb, sizeof(struct udphdr), &whdr, sizeof(whdr)) < 0)
|
||||
return -EBADMSG;
|
||||
if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(whdr)))
|
||||
BUG();
|
||||
|
||||
memset(sp, 0, sizeof(*sp));
|
||||
sp->hdr.epoch = ntohl(whdr.epoch);
|
||||
sp->hdr.cid = ntohl(whdr.cid);
|
||||
sp->hdr.callNumber = ntohl(whdr.callNumber);
|
||||
sp->hdr.seq = ntohl(whdr.seq);
|
||||
sp->hdr.serial = ntohl(whdr.serial);
|
||||
sp->hdr.flags = whdr.flags;
|
||||
sp->hdr.type = whdr.type;
|
||||
sp->hdr.userStatus = whdr.userStatus;
|
||||
sp->hdr.securityIndex = whdr.securityIndex;
|
||||
sp->hdr._rsvd = ntohs(whdr._rsvd);
|
||||
sp->hdr.serviceId = ntohs(whdr.serviceId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rxrpc_connection *rxrpc_conn_from_local(struct rxrpc_local *local,
|
||||
struct sk_buff *skb,
|
||||
struct rxrpc_skb_priv *sp)
|
||||
|
@ -686,29 +711,25 @@ void rxrpc_data_ready(struct sock *sk)
|
|||
|
||||
UDP_INC_STATS_BH(&init_net, UDP_MIB_INDATAGRAMS, 0);
|
||||
|
||||
/* the socket buffer we have is owned by UDP, with UDP's data all over
|
||||
* it, but we really want our own */
|
||||
/* The socket buffer we have is owned by UDP, with UDP's data all over
|
||||
* it, but we really want our own data there.
|
||||
*/
|
||||
skb_orphan(skb);
|
||||
sp = rxrpc_skb(skb);
|
||||
memset(sp, 0, sizeof(*sp));
|
||||
|
||||
_net("Rx UDP packet from %08x:%04hu",
|
||||
ntohl(ip_hdr(skb)->saddr), ntohs(udp_hdr(skb)->source));
|
||||
|
||||
/* dig out the RxRPC connection details */
|
||||
if (skb_copy_bits(skb, sizeof(struct udphdr), &sp->hdr,
|
||||
sizeof(sp->hdr)) < 0)
|
||||
if (rxrpc_extract_header(sp, skb) < 0)
|
||||
goto bad_message;
|
||||
if (!pskb_pull(skb, sizeof(struct udphdr) + sizeof(sp->hdr)))
|
||||
BUG();
|
||||
|
||||
_net("Rx RxRPC %s ep=%x call=%x:%x",
|
||||
sp->hdr.flags & RXRPC_CLIENT_INITIATED ? "ToServer" : "ToClient",
|
||||
ntohl(sp->hdr.epoch),
|
||||
ntohl(sp->hdr.cid),
|
||||
ntohl(sp->hdr.callNumber));
|
||||
sp->hdr.epoch, sp->hdr.cid, sp->hdr.callNumber);
|
||||
|
||||
if (sp->hdr.type == 0 || sp->hdr.type >= RXRPC_N_PACKET_TYPES) {
|
||||
if (sp->hdr.type >= RXRPC_N_PACKET_TYPES ||
|
||||
!((RXRPC_SUPPORTED_PACKET_TYPES >> sp->hdr.type) & 1)) {
|
||||
_proto("Rx Bad Packet Type %u", sp->hdr.type);
|
||||
goto bad_message;
|
||||
}
|
||||
|
@ -737,14 +758,9 @@ void rxrpc_data_ready(struct sock *sk)
|
|||
rxrpc_put_connection(conn);
|
||||
} else {
|
||||
struct rxrpc_call *call;
|
||||
u8 in_clientflag = 0;
|
||||
|
||||
if (sp->hdr.flags & RXRPC_CLIENT_INITIATED)
|
||||
in_clientflag = RXRPC_CLIENT_INITIATED;
|
||||
call = rxrpc_find_call_hash(in_clientflag, sp->hdr.cid,
|
||||
sp->hdr.callNumber, sp->hdr.epoch,
|
||||
sp->hdr.serviceId, local, AF_INET,
|
||||
(u8 *)&ip_hdr(skb)->saddr);
|
||||
call = rxrpc_find_call_hash(&sp->hdr, local,
|
||||
AF_INET, &ip_hdr(skb)->saddr);
|
||||
if (call)
|
||||
rxrpc_post_packet_to_call(call, skb);
|
||||
else
|
||||
|
@ -759,7 +775,7 @@ void rxrpc_data_ready(struct sock *sk)
|
|||
_debug("can't route call");
|
||||
if (sp->hdr.flags & RXRPC_CLIENT_INITIATED &&
|
||||
sp->hdr.type == RXRPC_PACKET_TYPE_DATA) {
|
||||
if (sp->hdr.seq == cpu_to_be32(1)) {
|
||||
if (sp->hdr.seq == 1) {
|
||||
_debug("first packet");
|
||||
skb_queue_tail(&local->accept_queue, skb);
|
||||
rxrpc_queue_work(&local->acceptor);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
BUG_ON(atomic_read((X)) >> (sizeof(atomic_t) - 2) == \
|
||||
(POISON_FREE << 8 | POISON_FREE))
|
||||
#else
|
||||
#define CHECK_SLAB_OKAY(X) do {} while(0)
|
||||
#define CHECK_SLAB_OKAY(X) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define FCRYPT_BSIZE 8
|
||||
|
@ -70,11 +70,30 @@ struct rxrpc_sock {
|
|||
#define RXRPC_SECURITY_MAX RXRPC_SECURITY_ENCRYPT
|
||||
struct sockaddr_rxrpc srx; /* local address */
|
||||
sa_family_t proto; /* protocol created with */
|
||||
__be16 service_id; /* service ID of local/remote service */
|
||||
};
|
||||
|
||||
#define rxrpc_sk(__sk) container_of((__sk), struct rxrpc_sock, sk)
|
||||
|
||||
/*
|
||||
* CPU-byteorder normalised Rx packet header.
|
||||
*/
|
||||
struct rxrpc_host_header {
|
||||
u32 epoch; /* client boot timestamp */
|
||||
u32 cid; /* connection and channel ID */
|
||||
u32 callNumber; /* call ID (0 for connection-level packets) */
|
||||
u32 seq; /* sequence number of pkt in call stream */
|
||||
u32 serial; /* serial number of pkt sent to network */
|
||||
u8 type; /* packet type */
|
||||
u8 flags; /* packet flags */
|
||||
u8 userStatus; /* app-layer defined status */
|
||||
u8 securityIndex; /* security protocol ID */
|
||||
union {
|
||||
u16 _rsvd; /* reserved */
|
||||
u16 cksum; /* kerberos security checksum */
|
||||
};
|
||||
u16 serviceId; /* service ID */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* RxRPC socket buffer private variables
|
||||
* - max 48 bytes (struct sk_buff::cb)
|
||||
|
@ -89,7 +108,7 @@ struct rxrpc_skb_priv {
|
|||
bool need_resend; /* T if needs resending */
|
||||
};
|
||||
|
||||
struct rxrpc_header hdr; /* RxRPC packet header from this packet */
|
||||
struct rxrpc_host_header hdr; /* RxRPC packet header from this packet */
|
||||
};
|
||||
|
||||
#define rxrpc_skb(__skb) ((struct rxrpc_skb_priv *) &(__skb)->cb)
|
||||
|
@ -230,7 +249,7 @@ struct rxrpc_conn_bundle {
|
|||
atomic_t usage;
|
||||
int debug_id; /* debug ID for printks */
|
||||
unsigned short num_conns; /* number of connections in this bundle */
|
||||
__be16 service_id; /* service ID */
|
||||
u16 service_id; /* Service ID for this bundle */
|
||||
u8 security_ix; /* security type */
|
||||
};
|
||||
|
||||
|
@ -260,7 +279,6 @@ struct rxrpc_connection {
|
|||
rwlock_t lock; /* access lock */
|
||||
spinlock_t state_lock; /* state-change lock */
|
||||
atomic_t usage;
|
||||
u32 real_conn_id; /* connection ID (host-endian) */
|
||||
enum { /* current state of connection */
|
||||
RXRPC_CONN_UNUSED, /* - connection not yet attempted */
|
||||
RXRPC_CONN_CLIENT, /* - client connection */
|
||||
|
@ -282,16 +300,75 @@ struct rxrpc_connection {
|
|||
u8 security_size; /* security header size */
|
||||
u32 security_level; /* security level negotiated */
|
||||
u32 security_nonce; /* response re-use preventer */
|
||||
|
||||
/* the following are all in net order */
|
||||
__be32 epoch; /* epoch of this connection */
|
||||
__be32 cid; /* connection ID */
|
||||
__be16 service_id; /* service ID */
|
||||
u32 epoch; /* epoch of this connection */
|
||||
u32 cid; /* connection ID */
|
||||
u16 service_id; /* service ID for this connection */
|
||||
u8 security_ix; /* security type */
|
||||
u8 in_clientflag; /* RXRPC_CLIENT_INITIATED if we are server */
|
||||
u8 out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags in call->flags.
|
||||
*/
|
||||
enum rxrpc_call_flag {
|
||||
RXRPC_CALL_RELEASED, /* call has been released - no more message to userspace */
|
||||
RXRPC_CALL_TERMINAL_MSG, /* call has given the socket its final message */
|
||||
RXRPC_CALL_RCVD_LAST, /* all packets received */
|
||||
RXRPC_CALL_RUN_RTIMER, /* Tx resend timer started */
|
||||
RXRPC_CALL_TX_SOFT_ACK, /* sent some soft ACKs */
|
||||
RXRPC_CALL_PROC_BUSY, /* the processor is busy */
|
||||
RXRPC_CALL_INIT_ACCEPT, /* acceptance was initiated */
|
||||
RXRPC_CALL_HAS_USERID, /* has a user ID attached */
|
||||
RXRPC_CALL_EXPECT_OOS, /* expect out of sequence packets */
|
||||
};
|
||||
|
||||
/*
|
||||
* Events that can be raised on a call.
|
||||
*/
|
||||
enum rxrpc_call_event {
|
||||
RXRPC_CALL_EV_RCVD_ACKALL, /* ACKALL or reply received */
|
||||
RXRPC_CALL_EV_RCVD_BUSY, /* busy packet received */
|
||||
RXRPC_CALL_EV_RCVD_ABORT, /* abort packet received */
|
||||
RXRPC_CALL_EV_RCVD_ERROR, /* network error received */
|
||||
RXRPC_CALL_EV_ACK_FINAL, /* need to generate final ACK (and release call) */
|
||||
RXRPC_CALL_EV_ACK, /* need to generate ACK */
|
||||
RXRPC_CALL_EV_REJECT_BUSY, /* need to generate busy message */
|
||||
RXRPC_CALL_EV_ABORT, /* need to generate abort */
|
||||
RXRPC_CALL_EV_CONN_ABORT, /* local connection abort generated */
|
||||
RXRPC_CALL_EV_RESEND_TIMER, /* Tx resend timer expired */
|
||||
RXRPC_CALL_EV_RESEND, /* Tx resend required */
|
||||
RXRPC_CALL_EV_DRAIN_RX_OOS, /* drain the Rx out of sequence queue */
|
||||
RXRPC_CALL_EV_LIFE_TIMER, /* call's lifetimer ran out */
|
||||
RXRPC_CALL_EV_ACCEPTED, /* incoming call accepted by userspace app */
|
||||
RXRPC_CALL_EV_SECURED, /* incoming call's connection is now secure */
|
||||
RXRPC_CALL_EV_POST_ACCEPT, /* need to post an "accept?" message to the app */
|
||||
RXRPC_CALL_EV_RELEASE, /* need to release the call's resources */
|
||||
};
|
||||
|
||||
/*
|
||||
* The states that a call can be in.
|
||||
*/
|
||||
enum rxrpc_call_state {
|
||||
RXRPC_CALL_CLIENT_SEND_REQUEST, /* - client sending request phase */
|
||||
RXRPC_CALL_CLIENT_AWAIT_REPLY, /* - client awaiting reply */
|
||||
RXRPC_CALL_CLIENT_RECV_REPLY, /* - client receiving reply phase */
|
||||
RXRPC_CALL_CLIENT_FINAL_ACK, /* - client sending final ACK phase */
|
||||
RXRPC_CALL_SERVER_SECURING, /* - server securing request connection */
|
||||
RXRPC_CALL_SERVER_ACCEPTING, /* - server accepting request */
|
||||
RXRPC_CALL_SERVER_RECV_REQUEST, /* - server receiving request */
|
||||
RXRPC_CALL_SERVER_ACK_REQUEST, /* - server pending ACK of request */
|
||||
RXRPC_CALL_SERVER_SEND_REPLY, /* - server sending reply */
|
||||
RXRPC_CALL_SERVER_AWAIT_ACK, /* - server awaiting final ACK */
|
||||
RXRPC_CALL_COMPLETE, /* - call completed */
|
||||
RXRPC_CALL_SERVER_BUSY, /* - call rejected by busy server */
|
||||
RXRPC_CALL_REMOTELY_ABORTED, /* - call aborted by peer */
|
||||
RXRPC_CALL_LOCALLY_ABORTED, /* - call aborted locally on error or close */
|
||||
RXRPC_CALL_NETWORK_ERROR, /* - call terminated by network error */
|
||||
RXRPC_CALL_DEAD, /* - call is dead */
|
||||
NR__RXRPC_CALL_STATES
|
||||
};
|
||||
|
||||
/*
|
||||
* RxRPC call definition
|
||||
* - matched by { connection, call_id }
|
||||
|
@ -317,57 +394,13 @@ struct rxrpc_call {
|
|||
unsigned long user_call_ID; /* user-defined call ID */
|
||||
unsigned long creation_jif; /* time of call creation */
|
||||
unsigned long flags;
|
||||
#define RXRPC_CALL_RELEASED 0 /* call has been released - no more message to userspace */
|
||||
#define RXRPC_CALL_TERMINAL_MSG 1 /* call has given the socket its final message */
|
||||
#define RXRPC_CALL_RCVD_LAST 2 /* all packets received */
|
||||
#define RXRPC_CALL_RUN_RTIMER 3 /* Tx resend timer started */
|
||||
#define RXRPC_CALL_TX_SOFT_ACK 4 /* sent some soft ACKs */
|
||||
#define RXRPC_CALL_PROC_BUSY 5 /* the processor is busy */
|
||||
#define RXRPC_CALL_INIT_ACCEPT 6 /* acceptance was initiated */
|
||||
#define RXRPC_CALL_HAS_USERID 7 /* has a user ID attached */
|
||||
#define RXRPC_CALL_EXPECT_OOS 8 /* expect out of sequence packets */
|
||||
unsigned long events;
|
||||
#define RXRPC_CALL_RCVD_ACKALL 0 /* ACKALL or reply received */
|
||||
#define RXRPC_CALL_RCVD_BUSY 1 /* busy packet received */
|
||||
#define RXRPC_CALL_RCVD_ABORT 2 /* abort packet received */
|
||||
#define RXRPC_CALL_RCVD_ERROR 3 /* network error received */
|
||||
#define RXRPC_CALL_ACK_FINAL 4 /* need to generate final ACK (and release call) */
|
||||
#define RXRPC_CALL_ACK 5 /* need to generate ACK */
|
||||
#define RXRPC_CALL_REJECT_BUSY 6 /* need to generate busy message */
|
||||
#define RXRPC_CALL_ABORT 7 /* need to generate abort */
|
||||
#define RXRPC_CALL_CONN_ABORT 8 /* local connection abort generated */
|
||||
#define RXRPC_CALL_RESEND_TIMER 9 /* Tx resend timer expired */
|
||||
#define RXRPC_CALL_RESEND 10 /* Tx resend required */
|
||||
#define RXRPC_CALL_DRAIN_RX_OOS 11 /* drain the Rx out of sequence queue */
|
||||
#define RXRPC_CALL_LIFE_TIMER 12 /* call's lifetimer ran out */
|
||||
#define RXRPC_CALL_ACCEPTED 13 /* incoming call accepted by userspace app */
|
||||
#define RXRPC_CALL_SECURED 14 /* incoming call's connection is now secure */
|
||||
#define RXRPC_CALL_POST_ACCEPT 15 /* need to post an "accept?" message to the app */
|
||||
#define RXRPC_CALL_RELEASE 16 /* need to release the call's resources */
|
||||
|
||||
spinlock_t lock;
|
||||
rwlock_t state_lock; /* lock for state transition */
|
||||
atomic_t usage;
|
||||
atomic_t sequence; /* Tx data packet sequence counter */
|
||||
u32 abort_code; /* local/remote abort code */
|
||||
enum { /* current state of call */
|
||||
RXRPC_CALL_CLIENT_SEND_REQUEST, /* - client sending request phase */
|
||||
RXRPC_CALL_CLIENT_AWAIT_REPLY, /* - client awaiting reply */
|
||||
RXRPC_CALL_CLIENT_RECV_REPLY, /* - client receiving reply phase */
|
||||
RXRPC_CALL_CLIENT_FINAL_ACK, /* - client sending final ACK phase */
|
||||
RXRPC_CALL_SERVER_SECURING, /* - server securing request connection */
|
||||
RXRPC_CALL_SERVER_ACCEPTING, /* - server accepting request */
|
||||
RXRPC_CALL_SERVER_RECV_REQUEST, /* - server receiving request */
|
||||
RXRPC_CALL_SERVER_ACK_REQUEST, /* - server pending ACK of request */
|
||||
RXRPC_CALL_SERVER_SEND_REPLY, /* - server sending reply */
|
||||
RXRPC_CALL_SERVER_AWAIT_ACK, /* - server awaiting final ACK */
|
||||
RXRPC_CALL_COMPLETE, /* - call completed */
|
||||
RXRPC_CALL_SERVER_BUSY, /* - call rejected by busy server */
|
||||
RXRPC_CALL_REMOTELY_ABORTED, /* - call aborted by peer */
|
||||
RXRPC_CALL_LOCALLY_ABORTED, /* - call aborted locally on error or close */
|
||||
RXRPC_CALL_NETWORK_ERROR, /* - call terminated by network error */
|
||||
RXRPC_CALL_DEAD, /* - call is dead */
|
||||
} state;
|
||||
enum rxrpc_call_state state : 8; /* current state of call */
|
||||
int debug_id; /* debug ID for printks */
|
||||
u8 channel; /* connection channel occupied by this call */
|
||||
|
||||
|
@ -389,9 +422,9 @@ struct rxrpc_call {
|
|||
rxrpc_seq_t rx_data_eaten; /* last data seq ID consumed by recvmsg */
|
||||
rxrpc_seq_t rx_first_oos; /* first packet in rx_oos_queue (or 0) */
|
||||
rxrpc_seq_t ackr_win_top; /* top of ACK window (rx_data_eaten is bottom) */
|
||||
rxrpc_seq_net_t ackr_prev_seq; /* previous sequence number received */
|
||||
rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */
|
||||
u8 ackr_reason; /* reason to ACK */
|
||||
__be32 ackr_serial; /* serial of packet being ACK'd */
|
||||
rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */
|
||||
atomic_t ackr_not_idle; /* number of packets in Rx queue */
|
||||
|
||||
/* received packet records, 1 bit per record */
|
||||
|
@ -403,11 +436,10 @@ struct rxrpc_call {
|
|||
u8 in_clientflag; /* Copy of conn->in_clientflag for hashing */
|
||||
struct rxrpc_local *local; /* Local endpoint. Used for hashing. */
|
||||
sa_family_t proto; /* Frame protocol */
|
||||
/* the following should all be in net order */
|
||||
__be32 cid; /* connection ID + channel index */
|
||||
__be32 call_id; /* call ID on connection */
|
||||
__be32 epoch; /* epoch of this connection */
|
||||
__be16 service_id; /* service ID */
|
||||
u32 call_id; /* call ID on connection */
|
||||
u32 cid; /* connection ID plus channel index */
|
||||
u32 epoch; /* epoch of this connection */
|
||||
u16 service_id; /* service ID */
|
||||
union { /* Peer IP address for hashing */
|
||||
__be32 ipv4_addr;
|
||||
__u8 ipv6_addr[16]; /* Anticipates eventual IPv6 support */
|
||||
|
@ -423,7 +455,7 @@ static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code)
|
|||
if (call->state < RXRPC_CALL_COMPLETE) {
|
||||
call->abort_code = abort_code;
|
||||
call->state = RXRPC_CALL_LOCALLY_ABORTED;
|
||||
set_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
}
|
||||
write_unlock_bh(&call->state_lock);
|
||||
}
|
||||
|
@ -432,7 +464,7 @@ static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code)
|
|||
* af_rxrpc.c
|
||||
*/
|
||||
extern atomic_t rxrpc_n_skbs;
|
||||
extern __be32 rxrpc_epoch;
|
||||
extern u32 rxrpc_epoch;
|
||||
extern atomic_t rxrpc_debug_id;
|
||||
extern struct workqueue_struct *rxrpc_workqueue;
|
||||
|
||||
|
@ -453,8 +485,8 @@ extern unsigned rxrpc_rx_window_size;
|
|||
extern unsigned rxrpc_rx_mtu;
|
||||
extern unsigned rxrpc_rx_jumbo_max;
|
||||
|
||||
void __rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool);
|
||||
void rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool);
|
||||
void __rxrpc_propose_ACK(struct rxrpc_call *, u8, u32, bool);
|
||||
void rxrpc_propose_ACK(struct rxrpc_call *, u8, u32, bool);
|
||||
void rxrpc_process_call(struct work_struct *);
|
||||
|
||||
/*
|
||||
|
@ -466,15 +498,15 @@ extern struct kmem_cache *rxrpc_call_jar;
|
|||
extern struct list_head rxrpc_calls;
|
||||
extern rwlock_t rxrpc_call_lock;
|
||||
|
||||
struct rxrpc_call *rxrpc_find_call_hash(u8, __be32, __be32, __be32,
|
||||
__be16, void *, sa_family_t, const u8 *);
|
||||
struct rxrpc_call *rxrpc_find_call_hash(struct rxrpc_host_header *,
|
||||
void *, sa_family_t, const void *);
|
||||
struct rxrpc_call *rxrpc_get_client_call(struct rxrpc_sock *,
|
||||
struct rxrpc_transport *,
|
||||
struct rxrpc_conn_bundle *,
|
||||
unsigned long, int, gfp_t);
|
||||
struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *,
|
||||
struct rxrpc_connection *,
|
||||
struct rxrpc_header *, gfp_t);
|
||||
struct rxrpc_host_header *, gfp_t);
|
||||
struct rxrpc_call *rxrpc_find_server_call(struct rxrpc_sock *, unsigned long);
|
||||
void rxrpc_release_call(struct rxrpc_call *);
|
||||
void rxrpc_release_calls_on_socket(struct rxrpc_sock *);
|
||||
|
@ -490,16 +522,16 @@ extern rwlock_t rxrpc_connection_lock;
|
|||
|
||||
struct rxrpc_conn_bundle *rxrpc_get_bundle(struct rxrpc_sock *,
|
||||
struct rxrpc_transport *,
|
||||
struct key *, __be16, gfp_t);
|
||||
struct key *, u16, gfp_t);
|
||||
void rxrpc_put_bundle(struct rxrpc_transport *, struct rxrpc_conn_bundle *);
|
||||
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_transport *,
|
||||
struct rxrpc_conn_bundle *, struct rxrpc_call *, gfp_t);
|
||||
void rxrpc_put_connection(struct rxrpc_connection *);
|
||||
void __exit rxrpc_destroy_all_connections(void);
|
||||
struct rxrpc_connection *rxrpc_find_connection(struct rxrpc_transport *,
|
||||
struct rxrpc_header *);
|
||||
struct rxrpc_host_header *);
|
||||
extern struct rxrpc_connection *
|
||||
rxrpc_incoming_connection(struct rxrpc_transport *, struct rxrpc_header *,
|
||||
rxrpc_incoming_connection(struct rxrpc_transport *, struct rxrpc_host_header *,
|
||||
gfp_t);
|
||||
|
||||
/*
|
||||
|
@ -694,7 +726,7 @@ do { \
|
|||
printk(KERN_ERR "RxRPC: Assertion failed\n"); \
|
||||
BUG(); \
|
||||
} \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define ASSERTCMP(X, OP, Y) \
|
||||
do { \
|
||||
|
@ -707,7 +739,7 @@ do { \
|
|||
(unsigned long)(X), (unsigned long)(Y)); \
|
||||
BUG(); \
|
||||
} \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define ASSERTIF(C, X) \
|
||||
do { \
|
||||
|
@ -716,7 +748,7 @@ do { \
|
|||
printk(KERN_ERR "RxRPC: Assertion failed\n"); \
|
||||
BUG(); \
|
||||
} \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define ASSERTIFCMP(C, X, OP, Y) \
|
||||
do { \
|
||||
|
@ -729,25 +761,25 @@ do { \
|
|||
(unsigned long)(X), (unsigned long)(Y)); \
|
||||
BUG(); \
|
||||
} \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define ASSERT(X) \
|
||||
do { \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define ASSERTCMP(X, OP, Y) \
|
||||
do { \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define ASSERTIF(C, X) \
|
||||
do { \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define ASSERTIFCMP(C, X, OP, Y) \
|
||||
do { \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#endif /* __KDEBUGALL */
|
||||
|
||||
|
@ -804,9 +836,9 @@ do { \
|
|||
CHECK_SLAB_OKAY(&(CALL)->usage); \
|
||||
if (atomic_inc_return(&(CALL)->usage) == 1) \
|
||||
BUG(); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
#define rxrpc_put_call(CALL) \
|
||||
do { \
|
||||
__rxrpc_put_call(CALL); \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
|
|
@ -323,9 +323,11 @@ void __exit rxrpc_destroy_all_locals(void)
|
|||
* Reply to a version request
|
||||
*/
|
||||
static void rxrpc_send_version_request(struct rxrpc_local *local,
|
||||
struct rxrpc_header *hdr,
|
||||
struct rxrpc_host_header *hdr,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
struct sockaddr_in sin;
|
||||
struct msghdr msg;
|
||||
struct kvec iov[2];
|
||||
|
@ -344,15 +346,20 @@ static void rxrpc_send_version_request(struct rxrpc_local *local,
|
|||
msg.msg_controllen = 0;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
hdr->seq = 0;
|
||||
hdr->serial = 0;
|
||||
hdr->type = RXRPC_PACKET_TYPE_VERSION;
|
||||
hdr->flags = RXRPC_LAST_PACKET | (~hdr->flags & RXRPC_CLIENT_INITIATED);
|
||||
hdr->userStatus = 0;
|
||||
hdr->_rsvd = 0;
|
||||
whdr.epoch = htonl(sp->hdr.epoch);
|
||||
whdr.cid = htonl(sp->hdr.cid);
|
||||
whdr.callNumber = htonl(sp->hdr.callNumber);
|
||||
whdr.seq = 0;
|
||||
whdr.serial = 0;
|
||||
whdr.type = RXRPC_PACKET_TYPE_VERSION;
|
||||
whdr.flags = RXRPC_LAST_PACKET | (~hdr->flags & RXRPC_CLIENT_INITIATED);
|
||||
whdr.userStatus = 0;
|
||||
whdr.securityIndex = 0;
|
||||
whdr._rsvd = 0;
|
||||
whdr.serviceId = htons(sp->hdr.serviceId);
|
||||
|
||||
iov[0].iov_base = hdr;
|
||||
iov[0].iov_len = sizeof(*hdr);
|
||||
iov[0].iov_base = &whdr;
|
||||
iov[0].iov_len = sizeof(whdr);
|
||||
iov[1].iov_base = (char *)rxrpc_version_string;
|
||||
iov[1].iov_len = sizeof(rxrpc_version_string);
|
||||
|
||||
|
@ -383,7 +390,7 @@ static void rxrpc_process_local_events(struct work_struct *work)
|
|||
while ((skb = skb_dequeue(&local->event_queue))) {
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
|
||||
kdebug("{%d},{%u}", local->debug_id, sp->hdr.type);
|
||||
_debug("{%d},{%u}", local->debug_id, sp->hdr.type);
|
||||
|
||||
switch (sp->hdr.type) {
|
||||
case RXRPC_PACKET_TYPE_VERSION:
|
||||
|
|
|
@ -111,11 +111,11 @@ static void rxrpc_send_abort(struct rxrpc_call *call, u32 abort_code)
|
|||
if (call->state <= RXRPC_CALL_COMPLETE) {
|
||||
call->state = RXRPC_CALL_LOCALLY_ABORTED;
|
||||
call->abort_code = abort_code;
|
||||
set_bit(RXRPC_CALL_ABORT, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ABORT, &call->events);
|
||||
del_timer_sync(&call->resend_timer);
|
||||
del_timer_sync(&call->ack_timer);
|
||||
clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_ACK, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events);
|
||||
clear_bit(RXRPC_CALL_EV_ACK, &call->events);
|
||||
clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ int rxrpc_client_sendmsg(struct rxrpc_sock *rx, struct rxrpc_transport *trans,
|
|||
struct rxrpc_call *call;
|
||||
unsigned long user_call_ID = 0;
|
||||
struct key *key;
|
||||
__be16 service_id;
|
||||
u16 service_id;
|
||||
u32 abort_code = 0;
|
||||
int ret;
|
||||
|
||||
|
@ -151,11 +151,11 @@ int rxrpc_client_sendmsg(struct rxrpc_sock *rx, struct rxrpc_transport *trans,
|
|||
|
||||
bundle = NULL;
|
||||
if (trans) {
|
||||
service_id = rx->service_id;
|
||||
service_id = rx->srx.srx_service;
|
||||
if (msg->msg_name) {
|
||||
DECLARE_SOCKADDR(struct sockaddr_rxrpc *, srx,
|
||||
msg->msg_name);
|
||||
service_id = htons(srx->srx_service);
|
||||
service_id = srx->srx_service;
|
||||
}
|
||||
key = rx->key;
|
||||
if (key && !rx->key->payload.data[0])
|
||||
|
@ -348,7 +348,7 @@ int rxrpc_send_packet(struct rxrpc_transport *trans, struct sk_buff *skb)
|
|||
|
||||
/* send the packet with the don't fragment bit set if we currently
|
||||
* think it's small enough */
|
||||
if (skb->len - sizeof(struct rxrpc_header) < trans->peer->maxdata) {
|
||||
if (skb->len - sizeof(struct rxrpc_wire_header) < trans->peer->maxdata) {
|
||||
down_read(&trans->local->defrag_sem);
|
||||
/* send the packet by UDP
|
||||
* - returns -EMSGSIZE if UDP would have to fragment the packet
|
||||
|
@ -401,7 +401,8 @@ static int rxrpc_wait_for_tx_window(struct rxrpc_sock *rx,
|
|||
int ret;
|
||||
|
||||
_enter(",{%d},%ld",
|
||||
CIRC_SPACE(call->acks_head, call->acks_tail, call->acks_winsz),
|
||||
CIRC_SPACE(call->acks_head, ACCESS_ONCE(call->acks_tail),
|
||||
call->acks_winsz),
|
||||
*timeo);
|
||||
|
||||
add_wait_queue(&call->tx_waitq, &myself);
|
||||
|
@ -409,7 +410,7 @@ static int rxrpc_wait_for_tx_window(struct rxrpc_sock *rx,
|
|||
for (;;) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
ret = 0;
|
||||
if (CIRC_SPACE(call->acks_head, call->acks_tail,
|
||||
if (CIRC_SPACE(call->acks_head, ACCESS_ONCE(call->acks_tail),
|
||||
call->acks_winsz) > 0)
|
||||
break;
|
||||
if (signal_pending(current)) {
|
||||
|
@ -437,7 +438,7 @@ static inline void rxrpc_instant_resend(struct rxrpc_call *call)
|
|||
if (try_to_del_timer_sync(&call->resend_timer) >= 0) {
|
||||
clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
|
||||
if (call->state < RXRPC_CALL_COMPLETE &&
|
||||
!test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_RESEND_TIMER, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
}
|
||||
read_unlock_bh(&call->state_lock);
|
||||
|
@ -480,8 +481,7 @@ static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb,
|
|||
write_unlock_bh(&call->state_lock);
|
||||
}
|
||||
|
||||
_proto("Tx DATA %%%u { #%u }",
|
||||
ntohl(sp->hdr.serial), ntohl(sp->hdr.seq));
|
||||
_proto("Tx DATA %%%u { #%u }", sp->hdr.serial, sp->hdr.seq);
|
||||
|
||||
sp->need_resend = false;
|
||||
sp->resend_at = jiffies + rxrpc_resend_timeout;
|
||||
|
@ -512,6 +512,29 @@ static void rxrpc_queue_packet(struct rxrpc_call *call, struct sk_buff *skb,
|
|||
_leave("");
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a host-endian header into a network-endian header.
|
||||
*/
|
||||
static void rxrpc_insert_header(struct sk_buff *skb)
|
||||
{
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
|
||||
whdr.epoch = htonl(sp->hdr.epoch);
|
||||
whdr.cid = htonl(sp->hdr.cid);
|
||||
whdr.callNumber = htonl(sp->hdr.callNumber);
|
||||
whdr.seq = htonl(sp->hdr.seq);
|
||||
whdr.serial = htonl(sp->hdr.serial);
|
||||
whdr.type = sp->hdr.type;
|
||||
whdr.flags = sp->hdr.flags;
|
||||
whdr.userStatus = sp->hdr.userStatus;
|
||||
whdr.securityIndex = sp->hdr.securityIndex;
|
||||
whdr._rsvd = htons(sp->hdr._rsvd);
|
||||
whdr.serviceId = htons(sp->hdr.serviceId);
|
||||
|
||||
memcpy(skb->head, &whdr, sizeof(whdr));
|
||||
}
|
||||
|
||||
/*
|
||||
* send data through a socket
|
||||
* - must be called in process context
|
||||
|
@ -548,7 +571,8 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
|
|||
|
||||
_debug("alloc");
|
||||
|
||||
if (CIRC_SPACE(call->acks_head, call->acks_tail,
|
||||
if (CIRC_SPACE(call->acks_head,
|
||||
ACCESS_ONCE(call->acks_tail),
|
||||
call->acks_winsz) <= 0) {
|
||||
ret = -EAGAIN;
|
||||
if (msg->msg_flags & MSG_DONTWAIT)
|
||||
|
@ -650,22 +674,22 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
|
|||
|
||||
seq = atomic_inc_return(&call->sequence);
|
||||
|
||||
sp->hdr.epoch = conn->epoch;
|
||||
sp->hdr.cid = call->cid;
|
||||
sp->hdr.epoch = conn->epoch;
|
||||
sp->hdr.cid = call->cid;
|
||||
sp->hdr.callNumber = call->call_id;
|
||||
sp->hdr.seq = htonl(seq);
|
||||
sp->hdr.serial =
|
||||
htonl(atomic_inc_return(&conn->serial));
|
||||
sp->hdr.type = RXRPC_PACKET_TYPE_DATA;
|
||||
sp->hdr.seq = seq;
|
||||
sp->hdr.serial = atomic_inc_return(&conn->serial);
|
||||
sp->hdr.type = RXRPC_PACKET_TYPE_DATA;
|
||||
sp->hdr.userStatus = 0;
|
||||
sp->hdr.securityIndex = conn->security_ix;
|
||||
sp->hdr._rsvd = 0;
|
||||
sp->hdr.serviceId = conn->service_id;
|
||||
sp->hdr._rsvd = 0;
|
||||
sp->hdr.serviceId = call->service_id;
|
||||
|
||||
sp->hdr.flags = conn->out_clientflag;
|
||||
if (msg_data_left(msg) == 0 && !more)
|
||||
sp->hdr.flags |= RXRPC_LAST_PACKET;
|
||||
else if (CIRC_SPACE(call->acks_head, call->acks_tail,
|
||||
else if (CIRC_SPACE(call->acks_head,
|
||||
ACCESS_ONCE(call->acks_tail),
|
||||
call->acks_winsz) > 1)
|
||||
sp->hdr.flags |= RXRPC_MORE_PACKETS;
|
||||
if (more && seq & 1)
|
||||
|
@ -673,12 +697,11 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
|
|||
|
||||
ret = rxrpc_secure_packet(
|
||||
call, skb, skb->mark,
|
||||
skb->head + sizeof(struct rxrpc_header));
|
||||
skb->head + sizeof(struct rxrpc_wire_header));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
memcpy(skb->head, &sp->hdr,
|
||||
sizeof(struct rxrpc_header));
|
||||
rxrpc_insert_header(skb);
|
||||
rxrpc_queue_packet(call, skb, !msg_data_left(msg) && !more);
|
||||
skb = NULL;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ static struct rxrpc_peer *rxrpc_alloc_peer(struct sockaddr_rxrpc *srx,
|
|||
BUG();
|
||||
}
|
||||
|
||||
peer->hdrsize += sizeof(struct rxrpc_header);
|
||||
peer->hdrsize += sizeof(struct rxrpc_wire_header);
|
||||
peer->maxdata = peer->mtu - peer->hdrsize;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,9 +74,9 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
|
|||
" %-8.8s %08x %lx\n",
|
||||
lbuff,
|
||||
rbuff,
|
||||
ntohs(call->conn->service_id),
|
||||
ntohl(call->conn->cid),
|
||||
ntohl(call->call_id),
|
||||
call->conn->service_id,
|
||||
call->cid,
|
||||
call->call_id,
|
||||
call->conn->in_clientflag ? "Svc" : "Clt",
|
||||
atomic_read(&call->usage),
|
||||
rxrpc_call_states[call->state],
|
||||
|
@ -157,8 +157,8 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
|
|||
" %s %08x %08x %08x\n",
|
||||
lbuff,
|
||||
rbuff,
|
||||
ntohs(conn->service_id),
|
||||
ntohl(conn->cid),
|
||||
conn->service_id,
|
||||
conn->cid,
|
||||
conn->call_counter,
|
||||
conn->in_clientflag ? "Svc" : "Clt",
|
||||
atomic_read(&conn->usage),
|
||||
|
|
|
@ -33,7 +33,7 @@ void rxrpc_remove_user_ID(struct rxrpc_sock *rx, struct rxrpc_call *call)
|
|||
|
||||
read_lock_bh(&call->state_lock);
|
||||
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
|
||||
!test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
|
||||
!test_and_set_bit(RXRPC_CALL_EV_RELEASE, &call->events))
|
||||
rxrpc_queue_call(call);
|
||||
read_unlock_bh(&call->state_lock);
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
|
|||
goto receive_non_data_message;
|
||||
|
||||
_debug("recvmsg DATA #%u { %d, %d }",
|
||||
ntohl(sp->hdr.seq), skb->len, sp->offset);
|
||||
sp->hdr.seq, skb->len, sp->offset);
|
||||
|
||||
if (!continue_call) {
|
||||
/* only set the control data once per recvmsg() */
|
||||
|
@ -169,11 +169,11 @@ int rxrpc_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
|
|||
ASSERT(test_bit(RXRPC_CALL_HAS_USERID, &call->flags));
|
||||
}
|
||||
|
||||
ASSERTCMP(ntohl(sp->hdr.seq), >=, call->rx_data_recv);
|
||||
ASSERTCMP(ntohl(sp->hdr.seq), <=, call->rx_data_recv + 1);
|
||||
call->rx_data_recv = ntohl(sp->hdr.seq);
|
||||
ASSERTCMP(sp->hdr.seq, >=, call->rx_data_recv);
|
||||
ASSERTCMP(sp->hdr.seq, <=, call->rx_data_recv + 1);
|
||||
call->rx_data_recv = sp->hdr.seq;
|
||||
|
||||
ASSERTCMP(ntohl(sp->hdr.seq), >, call->rx_data_eaten);
|
||||
ASSERTCMP(sp->hdr.seq, >, call->rx_data_eaten);
|
||||
|
||||
offset = sp->offset;
|
||||
copy = skb->len - offset;
|
||||
|
@ -364,11 +364,11 @@ void rxrpc_kernel_data_delivered(struct sk_buff *skb)
|
|||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
struct rxrpc_call *call = sp->call;
|
||||
|
||||
ASSERTCMP(ntohl(sp->hdr.seq), >=, call->rx_data_recv);
|
||||
ASSERTCMP(ntohl(sp->hdr.seq), <=, call->rx_data_recv + 1);
|
||||
call->rx_data_recv = ntohl(sp->hdr.seq);
|
||||
ASSERTCMP(sp->hdr.seq, >=, call->rx_data_recv);
|
||||
ASSERTCMP(sp->hdr.seq, <=, call->rx_data_recv + 1);
|
||||
call->rx_data_recv = sp->hdr.seq;
|
||||
|
||||
ASSERTCMP(ntohl(sp->hdr.seq), >, call->rx_data_eaten);
|
||||
ASSERTCMP(sp->hdr.seq, >, call->rx_data_eaten);
|
||||
rxrpc_free_skb(skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -167,11 +167,11 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
|
|||
struct rxrpc_sock *rx;
|
||||
struct key *key;
|
||||
key_ref_t kref;
|
||||
char kdesc[5+1+3+1];
|
||||
char kdesc[5 + 1 + 3 + 1];
|
||||
|
||||
_enter("");
|
||||
|
||||
sprintf(kdesc, "%u:%u", ntohs(conn->service_id), conn->security_ix);
|
||||
sprintf(kdesc, "%u:%u", conn->service_id, conn->security_ix);
|
||||
|
||||
sec = rxrpc_security_lookup(conn->security_ix);
|
||||
if (!sec) {
|
||||
|
@ -182,7 +182,7 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
|
|||
/* find the service */
|
||||
read_lock_bh(&local->services_lock);
|
||||
list_for_each_entry(rx, &local->services, listen_link) {
|
||||
if (rx->service_id == conn->service_id)
|
||||
if (rx->srx.srx_service == conn->service_id)
|
||||
goto found_service;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ static void rxrpc_request_final_ACK(struct rxrpc_call *call)
|
|||
/* get an extra ref on the call for the final-ACK generator to
|
||||
* release */
|
||||
rxrpc_get_call(call);
|
||||
set_bit(RXRPC_CALL_ACK_FINAL, &call->events);
|
||||
set_bit(RXRPC_CALL_EV_ACK_FINAL, &call->events);
|
||||
if (try_to_del_timer_sync(&call->ack_timer) >= 0)
|
||||
rxrpc_queue_call(call);
|
||||
break;
|
||||
|
@ -59,7 +59,7 @@ static void rxrpc_hard_ACK_data(struct rxrpc_call *call,
|
|||
|
||||
spin_lock_bh(&call->lock);
|
||||
|
||||
_debug("hard ACK #%u", ntohl(sp->hdr.seq));
|
||||
_debug("hard ACK #%u", sp->hdr.seq);
|
||||
|
||||
for (loop = 0; loop < RXRPC_ACKR_WINDOW_ASZ; loop++) {
|
||||
call->ackr_window[loop] >>= 1;
|
||||
|
@ -67,7 +67,7 @@ static void rxrpc_hard_ACK_data(struct rxrpc_call *call,
|
|||
call->ackr_window[loop + 1] << (BITS_PER_LONG - 1);
|
||||
}
|
||||
|
||||
seq = ntohl(sp->hdr.seq);
|
||||
seq = sp->hdr.seq;
|
||||
ASSERTCMP(seq, ==, call->rx_data_eaten + 1);
|
||||
call->rx_data_eaten = seq;
|
||||
|
||||
|
@ -133,5 +133,4 @@ void rxrpc_kernel_free_skb(struct sk_buff *skb)
|
|||
{
|
||||
rxrpc_free_skb(skb);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(rxrpc_kernel_free_skb);
|
||||
|
|
|
@ -51,6 +51,7 @@ static struct rxrpc_transport *rxrpc_alloc_transport(struct rxrpc_local *local,
|
|||
spin_lock_init(&trans->client_lock);
|
||||
rwlock_init(&trans->conn_lock);
|
||||
atomic_set(&trans->usage, 1);
|
||||
trans->conn_idcounter = peer->srx.srx_service << 16;
|
||||
trans->debug_id = atomic_inc_return(&rxrpc_debug_id);
|
||||
|
||||
if (peer->srx.transport.family == AF_INET) {
|
||||
|
|
|
@ -132,8 +132,8 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
|
|||
desc.info = iv.x;
|
||||
desc.flags = 0;
|
||||
|
||||
tmpbuf.x[0] = conn->epoch;
|
||||
tmpbuf.x[1] = conn->cid;
|
||||
tmpbuf.x[0] = htonl(conn->epoch);
|
||||
tmpbuf.x[1] = htonl(conn->cid);
|
||||
tmpbuf.x[2] = 0;
|
||||
tmpbuf.x[3] = htonl(conn->security_ix);
|
||||
|
||||
|
@ -142,7 +142,7 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
|
|||
crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
|
||||
|
||||
memcpy(&conn->csum_iv, &tmpbuf.x[2], sizeof(conn->csum_iv));
|
||||
ASSERTCMP(conn->csum_iv.n[0], ==, tmpbuf.x[2]);
|
||||
ASSERTCMP((u32 __force)conn->csum_iv.n[0], ==, (u32 __force)tmpbuf.x[2]);
|
||||
|
||||
_leave("");
|
||||
}
|
||||
|
@ -169,8 +169,8 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
|
|||
|
||||
_enter("");
|
||||
|
||||
check = ntohl(sp->hdr.seq ^ sp->hdr.callNumber);
|
||||
data_size |= (u32) check << 16;
|
||||
check = sp->hdr.seq ^ sp->hdr.callNumber;
|
||||
data_size |= (u32)check << 16;
|
||||
|
||||
tmpbuf.hdr.data_size = htonl(data_size);
|
||||
memcpy(&tmpbuf.first, sechdr + 4, sizeof(tmpbuf.first));
|
||||
|
@ -195,9 +195,9 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
|
|||
* wholly encrypt a packet (level 2 security)
|
||||
*/
|
||||
static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
|
||||
struct sk_buff *skb,
|
||||
u32 data_size,
|
||||
void *sechdr)
|
||||
struct sk_buff *skb,
|
||||
u32 data_size,
|
||||
void *sechdr)
|
||||
{
|
||||
const struct rxrpc_key_token *token;
|
||||
struct rxkad_level2_hdr rxkhdr
|
||||
|
@ -215,9 +215,9 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
|
|||
|
||||
_enter("");
|
||||
|
||||
check = ntohl(sp->hdr.seq ^ sp->hdr.callNumber);
|
||||
check = sp->hdr.seq ^ sp->hdr.callNumber;
|
||||
|
||||
rxkhdr.data_size = htonl(data_size | (u32) check << 16);
|
||||
rxkhdr.data_size = htonl(data_size | (u32)check << 16);
|
||||
rxkhdr.checksum = 0;
|
||||
|
||||
/* encrypt from the session key */
|
||||
|
@ -251,9 +251,9 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
|
|||
* checksum an RxRPC packet header
|
||||
*/
|
||||
static int rxkad_secure_packet(const struct rxrpc_call *call,
|
||||
struct sk_buff *skb,
|
||||
size_t data_size,
|
||||
void *sechdr)
|
||||
struct sk_buff *skb,
|
||||
size_t data_size,
|
||||
void *sechdr)
|
||||
{
|
||||
struct rxrpc_skb_priv *sp;
|
||||
struct blkcipher_desc desc;
|
||||
|
@ -262,14 +262,13 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
|
|||
struct {
|
||||
__be32 x[2];
|
||||
} tmpbuf __attribute__((aligned(8))); /* must all be in same page */
|
||||
__be32 x;
|
||||
u32 y;
|
||||
u32 x, y;
|
||||
int ret;
|
||||
|
||||
sp = rxrpc_skb(skb);
|
||||
|
||||
_enter("{%d{%x}},{#%u},%zu,",
|
||||
call->debug_id, key_serial(call->conn->key), ntohl(sp->hdr.seq),
|
||||
call->debug_id, key_serial(call->conn->key), sp->hdr.seq,
|
||||
data_size);
|
||||
|
||||
if (!call->conn->cipher)
|
||||
|
@ -286,10 +285,10 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
|
|||
desc.flags = 0;
|
||||
|
||||
/* calculate the security checksum */
|
||||
x = htonl(call->channel << (32 - RXRPC_CIDSHIFT));
|
||||
x |= sp->hdr.seq & cpu_to_be32(0x3fffffff);
|
||||
tmpbuf.x[0] = sp->hdr.callNumber;
|
||||
tmpbuf.x[1] = x;
|
||||
x = call->channel << (32 - RXRPC_CIDSHIFT);
|
||||
x |= sp->hdr.seq & 0x3fffffff;
|
||||
tmpbuf.x[0] = htonl(sp->hdr.callNumber);
|
||||
tmpbuf.x[1] = htonl(x);
|
||||
|
||||
sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf));
|
||||
sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
|
||||
|
@ -299,7 +298,7 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
|
|||
y = (y >> 16) & 0xffff;
|
||||
if (y == 0)
|
||||
y = 1; /* zero checksums are not permitted */
|
||||
sp->hdr.cksum = htons(y);
|
||||
sp->hdr.cksum = y;
|
||||
|
||||
switch (call->conn->security_level) {
|
||||
case RXRPC_SECURITY_PLAIN:
|
||||
|
@ -368,7 +367,7 @@ static int rxkad_verify_packet_auth(const struct rxrpc_call *call,
|
|||
data_size = buf & 0xffff;
|
||||
|
||||
check = buf >> 16;
|
||||
check ^= ntohl(sp->hdr.seq ^ sp->hdr.callNumber);
|
||||
check ^= sp->hdr.seq ^ sp->hdr.callNumber;
|
||||
check &= 0xffff;
|
||||
if (check != 0) {
|
||||
*_abort_code = RXKADSEALEDINCON;
|
||||
|
@ -453,7 +452,7 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
|
|||
data_size = buf & 0xffff;
|
||||
|
||||
check = buf >> 16;
|
||||
check ^= ntohl(sp->hdr.seq ^ sp->hdr.callNumber);
|
||||
check ^= sp->hdr.seq ^ sp->hdr.callNumber;
|
||||
check &= 0xffff;
|
||||
if (check != 0) {
|
||||
*_abort_code = RXKADSEALEDINCON;
|
||||
|
@ -494,16 +493,14 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
|
|||
struct {
|
||||
__be32 x[2];
|
||||
} tmpbuf __attribute__((aligned(8))); /* must all be in same page */
|
||||
__be32 x;
|
||||
__be16 cksum;
|
||||
u32 y;
|
||||
u16 cksum;
|
||||
u32 x, y;
|
||||
int ret;
|
||||
|
||||
sp = rxrpc_skb(skb);
|
||||
|
||||
_enter("{%d{%x}},{#%u}",
|
||||
call->debug_id, key_serial(call->conn->key),
|
||||
ntohl(sp->hdr.seq));
|
||||
call->debug_id, key_serial(call->conn->key), sp->hdr.seq);
|
||||
|
||||
if (!call->conn->cipher)
|
||||
return 0;
|
||||
|
@ -521,21 +518,20 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
|
|||
desc.flags = 0;
|
||||
|
||||
/* validate the security checksum */
|
||||
x = htonl(call->channel << (32 - RXRPC_CIDSHIFT));
|
||||
x |= sp->hdr.seq & cpu_to_be32(0x3fffffff);
|
||||
tmpbuf.x[0] = call->call_id;
|
||||
tmpbuf.x[1] = x;
|
||||
x = call->channel << (32 - RXRPC_CIDSHIFT);
|
||||
x |= sp->hdr.seq & 0x3fffffff;
|
||||
tmpbuf.x[0] = htonl(call->call_id);
|
||||
tmpbuf.x[1] = htonl(x);
|
||||
|
||||
sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf));
|
||||
sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
|
||||
crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
|
||||
|
||||
y = ntohl(tmpbuf.x[1]);
|
||||
y = (y >> 16) & 0xffff;
|
||||
if (y == 0)
|
||||
y = 1; /* zero checksums are not permitted */
|
||||
cksum = (y >> 16) & 0xffff;
|
||||
if (cksum == 0)
|
||||
cksum = 1; /* zero checksums are not permitted */
|
||||
|
||||
cksum = htons(y);
|
||||
if (sp->hdr.cksum != cksum) {
|
||||
*_abort_code = RXKADSEALEDINCON;
|
||||
_leave(" = -EPROTO [csum failed]");
|
||||
|
@ -567,10 +563,11 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
|
|||
static int rxkad_issue_challenge(struct rxrpc_connection *conn)
|
||||
{
|
||||
struct rxkad_challenge challenge;
|
||||
struct rxrpc_header hdr;
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct msghdr msg;
|
||||
struct kvec iov[2];
|
||||
size_t len;
|
||||
u32 serial;
|
||||
int ret;
|
||||
|
||||
_enter("{%d,%x}", conn->debug_id, key_serial(conn->key));
|
||||
|
@ -592,26 +589,27 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
|
|||
msg.msg_controllen = 0;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
hdr.epoch = conn->epoch;
|
||||
hdr.cid = conn->cid;
|
||||
hdr.callNumber = 0;
|
||||
hdr.seq = 0;
|
||||
hdr.type = RXRPC_PACKET_TYPE_CHALLENGE;
|
||||
hdr.flags = conn->out_clientflag;
|
||||
hdr.userStatus = 0;
|
||||
hdr.securityIndex = conn->security_ix;
|
||||
hdr._rsvd = 0;
|
||||
hdr.serviceId = conn->service_id;
|
||||
whdr.epoch = htonl(conn->epoch);
|
||||
whdr.cid = htonl(conn->cid);
|
||||
whdr.callNumber = 0;
|
||||
whdr.seq = 0;
|
||||
whdr.type = RXRPC_PACKET_TYPE_CHALLENGE;
|
||||
whdr.flags = conn->out_clientflag;
|
||||
whdr.userStatus = 0;
|
||||
whdr.securityIndex = conn->security_ix;
|
||||
whdr._rsvd = 0;
|
||||
whdr.serviceId = htons(conn->service_id);
|
||||
|
||||
iov[0].iov_base = &hdr;
|
||||
iov[0].iov_len = sizeof(hdr);
|
||||
iov[0].iov_base = &whdr;
|
||||
iov[0].iov_len = sizeof(whdr);
|
||||
iov[1].iov_base = &challenge;
|
||||
iov[1].iov_len = sizeof(challenge);
|
||||
|
||||
len = iov[0].iov_len + iov[1].iov_len;
|
||||
|
||||
hdr.serial = htonl(atomic_inc_return(&conn->serial));
|
||||
_proto("Tx CHALLENGE %%%u", ntohl(hdr.serial));
|
||||
serial = atomic_inc_return(&conn->serial);
|
||||
whdr.serial = htonl(serial);
|
||||
_proto("Tx CHALLENGE %%%u", serial);
|
||||
|
||||
ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 2, len);
|
||||
if (ret < 0) {
|
||||
|
@ -627,13 +625,15 @@ static int rxkad_issue_challenge(struct rxrpc_connection *conn)
|
|||
* send a Kerberos security response
|
||||
*/
|
||||
static int rxkad_send_response(struct rxrpc_connection *conn,
|
||||
struct rxrpc_header *hdr,
|
||||
struct rxrpc_host_header *hdr,
|
||||
struct rxkad_response *resp,
|
||||
const struct rxkad_key *s2)
|
||||
{
|
||||
struct rxrpc_wire_header whdr;
|
||||
struct msghdr msg;
|
||||
struct kvec iov[3];
|
||||
size_t len;
|
||||
u32 serial;
|
||||
int ret;
|
||||
|
||||
_enter("");
|
||||
|
@ -644,24 +644,26 @@ static int rxkad_send_response(struct rxrpc_connection *conn,
|
|||
msg.msg_controllen = 0;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
hdr->epoch = conn->epoch;
|
||||
hdr->seq = 0;
|
||||
hdr->type = RXRPC_PACKET_TYPE_RESPONSE;
|
||||
hdr->flags = conn->out_clientflag;
|
||||
hdr->userStatus = 0;
|
||||
hdr->_rsvd = 0;
|
||||
memset(&whdr, 0, sizeof(whdr));
|
||||
whdr.epoch = htonl(hdr->epoch);
|
||||
whdr.cid = htonl(hdr->cid);
|
||||
whdr.type = RXRPC_PACKET_TYPE_RESPONSE;
|
||||
whdr.flags = conn->out_clientflag;
|
||||
whdr.securityIndex = hdr->securityIndex;
|
||||
whdr.serviceId = htons(hdr->serviceId);
|
||||
|
||||
iov[0].iov_base = hdr;
|
||||
iov[0].iov_len = sizeof(*hdr);
|
||||
iov[0].iov_base = &whdr;
|
||||
iov[0].iov_len = sizeof(whdr);
|
||||
iov[1].iov_base = resp;
|
||||
iov[1].iov_len = sizeof(*resp);
|
||||
iov[2].iov_base = (void *) s2->ticket;
|
||||
iov[2].iov_base = (void *)s2->ticket;
|
||||
iov[2].iov_len = s2->ticket_len;
|
||||
|
||||
len = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len;
|
||||
|
||||
hdr->serial = htonl(atomic_inc_return(&conn->serial));
|
||||
_proto("Tx RESPONSE %%%u", ntohl(hdr->serial));
|
||||
serial = atomic_inc_return(&conn->serial);
|
||||
whdr.serial = htonl(serial);
|
||||
_proto("Tx RESPONSE %%%u", serial);
|
||||
|
||||
ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 3, len);
|
||||
if (ret < 0) {
|
||||
|
@ -770,7 +772,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
|
|||
min_level = ntohl(challenge.min_level);
|
||||
|
||||
_proto("Rx CHALLENGE %%%u { v=%u n=%u ml=%u }",
|
||||
ntohl(sp->hdr.serial), version, nonce, min_level);
|
||||
sp->hdr.serial, version, nonce, min_level);
|
||||
|
||||
abort_code = RXKADINCONSISTENCY;
|
||||
if (version != RXKAD_VERSION)
|
||||
|
@ -785,22 +787,23 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
|
|||
/* build the response packet */
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
resp.version = RXKAD_VERSION;
|
||||
resp.encrypted.epoch = conn->epoch;
|
||||
resp.encrypted.cid = conn->cid;
|
||||
resp.encrypted.securityIndex = htonl(conn->security_ix);
|
||||
resp.version = htonl(RXKAD_VERSION);
|
||||
resp.encrypted.epoch = htonl(conn->epoch);
|
||||
resp.encrypted.cid = htonl(conn->cid);
|
||||
resp.encrypted.securityIndex = htonl(conn->security_ix);
|
||||
resp.encrypted.inc_nonce = htonl(nonce + 1);
|
||||
resp.encrypted.level = htonl(conn->security_level);
|
||||
resp.kvno = htonl(token->kad->kvno);
|
||||
resp.ticket_len = htonl(token->kad->ticket_len);
|
||||
|
||||
resp.encrypted.call_id[0] =
|
||||
(conn->channels[0] ? conn->channels[0]->call_id : 0);
|
||||
htonl(conn->channels[0] ? conn->channels[0]->call_id : 0);
|
||||
resp.encrypted.call_id[1] =
|
||||
(conn->channels[1] ? conn->channels[1]->call_id : 0);
|
||||
htonl(conn->channels[1] ? conn->channels[1]->call_id : 0);
|
||||
resp.encrypted.call_id[2] =
|
||||
(conn->channels[2] ? conn->channels[2]->call_id : 0);
|
||||
htonl(conn->channels[2] ? conn->channels[2]->call_id : 0);
|
||||
resp.encrypted.call_id[3] =
|
||||
(conn->channels[3] ? conn->channels[3]->call_id : 0);
|
||||
resp.encrypted.inc_nonce = htonl(nonce + 1);
|
||||
resp.encrypted.level = htonl(conn->security_level);
|
||||
resp.kvno = htonl(token->kad->kvno);
|
||||
resp.ticket_len = htonl(token->kad->ticket_len);
|
||||
htonl(conn->channels[3] ? conn->channels[3]->call_id : 0);
|
||||
|
||||
/* calculate the response checksum and then do the encryption */
|
||||
rxkad_calc_response_checksum(&resp);
|
||||
|
@ -1022,7 +1025,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
|
|||
kvno = ntohl(response.kvno);
|
||||
sp = rxrpc_skb(skb);
|
||||
_proto("Rx RESPONSE %%%u { v=%u kv=%u tl=%u }",
|
||||
ntohl(sp->hdr.serial), version, kvno, ticket_len);
|
||||
sp->hdr.serial, version, kvno, ticket_len);
|
||||
|
||||
abort_code = RXKADINCONSISTENCY;
|
||||
if (version != RXKAD_VERSION)
|
||||
|
@ -1058,9 +1061,9 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
|
|||
rxkad_decrypt_response(conn, &response, &session_key);
|
||||
|
||||
abort_code = RXKADSEALEDINCON;
|
||||
if (response.encrypted.epoch != conn->epoch)
|
||||
if (ntohl(response.encrypted.epoch) != conn->epoch)
|
||||
goto protocol_error_free;
|
||||
if (response.encrypted.cid != conn->cid)
|
||||
if (ntohl(response.encrypted.cid) != conn->cid)
|
||||
goto protocol_error_free;
|
||||
if (ntohl(response.encrypted.securityIndex) != conn->security_ix)
|
||||
goto protocol_error_free;
|
||||
|
@ -1077,7 +1080,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
|
|||
goto protocol_error_free;
|
||||
|
||||
abort_code = RXKADOUTOFSEQUENCE;
|
||||
if (response.encrypted.inc_nonce != htonl(conn->security_nonce + 1))
|
||||
if (ntohl(response.encrypted.inc_nonce) != conn->security_nonce + 1)
|
||||
goto protocol_error_free;
|
||||
|
||||
abort_code = RXKADLEVELFAIL;
|
||||
|
|
|
@ -115,7 +115,7 @@ static struct ctl_table rxrpc_sysctl_table[] = {
|
|||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = (void *)&one,
|
||||
.extra1 = (void *)&n_65535,
|
||||
.extra2 = (void *)&n_65535,
|
||||
},
|
||||
{
|
||||
.procname = "rx_jumbo_max",
|
||||
|
|
Loading…
Reference in New Issue