^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * (C) Copyright IBM Corp. 2001, 2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 1999-2000 Cisco, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 1999-2001 Motorola, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2001-2002 Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is part of the SCTP kernel implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * These functions work with the state functions in sctp_sm_statefuns.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * to implement the state operations. These functions implement the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * steps which require modifying existing data structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Please send any bug reports or fixes you make to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * email address(es):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * lksctp developers <linux-sctp@vger.kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Written or modified by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * La Monte H.P. Yarroll <piggy@acm.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Karl Knutson <karl@athena.chicago.il.us>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * C. Robin <chris@hundredacre.ac.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Jon Grimm <jgrimm@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Xingang Guo <xingang.guo@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Dajiang Zhang <dajiang.zhang@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Sridhar Samudrala <sri@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Daisy Chang <daisyc@us.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Ardelle Fan <ardelle.fan@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Kevin Gao <kevin.gao@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <crypto/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/scatterlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/random.h> /* for get_random_bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <net/sctp/sctp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <net/sctp/sm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) __u8 type, __u8 flags, int paylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) __u8 flags, int paylen, gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __u8 type, __u8 flags, int paylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static struct sctp_cookie_param *sctp_pack_cookie(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) const struct sctp_chunk *init_chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int *cookie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) const __u8 *raw_addrs, int addrs_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int sctp_process_param(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) union sctp_params param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const union sctp_addr *peer_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Control chunk destructor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static void sctp_control_release_owner(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct sctp_chunk *chunk = skb_shinfo(skb)->destructor_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (chunk->shkey) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct sctp_shared_key *shkey = chunk->shkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct sctp_association *asoc = chunk->asoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* refcnt == 2 and !list_empty mean after this release, it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * not being used anywhere, and it's time to notify userland
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * that this shkey can be freed if it's been deactivated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (shkey->deactivated && !list_empty(&shkey->key_list) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) refcount_read(&shkey->refcnt) == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct sctp_ulpevent *ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ev = sctp_ulpevent_make_authkey(asoc, shkey->key_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) SCTP_AUTH_FREE_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) asoc->stream.si->enqueue_event(&asoc->ulpq, ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) sctp_auth_shkey_release(chunk->shkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct sctp_association *asoc = chunk->asoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct sk_buff *skb = chunk->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* TODO: properly account for control chunks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * To do it right we'll need:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * 1) endpoint if association isn't known.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * 2) proper memory accounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * For now don't do anything for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (chunk->auth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) chunk->shkey = asoc->shkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) sctp_auth_shkey_hold(chunk->shkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) skb->sk = asoc ? asoc->base.sk : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) skb_shinfo(skb)->destructor_arg = chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) skb->destructor = sctp_control_release_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* What was the inbound interface for this chunk? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int sctp_chunk_iif(const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct sk_buff *skb = chunk->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return SCTP_INPUT_CB(skb)->af->skb_iif(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* RFC 2960 3.3.2 Initiation (INIT) (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Note 2: The ECN capable field is reserved for future use of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Explicit Congestion Notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static const struct sctp_paramhdr ecap_param = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) SCTP_PARAM_ECN_CAPABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) cpu_to_be16(sizeof(struct sctp_paramhdr)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static const struct sctp_paramhdr prsctp_param = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) SCTP_PARAM_FWD_TSN_SUPPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) cpu_to_be16(sizeof(struct sctp_paramhdr)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* A helper to initialize an op error inside a provided chunk, as most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * cause codes will be embedded inside an abort chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) size_t paylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct sctp_errhdr err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) __u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Cause code constants are now defined in network order. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) err.cause = cause_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) len = sizeof(err) + paylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) err.length = htons(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (skb_tailroom(chunk->skb) < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(err), &err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* 3.3.2 Initiation (INIT) (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * This chunk is used to initiate a SCTP association between two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * endpoints. The format of the INIT chunk is shown below:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * | Type = 1 | Chunk Flags | Chunk Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * | Initiate Tag |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * | Advertised Receiver Window Credit (a_rwnd) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * | Number of Outbound Streams | Number of Inbound Streams |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * | Initial TSN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * / Optional/Variable-Length Parameters /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * The INIT chunk contains the following parameters. Unless otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * noted, each parameter MUST only be included once in the INIT chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Fixed Parameters Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * ----------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * Initiate Tag Mandatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Advertised Receiver Window Credit Mandatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Number of Outbound Streams Mandatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * Number of Inbound Streams Mandatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Initial TSN Mandatory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Variable Parameters Status Type Value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * -------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * IPv4 Address (Note 1) Optional 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * IPv6 Address (Note 1) Optional 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * Cookie Preservative Optional 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Reserved for ECN Capable (Note 2) Optional 32768 (0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Host Name Address (Note 3) Optional 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Supported Address Types (Note 4) Optional 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) const struct sctp_bind_addr *bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) gfp_t gfp, int vparam_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct sctp_supported_ext_param ext_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct sctp_adaptation_ind_param aiparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct sctp_paramhdr *auth_chunks = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct sctp_paramhdr *auth_hmacs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct sctp_supported_addrs_param sat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct sctp_endpoint *ep = asoc->ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct sctp_chunk *retval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int num_types, addrs_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct sctp_inithdr init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) union sctp_params addrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct sctp_sock *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) __u8 extensions[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) size_t chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) __be16 types[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int num_ext = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* RFC 2960 3.3.2 Initiation (INIT) (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Note 1: The INIT chunks can contain multiple addresses that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * can be IPv4 and/or IPv6 in any combination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Convert the provided bind address list to raw format. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) addrs = sctp_bind_addrs_to_raw(bp, &addrs_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) init.init_tag = htonl(asoc->c.my_vtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) init.a_rwnd = htonl(asoc->rwnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) init.num_outbound_streams = htons(asoc->c.sinit_num_ostreams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) init.num_inbound_streams = htons(asoc->c.sinit_max_instreams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) init.initial_tsn = htonl(asoc->c.initial_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* How many address types are needed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) sp = sctp_sk(asoc->base.sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) num_types = sp->pf->supported_addrs(sp, types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) chunksize = sizeof(init) + addrs_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) chunksize += SCTP_PAD4(SCTP_SAT_LEN(num_types));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (asoc->ep->ecn_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) chunksize += sizeof(ecap_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (asoc->ep->prsctp_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) chunksize += sizeof(prsctp_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* ADDIP: Section 4.2.7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * An implementation supporting this extension [ADDIP] MUST list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * the ASCONF,the ASCONF-ACK, and the AUTH chunks in its INIT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * INIT-ACK parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (asoc->ep->asconf_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) extensions[num_ext] = SCTP_CID_ASCONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) extensions[num_ext+1] = SCTP_CID_ASCONF_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) num_ext += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (asoc->ep->reconf_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) extensions[num_ext] = SCTP_CID_RECONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) num_ext += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (sp->adaptation_ind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) chunksize += sizeof(aiparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (asoc->ep->intl_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) extensions[num_ext] = SCTP_CID_I_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) num_ext += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) chunksize += vparam_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* Account for AUTH related parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (ep->auth_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* Add random parameter length*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) chunksize += sizeof(asoc->c.auth_random);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* Add HMACS parameter length if any were defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) auth_hmacs = (struct sctp_paramhdr *)asoc->c.auth_hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (auth_hmacs->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) chunksize += SCTP_PAD4(ntohs(auth_hmacs->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) auth_hmacs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Add CHUNKS parameter length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) auth_chunks = (struct sctp_paramhdr *)asoc->c.auth_chunks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (auth_chunks->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) chunksize += SCTP_PAD4(ntohs(auth_chunks->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) auth_chunks = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) extensions[num_ext] = SCTP_CID_AUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) num_ext += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* If we have any extensions to report, account for that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (num_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) chunksize += SCTP_PAD4(sizeof(ext_param) + num_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* RFC 2960 3.3.2 Initiation (INIT) (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Note 3: An INIT chunk MUST NOT contain more than one Host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * Name address parameter. Moreover, the sender of the INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * MUST NOT combine any other address types with the Host Name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * address in the INIT. The receiver of INIT MUST ignore any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * other address types if the Host Name address parameter is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * present in the received INIT chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * PLEASE DO NOT FIXME [This version does not support Host Name.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) retval->subh.init_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) sctp_addto_chunk(retval, sizeof(init), &init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) retval->param_hdr.v =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) sctp_addto_chunk(retval, addrs_len, addrs.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* RFC 2960 3.3.2 Initiation (INIT) (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * Note 4: This parameter, when present, specifies all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * address types the sending endpoint can support. The absence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * of this parameter indicates that the sending endpoint can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * support any address type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) sat.param_hdr.type = SCTP_PARAM_SUPPORTED_ADDRESS_TYPES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) sat.param_hdr.length = htons(SCTP_SAT_LEN(num_types));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) sctp_addto_chunk(retval, sizeof(sat), &sat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) sctp_addto_chunk(retval, num_types * sizeof(__u16), &types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (asoc->ep->ecn_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* Add the supported extensions parameter. Be nice and add this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * fist before addiding the parameters for the extensions themselves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (num_ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ext_param.param_hdr.type = SCTP_PARAM_SUPPORTED_EXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ext_param.param_hdr.length = htons(sizeof(ext_param) + num_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) sctp_addto_chunk(retval, sizeof(ext_param), &ext_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) sctp_addto_param(retval, num_ext, extensions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (asoc->ep->prsctp_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (sp->adaptation_ind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) aiparam.param_hdr.length = htons(sizeof(aiparam));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) aiparam.adaptation_ind = htonl(sp->adaptation_ind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* Add SCTP-AUTH chunks to the parameter list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ep->auth_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) asoc->c.auth_random);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (auth_hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) sctp_addto_chunk(retval, ntohs(auth_hmacs->length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) auth_hmacs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (auth_chunks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) sctp_addto_chunk(retval, ntohs(auth_chunks->length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) auth_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) kfree(addrs.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) gfp_t gfp, int unkparam_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct sctp_supported_ext_param ext_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct sctp_adaptation_ind_param aiparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct sctp_paramhdr *auth_chunks = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct sctp_paramhdr *auth_random = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct sctp_paramhdr *auth_hmacs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct sctp_chunk *retval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct sctp_cookie_param *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct sctp_inithdr initack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) union sctp_params addrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct sctp_sock *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) __u8 extensions[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) size_t chunksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) int num_ext = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int cookie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int addrs_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* Note: there may be no addresses to embed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) addrs = sctp_bind_addrs_to_raw(&asoc->base.bind_addr, &addrs_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) initack.init_tag = htonl(asoc->c.my_vtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) initack.a_rwnd = htonl(asoc->rwnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) initack.num_outbound_streams = htons(asoc->c.sinit_num_ostreams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) initack.num_inbound_streams = htons(asoc->c.sinit_max_instreams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) initack.initial_tsn = htonl(asoc->c.initial_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* FIXME: We really ought to build the cookie right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * into the packet instead of allocating more fresh memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) cookie = sctp_pack_cookie(asoc->ep, asoc, chunk, &cookie_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) addrs.v, addrs_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto nomem_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Calculate the total size of allocation, include the reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * space for reporting unknown parameters if it is specified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) sp = sctp_sk(asoc->base.sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) chunksize = sizeof(initack) + addrs_len + cookie_len + unkparam_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Tell peer that we'll do ECN only if peer advertised such cap. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (asoc->peer.ecn_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) chunksize += sizeof(ecap_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (asoc->peer.prsctp_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) chunksize += sizeof(prsctp_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (asoc->peer.asconf_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) extensions[num_ext] = SCTP_CID_ASCONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) extensions[num_ext+1] = SCTP_CID_ASCONF_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) num_ext += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (asoc->peer.reconf_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) extensions[num_ext] = SCTP_CID_RECONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) num_ext += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (sp->adaptation_ind)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) chunksize += sizeof(aiparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (asoc->peer.intl_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) extensions[num_ext] = SCTP_CID_I_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) num_ext += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (asoc->peer.auth_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) auth_random = (struct sctp_paramhdr *)asoc->c.auth_random;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) chunksize += ntohs(auth_random->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) auth_hmacs = (struct sctp_paramhdr *)asoc->c.auth_hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (auth_hmacs->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) chunksize += SCTP_PAD4(ntohs(auth_hmacs->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) auth_hmacs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) auth_chunks = (struct sctp_paramhdr *)asoc->c.auth_chunks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (auth_chunks->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) chunksize += SCTP_PAD4(ntohs(auth_chunks->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) auth_chunks = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) extensions[num_ext] = SCTP_CID_AUTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) num_ext += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (num_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) chunksize += SCTP_PAD4(sizeof(ext_param) + num_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* Now allocate and fill out the chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) goto nomem_chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * address from which it received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * [INIT ACK back to where the INIT came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (chunk->transport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) retval->transport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) sctp_assoc_lookup_paddr(asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) &chunk->transport->ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) retval->subh.init_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) sctp_addto_chunk(retval, sizeof(initack), &initack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) retval->param_hdr.v = sctp_addto_chunk(retval, addrs_len, addrs.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) sctp_addto_chunk(retval, cookie_len, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (asoc->peer.ecn_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (num_ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ext_param.param_hdr.type = SCTP_PARAM_SUPPORTED_EXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ext_param.param_hdr.length = htons(sizeof(ext_param) + num_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) sctp_addto_chunk(retval, sizeof(ext_param), &ext_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) sctp_addto_param(retval, num_ext, extensions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (asoc->peer.prsctp_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (sp->adaptation_ind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) aiparam.param_hdr.length = htons(sizeof(aiparam));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) aiparam.adaptation_ind = htonl(sp->adaptation_ind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (asoc->peer.auth_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) sctp_addto_chunk(retval, ntohs(auth_random->length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) auth_random);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (auth_hmacs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) sctp_addto_chunk(retval, ntohs(auth_hmacs->length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) auth_hmacs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (auth_chunks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) sctp_addto_chunk(retval, ntohs(auth_chunks->length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) auth_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* We need to remove the const qualifier at this point. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) retval->asoc = (struct sctp_association *) asoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) nomem_chunk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) kfree(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) nomem_cookie:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) kfree(addrs.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /* 3.3.11 Cookie Echo (COOKIE ECHO) (10):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * This chunk is used only during the initialization of an association.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * It is sent by the initiator of an association to its peer to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * the initialization process. This chunk MUST precede any DATA chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * sent within the association, but MAY be bundled with one or more DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * chunks in the same packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * | Type = 10 |Chunk Flags | Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * / Cookie /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * Chunk Flags: 8 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * Set to zero on transmit and ignored on receipt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * Length: 16 bits (unsigned integer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * Set to the size of the chunk in bytes, including the 4 bytes of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * the chunk header and the size of the Cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * Cookie: variable size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * This field must contain the exact cookie received in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * State Cookie parameter from the previous INIT ACK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * An implementation SHOULD make the cookie as small as possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * to insure interoperability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int cookie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) void *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) cookie = asoc->peer.cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) cookie_len = asoc->peer.cookie_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* Build a cookie echo chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) cookie_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) retval->subh.cookie_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) sctp_addto_chunk(retval, cookie_len, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * [COOKIE ECHO back to where the INIT ACK came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* 3.3.12 Cookie Acknowledgement (COOKIE ACK) (11):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * This chunk is used only during the initialization of an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * association. It is used to acknowledge the receipt of a COOKIE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * ECHO chunk. This chunk MUST precede any DATA or SACK chunk sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * within the association, but MAY be bundled with one or more DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * chunks or SACK chunk in the same SCTP packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * | Type = 11 |Chunk Flags | Length = 4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * Chunk Flags: 8 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * Set to zero on transmit and ignored on receipt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * [COOKIE ACK back to where the COOKIE ECHO came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (retval && chunk && chunk->transport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) retval->transport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) sctp_assoc_lookup_paddr(asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) &chunk->transport->ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * Appendix A: Explicit Congestion Notification:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * CWR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * RFC 2481 details a specific bit for a sender to send in the header of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * its next outbound TCP segment to indicate to its peer that it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * reduced its congestion window. This is termed the CWR bit. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * SCTP the same indication is made by including the CWR chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * This chunk contains one data element, i.e. the TSN number that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * was sent in the ECNE chunk. This element represents the lowest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * TSN number in the datagram that was originally marked with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * CE bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * | Chunk Type=13 | Flags=00000000| Chunk Length = 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * | Lowest TSN Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * Note: The CWR is considered a Control chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) const __u32 lowest_tsn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct sctp_cwrhdr cwr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) cwr.lowest_tsn = htonl(lowest_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) retval = sctp_make_control(asoc, SCTP_CID_ECN_CWR, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) sizeof(cwr), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) retval->subh.ecn_cwr_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sctp_addto_chunk(retval, sizeof(cwr), &cwr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * [Report a reduced congestion window back to where the ECNE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /* Make an ECNE chunk. This is a congestion experienced report. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) const __u32 lowest_tsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct sctp_ecnehdr ecne;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ecne.lowest_tsn = htonl(lowest_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) retval = sctp_make_control(asoc, SCTP_CID_ECN_ECNE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) sizeof(ecne), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) retval->subh.ecne_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) sctp_addto_chunk(retval, sizeof(ecne), &ecne);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Make a DATA chunk for the given association from the provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * parameters. However, do not populate the data payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct sctp_chunk *sctp_make_datafrag_empty(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) const struct sctp_sndrcvinfo *sinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) int len, __u8 flags, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct sctp_datahdr dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* We assign the TSN as LATE as possible, not here when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * creating the chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) memset(&dp, 0, sizeof(dp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) dp.ppid = sinfo->sinfo_ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dp.stream = htons(sinfo->sinfo_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* Set the flags for an unordered send. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (sinfo->sinfo_flags & SCTP_UNORDERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) flags |= SCTP_DATA_UNORDERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) retval = sctp_make_data(asoc, flags, sizeof(dp) + len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) retval->subh.data_hdr = sctp_addto_chunk(retval, sizeof(dp), &dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* Create a selective ackowledgement (SACK) for the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * association. This reports on which TSN's we've seen to date,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * including duplicates and gaps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct sctp_chunk *sctp_make_sack(struct sctp_association *asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct sctp_gap_ack_block gabs[SCTP_MAX_GABS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) __u16 num_gabs, num_dup_tsns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct sctp_transport *trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct sctp_sackhdr sack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) __u32 ctsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) memset(gabs, 0, sizeof(gabs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ctsn = sctp_tsnmap_get_ctsn(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) pr_debug("%s: sackCTSNAck sent:0x%x\n", __func__, ctsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* How much room is needed in the chunk? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) num_gabs = sctp_tsnmap_num_gabs(map, gabs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) num_dup_tsns = sctp_tsnmap_num_dups(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* Initialize the SACK header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) sack.cum_tsn_ack = htonl(ctsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) sack.a_rwnd = htonl(asoc->a_rwnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) sack.num_gap_ack_blocks = htons(num_gabs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) sack.num_dup_tsns = htons(num_dup_tsns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) len = sizeof(sack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) + sizeof(struct sctp_gap_ack_block) * num_gabs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) + sizeof(__u32) * num_dup_tsns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* Create the chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * HEARTBEAT ACK, etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * address from which it received the DATA or control chunk to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * which it is replying. This rule should also be followed if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * the endpoint is bundling DATA chunks together with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * reply chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * However, when acknowledging multiple DATA chunks received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * in packets from different source addresses in a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * SACK, the SACK chunk may be transmitted to one of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * destination transport addresses from which the DATA or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * control chunks being acknowledged were received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * [BUG: We do not implement the following paragraph.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * Perhaps we should remember the last transport we used for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * SACK and avoid that (if possible) if we have seen any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * duplicates. --piggy]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * When a receiver of a duplicate DATA chunk sends a SACK to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * multi- homed endpoint it MAY be beneficial to vary the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * destination address and not use the source address of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * DATA chunk. The reason being that receiving a duplicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * from a multi-homed endpoint might indicate that the return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * path (as specified in the source address of the DATA chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * for the SACK is broken.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * [Send to the address from which we last received a DATA chunk.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) retval->transport = asoc->peer.last_data_from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) retval->subh.sack_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) sctp_addto_chunk(retval, sizeof(sack), &sack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* Add the gap ack block information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (num_gabs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) sctp_addto_chunk(retval, sizeof(__u32) * num_gabs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) gabs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Add the duplicate TSN information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (num_dup_tsns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) asoc->stats.idupchunks += num_dup_tsns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) sctp_tsnmap_get_dups(map));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* Once we have a sack generated, check to see what our sack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * generation is, if its 0, reset the transports to 0, and reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * the association generation to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * The idea is that zero is never used as a valid generation for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * association so no transport will match after a wrap event like this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * Until the next sack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (++asoc->peer.sack_generation == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) list_for_each_entry(trans, &asoc->peer.transport_addr_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) transports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) trans->sack_generation = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) asoc->peer.sack_generation = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /* Make a SHUTDOWN chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct sctp_shutdownhdr shut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) __u32 ctsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (chunk && chunk->asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ctsn = sctp_tsnmap_get_ctsn(&chunk->asoc->peer.tsn_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) shut.cum_tsn_ack = htonl(ctsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) sizeof(shut), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) retval->subh.shutdown_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) sctp_addto_chunk(retval, sizeof(shut), &shut);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * [ACK back to where the SHUTDOWN came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (retval && chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct sctp_chunk *sctp_make_shutdown_complete(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) __u8 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* Set the T-bit if we have no association (vtag will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * reflected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * [Report SHUTDOWN COMPLETE back to where the SHUTDOWN ACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) * came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (retval && chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* Create an ABORT. Note that we set the T bit if we have no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * association, except when responding to an INIT (sctpimpguide 2.41).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) const size_t hint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) __u8 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /* Set the T-bit if we have no association and 'chunk' is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * an INIT (vtag will be reflected).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (!asoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (chunk && chunk->chunk_hdr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) chunk->chunk_hdr->type == SCTP_CID_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) flags = SCTP_CHUNK_FLAG_T;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * [ABORT back to where the offender came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (retval && chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* Helper to create ABORT with a NO_USER_DATA error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct sctp_chunk *sctp_make_abort_no_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) __u32 tsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) __be32 payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) retval = sctp_make_abort(asoc, chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) sizeof(struct sctp_errhdr) + sizeof(tsn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) goto no_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* Put the tsn back into network byte order. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) payload = htonl(tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) sctp_init_cause(retval, SCTP_ERROR_NO_DATA, sizeof(payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) sctp_addto_chunk(retval, sizeof(payload), (const void *)&payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * [ABORT back to where the offender came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) no_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct msghdr *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) size_t paylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) void *payload = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) retval = sctp_make_abort(asoc, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) sizeof(struct sctp_errhdr) + paylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) goto err_chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (paylen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* Put the msg_iov together into payload. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) payload = kmalloc(paylen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (!payload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) goto err_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) err = memcpy_from_msg(payload, msg, paylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) goto err_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, paylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) sctp_addto_chunk(retval, paylen, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (paylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) kfree(payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) err_copy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) kfree(payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) err_payload:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) sctp_chunk_free(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) retval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) err_chunk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* Append bytes to the end of a parameter. Will panic if chunk is not big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) int chunklen = ntohs(chunk->chunk_hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) void *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) target = skb_put(chunk->skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) memcpy(target, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) memset(target, 0, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /* Adjust the chunk length field. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) chunk->chunk_hdr->length = htons(chunklen + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) chunk->chunk_end = skb_tail_pointer(chunk->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) /* Make an ABORT chunk with a PROTOCOL VIOLATION cause code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct sctp_chunk *sctp_make_abort_violation(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) const __u8 *payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) const size_t paylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct sctp_paramhdr phdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) retval = sctp_make_abort(asoc, chunk, sizeof(struct sctp_errhdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) paylen + sizeof(phdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, paylen +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) sizeof(phdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) phdr.type = htons(chunk->chunk_hdr->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) phdr.length = chunk->chunk_hdr->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) sctp_addto_chunk(retval, paylen, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) sctp_addto_param(retval, sizeof(phdr), &phdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) struct sctp_chunk *sctp_make_violation_paramlen(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct sctp_paramhdr *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static const char error[] = "The following parameter had invalid length:";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) size_t payload_len = sizeof(error) + sizeof(struct sctp_errhdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) sizeof(*param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) retval = sctp_make_abort(asoc, chunk, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) sizeof(error) + sizeof(*param));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) sctp_addto_chunk(retval, sizeof(error), error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) sctp_addto_param(retval, sizeof(*param), param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) struct sctp_chunk *sctp_make_violation_max_retrans(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static const char error[] = "Association exceeded its max_retrans count";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) size_t payload_len = sizeof(error) + sizeof(struct sctp_errhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) retval = sctp_make_abort(asoc, chunk, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, sizeof(error));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) sctp_addto_chunk(retval, sizeof(error), error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* Make a HEARTBEAT chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) const struct sctp_transport *transport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct sctp_sender_hb_info hbinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) sizeof(hbinfo), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) hbinfo.param_hdr.length = htons(sizeof(hbinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) hbinfo.daddr = transport->ipaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) hbinfo.sent_at = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) hbinfo.hb_nonce = transport->hb_nonce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* Cast away the 'const', as this is just telling the chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) * what transport it belongs to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) retval->transport = (struct sctp_transport *) transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) retval->subh.hbs_hdr = sctp_addto_chunk(retval, sizeof(hbinfo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) &hbinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) const void *payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) const size_t paylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) retval->subh.hbs_hdr = sctp_addto_chunk(retval, paylen, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * HEARTBEAT ACK, * etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * address from which it * received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * [HBACK back to where the HEARTBEAT came from.]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* Create an Operation Error chunk with the specified space reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * This routine can be used for containing multiple causes in the chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static struct sctp_chunk *sctp_make_op_error_space(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) retval = sctp_make_control(asoc, SCTP_CID_ERROR, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) sizeof(struct sctp_errhdr) + size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) /* RFC 2960 6.4 Multi-homed SCTP Endpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * An endpoint SHOULD transmit reply chunks (e.g., SACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * HEARTBEAT ACK, etc.) to the same destination transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * address from which it received the DATA or control chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * to which it is replying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) retval->transport = chunk->transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) /* Create an Operation Error chunk of a fixed size, specifically,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * min(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT) - overheads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * This is a helper function to allocate an error chunk for those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * invalid parameter codes in which we may not want to report all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * errors, if the incoming chunk is large. If it can't fit in a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) * packet, we ignore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static inline struct sctp_chunk *sctp_make_op_error_limited(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) size_t size = SCTP_DEFAULT_MAXSEGMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct sctp_sock *sp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (asoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) size = min_t(size_t, size, asoc->pathmtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) sp = sctp_sk(asoc->base.sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) size = sctp_mtu_payload(sp, size, sizeof(struct sctp_errhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return sctp_make_op_error_space(asoc, chunk, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* Create an Operation Error chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) __be16 cause_code, const void *payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) size_t paylen, size_t reserve_tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) retval = sctp_make_op_error_space(asoc, chunk, paylen + reserve_tail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) sctp_init_cause(retval, cause_code, paylen + reserve_tail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) sctp_addto_chunk(retval, paylen, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (reserve_tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) sctp_addto_param(retval, reserve_tail, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) __u16 key_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct sctp_authhdr auth_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) struct sctp_hmac *hmac_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) /* Get the first hmac that the peer told us to use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) hmac_desc = sctp_auth_asoc_get_hmac(asoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (unlikely(!hmac_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) retval = sctp_make_control(asoc, SCTP_CID_AUTH, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) hmac_desc->hmac_len + sizeof(auth_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) auth_hdr.hmac_id = htons(hmac_desc->hmac_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) auth_hdr.shkey_id = htons(key_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) retval->subh.auth_hdr = sctp_addto_chunk(retval, sizeof(auth_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) &auth_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) skb_put_zero(retval->skb, hmac_desc->hmac_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /* Adjust the chunk header to include the empty MAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) retval->chunk_hdr->length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) htons(ntohs(retval->chunk_hdr->length) + hmac_desc->hmac_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) retval->chunk_end = skb_tail_pointer(retval->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * 2nd Level Abstractions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) ********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /* Turn an skb into a chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * FIXME: Eventually move the structure directly inside the skb->cb[].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) * sctpimpguide-05.txt Section 2.8.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * M1) Each time a new DATA chunk is transmitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * set the 'TSN.Missing.Report' count for that TSN to 0. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * 'TSN.Missing.Report' count will be used to determine missing chunks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * and when to fast retransmit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) struct sock *sk, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) retval = kmem_cache_zalloc(sctp_chunk_cachep, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (!sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) pr_debug("%s: chunkifying skb:%p w/o an sk\n", __func__, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) INIT_LIST_HEAD(&retval->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) retval->skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) retval->asoc = (struct sctp_association *)asoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) retval->singleton = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) retval->fast_retransmit = SCTP_CAN_FRTX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) /* Polish the bead hole. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) INIT_LIST_HEAD(&retval->transmitted_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) INIT_LIST_HEAD(&retval->frag_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) SCTP_DBG_OBJCNT_INC(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) refcount_set(&retval->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) /* Set chunk->source and dest based on the IP header in chunk->skb. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) void sctp_init_addrs(struct sctp_chunk *chunk, union sctp_addr *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) union sctp_addr *dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) memcpy(&chunk->source, src, sizeof(union sctp_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) memcpy(&chunk->dest, dest, sizeof(union sctp_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) /* Extract the source address from a chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* If we have a known transport, use that. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (chunk->transport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return &chunk->transport->ipaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* Otherwise, extract it from the IP header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return &chunk->source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) /* Create a new chunk, setting the type and flags headers from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) * arguments, reserving enough space for a 'paylen' byte payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) __u8 type, __u8 flags, int paylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct sctp_chunkhdr *chunk_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) int chunklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) chunklen = SCTP_PAD4(sizeof(*chunk_hdr) + paylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (chunklen > SCTP_MAX_CHUNK_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) /* No need to allocate LL here, as this is only a chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) skb = alloc_skb(chunklen, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) /* Make room for the chunk header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) chunk_hdr = (struct sctp_chunkhdr *)skb_put(skb, sizeof(*chunk_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) chunk_hdr->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) chunk_hdr->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) chunk_hdr->length = htons(sizeof(*chunk_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) sk = asoc ? asoc->base.sk : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) retval = sctp_chunkify(skb, asoc, sk, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (!retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) retval->chunk_hdr = chunk_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) retval->chunk_end = ((__u8 *)chunk_hdr) + sizeof(*chunk_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /* Determine if the chunk needs to be authenticated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (sctp_auth_send_cid(type, asoc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) retval->auth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) __u8 flags, int paylen, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct sctp_chunk *sctp_make_idata(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) __u8 flags, int paylen, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return _sctp_make_chunk(asoc, SCTP_CID_I_DATA, flags, paylen, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) __u8 type, __u8 flags, int paylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) struct sctp_chunk *chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) chunk = _sctp_make_chunk(asoc, type, flags, paylen, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) sctp_control_set_owner_w(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /* Release the memory occupied by a chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) static void sctp_chunk_destroy(struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) BUG_ON(!list_empty(&chunk->list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) list_del_init(&chunk->transmitted_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) consume_skb(chunk->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) consume_skb(chunk->auth_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) SCTP_DBG_OBJCNT_DEC(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) kmem_cache_free(sctp_chunk_cachep, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /* Possibly, free the chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) void sctp_chunk_free(struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /* Release our reference on the message tracker. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) if (chunk->msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) sctp_datamsg_put(chunk->msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) sctp_chunk_put(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /* Grab a reference to the chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) void sctp_chunk_hold(struct sctp_chunk *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) refcount_inc(&ch->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) /* Release a reference to the chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) void sctp_chunk_put(struct sctp_chunk *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) if (refcount_dec_and_test(&ch->refcnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) sctp_chunk_destroy(ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) /* Append bytes to the end of a chunk. Will panic if chunk is not big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) int chunklen = ntohs(chunk->chunk_hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) int padlen = SCTP_PAD4(chunklen) - chunklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) void *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) skb_put_zero(chunk->skb, padlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) target = skb_put_data(chunk->skb, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /* Adjust the chunk length field. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) chunk->chunk_hdr->length = htons(chunklen + padlen + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) chunk->chunk_end = skb_tail_pointer(chunk->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) return target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) /* Append bytes from user space to the end of a chunk. Will panic if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * chunk is not big enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * Returns a kernel err value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) struct iov_iter *from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) void *target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) /* Make room in chunk for data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) target = skb_put(chunk->skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) /* Copy data (whole iovec) into chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (!copy_from_iter_full(target, len, from))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) /* Adjust the chunk length field. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) chunk->chunk_hdr->length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) htons(ntohs(chunk->chunk_hdr->length) + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) chunk->chunk_end = skb_tail_pointer(chunk->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /* Helper function to assign a TSN if needed. This assumes that both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * the data_hdr and association have already been assigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) struct sctp_stream *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) struct sctp_chunk *lchunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) struct sctp_datamsg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) __u16 ssn, sid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (chunk->has_ssn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) /* All fragments will be on the same stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) sid = ntohs(chunk->subh.data_hdr->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) stream = &chunk->asoc->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) /* Now assign the sequence number to the entire message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) * All fragments must have the same stream sequence number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) msg = chunk->msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) list_for_each_entry(lchunk, &msg->chunks, frag_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (lchunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ssn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) ssn = sctp_ssn_next(stream, out, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) ssn = sctp_ssn_peek(stream, out, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) lchunk->subh.data_hdr->ssn = htons(ssn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) lchunk->has_ssn = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) /* Helper function to assign a TSN if needed. This assumes that both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) * the data_hdr and association have already been assigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) void sctp_chunk_assign_tsn(struct sctp_chunk *chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (!chunk->has_tsn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /* This is the last possible instant to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) * assign a TSN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) chunk->subh.data_hdr->tsn =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) htonl(sctp_association_get_next_tsn(chunk->asoc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) chunk->has_tsn = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /* Create a CLOSED association to use with an incoming packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) struct sctp_association *asoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) enum sctp_scope scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /* Create the bare association. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) scope = sctp_scope(sctp_source(chunk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) asoc = sctp_association_new(ep, ep->base.sk, scope, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (!asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) asoc->temp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) skb = chunk->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* Create an entry for the source address of the packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) SCTP_INPUT_CB(skb)->af->from_skb(&asoc->c.peer_addr, skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) return asoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) /* Build a cookie representing asoc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) * This INCLUDES the param header needed to put the cookie in the INIT ACK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) static struct sctp_cookie_param *sctp_pack_cookie(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) const struct sctp_chunk *init_chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) int *cookie_len, const __u8 *raw_addrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) int addrs_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) struct sctp_signed_cookie *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) struct sctp_cookie_param *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) int headersize, bodysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) /* Header size is static data prior to the actual cookie, including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) * any padding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) headersize = sizeof(struct sctp_paramhdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) (sizeof(struct sctp_signed_cookie) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) sizeof(struct sctp_cookie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) bodysize = sizeof(struct sctp_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) + ntohs(init_chunk->chunk_hdr->length) + addrs_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* Pad out the cookie to a multiple to make the signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * functions simpler to write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (bodysize % SCTP_COOKIE_MULTIPLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) bodysize += SCTP_COOKIE_MULTIPLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) - (bodysize % SCTP_COOKIE_MULTIPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) *cookie_len = headersize + bodysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) /* Clear this memory since we are sending this data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) * out on the network.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) retval = kzalloc(*cookie_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) cookie = (struct sctp_signed_cookie *) retval->body;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) /* Set up the parameter header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) retval->p.type = SCTP_PARAM_STATE_COOKIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) retval->p.length = htons(*cookie_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) /* Copy the cookie part of the association itself. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) cookie->c = asoc->c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) /* Save the raw address list length in the cookie. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) cookie->c.raw_addr_list_len = addrs_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) /* Remember PR-SCTP capability. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) cookie->c.prsctp_capable = asoc->peer.prsctp_capable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) /* Save adaptation indication in the cookie. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) cookie->c.adaptation_ind = asoc->peer.adaptation_ind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) /* Set an expiration time for the cookie. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) cookie->c.expiration = ktime_add(asoc->cookie_life,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) ktime_get_real());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /* Copy the peer's init packet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) ntohs(init_chunk->chunk_hdr->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) /* Copy the raw local address list of the association. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) memcpy((__u8 *)&cookie->c.peer_init[0] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (sctp_sk(ep->base.sk)->hmac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct crypto_shash *tfm = sctp_sk(ep->base.sk)->hmac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) /* Sign the message. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) err = crypto_shash_setkey(tfm, ep->secret_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) sizeof(ep->secret_key)) ?:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) crypto_shash_tfm_digest(tfm, (u8 *)&cookie->c, bodysize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) cookie->signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) goto free_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) free_cookie:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) kfree(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) *cookie_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) /* Unpack the cookie from COOKIE ECHO chunk, recreating the association. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) struct sctp_association *sctp_unpack_cookie(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct sctp_chunk *chunk, gfp_t gfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) int *error, struct sctp_chunk **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) struct sctp_association *retval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) int headersize, bodysize, fixed_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) struct sctp_signed_cookie *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) struct sk_buff *skb = chunk->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) struct sctp_cookie *bear_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) __u8 *digest = ep->digest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) enum sctp_scope scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) ktime_t kt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) /* Header size is static data prior to the actual cookie, including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) * any padding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) headersize = sizeof(struct sctp_chunkhdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) (sizeof(struct sctp_signed_cookie) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) sizeof(struct sctp_cookie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) bodysize = ntohs(chunk->chunk_hdr->length) - headersize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) fixed_size = headersize + sizeof(struct sctp_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) /* Verify that the chunk looks like it even has a cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) * There must be enough room for our cookie and our peer's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * INIT chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) len = ntohs(chunk->chunk_hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (len < fixed_size + sizeof(struct sctp_chunkhdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) goto malformed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) /* Verify that the cookie has been padded out. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) if (bodysize % SCTP_COOKIE_MULTIPLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) goto malformed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) /* Process the cookie. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) cookie = chunk->subh.cookie_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) bear_cookie = &cookie->c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (!sctp_sk(ep->base.sk)->hmac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) goto no_hmac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) /* Check the signature. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) struct crypto_shash *tfm = sctp_sk(ep->base.sk)->hmac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) err = crypto_shash_setkey(tfm, ep->secret_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) sizeof(ep->secret_key)) ?:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) crypto_shash_tfm_digest(tfm, (u8 *)bear_cookie, bodysize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) *error = -SCTP_IERROR_NOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) *error = -SCTP_IERROR_BAD_SIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) no_hmac:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) /* IG Section 2.35.2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) * 3) Compare the port numbers and the verification tag contained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) * within the COOKIE ECHO chunk to the actual port numbers and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) * verification tag within the SCTP common header of the received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) * packet. If these values do not match the packet MUST be silently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) * discarded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (ntohl(chunk->sctp_hdr->vtag) != bear_cookie->my_vtag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) *error = -SCTP_IERROR_BAD_TAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (chunk->sctp_hdr->source != bear_cookie->peer_addr.v4.sin_port ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) *error = -SCTP_IERROR_BAD_PORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /* Check to see if the cookie is stale. If there is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) * an association, there is no need to check cookie's expiration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) * for init collision case of lost COOKIE ACK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) * If skb has been timestamped, then use the stamp, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) * use current time. This introduces a small possibility that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) * a cookie may be considered expired, but this would only slow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) * down the new association establishment instead of every packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) kt = skb_get_ktime(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) kt = ktime_get_real();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (!asoc && ktime_before(bear_cookie->expiration, kt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) suseconds_t usecs = ktime_to_us(ktime_sub(kt, bear_cookie->expiration));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) __be32 n = htonl(usecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) * Section 3.3.10.3 Stale Cookie Error (3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) * Cause of error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) * ---------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) * Stale Cookie Error: Indicates the receipt of a valid State
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) * Cookie that has expired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) *errp = sctp_make_op_error(asoc, chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) SCTP_ERROR_STALE_COOKIE, &n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) sizeof(n), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (*errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) *error = -SCTP_IERROR_STALE_COOKIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) *error = -SCTP_IERROR_NOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /* Make a new base association. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) scope = sctp_scope(sctp_source(chunk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) retval = sctp_association_new(ep, ep->base.sk, scope, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (!retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) *error = -SCTP_IERROR_NOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) /* Set up our peer's port number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) retval->peer.port = ntohs(chunk->sctp_hdr->source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) /* Populate the association from the cookie. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) memcpy(&retval->c, bear_cookie, sizeof(*bear_cookie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if (sctp_assoc_set_bind_addr_from_cookie(retval, bear_cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) GFP_ATOMIC) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) *error = -SCTP_IERROR_NOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) /* Also, add the destination address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (list_empty(&retval->base.bind_addr.address_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) sizeof(chunk->dest), SCTP_ADDR_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) retval->next_tsn = retval->c.initial_tsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) retval->ctsn_ack_point = retval->next_tsn - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) retval->addip_serial = retval->c.initial_tsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) retval->strreset_outseq = retval->c.initial_tsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) retval->adv_peer_ack_point = retval->ctsn_ack_point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) retval->peer.prsctp_capable = retval->c.prsctp_capable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) retval->peer.adaptation_ind = retval->c.adaptation_ind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) /* The INIT stuff will be done by the side effects. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) sctp_association_free(retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) malformed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) /* Yikes! The packet is either corrupt or deliberately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) * malformed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) *error = -SCTP_IERROR_MALFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) /********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * 3rd Level Abstractions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) ********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct __sctp_missing {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) __be32 num_missing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) __be16 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) * Report a missing mandatory parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) static int sctp_process_missing_param(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) enum sctp_param paramtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) struct sctp_chunk **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) struct __sctp_missing report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) __u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) len = SCTP_PAD4(sizeof(report));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) /* Make an ERROR chunk, preparing enough room for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) * returning multiple unknown parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (!*errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) *errp = sctp_make_op_error_space(asoc, chunk, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (*errp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) report.num_missing = htonl(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) report.type = paramtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) sctp_init_cause(*errp, SCTP_ERROR_MISS_PARAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) sizeof(report));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) sctp_addto_chunk(*errp, sizeof(report), &report);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) /* Stop processing this chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) /* Report an Invalid Mandatory Parameter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) static int sctp_process_inv_mandatory(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) struct sctp_chunk **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) /* Invalid Mandatory Parameter Error has no payload. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (!*errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) *errp = sctp_make_op_error_space(asoc, chunk, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (*errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) sctp_init_cause(*errp, SCTP_ERROR_INV_PARAM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) /* Stop processing this chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) struct sctp_paramhdr *param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) const struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) struct sctp_chunk **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) /* This is a fatal error. Any accumulated non-fatal errors are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) * not reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) if (*errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) sctp_chunk_free(*errp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) /* Create an error chunk and fill it in with our payload. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) *errp = sctp_make_violation_paramlen(asoc, chunk, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) /* Do not attempt to handle the HOST_NAME parm. However, do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) * send back an indicator to the peer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) static int sctp_process_hn_param(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) union sctp_params param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) struct sctp_chunk **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) __u16 len = ntohs(param.p->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) /* Processing of the HOST_NAME parameter will generate an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * ABORT. If we've accumulated any non-fatal errors, they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) * would be unrecognized parameters and we should not include
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * them in the ABORT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (*errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) sctp_chunk_free(*errp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) *errp = sctp_make_op_error(asoc, chunk, SCTP_ERROR_DNS_FAILED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) param.v, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) /* Stop processing this chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) static int sctp_verify_ext_param(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) union sctp_params param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) __u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) int have_asconf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) int have_auth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) for (i = 0; i < num_ext; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) switch (param.ext->chunks[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) case SCTP_CID_AUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) have_auth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) case SCTP_CID_ASCONF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) case SCTP_CID_ASCONF_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) have_asconf = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) /* ADD-IP Security: The draft requires us to ABORT or ignore the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) * INIT/INIT-ACK if ADD-IP is listed, but AUTH is not. Do this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) * only if ADD-IP is turned on and we are not backward-compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) * mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if (net->sctp.addip_noauth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (ep->asconf_enable && !have_auth && have_asconf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) static void sctp_process_ext_param(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) union sctp_params param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) __u16 num_ext = ntohs(param.p->length) - sizeof(struct sctp_paramhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) for (i = 0; i < num_ext; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) switch (param.ext->chunks[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) case SCTP_CID_RECONF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (asoc->ep->reconf_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) asoc->peer.reconf_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) case SCTP_CID_FWD_TSN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (asoc->ep->prsctp_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) asoc->peer.prsctp_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) case SCTP_CID_AUTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) /* if the peer reports AUTH, assume that he
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) * supports AUTH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) if (asoc->ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) asoc->peer.auth_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) case SCTP_CID_ASCONF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) case SCTP_CID_ASCONF_ACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) if (asoc->ep->asconf_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) asoc->peer.asconf_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) case SCTP_CID_I_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) if (asoc->ep->intl_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) asoc->peer.intl_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) /* RFC 3.2.1 & the Implementers Guide 2.2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) * The Parameter Types are encoded such that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) * highest-order two bits specify the action that must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) * taken if the processing endpoint does not recognize the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) * Parameter Type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) * 00 - Stop processing this parameter; do not process any further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) * parameters within this chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) * 01 - Stop processing this parameter, do not process any further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) * parameters within this chunk, and report the unrecognized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) * parameter in an 'Unrecognized Parameter' ERROR chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) * 10 - Skip this parameter and continue processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) * 11 - Skip this parameter and continue processing but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) * report the unrecognized parameter in an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * 'Unrecognized Parameter' ERROR chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) * Return value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * SCTP_IERROR_NO_ERROR - continue with the chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) * SCTP_IERROR_ERROR - stop and report an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) * SCTP_IERROR_NOMEME - out of memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) static enum sctp_ierror sctp_process_unk_param(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) union sctp_params param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) struct sctp_chunk **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) int retval = SCTP_IERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) switch (param.p->type & SCTP_PARAM_ACTION_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) case SCTP_PARAM_ACTION_DISCARD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) retval = SCTP_IERROR_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) case SCTP_PARAM_ACTION_SKIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) case SCTP_PARAM_ACTION_DISCARD_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) retval = SCTP_IERROR_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) case SCTP_PARAM_ACTION_SKIP_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) /* Make an ERROR chunk, preparing enough room for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) * returning multiple unknown parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) if (!*errp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) *errp = sctp_make_op_error_limited(asoc, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) if (!*errp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) /* If there is no memory for generating the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) * ERROR report as specified, an ABORT will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) * triggered to the peer and the association
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) * won't be established.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) retval = SCTP_IERROR_NOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (!sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) ntohs(param.p->length)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) sctp_addto_chunk(*errp, ntohs(param.p->length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) param.v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /* Verify variable length parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) * Return values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) * SCTP_IERROR_ABORT - trigger an ABORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) * SCTP_IERROR_NOMEM - out of memory (abort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) * SCTP_IERROR_ERROR - stop processing, trigger an ERROR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) * SCTP_IERROR_NO_ERROR - continue with the chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) static enum sctp_ierror sctp_verify_param(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) union sctp_params param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) enum sctp_cid cid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) struct sctp_chunk **err_chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) struct sctp_hmac_algo_param *hmacs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) int retval = SCTP_IERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) __u16 n_elt, id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) /* FIXME - This routine is not looking at each parameter per the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) * chunk type, i.e., unrecognized parameters should be further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) * identified based on the chunk id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) switch (param.p->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) case SCTP_PARAM_IPV4_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) case SCTP_PARAM_IPV6_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) case SCTP_PARAM_COOKIE_PRESERVATIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) case SCTP_PARAM_STATE_COOKIE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) case SCTP_PARAM_HEARTBEAT_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) case SCTP_PARAM_ECN_CAPABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) case SCTP_PARAM_ADAPTATION_LAYER_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) case SCTP_PARAM_SUPPORTED_EXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) if (!sctp_verify_ext_param(net, ep, param))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) return SCTP_IERROR_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) case SCTP_PARAM_SET_PRIMARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (!ep->asconf_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) goto unhandled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) if (ntohs(param.p->length) < sizeof(struct sctp_addip_param) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) sizeof(struct sctp_paramhdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) sctp_process_inv_paramlength(asoc, param.p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) chunk, err_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) retval = SCTP_IERROR_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) case SCTP_PARAM_HOST_NAME_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) /* Tell the peer, we won't support this param. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) sctp_process_hn_param(asoc, param, chunk, err_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) retval = SCTP_IERROR_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) case SCTP_PARAM_FWD_TSN_SUPPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) if (ep->prsctp_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) goto unhandled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) case SCTP_PARAM_RANDOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) goto unhandled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) /* SCTP-AUTH: Secion 6.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) * If the random number is not 32 byte long the association
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) * MUST be aborted. The ABORT chunk SHOULD contain the error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) * cause 'Protocol Violation'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) if (SCTP_AUTH_RANDOM_LENGTH != ntohs(param.p->length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) sizeof(struct sctp_paramhdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) sctp_process_inv_paramlength(asoc, param.p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) chunk, err_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) retval = SCTP_IERROR_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) case SCTP_PARAM_CHUNKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) goto unhandled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) /* SCTP-AUTH: Section 3.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) * The CHUNKS parameter MUST be included once in the INIT or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) * INIT-ACK chunk if the sender wants to receive authenticated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) * chunks. Its maximum length is 260 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (260 < ntohs(param.p->length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) sctp_process_inv_paramlength(asoc, param.p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) chunk, err_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) retval = SCTP_IERROR_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) case SCTP_PARAM_HMAC_ALGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) goto unhandled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) hmacs = (struct sctp_hmac_algo_param *)param.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) n_elt = (ntohs(param.p->length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) sizeof(struct sctp_paramhdr)) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) /* SCTP-AUTH: Section 6.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) * The HMAC algorithm based on SHA-1 MUST be supported and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) * included in the HMAC-ALGO parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) for (i = 0; i < n_elt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) id = ntohs(hmacs->hmac_ids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) if (id == SCTP_AUTH_HMAC_ID_SHA1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (id != SCTP_AUTH_HMAC_ID_SHA1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) sctp_process_inv_paramlength(asoc, param.p, chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) err_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) retval = SCTP_IERROR_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) unhandled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) pr_debug("%s: unrecognized param:%d for chunk:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) __func__, ntohs(param.p->type), cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) retval = sctp_process_unk_param(asoc, param, chunk, err_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) /* Verify the INIT packet before we process it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) const struct sctp_association *asoc, enum sctp_cid cid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) struct sctp_init_chunk *peer_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) struct sctp_chunk *chunk, struct sctp_chunk **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) union sctp_params param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) bool has_cookie = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) /* Check for missing mandatory parameters. Note: Initial TSN is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * also mandatory, but is not checked here since the valid range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) * is 0..2**32-1. RFC4960, section 3.3.3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (peer_init->init_hdr.num_outbound_streams == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) peer_init->init_hdr.num_inbound_streams == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) peer_init->init_hdr.init_tag == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) ntohl(peer_init->init_hdr.a_rwnd) < SCTP_DEFAULT_MINWINDOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) return sctp_process_inv_mandatory(asoc, chunk, errp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) sctp_walk_params(param, peer_init, init_hdr.params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) if (param.p->type == SCTP_PARAM_STATE_COOKIE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) has_cookie = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) /* There is a possibility that a parameter length was bad and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) * in that case we would have stoped walking the parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * The current param.p would point at the bad one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) * Current consensus on the mailing list is to generate a PROTOCOL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) * VIOLATION error. We build the ERROR chunk here and let the normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) * error handling code build and send the packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (param.v != (void *)chunk->chunk_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) return sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) /* The only missing mandatory param possible today is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) * the state cookie for an INIT-ACK chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if ((SCTP_CID_INIT_ACK == cid) && !has_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) return sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) chunk, errp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) /* Verify all the variable length parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) sctp_walk_params(param, peer_init, init_hdr.params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) result = sctp_verify_param(net, ep, asoc, param, cid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) chunk, errp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) switch (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) case SCTP_IERROR_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) case SCTP_IERROR_NOMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) case SCTP_IERROR_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) case SCTP_IERROR_NO_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) } /* for (loop through all parameters) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) /* Unpack the parameters in an INIT packet into an association.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) * Returns 0 on failure, else success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) * FIXME: This is an association method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) const union sctp_addr *peer_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) struct sctp_init_chunk *peer_init, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) struct sctp_transport *transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) struct list_head *pos, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) union sctp_params param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) union sctp_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) struct sctp_af *af;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) int src_match = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) /* We must include the address that the INIT packet came from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) * This is the only address that matters for an INIT packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) * When processing a COOKIE ECHO, we retrieve the from address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) * of the INIT from the cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) /* This implementation defaults to making the first transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) * added as the primary transport. The source address seems to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) * be a better choice than any of the embedded addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) if (!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) goto nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) src_match = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) /* Process the initialization parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) sctp_walk_params(param, peer_init, init_hdr.params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) if (!src_match &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) param.p->type == SCTP_PARAM_IPV6_ADDRESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) af = sctp_get_af_specific(param_type2af(param.p->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) if (!af->from_addr_param(&addr, param.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) chunk->sctp_hdr->source, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) if (sctp_cmp_addr_exact(sctp_source(chunk), &addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) src_match = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) if (!sctp_process_param(asoc, param, peer_addr, gfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) /* source address of chunk may not match any valid address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) if (!src_match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) /* AUTH: After processing the parameters, make sure that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) * have all the required info to potentially do authentications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) if (asoc->peer.auth_capable && (!asoc->peer.peer_random ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) !asoc->peer.peer_hmacs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) asoc->peer.auth_capable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) /* In a non-backward compatible mode, if the peer claims
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) * support for ADD-IP but not AUTH, the ADD-IP spec states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) * that we MUST ABORT the association. Section 6. The section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) * also give us an option to silently ignore the packet, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) * is what we'll do here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) if (!asoc->base.net->sctp.addip_noauth &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) asoc->peer.addip_disabled_mask |= (SCTP_PARAM_ADD_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) SCTP_PARAM_DEL_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) SCTP_PARAM_SET_PRIMARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) asoc->peer.asconf_capable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) /* Walk list of transports, removing transports in the UNKNOWN state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) transport = list_entry(pos, struct sctp_transport, transports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) if (transport->state == SCTP_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) sctp_assoc_rm_peer(asoc, transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) /* The fixed INIT headers are always in network byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) * order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) asoc->peer.i.init_tag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) ntohl(peer_init->init_hdr.init_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) asoc->peer.i.a_rwnd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) ntohl(peer_init->init_hdr.a_rwnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) asoc->peer.i.num_outbound_streams =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) ntohs(peer_init->init_hdr.num_outbound_streams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) asoc->peer.i.num_inbound_streams =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) ntohs(peer_init->init_hdr.num_inbound_streams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) asoc->peer.i.initial_tsn =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) ntohl(peer_init->init_hdr.initial_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) asoc->strreset_inseq = asoc->peer.i.initial_tsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) /* Apply the upper bounds for output streams based on peer's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) * number of inbound streams.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) if (asoc->c.sinit_num_ostreams >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) ntohs(peer_init->init_hdr.num_inbound_streams)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) asoc->c.sinit_num_ostreams =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) ntohs(peer_init->init_hdr.num_inbound_streams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) if (asoc->c.sinit_max_instreams >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) ntohs(peer_init->init_hdr.num_outbound_streams)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) asoc->c.sinit_max_instreams =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) ntohs(peer_init->init_hdr.num_outbound_streams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /* Copy Initiation tag from INIT to VT_peer in cookie. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) asoc->c.peer_vtag = asoc->peer.i.init_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) /* Peer Rwnd : Current calculated value of the peer's rwnd. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) asoc->peer.rwnd = asoc->peer.i.a_rwnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) /* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) * high (for example, implementations MAY use the size of the receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) * advertised window).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) list_for_each_entry(transport, &asoc->peer.transport_addr_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) transports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) transport->ssthresh = asoc->peer.i.a_rwnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) /* Set up the TSN tracking pieces. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) if (!sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) asoc->peer.i.initial_tsn, gfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) * The stream sequence number in all the streams shall start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) * from 0 when the association is established. Also, when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) * stream sequence number reaches the value 65535 the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) * stream sequence number shall be set to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) if (sctp_stream_init(&asoc->stream, asoc->c.sinit_num_ostreams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) asoc->c.sinit_max_instreams, gfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) /* Update frag_point when stream_interleave may get changed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) sctp_assoc_update_frag_point(asoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) if (!asoc->temp && sctp_assoc_set_id(asoc, gfp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) goto clean_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) /* ADDIP Section 4.1 ASCONF Chunk Procedures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) * When an endpoint has an ASCONF signaled change to be sent to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) * remote endpoint it should do the following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) * ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) * A2) A serial number should be assigned to the Chunk. The serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) * number should be a monotonically increasing number. All serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) * numbers are defined to be initialized at the start of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) * association to the same value as the Initial TSN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) asoc->peer.addip_serial = asoc->peer.i.initial_tsn - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) clean_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) /* Release the transport structures. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) transport = list_entry(pos, struct sctp_transport, transports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) if (transport->state != SCTP_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) sctp_assoc_rm_peer(asoc, transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) /* Update asoc with the option described in param.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) * RFC2960 3.3.2.1 Optional/Variable Length Parameters in INIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) * asoc is the association to update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) * param is the variable length parameter to use for update.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) * cid tells us if this is an INIT, INIT ACK or COOKIE ECHO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) * If the current packet is an INIT we want to minimize the amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) * work we do. In particular, we should not build transport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) * structures for the addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) static int sctp_process_param(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) union sctp_params param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) const union sctp_addr *peer_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) struct sctp_endpoint *ep = asoc->ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) union sctp_addr_param *addr_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) struct net *net = asoc->base.net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) struct sctp_transport *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) enum sctp_scope scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) union sctp_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) struct sctp_af *af;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) int retval = 1, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) u32 stale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) __u16 sat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) /* We maintain all INIT parameters in network byte order all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) * time. This allows us to not worry about whether the parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) * came from a fresh INIT, and INIT ACK, or were stored in a cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) switch (param.p->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) case SCTP_PARAM_IPV6_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (PF_INET6 != asoc->base.sk->sk_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) goto do_addr_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) case SCTP_PARAM_IPV4_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) /* v4 addresses are not allowed on v6-only socket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (ipv6_only_sock(asoc->base.sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) do_addr_param:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) af = sctp_get_af_specific(param_type2af(param.p->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (!af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) scope = sctp_scope(peer_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) if (sctp_in_scope(net, &addr, scope))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) case SCTP_PARAM_COOKIE_PRESERVATIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) if (!net->sctp.cookie_preserve_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) stale = ntohl(param.life->lifespan_increment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) /* Suggested Cookie Life span increment's unit is msec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) * (1/1000sec).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) asoc->cookie_life = ktime_add_ms(asoc->cookie_life, stale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) case SCTP_PARAM_HOST_NAME_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) pr_debug("%s: unimplemented SCTP_HOST_NAME_ADDRESS\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) /* Turn off the default values first so we'll know which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) * ones are really set by the peer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) asoc->peer.ipv4_address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) asoc->peer.ipv6_address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) /* Assume that peer supports the address family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) * by which it sends a packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) if (peer_addr->sa.sa_family == AF_INET6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) asoc->peer.ipv6_address = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) else if (peer_addr->sa.sa_family == AF_INET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) asoc->peer.ipv4_address = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) /* Cycle through address types; avoid divide by 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) sat = ntohs(param.p->length) - sizeof(struct sctp_paramhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) if (sat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) sat /= sizeof(__u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) for (i = 0; i < sat; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) switch (param.sat->types[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) case SCTP_PARAM_IPV4_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) asoc->peer.ipv4_address = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) case SCTP_PARAM_IPV6_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) if (PF_INET6 == asoc->base.sk->sk_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) asoc->peer.ipv6_address = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) case SCTP_PARAM_HOST_NAME_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) asoc->peer.hostname_address = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) default: /* Just ignore anything else. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) case SCTP_PARAM_STATE_COOKIE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) asoc->peer.cookie_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) ntohs(param.p->length) - sizeof(struct sctp_paramhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) kfree(asoc->peer.cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) asoc->peer.cookie = kmemdup(param.cookie->body, asoc->peer.cookie_len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) if (!asoc->peer.cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) case SCTP_PARAM_HEARTBEAT_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) /* Would be odd to receive, but it causes no problems. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) /* Rejected during verify stage. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) case SCTP_PARAM_ECN_CAPABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) if (asoc->ep->ecn_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) asoc->peer.ecn_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) /* Fall Through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) goto fall_through;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) case SCTP_PARAM_ADAPTATION_LAYER_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) asoc->peer.adaptation_ind = ntohl(param.aind->adaptation_ind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) case SCTP_PARAM_SET_PRIMARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) if (!ep->asconf_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) goto fall_through;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) addr_param = param.v + sizeof(struct sctp_addip_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) af = sctp_get_af_specific(param_type2af(addr_param->p.type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) if (!af)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) if (!af->from_addr_param(&addr, addr_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) htons(asoc->peer.port), 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) if (!af->addr_valid(&addr, NULL, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) t = sctp_assoc_lookup_paddr(asoc, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) if (!t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) sctp_assoc_set_primary(asoc, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) case SCTP_PARAM_SUPPORTED_EXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) sctp_process_ext_param(asoc, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) case SCTP_PARAM_FWD_TSN_SUPPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) if (asoc->ep->prsctp_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) asoc->peer.prsctp_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) /* Fall Through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) goto fall_through;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) case SCTP_PARAM_RANDOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) goto fall_through;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) /* Save peer's random parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) kfree(asoc->peer.peer_random);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) asoc->peer.peer_random = kmemdup(param.p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) ntohs(param.p->length), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (!asoc->peer.peer_random) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) case SCTP_PARAM_HMAC_ALGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) goto fall_through;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) /* Save peer's HMAC list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) kfree(asoc->peer.peer_hmacs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) asoc->peer.peer_hmacs = kmemdup(param.p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) ntohs(param.p->length), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) if (!asoc->peer.peer_hmacs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) /* Set the default HMAC the peer requested*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) sctp_auth_asoc_set_default_hmac(asoc, param.hmac_algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) case SCTP_PARAM_CHUNKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) if (!ep->auth_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) goto fall_through;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) kfree(asoc->peer.peer_chunks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) asoc->peer.peer_chunks = kmemdup(param.p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) ntohs(param.p->length), gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) if (!asoc->peer.peer_chunks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) fall_through:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) /* Any unrecognized parameters should have been caught
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) * and handled by sctp_verify_param() which should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) * called prior to this routine. Simply log the error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) pr_debug("%s: ignoring param:%d for association:%p.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) __func__, ntohs(param.p->type), asoc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) /* Select a new verification tag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) __u32 sctp_generate_tag(const struct sctp_endpoint *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) /* I believe that this random number generator complies with RFC1750.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) * A tag of 0 is reserved for special cases (e.g. INIT).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) __u32 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) get_random_bytes(&x, sizeof(__u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) } while (x == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) return x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) /* Select an initial TSN to send during startup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) __u32 sctp_generate_tsn(const struct sctp_endpoint *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) __u32 retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) get_random_bytes(&retval, sizeof(__u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) * ADDIP 3.1.1 Address Configuration Change Chunk (ASCONF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) * | Type = 0xC1 | Chunk Flags | Chunk Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) * | Serial Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) * | Address Parameter |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) * | ASCONF Parameter #1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) * / .... /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) * | ASCONF Parameter #N |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) * Address Parameter and other parameter will not be wrapped in this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) union sctp_addr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) int vparam_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) struct sctp_addiphdr asconf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) int length = sizeof(asconf) + vparam_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) union sctp_addr_param addrparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) int addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) addrlen = af->to_addr_param(addr, &addrparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) if (!addrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) length += addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) /* Create the chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) asconf.serial = htonl(asoc->addip_serial++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) retval->subh.addip_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) sctp_addto_chunk(retval, sizeof(asconf), &asconf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) retval->param_hdr.v =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) sctp_addto_chunk(retval, addrlen, &addrparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) /* ADDIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) * 3.2.1 Add IP Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) * | Type = 0xC001 | Length = Variable |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) * | ASCONF-Request Correlation ID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) * | Address Parameter |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) * 3.2.2 Delete IP Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) * | Type = 0xC002 | Length = Variable |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) * | ASCONF-Request Correlation ID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) * | Address Parameter |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) union sctp_addr *laddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) struct sockaddr *addrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) int addrcnt, __be16 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) union sctp_addr_param addr_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) struct sctp_addip_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) int paramlen = sizeof(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) int addr_param_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) union sctp_addr *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) int totallen = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) int del_pickup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) struct sctp_af *af;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) void *addr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) /* Get total length of all the address parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) addr_buf = addrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) for (i = 0; i < addrcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) addr = addr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) af = sctp_get_af_specific(addr->v4.sin_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) addr_param_len = af->to_addr_param(addr, &addr_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) totallen += paramlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) totallen += addr_param_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) addr_buf += af->sockaddr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) if (asoc->asconf_addr_del_pending && !del_pickup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) /* reuse the parameter length from the same scope one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) totallen += paramlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) totallen += addr_param_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) del_pickup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) pr_debug("%s: picked same-scope del_pending addr, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) "totallen for all addresses is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) __func__, totallen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) /* Create an asconf chunk with the required length. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) retval = sctp_make_asconf(asoc, laddr, totallen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) /* Add the address parameters to the asconf chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) addr_buf = addrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) for (i = 0; i < addrcnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) addr = addr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) af = sctp_get_af_specific(addr->v4.sin_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) addr_param_len = af->to_addr_param(addr, &addr_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) param.param_hdr.type = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) param.param_hdr.length = htons(paramlen + addr_param_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) param.crr_id = htonl(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) sctp_addto_chunk(retval, paramlen, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) sctp_addto_chunk(retval, addr_param_len, &addr_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) addr_buf += af->sockaddr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) addr = asoc->asconf_addr_del_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) af = sctp_get_af_specific(addr->v4.sin_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) addr_param_len = af->to_addr_param(addr, &addr_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) param.param_hdr.type = SCTP_PARAM_DEL_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) param.param_hdr.length = htons(paramlen + addr_param_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) param.crr_id = htonl(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) sctp_addto_chunk(retval, paramlen, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) sctp_addto_chunk(retval, addr_param_len, &addr_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) /* ADDIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) * 3.2.4 Set Primary IP Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) * | Type =0xC004 | Length = Variable |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) * | ASCONF-Request Correlation ID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) * | Address Parameter |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) * Create an ASCONF chunk with Set Primary IP address parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) union sctp_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) union sctp_addr_param addrparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) struct sctp_addip_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) int len = sizeof(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) int addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) addrlen = af->to_addr_param(addr, &addrparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) if (!addrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) len += addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) /* Create the chunk and make asconf header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) retval = sctp_make_asconf(asoc, addr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) param.param_hdr.type = SCTP_PARAM_SET_PRIMARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) param.param_hdr.length = htons(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) param.crr_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) sctp_addto_chunk(retval, sizeof(param), ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) sctp_addto_chunk(retval, addrlen, &addrparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) /* ADDIP 3.1.2 Address Configuration Acknowledgement Chunk (ASCONF-ACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) * | Type = 0x80 | Chunk Flags | Chunk Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) * | Serial Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) * | ASCONF Parameter Response#1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) * / .... /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) * | ASCONF Parameter Response#N |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) * Create an ASCONF_ACK chunk with enough space for the parameter responses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) __u32 serial, int vparam_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) struct sctp_addiphdr asconf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) int length = sizeof(asconf) + vparam_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) /* Create the chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) asconf.serial = htonl(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) retval->subh.addip_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) sctp_addto_chunk(retval, sizeof(asconf), &asconf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) /* Add response parameters to an ASCONF_ACK chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) static void sctp_add_asconf_response(struct sctp_chunk *chunk, __be32 crr_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) __be16 err_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) struct sctp_addip_param *asconf_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) struct sctp_addip_param ack_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) struct sctp_errhdr err_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) int asconf_param_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) int err_param_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) __be16 response_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) if (SCTP_ERROR_NO_ERROR == err_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) response_type = SCTP_PARAM_SUCCESS_REPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) response_type = SCTP_PARAM_ERR_CAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) err_param_len = sizeof(err_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) if (asconf_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) asconf_param_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) ntohs(asconf_param->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) /* Add Success Indication or Error Cause Indication parameter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) ack_param.param_hdr.type = response_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) ack_param.param_hdr.length = htons(sizeof(ack_param) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) err_param_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) asconf_param_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) ack_param.crr_id = crr_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) sctp_addto_chunk(chunk, sizeof(ack_param), &ack_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) if (SCTP_ERROR_NO_ERROR == err_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) /* Add Error Cause parameter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) err_param.cause = err_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) err_param.length = htons(err_param_len + asconf_param_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) sctp_addto_chunk(chunk, err_param_len, &err_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) /* Add the failed TLV copied from ASCONF chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) if (asconf_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) sctp_addto_chunk(chunk, asconf_param_len, asconf_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) /* Process a asconf parameter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) struct sctp_chunk *asconf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) struct sctp_addip_param *asconf_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) union sctp_addr_param *addr_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) struct sctp_transport *peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) union sctp_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) struct sctp_af *af;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) addr_param = (void *)asconf_param + sizeof(*asconf_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) if (asconf_param->param_hdr.type != SCTP_PARAM_ADD_IP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) asconf_param->param_hdr.type != SCTP_PARAM_DEL_IP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) return SCTP_ERROR_UNKNOWN_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) switch (addr_param->p.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) case SCTP_PARAM_IPV6_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) if (!asoc->peer.ipv6_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) case SCTP_PARAM_IPV4_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) if (!asoc->peer.ipv4_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) af = sctp_get_af_specific(param_type2af(addr_param->p.type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) if (unlikely(!af))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) if (!af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) /* ADDIP 4.2.1 This parameter MUST NOT contain a broadcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) * or multicast address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) * (note: wildcard is permitted and requires special handling so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) * make sure we check for that)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) switch (asconf_param->param_hdr.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) case SCTP_PARAM_ADD_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) /* Section 4.2.1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) * If the address 0.0.0.0 or ::0 is provided, the source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) * address of the packet MUST be added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) if (af->is_any(&addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) memcpy(&addr, &asconf->source, sizeof(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) if (security_sctp_bind_connect(asoc->ep->base.sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) SCTP_PARAM_ADD_IP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) (struct sockaddr *)&addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) af->sockaddr_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) return SCTP_ERROR_REQ_REFUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) /* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) * request and does not have the local resources to add this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) * new address to the association, it MUST return an Error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) * Cause TLV set to the new error code 'Operation Refused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) * Due to Resource Shortage'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_UNCONFIRMED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) if (!peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) return SCTP_ERROR_RSRC_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) /* Start the heartbeat timer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) sctp_transport_reset_hb_timer(peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) asoc->new_transport = peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) case SCTP_PARAM_DEL_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) /* ADDIP 4.3 D7) If a request is received to delete the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) * last remaining IP address of a peer endpoint, the receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) * MUST send an Error Cause TLV with the error cause set to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) * new error code 'Request to Delete Last Remaining IP Address'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) if (asoc->peer.transport_count == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) return SCTP_ERROR_DEL_LAST_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) /* ADDIP 4.3 D8) If a request is received to delete an IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) * address which is also the source address of the IP packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) * which contained the ASCONF chunk, the receiver MUST reject
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) * this request. To reject the request the receiver MUST send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) * an Error Cause TLV set to the new error code 'Request to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) * Delete Source IP Address'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) if (sctp_cmp_addr_exact(&asconf->source, &addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) return SCTP_ERROR_DEL_SRC_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) /* Section 4.2.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) * If the address 0.0.0.0 or ::0 is provided, all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) * addresses of the peer except the source address of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) * packet MUST be deleted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) if (af->is_any(&addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) sctp_assoc_set_primary(asoc, asconf->transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) sctp_assoc_del_nonprimary_peers(asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) asconf->transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) return SCTP_ERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) /* If the address is not part of the association, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) * ASCONF-ACK with Error Cause Indication Parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) * which including cause of Unresolvable Address should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) * be sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) peer = sctp_assoc_lookup_paddr(asoc, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (!peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) sctp_assoc_rm_peer(asoc, peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) case SCTP_PARAM_SET_PRIMARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) /* ADDIP Section 4.2.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) * If the address 0.0.0.0 or ::0 is provided, the receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) * MAY mark the source address of the packet as its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) * primary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) if (af->is_any(&addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) memcpy(&addr, sctp_source(asconf), sizeof(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) if (security_sctp_bind_connect(asoc->ep->base.sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) SCTP_PARAM_SET_PRIMARY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) (struct sockaddr *)&addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) af->sockaddr_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) return SCTP_ERROR_REQ_REFUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) peer = sctp_assoc_lookup_paddr(asoc, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) if (!peer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) return SCTP_ERROR_DNS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) sctp_assoc_set_primary(asoc, peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) return SCTP_ERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) /* Verify the ASCONF packet before we process it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) bool sctp_verify_asconf(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) struct sctp_chunk *chunk, bool addr_param_needed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) struct sctp_paramhdr **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) struct sctp_addip_chunk *addip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) bool addr_param_seen = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) union sctp_params param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) addip = (struct sctp_addip_chunk *)chunk->chunk_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) sctp_walk_params(param, addip, addip_hdr.params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) size_t length = ntohs(param.p->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) *errp = param.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) switch (param.p->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) case SCTP_PARAM_ERR_CAUSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) case SCTP_PARAM_IPV4_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) if (length != sizeof(struct sctp_ipv4addr_param))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) /* ensure there is only one addr param and it's in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) * beginning of addip_hdr params, or we reject it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) if (param.v != addip->addip_hdr.params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) addr_param_seen = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) case SCTP_PARAM_IPV6_ADDRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) if (length != sizeof(struct sctp_ipv6addr_param))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) if (param.v != addip->addip_hdr.params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) addr_param_seen = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) case SCTP_PARAM_ADD_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) case SCTP_PARAM_DEL_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) case SCTP_PARAM_SET_PRIMARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) /* In ASCONF chunks, these need to be first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) if (addr_param_needed && !addr_param_seen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) length = ntohs(param.addip->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) if (length < sizeof(struct sctp_addip_param) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) sizeof(**errp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) case SCTP_PARAM_SUCCESS_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) case SCTP_PARAM_ADAPTATION_LAYER_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) if (length != sizeof(struct sctp_addip_param))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) /* This is unkown to us, reject! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) /* Remaining sanity checks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) if (addr_param_needed && !addr_param_seen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) if (!addr_param_needed && addr_param_seen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) if (param.v != chunk->chunk_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) /* Process an incoming ASCONF chunk with the next expected serial no. and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) * return an ASCONF_ACK chunk to be sent in response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) struct sctp_chunk *asconf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) union sctp_addr_param *addr_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) struct sctp_addip_chunk *addip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) struct sctp_chunk *asconf_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) bool all_param_pass = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) struct sctp_addiphdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) int length = 0, chunk_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) union sctp_params param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) __be16 err_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) __u32 serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) addip = (struct sctp_addip_chunk *)asconf->chunk_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) chunk_len = ntohs(asconf->chunk_hdr->length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) sizeof(struct sctp_chunkhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) hdr = (struct sctp_addiphdr *)asconf->skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) serial = ntohl(hdr->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) /* Skip the addiphdr and store a pointer to address parameter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) length = sizeof(*hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) addr_param = (union sctp_addr_param *)(asconf->skb->data + length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) chunk_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) /* Skip the address parameter and store a pointer to the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) * asconf parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) length = ntohs(addr_param->p.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) chunk_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) /* create an ASCONF_ACK chunk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) * Based on the definitions of parameters, we know that the size of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) * ASCONF_ACK parameters are less than or equal to the fourfold of ASCONF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) * parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) if (!asconf_ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) /* Process the TLVs contained within the ASCONF chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) sctp_walk_params(param, addip, addip_hdr.params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) /* Skip preceeding address parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) if (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) param.p->type == SCTP_PARAM_IPV6_ADDRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) err_code = sctp_process_asconf_param(asoc, asconf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) param.addip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) /* ADDIP 4.1 A7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) * If an error response is received for a TLV parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) * all TLVs with no response before the failed TLV are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) * considered successful if not reported. All TLVs after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) * the failed response are considered unsuccessful unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) * a specific success indication is present for the parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) if (err_code != SCTP_ERROR_NO_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) all_param_pass = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) if (!all_param_pass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) sctp_add_asconf_response(asconf_ack, param.addip->crr_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) err_code, param.addip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) /* ADDIP 4.3 D11) When an endpoint receiving an ASCONF to add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) * an IP address sends an 'Out of Resource' in its response, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) * MUST also fail any subsequent add or delete requests bundled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) * in the ASCONF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) if (err_code == SCTP_ERROR_RSRC_LOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) asoc->peer.addip_serial++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) /* If we are sending a new ASCONF_ACK hold a reference to it in assoc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) * after freeing the reference to old asconf ack if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) if (asconf_ack) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) sctp_chunk_hold(asconf_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) list_add_tail(&asconf_ack->transmitted_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) &asoc->asconf_ack_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) return asconf_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) /* Process a asconf parameter that is successfully acked. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) static void sctp_asconf_param_success(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) struct sctp_addip_param *asconf_param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) struct sctp_bind_addr *bp = &asoc->base.bind_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) union sctp_addr_param *addr_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) struct sctp_sockaddr_entry *saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) struct sctp_transport *transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) union sctp_addr addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) struct sctp_af *af;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) addr_param = (void *)asconf_param + sizeof(*asconf_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) /* We have checked the packet before, so we do not check again. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) af = sctp_get_af_specific(param_type2af(addr_param->p.type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) if (!af->from_addr_param(&addr, addr_param, htons(bp->port), 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) switch (asconf_param->param_hdr.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) case SCTP_PARAM_ADD_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) /* This is always done in BH context with a socket lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) * held, so the list can not change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) list_for_each_entry(saddr, &bp->address_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) if (sctp_cmp_addr_exact(&saddr->a, &addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) saddr->state = SCTP_ADDR_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) list_for_each_entry(transport, &asoc->peer.transport_addr_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) transports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) sctp_transport_dst_release(transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) case SCTP_PARAM_DEL_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) local_bh_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) sctp_del_bind_addr(bp, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) if (asoc->asconf_addr_del_pending != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) sctp_cmp_addr_exact(asoc->asconf_addr_del_pending, &addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) kfree(asoc->asconf_addr_del_pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) asoc->asconf_addr_del_pending = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) local_bh_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) list_for_each_entry(transport, &asoc->peer.transport_addr_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) transports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) sctp_transport_dst_release(transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) /* Get the corresponding ASCONF response error code from the ASCONF_ACK chunk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) * for the given asconf parameter. If there is no response for this parameter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) * return the error code based on the third argument 'no_err'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) * ADDIP 4.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) * A7) If an error response is received for a TLV parameter, all TLVs with no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) * response before the failed TLV are considered successful if not reported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) * All TLVs after the failed response are considered unsuccessful unless a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) * specific success indication is present for the parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) struct sctp_addip_param *asconf_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) int no_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) struct sctp_addip_param *asconf_ack_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) struct sctp_errhdr *err_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) int asconf_ack_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) __be16 err_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) if (no_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) err_code = SCTP_ERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) err_code = SCTP_ERROR_REQ_REFUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) asconf_ack_len = ntohs(asconf_ack->chunk_hdr->length) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) sizeof(struct sctp_chunkhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) /* Skip the addiphdr from the asconf_ack chunk and store a pointer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) * the first asconf_ack parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) length = sizeof(struct sctp_addiphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) asconf_ack_param = (struct sctp_addip_param *)(asconf_ack->skb->data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) asconf_ack_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) while (asconf_ack_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) if (asconf_ack_param->crr_id == asconf_param->crr_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) switch (asconf_ack_param->param_hdr.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) case SCTP_PARAM_SUCCESS_REPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) return SCTP_ERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) case SCTP_PARAM_ERR_CAUSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) length = sizeof(*asconf_ack_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) err_param = (void *)asconf_ack_param + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) asconf_ack_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) if (asconf_ack_len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) return err_param->cause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) return SCTP_ERROR_INV_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) return SCTP_ERROR_INV_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) length = ntohs(asconf_ack_param->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) asconf_ack_param = (void *)asconf_ack_param + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) asconf_ack_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) return err_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) /* Process an incoming ASCONF_ACK chunk against the cached last ASCONF chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) int sctp_process_asconf_ack(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) struct sctp_chunk *asconf_ack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) struct sctp_chunk *asconf = asoc->addip_last_asconf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) struct sctp_addip_param *asconf_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) __be16 err_code = SCTP_ERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) union sctp_addr_param *addr_param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) int asconf_len = asconf->skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) int all_param_pass = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) int length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) int no_err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) /* Skip the chunkhdr and addiphdr from the last asconf sent and store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) * a pointer to address parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) length = sizeof(struct sctp_addip_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) addr_param = (union sctp_addr_param *)(asconf->skb->data + length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) asconf_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) /* Skip the address parameter in the last asconf sent and store a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) * pointer to the first asconf parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) length = ntohs(addr_param->p.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) asconf_param = (void *)addr_param + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) asconf_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) /* ADDIP 4.1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) * A8) If there is no response(s) to specific TLV parameter(s), and no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) * failures are indicated, then all request(s) are considered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) * successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) if (asconf_ack->skb->len == sizeof(struct sctp_addiphdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) all_param_pass = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) /* Process the TLVs contained in the last sent ASCONF chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) while (asconf_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) if (all_param_pass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) err_code = SCTP_ERROR_NO_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) err_code = sctp_get_asconf_response(asconf_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) asconf_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) no_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) if (no_err && (SCTP_ERROR_NO_ERROR != err_code))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) no_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) switch (err_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) case SCTP_ERROR_NO_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) sctp_asconf_param_success(asoc, asconf_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) case SCTP_ERROR_RSRC_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) retval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) case SCTP_ERROR_UNKNOWN_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) /* Disable sending this type of asconf parameter in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) * future.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) asoc->peer.addip_disabled_mask |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) asconf_param->param_hdr.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) case SCTP_ERROR_REQ_REFUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) case SCTP_ERROR_DEL_LAST_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) case SCTP_ERROR_DEL_SRC_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) /* Skip the processed asconf parameter and move to the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) * one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) length = ntohs(asconf_param->param_hdr.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) asconf_param = (void *)asconf_param + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) asconf_len -= length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) if (no_err && asoc->src_out_of_asoc_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) asoc->src_out_of_asoc_ok = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) sctp_transport_immediate_rtx(asoc->peer.primary_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) /* Free the cached last sent asconf chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) list_del_init(&asconf->transmitted_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) sctp_chunk_free(asconf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) asoc->addip_last_asconf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) /* Make a FWD TSN chunk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) __u32 new_cum_tsn, size_t nstreams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) struct sctp_fwdtsn_skip *skiplist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) struct sctp_chunk *retval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) struct sctp_fwdtsn_hdr ftsn_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) struct sctp_fwdtsn_skip skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) size_t hint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) hint = (nstreams + 1) * sizeof(__u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) retval->subh.fwdtsn_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) for (i = 0; i < nstreams; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) skip.stream = skiplist[i].stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) skip.ssn = skiplist[i].ssn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) sctp_addto_chunk(retval, sizeof(skip), &skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) struct sctp_chunk *sctp_make_ifwdtsn(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) __u32 new_cum_tsn, size_t nstreams,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) struct sctp_ifwdtsn_skip *skiplist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) struct sctp_chunk *retval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) struct sctp_ifwdtsn_hdr ftsn_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) size_t hint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) hint = (nstreams + 1) * sizeof(__u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) retval = sctp_make_control(asoc, SCTP_CID_I_FWD_TSN, 0, hint,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) retval->subh.ifwdtsn_hdr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) sctp_addto_chunk(retval, nstreams * sizeof(skiplist[0]), skiplist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) /* RE-CONFIG 3.1 (RE-CONFIG chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) * | Type = 130 | Chunk Flags | Chunk Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) * / Re-configuration Parameter /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) * / Re-configuration Parameter (optional) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) * \ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) static struct sctp_chunk *sctp_make_reconf(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) struct sctp_reconf_chunk *reconf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) retval = sctp_make_control(asoc, SCTP_CID_RECONF, 0, length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) reconf = (struct sctp_reconf_chunk *)retval->chunk_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) retval->param_hdr.v = reconf->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) /* RE-CONFIG 4.1 (STREAM OUT RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) * | Parameter Type = 13 | Parameter Length = 16 + 2 * N |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) * | Re-configuration Request Sequence Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) * | Re-configuration Response Sequence Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) * | Sender's Last Assigned TSN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) * | Stream Number 1 (optional) | Stream Number 2 (optional) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) * / ...... /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) * | Stream Number N-1 (optional) | Stream Number N (optional) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) * RE-CONFIG 4.2 (STREAM IN RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) * | Parameter Type = 14 | Parameter Length = 8 + 2 * N |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) * | Re-configuration Request Sequence Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) * | Stream Number 1 (optional) | Stream Number 2 (optional) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) * / ...... /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) * | Stream Number N-1 (optional) | Stream Number N (optional) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) struct sctp_chunk *sctp_make_strreset_req(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) __u16 stream_num, __be16 *stream_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) bool out, bool in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) __u16 stream_len = stream_num * sizeof(__u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) struct sctp_strreset_outreq outreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) struct sctp_strreset_inreq inreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) __u16 outlen, inlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) outlen = (sizeof(outreq) + stream_len) * out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) inlen = (sizeof(inreq) + stream_len) * in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) retval = sctp_make_reconf(asoc, SCTP_PAD4(outlen) + SCTP_PAD4(inlen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) if (outlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) outreq.param_hdr.type = SCTP_PARAM_RESET_OUT_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) outreq.param_hdr.length = htons(outlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) outreq.request_seq = htonl(asoc->strreset_outseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) outreq.response_seq = htonl(asoc->strreset_inseq - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) outreq.send_reset_at_tsn = htonl(asoc->next_tsn - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) sctp_addto_chunk(retval, sizeof(outreq), &outreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) if (stream_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) sctp_addto_chunk(retval, stream_len, stream_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) if (inlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) inreq.param_hdr.type = SCTP_PARAM_RESET_IN_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) inreq.param_hdr.length = htons(inlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) inreq.request_seq = htonl(asoc->strreset_outseq + out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) sctp_addto_chunk(retval, sizeof(inreq), &inreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) if (stream_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) sctp_addto_chunk(retval, stream_len, stream_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) /* RE-CONFIG 4.3 (SSN/TSN RESET ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) * | Parameter Type = 15 | Parameter Length = 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) * | Re-configuration Request Sequence Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) struct sctp_chunk *sctp_make_strreset_tsnreq(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) const struct sctp_association *asoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) struct sctp_strreset_tsnreq tsnreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) __u16 length = sizeof(tsnreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) retval = sctp_make_reconf(asoc, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) tsnreq.param_hdr.type = SCTP_PARAM_RESET_TSN_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) tsnreq.param_hdr.length = htons(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) tsnreq.request_seq = htonl(asoc->strreset_outseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) sctp_addto_chunk(retval, sizeof(tsnreq), &tsnreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) /* RE-CONFIG 4.5/4.6 (ADD STREAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) * | Parameter Type = 17 | Parameter Length = 12 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) * | Re-configuration Request Sequence Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) * | Number of new streams | Reserved |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) struct sctp_chunk *sctp_make_strreset_addstrm(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) __u16 out, __u16 in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) struct sctp_strreset_addstrm addstrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) __u16 size = sizeof(addstrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) retval = sctp_make_reconf(asoc, (!!out + !!in) * size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) if (out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) addstrm.param_hdr.type = SCTP_PARAM_RESET_ADD_OUT_STREAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) addstrm.param_hdr.length = htons(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) addstrm.number_of_streams = htons(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) addstrm.request_seq = htonl(asoc->strreset_outseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) addstrm.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) sctp_addto_chunk(retval, size, &addstrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) if (in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) addstrm.param_hdr.type = SCTP_PARAM_RESET_ADD_IN_STREAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) addstrm.param_hdr.length = htons(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) addstrm.number_of_streams = htons(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) addstrm.request_seq = htonl(asoc->strreset_outseq + !!out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) addstrm.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) sctp_addto_chunk(retval, size, &addstrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) /* RE-CONFIG 4.4 (RESP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) * | Parameter Type = 16 | Parameter Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) * | Re-configuration Response Sequence Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) * | Result |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) struct sctp_chunk *sctp_make_strreset_resp(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) __u32 result, __u32 sn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) struct sctp_strreset_resp resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) __u16 length = sizeof(resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) retval = sctp_make_reconf(asoc, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) resp.param_hdr.type = SCTP_PARAM_RESET_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) resp.param_hdr.length = htons(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) resp.response_seq = htonl(sn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) resp.result = htonl(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) sctp_addto_chunk(retval, sizeof(resp), &resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) /* RE-CONFIG 4.4 OPTIONAL (TSNRESP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) * 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) * | Parameter Type = 16 | Parameter Length |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) * | Re-configuration Response Sequence Number |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) * | Result |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) * | Sender's Next TSN (optional) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) * | Receiver's Next TSN (optional) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) struct sctp_chunk *sctp_make_strreset_tsnresp(struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) __u32 result, __u32 sn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) __u32 sender_tsn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) __u32 receiver_tsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) struct sctp_strreset_resptsn tsnresp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) __u16 length = sizeof(tsnresp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) struct sctp_chunk *retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) retval = sctp_make_reconf(asoc, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) tsnresp.param_hdr.type = SCTP_PARAM_RESET_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) tsnresp.param_hdr.length = htons(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) tsnresp.response_seq = htonl(sn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) tsnresp.result = htonl(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) tsnresp.senders_next_tsn = htonl(sender_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) tsnresp.receivers_next_tsn = htonl(receiver_tsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) sctp_addto_chunk(retval, sizeof(tsnresp), &tsnresp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) bool sctp_verify_reconf(const struct sctp_association *asoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) struct sctp_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) struct sctp_paramhdr **errp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) struct sctp_reconf_chunk *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) union sctp_params param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) __be16 last = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) __u16 cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) sctp_walk_params(param, hdr, params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) __u16 length = ntohs(param.p->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) *errp = param.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) if (cnt++ > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) switch (param.p->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) case SCTP_PARAM_RESET_OUT_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) if (length < sizeof(struct sctp_strreset_outreq) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) (last && last != SCTP_PARAM_RESET_RESPONSE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) last != SCTP_PARAM_RESET_IN_REQUEST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) case SCTP_PARAM_RESET_IN_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) if (length < sizeof(struct sctp_strreset_inreq) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) (last && last != SCTP_PARAM_RESET_OUT_REQUEST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) case SCTP_PARAM_RESET_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) if ((length != sizeof(struct sctp_strreset_resp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) length != sizeof(struct sctp_strreset_resptsn)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) (last && last != SCTP_PARAM_RESET_RESPONSE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) last != SCTP_PARAM_RESET_OUT_REQUEST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) case SCTP_PARAM_RESET_TSN_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) if (length !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) sizeof(struct sctp_strreset_tsnreq) || last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) case SCTP_PARAM_RESET_ADD_IN_STREAMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) if (length != sizeof(struct sctp_strreset_addstrm) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) (last && last != SCTP_PARAM_RESET_ADD_OUT_STREAMS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) case SCTP_PARAM_RESET_ADD_OUT_STREAMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) if (length != sizeof(struct sctp_strreset_addstrm) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) (last && last != SCTP_PARAM_RESET_ADD_IN_STREAMS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) last = param.p->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) }