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:
David S. Miller 2016-03-04 17:19:16 -05:00
commit 94f7153e41
20 changed files with 636 additions and 569 deletions

View File

@ -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

View File

@ -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(

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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:

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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),

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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",