Skip to content

Commit 9908b36

Browse files
committed
Merge branch 'sctp-unify-sctp_make_op_error_fixed-and-sctp_make_op_error_space'
Marcelo Ricardo Leitner says: ==================== sctp: unify sctp_make_op_error_fixed and sctp_make_op_error_space These two variants are very close to each other and can be merged to avoid code duplication. That's what this patchset does. First, we allow sctp_init_cause to return errors, which then allow us to add sctp_make_op_error_limited that handles both situations. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 065662d + 8914f4b commit 9908b36

File tree

2 files changed

+52
-84
lines changed

2 files changed

+52
-84
lines changed

include/net/sctp/sm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
215215
struct sctp_chunk *sctp_make_shutdown_complete(
216216
const struct sctp_association *asoc,
217217
const struct sctp_chunk *chunk);
218-
void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause, size_t paylen);
218+
int sctp_init_cause(struct sctp_chunk *chunk, __be16 cause, size_t paylen);
219219
struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
220220
const struct sctp_chunk *chunk,
221221
const size_t hint);

net/sctp/sm_make_chunk.c

Lines changed: 51 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ static int sctp_process_param(struct sctp_association *asoc,
8181
gfp_t gfp);
8282
static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
8383
const void *data);
84-
static void *sctp_addto_chunk_fixed(struct sctp_chunk *, int len,
85-
const void *data);
8684

8785
/* Control chunk destructor */
8886
static void sctp_control_release_owner(struct sk_buff *skb)
@@ -154,46 +152,28 @@ static const struct sctp_paramhdr prsctp_param = {
154152
cpu_to_be16(sizeof(struct sctp_paramhdr)),
155153
};
156154

157-
/* A helper to initialize an op error inside a
158-
* provided chunk, as most cause codes will be embedded inside an
159-
* abort chunk.
155+
/* A helper to initialize an op error inside a provided chunk, as most
156+
* cause codes will be embedded inside an abort chunk.
160157
*/
161-
void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
162-
size_t paylen)
158+
int sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
159+
size_t paylen)
163160
{
164161
struct sctp_errhdr err;
165162
__u16 len;
166163

167164
/* Cause code constants are now defined in network order. */
168165
err.cause = cause_code;
169166
len = sizeof(err) + paylen;
170-
err.length = htons(len);
171-
chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(err), &err);
172-
}
173-
174-
/* A helper to initialize an op error inside a
175-
* provided chunk, as most cause codes will be embedded inside an
176-
* abort chunk. Differs from sctp_init_cause in that it won't oops
177-
* if there isn't enough space in the op error chunk
178-
*/
179-
static int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code,
180-
size_t paylen)
181-
{
182-
struct sctp_errhdr err;
183-
__u16 len;
184-
185-
/* Cause code constants are now defined in network order. */
186-
err.cause = cause_code;
187-
len = sizeof(err) + paylen;
188-
err.length = htons(len);
167+
err.length = htons(len);
189168

190169
if (skb_tailroom(chunk->skb) < len)
191170
return -ENOSPC;
192171

193-
chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk, sizeof(err), &err);
172+
chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(err), &err);
194173

195174
return 0;
196175
}
176+
197177
/* 3.3.2 Initiation (INIT) (1)
198178
*
199179
* This chunk is used to initiate a SCTP association between two
@@ -1257,20 +1237,26 @@ static struct sctp_chunk *sctp_make_op_error_space(
12571237
return retval;
12581238
}
12591239

1260-
/* Create an Operation Error chunk of a fixed size,
1261-
* specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT)
1262-
* This is a helper function to allocate an error chunk for
1263-
* for those invalid parameter codes in which we may not want
1264-
* to report all the errors, if the incoming chunk is large
1240+
/* Create an Operation Error chunk of a fixed size, specifically,
1241+
* min(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) - overheads.
1242+
* This is a helper function to allocate an error chunk for for those
1243+
* invalid parameter codes in which we may not want to report all the
1244+
* errors, if the incoming chunk is large. If it can't fit in a single
1245+
* packet, we ignore it.
12651246
*/
1266-
static inline struct sctp_chunk *sctp_make_op_error_fixed(
1247+
static inline struct sctp_chunk *sctp_make_op_error_limited(
12671248
const struct sctp_association *asoc,
12681249
const struct sctp_chunk *chunk)
12691250
{
1270-
size_t size = asoc ? asoc->pathmtu : 0;
1251+
size_t size = SCTP_DEFAULT_MAXSEGMENT;
1252+
struct sctp_sock *sp = NULL;
12711253

1272-
if (!size)
1273-
size = SCTP_DEFAULT_MAXSEGMENT;
1254+
if (asoc) {
1255+
size = min_t(size_t, size, asoc->pathmtu);
1256+
sp = sctp_sk(asoc->base.sk);
1257+
}
1258+
1259+
size = sctp_mtu_payload(sp, size, sizeof(struct sctp_errhdr));
12741260

12751261
return sctp_make_op_error_space(asoc, chunk, size);
12761262
}
@@ -1522,18 +1508,6 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)
15221508
return target;
15231509
}
15241510

1525-
/* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient
1526-
* space in the chunk
1527-
*/
1528-
static void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk,
1529-
int len, const void *data)
1530-
{
1531-
if (skb_tailroom(chunk->skb) >= len)
1532-
return sctp_addto_chunk(chunk, len, data);
1533-
else
1534-
return NULL;
1535-
}
1536-
15371511
/* Append bytes from user space to the end of a chunk. Will panic if
15381512
* chunk is not big enough.
15391513
* Returns a kernel err value.
@@ -1828,6 +1802,9 @@ struct sctp_association *sctp_unpack_cookie(
18281802
kt = ktime_get_real();
18291803

18301804
if (!asoc && ktime_before(bear_cookie->expiration, kt)) {
1805+
suseconds_t usecs = ktime_to_us(ktime_sub(kt, bear_cookie->expiration));
1806+
__be32 n = htonl(usecs);
1807+
18311808
/*
18321809
* Section 3.3.10.3 Stale Cookie Error (3)
18331810
*
@@ -1836,17 +1813,12 @@ struct sctp_association *sctp_unpack_cookie(
18361813
* Stale Cookie Error: Indicates the receipt of a valid State
18371814
* Cookie that has expired.
18381815
*/
1839-
len = ntohs(chunk->chunk_hdr->length);
1840-
*errp = sctp_make_op_error_space(asoc, chunk, len);
1841-
if (*errp) {
1842-
suseconds_t usecs = ktime_to_us(ktime_sub(kt, bear_cookie->expiration));
1843-
__be32 n = htonl(usecs);
1844-
1845-
sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE,
1846-
sizeof(n));
1847-
sctp_addto_chunk(*errp, sizeof(n), &n);
1816+
*errp = sctp_make_op_error(asoc, chunk,
1817+
SCTP_ERROR_STALE_COOKIE, &n,
1818+
sizeof(n), 0);
1819+
if (*errp)
18481820
*error = -SCTP_IERROR_STALE_COOKIE;
1849-
} else
1821+
else
18501822
*error = -SCTP_IERROR_NOMEM;
18511823

18521824
goto fail;
@@ -1997,12 +1969,8 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
19971969
if (*errp)
19981970
sctp_chunk_free(*errp);
19991971

2000-
*errp = sctp_make_op_error_space(asoc, chunk, len);
2001-
2002-
if (*errp) {
2003-
sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, len);
2004-
sctp_addto_chunk(*errp, len, param.v);
2005-
}
1972+
*errp = sctp_make_op_error(asoc, chunk, SCTP_ERROR_DNS_FAILED,
1973+
param.v, len, 0);
20061974

20071975
/* Stop processing this chunk. */
20081976
return 0;
@@ -2127,23 +2095,23 @@ static enum sctp_ierror sctp_process_unk_param(
21272095
/* Make an ERROR chunk, preparing enough room for
21282096
* returning multiple unknown parameters.
21292097
*/
2130-
if (NULL == *errp)
2131-
*errp = sctp_make_op_error_fixed(asoc, chunk);
2132-
2133-
if (*errp) {
2134-
if (!sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM,
2135-
SCTP_PAD4(ntohs(param.p->length))))
2136-
sctp_addto_chunk_fixed(*errp,
2137-
SCTP_PAD4(ntohs(param.p->length)),
2138-
param.v);
2139-
} else {
2140-
/* If there is no memory for generating the ERROR
2141-
* report as specified, an ABORT will be triggered
2142-
* to the peer and the association won't be
2143-
* established.
2144-
*/
2145-
retval = SCTP_IERROR_NOMEM;
2098+
if (!*errp) {
2099+
*errp = sctp_make_op_error_limited(asoc, chunk);
2100+
if (!*errp) {
2101+
/* If there is no memory for generating the
2102+
* ERROR report as specified, an ABORT will be
2103+
* triggered to the peer and the association
2104+
* won't be established.
2105+
*/
2106+
retval = SCTP_IERROR_NOMEM;
2107+
break;
2108+
}
21462109
}
2110+
2111+
if (!sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
2112+
ntohs(param.p->length)))
2113+
sctp_addto_chunk(*errp, ntohs(param.p->length),
2114+
param.v);
21472115
break;
21482116
default:
21492117
break;
@@ -2219,10 +2187,10 @@ static enum sctp_ierror sctp_verify_param(struct net *net,
22192187
* MUST be aborted. The ABORT chunk SHOULD contain the error
22202188
* cause 'Protocol Violation'.
22212189
*/
2222-
if (SCTP_AUTH_RANDOM_LENGTH !=
2223-
ntohs(param.p->length) - sizeof(struct sctp_paramhdr)) {
2190+
if (SCTP_AUTH_RANDOM_LENGTH != ntohs(param.p->length) -
2191+
sizeof(struct sctp_paramhdr)) {
22242192
sctp_process_inv_paramlength(asoc, param.p,
2225-
chunk, err_chunk);
2193+
chunk, err_chunk);
22262194
retval = SCTP_IERROR_ABORT;
22272195
}
22282196
break;

0 commit comments

Comments
 (0)