net: sctp: migrate cookie life from timeval to ktime
Currently, SCTP code defines its own timeval functions (since timeval is rarely used inside the kernel by others), namely tv_lt() and TIMEVAL_ADD() macros, that operate on SCTP cookie expiration. We might as well remove all those, and operate directly on ktime structures for a couple of reasons: ktime is available on all archs; complexity of ktime calculations depending on the arch is less than (reduces to a simple arithmetic operations on archs with BITS_PER_LONG == 64 or CONFIG_KTIME_SCALAR) or equal to timeval functions (other archs); code becomes more readable; macros can be thrown out. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Acked-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
d36f82b243
Коммит
52db882f3f
|
@ -560,24 +560,6 @@ for (pos = chunk->subh.fwdtsn_hdr->skip;\
|
||||||
/* Round an int up to the next multiple of 4. */
|
/* Round an int up to the next multiple of 4. */
|
||||||
#define WORD_ROUND(s) (((s)+3)&~3)
|
#define WORD_ROUND(s) (((s)+3)&~3)
|
||||||
|
|
||||||
/* Compare two timevals. */
|
|
||||||
#define tv_lt(s, t) \
|
|
||||||
(s.tv_sec < t.tv_sec || (s.tv_sec == t.tv_sec && s.tv_usec < t.tv_usec))
|
|
||||||
|
|
||||||
/* Add tv1 to tv2. */
|
|
||||||
#define TIMEVAL_ADD(tv1, tv2) \
|
|
||||||
({ \
|
|
||||||
suseconds_t usecs = (tv2).tv_usec + (tv1).tv_usec; \
|
|
||||||
time_t secs = (tv2).tv_sec + (tv1).tv_sec; \
|
|
||||||
\
|
|
||||||
if (usecs >= 1000000) { \
|
|
||||||
usecs -= 1000000; \
|
|
||||||
secs++; \
|
|
||||||
} \
|
|
||||||
(tv2).tv_sec = secs; \
|
|
||||||
(tv2).tv_usec = usecs; \
|
|
||||||
})
|
|
||||||
|
|
||||||
/* External references. */
|
/* External references. */
|
||||||
|
|
||||||
extern struct proto sctp_prot;
|
extern struct proto sctp_prot;
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
#ifndef __sctp_structs_h__
|
#ifndef __sctp_structs_h__
|
||||||
#define __sctp_structs_h__
|
#define __sctp_structs_h__
|
||||||
|
|
||||||
#include <linux/time.h> /* We get struct timespec. */
|
#include <linux/ktime.h>
|
||||||
#include <linux/socket.h> /* linux/in.h needs this!! */
|
#include <linux/socket.h> /* linux/in.h needs this!! */
|
||||||
#include <linux/in.h> /* We get struct sockaddr_in. */
|
#include <linux/in.h> /* We get struct sockaddr_in. */
|
||||||
#include <linux/in6.h> /* We get struct in6_addr */
|
#include <linux/in6.h> /* We get struct in6_addr */
|
||||||
|
@ -284,7 +284,7 @@ struct sctp_cookie {
|
||||||
__u32 peer_ttag;
|
__u32 peer_ttag;
|
||||||
|
|
||||||
/* When does this cookie expire? */
|
/* When does this cookie expire? */
|
||||||
struct timeval expiration;
|
ktime_t expiration;
|
||||||
|
|
||||||
/* Number of inbound/outbound streams which are set
|
/* Number of inbound/outbound streams which are set
|
||||||
* and negotiated during the INIT process.
|
* and negotiated during the INIT process.
|
||||||
|
@ -1537,7 +1537,7 @@ struct sctp_association {
|
||||||
sctp_state_t state;
|
sctp_state_t state;
|
||||||
|
|
||||||
/* The cookie life I award for any cookie. */
|
/* The cookie life I award for any cookie. */
|
||||||
struct timeval cookie_life;
|
ktime_t cookie_life;
|
||||||
|
|
||||||
/* Overall : The overall association error count.
|
/* Overall : The overall association error count.
|
||||||
* Error Count : [Clear this any time I get something.]
|
* Error Count : [Clear this any time I get something.]
|
||||||
|
|
|
@ -102,13 +102,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
|
||||||
sctp_bind_addr_init(&asoc->base.bind_addr, ep->base.bind_addr.port);
|
sctp_bind_addr_init(&asoc->base.bind_addr, ep->base.bind_addr.port);
|
||||||
|
|
||||||
asoc->state = SCTP_STATE_CLOSED;
|
asoc->state = SCTP_STATE_CLOSED;
|
||||||
|
asoc->cookie_life = ms_to_ktime(sp->assocparams.sasoc_cookie_life);
|
||||||
/* Set these values from the socket values, a conversion between
|
|
||||||
* millsecons to seconds/microseconds must also be done.
|
|
||||||
*/
|
|
||||||
asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000;
|
|
||||||
asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000)
|
|
||||||
* 1000;
|
|
||||||
asoc->frag_point = 0;
|
asoc->frag_point = 0;
|
||||||
asoc->user_frag = sp->user_frag;
|
asoc->user_frag = sp->user_frag;
|
||||||
|
|
||||||
|
|
|
@ -1630,8 +1630,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
|
||||||
cookie->c.adaptation_ind = asoc->peer.adaptation_ind;
|
cookie->c.adaptation_ind = asoc->peer.adaptation_ind;
|
||||||
|
|
||||||
/* Set an expiration time for the cookie. */
|
/* Set an expiration time for the cookie. */
|
||||||
do_gettimeofday(&cookie->c.expiration);
|
cookie->c.expiration = ktime_add(asoc->cookie_life,
|
||||||
TIMEVAL_ADD(asoc->cookie_life, cookie->c.expiration);
|
ktime_get());
|
||||||
|
|
||||||
/* Copy the peer's init packet. */
|
/* Copy the peer's init packet. */
|
||||||
memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr,
|
memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr,
|
||||||
|
@ -1680,7 +1680,7 @@ struct sctp_association *sctp_unpack_cookie(
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
sctp_scope_t scope;
|
sctp_scope_t scope;
|
||||||
struct sk_buff *skb = chunk->skb;
|
struct sk_buff *skb = chunk->skb;
|
||||||
struct timeval tv;
|
ktime_t kt;
|
||||||
struct hash_desc desc;
|
struct hash_desc desc;
|
||||||
|
|
||||||
/* Header size is static data prior to the actual cookie, including
|
/* Header size is static data prior to the actual cookie, including
|
||||||
|
@ -1757,11 +1757,11 @@ no_hmac:
|
||||||
* down the new association establishment instead of every packet.
|
* down the new association establishment instead of every packet.
|
||||||
*/
|
*/
|
||||||
if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
|
if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
|
||||||
skb_get_timestamp(skb, &tv);
|
kt = skb_get_ktime(skb);
|
||||||
else
|
else
|
||||||
do_gettimeofday(&tv);
|
kt = ktime_get();
|
||||||
|
|
||||||
if (!asoc && tv_lt(bear_cookie->expiration, tv)) {
|
if (!asoc && ktime_compare(bear_cookie->expiration, kt) < 0) {
|
||||||
/*
|
/*
|
||||||
* Section 3.3.10.3 Stale Cookie Error (3)
|
* Section 3.3.10.3 Stale Cookie Error (3)
|
||||||
*
|
*
|
||||||
|
@ -1773,9 +1773,7 @@ no_hmac:
|
||||||
len = ntohs(chunk->chunk_hdr->length);
|
len = ntohs(chunk->chunk_hdr->length);
|
||||||
*errp = sctp_make_op_error_space(asoc, chunk, len);
|
*errp = sctp_make_op_error_space(asoc, chunk, len);
|
||||||
if (*errp) {
|
if (*errp) {
|
||||||
suseconds_t usecs = (tv.tv_sec -
|
suseconds_t usecs = ktime_to_us(ktime_sub(kt, bear_cookie->expiration));
|
||||||
bear_cookie->expiration.tv_sec) * 1000000L +
|
|
||||||
tv.tv_usec - bear_cookie->expiration.tv_usec;
|
|
||||||
__be32 n = htonl(usecs);
|
__be32 n = htonl(usecs);
|
||||||
|
|
||||||
sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE,
|
sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE,
|
||||||
|
@ -2514,8 +2512,7 @@ do_addr_param:
|
||||||
/* Suggested Cookie Life span increment's unit is msec,
|
/* Suggested Cookie Life span increment's unit is msec,
|
||||||
* (1/1000sec).
|
* (1/1000sec).
|
||||||
*/
|
*/
|
||||||
asoc->cookie_life.tv_sec += stale / 1000;
|
asoc->cookie_life = ktime_add_ms(asoc->cookie_life, stale);
|
||||||
asoc->cookie_life.tv_usec += (stale % 1000) * 1000;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCTP_PARAM_HOST_NAME_ADDRESS:
|
case SCTP_PARAM_HOST_NAME_ADDRESS:
|
||||||
|
|
|
@ -2910,13 +2910,8 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsig
|
||||||
asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
|
asoc->max_retrans = assocparams.sasoc_asocmaxrxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assocparams.sasoc_cookie_life != 0) {
|
if (assocparams.sasoc_cookie_life != 0)
|
||||||
asoc->cookie_life.tv_sec =
|
asoc->cookie_life = ms_to_ktime(assocparams.sasoc_cookie_life);
|
||||||
assocparams.sasoc_cookie_life / 1000;
|
|
||||||
asoc->cookie_life.tv_usec =
|
|
||||||
(assocparams.sasoc_cookie_life % 1000)
|
|
||||||
* 1000;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* Set the values to the endpoint */
|
/* Set the values to the endpoint */
|
||||||
struct sctp_sock *sp = sctp_sk(sk);
|
struct sctp_sock *sp = sctp_sk(sk);
|
||||||
|
@ -5074,10 +5069,7 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len,
|
||||||
assocparams.sasoc_asocmaxrxt = asoc->max_retrans;
|
assocparams.sasoc_asocmaxrxt = asoc->max_retrans;
|
||||||
assocparams.sasoc_peer_rwnd = asoc->peer.rwnd;
|
assocparams.sasoc_peer_rwnd = asoc->peer.rwnd;
|
||||||
assocparams.sasoc_local_rwnd = asoc->a_rwnd;
|
assocparams.sasoc_local_rwnd = asoc->a_rwnd;
|
||||||
assocparams.sasoc_cookie_life = (asoc->cookie_life.tv_sec
|
assocparams.sasoc_cookie_life = ktime_to_ms(asoc->cookie_life);
|
||||||
* 1000) +
|
|
||||||
(asoc->cookie_life.tv_usec
|
|
||||||
/ 1000);
|
|
||||||
|
|
||||||
list_for_each(pos, &asoc->peer.transport_addr_list) {
|
list_for_each(pos, &asoc->peer.transport_addr_list) {
|
||||||
cnt ++;
|
cnt ++;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче