diff options
author | Xin Long <lucien.xin@gmail.com> | 2018-03-14 19:05:30 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-14 13:48:27 -0400 |
commit | 1b1e0bc9947427ae58bbe7de0ce9cfd591b589b9 (patch) | |
tree | 4d113bf0c79a697420a1463d6fe1798ad6f4e0d9 /net/sctp/output.c | |
parent | c469012729bda6515779590d9588d3e36fdf449d (diff) | |
download | linux-1b1e0bc9947427ae58bbe7de0ce9cfd591b589b9.tar.gz linux-1b1e0bc9947427ae58bbe7de0ce9cfd591b589b9.tar.bz2 linux-1b1e0bc9947427ae58bbe7de0ce9cfd591b589b9.zip |
sctp: add refcnt support for sh_key
With refcnt support for sh_key, chunks auth sh_keys can be decided
before enqueuing it. Changing the active key later will not affect
the chunks already enqueued.
Furthermore, this is necessary when adding the support for authinfo
for sendmsg in next patch.
Note that struct sctp_chunk can't be grown due to that performance
drop issue on slow cpu, so it just reuses head_skb memory for shkey
in sctp_chunk.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/output.c')
-rw-r--r-- | net/sctp/output.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/net/sctp/output.c b/net/sctp/output.c index 01a26ee051e3..d6e1c90cc09a 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -241,10 +241,13 @@ static enum sctp_xmit sctp_packet_bundle_auth(struct sctp_packet *pkt, if (!chunk->auth) return retval; - auth = sctp_make_auth(asoc); + auth = sctp_make_auth(asoc, chunk->shkey->key_id); if (!auth) return retval; + auth->shkey = chunk->shkey; + sctp_auth_shkey_hold(auth->shkey); + retval = __sctp_packet_append_chunk(pkt, auth); if (retval != SCTP_XMIT_OK) @@ -490,7 +493,8 @@ merge: } if (auth) { - sctp_auth_calculate_hmac(tp->asoc, nskb, auth, gfp); + sctp_auth_calculate_hmac(tp->asoc, nskb, auth, + packet->auth->shkey, gfp); /* free auth if no more chunks, or add it back */ if (list_empty(&packet->chunk_list)) sctp_chunk_free(packet->auth); @@ -770,6 +774,16 @@ static enum sctp_xmit sctp_packet_will_fit(struct sctp_packet *packet, enum sctp_xmit retval = SCTP_XMIT_OK; size_t psize, pmtu, maxsize; + /* Don't bundle in this packet if this chunk's auth key doesn't + * match other chunks already enqueued on this packet. Also, + * don't bundle the chunk with auth key if other chunks in this + * packet don't have auth key. + */ + if ((packet->auth && chunk->shkey != packet->auth->shkey) || + (!packet->auth && chunk->shkey && + chunk->chunk_hdr->type != SCTP_CID_AUTH)) + return SCTP_XMIT_PMTU_FULL; + psize = packet->size; if (packet->transport->asoc) pmtu = packet->transport->asoc->pathmtu; |