Allow for a security trailer to added to a packet. The size is stored in conn->security_trailer. Note any size alignment set by the security class must be applied after subtracting the trailer (but the alignment includes the security header, which is assumed to be encrypted).
Signed-off-by: David Howells <dhowe...@redhat.com> --- net/rxrpc/ar-internal.h | 1 + net/rxrpc/sendmsg.c | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index dce48162f6c2..5aacd6d7cf28 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -455,6 +455,7 @@ struct rxrpc_connection { u32 service_id; /* Service ID, possibly upgraded */ u8 size_align; /* data size alignment (for security) */ u8 security_size; /* security header size */ + u8 security_trailer; /* Security trailer size */ u8 security_ix; /* security type */ u8 out_clientflag; /* RXRPC_CLIENT_INITIATED if we are client */ u8 bundle_shift; /* Index into bundle->avail_chans */ diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index d27140c836cc..258224bb1227 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -327,7 +327,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, rxrpc_send_ack_packet(call, false, NULL); if (!skb) { - size_t size, chunk, max, space; + size_t size, chunk, limit, space, shdr; _debug("alloc"); @@ -342,18 +342,22 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, goto maybe_error; } - max = RXRPC_JUMBO_DATALEN; - max -= call->conn->security_size; - max &= ~(call->conn->size_align - 1UL); - - chunk = max; - if (chunk > msg_data_left(msg) && !more) + /* Work out the maximum size of a packet. Assume that + * the security header is going to be in the padded + * region (enc blocksize), but the trailer is not. + */ + shdr = call->conn->security_size; + limit = RXRPC_JUMBO_DATALEN; + limit -= call->conn->security_trailer; + space = round_down(limit, call->conn->size_align); + + chunk = space - shdr; + if (msg_data_left(msg) < chunk && !more) { chunk = msg_data_left(msg); + space = round_up(shdr + chunk, call->conn->size_align); + } - space = chunk + call->conn->size_align; - space &= ~(call->conn->size_align - 1UL); - - size = space + call->conn->security_size; + size = space + call->conn->security_trailer; _debug("SIZE: %zu/%zu/%zu", chunk, space, size); @@ -425,7 +429,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, size_t pad; /* pad out if we're using security */ - if (conn->security_ix) { + if (conn->size_align > 0) { pad = conn->security_size + skb->mark; pad = conn->size_align - pad; pad &= conn->size_align - 1;