Coverage Report

Created: 2022-08-24 06:02

/src/usrsctp/usrsctplib/netinet/sctp_asconf.c
Line
Count
Source (jump to first uncovered line)
1
/*-
2
 * SPDX-License-Identifier: BSD-3-Clause
3
 *
4
 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
5
 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6
 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are met:
10
 *
11
 * a) Redistributions of source code must retain the above copyright notice,
12
 *    this list of conditions and the following disclaimer.
13
 *
14
 * b) Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in
16
 *    the documentation and/or other materials provided with the distribution.
17
 *
18
 * c) Neither the name of Cisco Systems, Inc. nor the names of its
19
 *    contributors may be used to endorse or promote products derived
20
 *    from this software without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32
 * THE POSSIBILITY OF SUCH DAMAGE.
33
 */
34
35
#if defined(__FreeBSD__) && !defined(__Userspace__)
36
#include <sys/cdefs.h>
37
__FBSDID("$FreeBSD$");
38
#endif
39
40
#include <netinet/sctp_os.h>
41
#include <netinet/sctp_var.h>
42
#include <netinet/sctp_sysctl.h>
43
#include <netinet/sctp_pcb.h>
44
#include <netinet/sctp_header.h>
45
#include <netinet/sctputil.h>
46
#include <netinet/sctp_output.h>
47
#include <netinet/sctp_asconf.h>
48
#include <netinet/sctp_timer.h>
49
50
/*
51
 * debug flags:
52
 * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
53
 * SCTP_DEBUG_ASCONF2: detailed info
54
 */
55
56
/*
57
 * RFC 5061
58
 *
59
 * An ASCONF parameter queue exists per asoc which holds the pending address
60
 * operations.  Lists are updated upon receipt of ASCONF-ACK.
61
 *
62
 * A restricted_addrs list exists per assoc to hold local addresses that are
63
 * not (yet) usable by the assoc as a source address.  These addresses are
64
 * either pending an ASCONF operation (and exist on the ASCONF parameter
65
 * queue), or they are permanently restricted (the peer has returned an
66
 * ERROR indication to an ASCONF(ADD), or the peer does not support ASCONF).
67
 *
68
 * Deleted addresses are always immediately removed from the lists as they will
69
 * (shortly) no longer exist in the kernel.  We send ASCONFs as a courtesy,
70
 * only if allowed.
71
 */
72
73
/*
74
 * ASCONF parameter processing.
75
 * response_required: set if a reply is required (eg. SUCCESS_REPORT).
76
 * returns a mbuf to an "error" response parameter or NULL/"success" if ok.
77
 * FIX: allocating this many mbufs on the fly is pretty inefficient...
78
 */
79
static struct mbuf *
80
sctp_asconf_success_response(uint32_t id)
81
83.9k
{
82
83.9k
  struct mbuf *m_reply = NULL;
83
83.9k
  struct sctp_asconf_paramhdr *aph;
84
85
83.9k
  m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
86
83.9k
          0, M_NOWAIT, 1, MT_DATA);
87
83.9k
  if (m_reply == NULL) {
88
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
89
0
      "asconf_success_response: couldn't get mbuf!\n");
90
0
    return (NULL);
91
0
  }
92
83.9k
  aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
93
83.9k
  aph->correlation_id = id;
94
83.9k
  aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
95
83.9k
  aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
96
83.9k
  SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
97
83.9k
  aph->ph.param_length = htons(aph->ph.param_length);
98
99
83.9k
  return (m_reply);
100
83.9k
}
101
102
static struct mbuf *
103
sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t *error_tlv,
104
                           uint16_t tlv_length)
105
12.0k
{
106
12.0k
  struct mbuf *m_reply = NULL;
107
12.0k
  struct sctp_asconf_paramhdr *aph;
108
12.0k
  struct sctp_error_cause *error;
109
12.0k
  uint32_t buf_len;
110
12.0k
  uint16_t i, param_length, cause_length, padding_length;
111
12.0k
  uint8_t *tlv;
112
113
12.0k
  if (error_tlv == NULL) {
114
0
    tlv_length = 0;
115
0
  }
116
12.0k
  cause_length = sizeof(struct sctp_error_cause) + tlv_length;
117
12.0k
  param_length = sizeof(struct sctp_asconf_paramhdr) + cause_length;
118
12.0k
  padding_length = tlv_length % 4;
119
12.0k
  if (padding_length != 0) {
120
258
    padding_length = 4 - padding_length;
121
258
  }
122
12.0k
  buf_len = param_length + padding_length;
123
12.0k
  if (buf_len > MLEN) {
124
31
    SCTPDBG(SCTP_DEBUG_ASCONF1,
125
31
      "asconf_error_response: tlv_length (%xh) too big\n",
126
31
      tlv_length);
127
31
    return (NULL);
128
31
  }
129
12.0k
  m_reply = sctp_get_mbuf_for_msg(buf_len, 0, M_NOWAIT, 1, MT_DATA);
130
12.0k
  if (m_reply == NULL) {
131
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
132
0
      "asconf_error_response: couldn't get mbuf!\n");
133
0
    return (NULL);
134
0
  }
135
12.0k
  aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
136
12.0k
  aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
137
12.0k
  aph->ph.param_length = htons(param_length);
138
12.0k
  aph->correlation_id = id;
139
12.0k
  error = (struct sctp_error_cause *)(aph + 1);
140
12.0k
  error->code = htons(cause);
141
12.0k
  error->length = htons(cause_length);
142
12.0k
  if (error_tlv != NULL) {
143
12.0k
    tlv = (uint8_t *) (error + 1);
144
12.0k
    memcpy(tlv, error_tlv, tlv_length);
145
12.6k
    for (i = 0; i < padding_length; i++) {
146
620
      tlv[tlv_length + i] = 0;
147
620
    }
148
12.0k
  }
149
12.0k
  SCTP_BUF_LEN(m_reply) = buf_len;
150
12.0k
  return (m_reply);
151
12.0k
}
152
153
static struct mbuf *
154
sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *aph,
155
                           struct sctp_tcb *stcb, int send_hb, int response_required)
156
90.5k
{
157
90.5k
  struct sctp_nets *net;
158
90.5k
  struct mbuf *m_reply = NULL;
159
90.5k
  union sctp_sockstore store;
160
90.5k
  struct sctp_paramhdr *ph;
161
90.5k
  uint16_t param_type, aparam_length;
162
90.5k
#if defined(INET) || defined(INET6)
163
90.5k
  uint16_t param_length;
164
90.5k
#endif
165
90.5k
  struct sockaddr *sa;
166
90.5k
  int zero_address = 0;
167
90.5k
  int bad_address = 0;
168
90.5k
#ifdef INET
169
90.5k
  struct sockaddr_in *sin;
170
90.5k
  struct sctp_ipv4addr_param *v4addr;
171
90.5k
#endif
172
90.5k
#ifdef INET6
173
90.5k
  struct sockaddr_in6 *sin6;
174
90.5k
  struct sctp_ipv6addr_param *v6addr;
175
90.5k
#endif
176
177
90.5k
  aparam_length = ntohs(aph->ph.param_length);
178
90.5k
  if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
179
2.02k
    return (NULL);
180
2.02k
  }
181
88.5k
  ph = (struct sctp_paramhdr *)(aph + 1);
182
88.5k
  param_type = ntohs(ph->param_type);
183
88.5k
#if defined(INET) || defined(INET6)
184
88.5k
  param_length = ntohs(ph->param_length);
185
88.5k
  if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
186
11.5k
    return (NULL);
187
11.5k
  }
188
76.9k
#endif
189
76.9k
  sa = &store.sa;
190
76.9k
  switch (param_type) {
191
0
#ifdef INET
192
61.9k
  case SCTP_IPV4_ADDRESS:
193
61.9k
    if (param_length != sizeof(struct sctp_ipv4addr_param)) {
194
      /* invalid param size */
195
119
      return (NULL);
196
119
    }
197
61.8k
    v4addr = (struct sctp_ipv4addr_param *)ph;
198
61.8k
    sin = &store.sin;
199
61.8k
    memset(sin, 0, sizeof(*sin));
200
61.8k
    sin->sin_family = AF_INET;
201
#ifdef HAVE_SIN_LEN
202
    sin->sin_len = sizeof(struct sockaddr_in);
203
#endif
204
61.8k
    sin->sin_port = stcb->rport;
205
61.8k
    sin->sin_addr.s_addr = v4addr->addr;
206
61.8k
    if ((sin->sin_addr.s_addr == INADDR_BROADCAST) ||
207
61.8k
        IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
208
408
      bad_address = 1;
209
408
    }
210
61.8k
    if (sin->sin_addr.s_addr == INADDR_ANY)
211
3.60k
      zero_address = 1;
212
61.8k
    SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
213
61.8k
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
214
61.8k
    break;
215
0
#endif
216
0
#ifdef INET6
217
10.4k
  case SCTP_IPV6_ADDRESS:
218
10.4k
    if (param_length != sizeof(struct sctp_ipv6addr_param)) {
219
      /* invalid param size */
220
72
      return (NULL);
221
72
    }
222
10.4k
    v6addr = (struct sctp_ipv6addr_param *)ph;
223
10.4k
    sin6 = &store.sin6;
224
10.4k
    memset(sin6, 0, sizeof(*sin6));
225
10.4k
    sin6->sin6_family = AF_INET6;
226
#ifdef HAVE_SIN6_LEN
227
    sin6->sin6_len = sizeof(struct sockaddr_in6);
228
#endif
229
10.4k
    sin6->sin6_port = stcb->rport;
230
10.4k
    memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
231
10.4k
        sizeof(struct in6_addr));
232
10.4k
    if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
233
102
      bad_address = 1;
234
102
    }
235
10.4k
    if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
236
22
      zero_address = 1;
237
10.4k
    SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
238
10.4k
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
239
10.4k
    break;
240
0
#endif
241
4.58k
  default:
242
4.58k
    m_reply = sctp_asconf_error_response(aph->correlation_id,
243
4.58k
        SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
244
4.58k
        aparam_length);
245
4.58k
    return (m_reply);
246
76.9k
  }      /* end switch */
247
248
  /* if 0.0.0.0/::0, add the source address instead */
249
72.2k
  if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
250
3.62k
    sa = src;
251
3.62k
    SCTPDBG(SCTP_DEBUG_ASCONF1,
252
3.62k
            "process_asconf_add_ip: using source addr ");
253
3.62k
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
254
3.62k
  }
255
72.2k
  net = NULL;
256
  /* add the address */
257
72.2k
  if (bad_address) {
258
510
    m_reply = sctp_asconf_error_response(aph->correlation_id,
259
510
        SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
260
510
        aparam_length);
261
71.7k
  } else if (sctp_add_remote_addr(stcb, sa, &net, stcb->asoc.port,
262
71.7k
                                  SCTP_DONOT_SETSCOPE,
263
71.7k
                                  SCTP_ADDR_DYNAMIC_ADDED) != 0) {
264
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
265
0
      "process_asconf_add_ip: error adding address\n");
266
0
    m_reply = sctp_asconf_error_response(aph->correlation_id,
267
0
        SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *) aph,
268
0
        aparam_length);
269
71.7k
  } else {
270
71.7k
    if (response_required) {
271
62.5k
      m_reply =
272
62.5k
          sctp_asconf_success_response(aph->correlation_id);
273
62.5k
    }
274
71.7k
    if (net != NULL) {
275
      /* notify upper layer */
276
61.7k
      sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
277
61.7k
      sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
278
61.7k
      sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
279
61.7k
           stcb, net);
280
61.7k
      if (send_hb) {
281
2.92k
        sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
282
2.92k
      }
283
61.7k
    }
284
71.7k
  }
285
72.2k
  return (m_reply);
286
76.9k
}
287
288
static int
289
sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
290
12.2k
{
291
12.2k
  struct sctp_nets *src_net, *net, *nnet;
292
293
  /* make sure the source address exists as a destination net */
294
12.2k
  src_net = sctp_findnet(stcb, src);
295
12.2k
  if (src_net == NULL) {
296
    /* not found */
297
0
    return (-1);
298
0
  }
299
300
  /* delete all destination addresses except the source */
301
66.2k
  TAILQ_FOREACH_SAFE(net, &stcb->asoc.nets, sctp_next, nnet) {
302
66.2k
    if (net != src_net) {
303
      /* delete this address */
304
53.9k
      SCTPDBG(SCTP_DEBUG_ASCONF1,
305
53.9k
        "asconf_del_remote_addrs_except: deleting ");
306
53.9k
      SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
307
53.9k
             (struct sockaddr *)&net->ro._l_addr);
308
      /* notify upper layer */
309
53.9k
      sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
310
53.9k
          (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
311
53.9k
      sctp_remove_net(stcb, net);
312
53.9k
    }
313
66.2k
  }
314
12.2k
  return (0);
315
12.2k
}
316
317
static struct mbuf *
318
sctp_process_asconf_delete_ip(struct sockaddr *src,
319
                              struct sctp_asconf_paramhdr *aph,
320
            struct sctp_tcb *stcb, int response_required)
321
29.4k
{
322
29.4k
  struct mbuf *m_reply = NULL;
323
29.4k
  union sctp_sockstore store;
324
29.4k
  struct sctp_paramhdr *ph;
325
29.4k
  uint16_t param_type, aparam_length;
326
29.4k
#if defined(INET) || defined(INET6)
327
29.4k
  uint16_t param_length;
328
29.4k
#endif
329
29.4k
  struct sockaddr *sa;
330
29.4k
  int zero_address = 0;
331
29.4k
  int result;
332
29.4k
#ifdef INET
333
29.4k
  struct sockaddr_in *sin;
334
29.4k
  struct sctp_ipv4addr_param *v4addr;
335
29.4k
#endif
336
29.4k
#ifdef INET6
337
29.4k
  struct sockaddr_in6 *sin6;
338
29.4k
  struct sctp_ipv6addr_param *v6addr;
339
29.4k
#endif
340
341
29.4k
  aparam_length = ntohs(aph->ph.param_length);
342
29.4k
  if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
343
1.93k
    return (NULL);
344
1.93k
  }
345
27.5k
  ph = (struct sctp_paramhdr *)(aph + 1);
346
27.5k
  param_type = ntohs(ph->param_type);
347
27.5k
#if defined(INET) || defined(INET6)
348
27.5k
  param_length = ntohs(ph->param_length);
349
27.5k
  if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
350
3.22k
    return (NULL);
351
3.22k
  }
352
24.2k
#endif
353
24.2k
  sa = &store.sa;
354
24.2k
  switch (param_type) {
355
0
#ifdef INET
356
21.4k
  case SCTP_IPV4_ADDRESS:
357
21.4k
    if (param_length != sizeof(struct sctp_ipv4addr_param)) {
358
      /* invalid param size */
359
10
      return (NULL);
360
10
    }
361
21.4k
    v4addr = (struct sctp_ipv4addr_param *)ph;
362
21.4k
    sin = &store.sin;
363
21.4k
    memset(sin, 0, sizeof(*sin));
364
21.4k
    sin->sin_family = AF_INET;
365
#ifdef HAVE_SIN_LEN
366
    sin->sin_len = sizeof(struct sockaddr_in);
367
#endif
368
21.4k
    sin->sin_port = stcb->rport;
369
21.4k
    sin->sin_addr.s_addr = v4addr->addr;
370
21.4k
    if (sin->sin_addr.s_addr == INADDR_ANY)
371
12.1k
      zero_address = 1;
372
21.4k
    SCTPDBG(SCTP_DEBUG_ASCONF1,
373
21.4k
      "process_asconf_delete_ip: deleting ");
374
21.4k
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
375
21.4k
    break;
376
0
#endif
377
0
#ifdef INET6
378
1.25k
  case SCTP_IPV6_ADDRESS:
379
1.25k
    if (param_length != sizeof(struct sctp_ipv6addr_param)) {
380
      /* invalid param size */
381
122
      return (NULL);
382
122
    }
383
1.13k
    v6addr = (struct sctp_ipv6addr_param *)ph;
384
1.13k
    sin6 = &store.sin6;
385
1.13k
    memset(sin6, 0, sizeof(*sin6));
386
1.13k
    sin6->sin6_family = AF_INET6;
387
#ifdef HAVE_SIN6_LEN
388
    sin6->sin6_len = sizeof(struct sockaddr_in6);
389
#endif
390
1.13k
    sin6->sin6_port = stcb->rport;
391
1.13k
    memcpy(&sin6->sin6_addr, v6addr->addr,
392
1.13k
        sizeof(struct in6_addr));
393
1.13k
    if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
394
191
      zero_address = 1;
395
1.13k
    SCTPDBG(SCTP_DEBUG_ASCONF1,
396
1.13k
      "process_asconf_delete_ip: deleting ");
397
1.13k
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
398
1.13k
    break;
399
0
#endif
400
1.59k
  default:
401
1.59k
    m_reply = sctp_asconf_error_response(aph->correlation_id,
402
1.59k
        SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
403
1.59k
        aparam_length);
404
1.59k
    return (m_reply);
405
24.2k
  }
406
407
  /* make sure the source address is not being deleted */
408
22.5k
  if (sctp_cmpaddr(sa, src)) {
409
    /* trying to delete the source address! */
410
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
411
0
    m_reply = sctp_asconf_error_response(aph->correlation_id,
412
0
        SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *) aph,
413
0
        aparam_length);
414
0
    return (m_reply);
415
0
  }
416
417
  /* if deleting 0.0.0.0/::0, delete all addresses except src addr */
418
22.5k
  if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
419
12.2k
    result = sctp_asconf_del_remote_addrs_except(stcb, src);
420
421
12.2k
    if (result) {
422
      /* src address did not exist? */
423
0
      SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
424
      /* what error to reply with?? */
425
0
      m_reply =
426
0
          sctp_asconf_error_response(aph->correlation_id,
427
0
          SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *) aph,
428
0
          aparam_length);
429
12.2k
    } else if (response_required) {
430
10.9k
      m_reply =
431
10.9k
          sctp_asconf_success_response(aph->correlation_id);
432
10.9k
    }
433
12.2k
    return (m_reply);
434
12.2k
  }
435
436
  /* delete the address */
437
10.2k
  result = sctp_del_remote_addr(stcb, sa);
438
  /*
439
   * note if result == -2, the address doesn't exist in the asoc but
440
   * since it's being deleted anyways, we just ack the delete -- but
441
   * this probably means something has already gone awry
442
   */
443
10.2k
  if (result == -1) {
444
    /* only one address in the asoc */
445
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete last IP addr!\n");
446
0
    m_reply = sctp_asconf_error_response(aph->correlation_id,
447
0
        SCTP_CAUSE_DELETING_LAST_ADDR, (uint8_t *) aph,
448
0
        aparam_length);
449
10.2k
  } else {
450
10.2k
    if (response_required) {
451
8.96k
      m_reply = sctp_asconf_success_response(aph->correlation_id);
452
8.96k
    }
453
    /* notify upper layer */
454
10.2k
    sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
455
10.2k
  }
456
10.2k
  return (m_reply);
457
22.5k
}
458
459
static struct mbuf *
460
sctp_process_asconf_set_primary(struct sockaddr *src,
461
        struct sctp_asconf_paramhdr *aph,
462
        struct sctp_tcb *stcb, int response_required)
463
9.68k
{
464
9.68k
  struct mbuf *m_reply = NULL;
465
9.68k
  union sctp_sockstore store;
466
9.68k
  struct sctp_paramhdr *ph;
467
9.68k
  uint16_t param_type, aparam_length;
468
9.68k
#if defined(INET) || defined(INET6)
469
9.68k
  uint16_t param_length;
470
9.68k
#endif
471
9.68k
  struct sockaddr *sa;
472
9.68k
  int zero_address = 0;
473
9.68k
#ifdef INET
474
9.68k
  struct sockaddr_in *sin;
475
9.68k
  struct sctp_ipv4addr_param *v4addr;
476
9.68k
#endif
477
9.68k
#ifdef INET6
478
9.68k
  struct sockaddr_in6 *sin6;
479
9.68k
  struct sctp_ipv6addr_param *v6addr;
480
9.68k
#endif
481
482
9.68k
  aparam_length = ntohs(aph->ph.param_length);
483
9.68k
  if (aparam_length < sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_paramhdr)) {
484
91
    return (NULL);
485
91
  }
486
9.59k
  ph = (struct sctp_paramhdr *)(aph + 1);
487
9.59k
  param_type = ntohs(ph->param_type);
488
9.59k
#if defined(INET) || defined(INET6)
489
9.59k
  param_length = ntohs(ph->param_length);
490
9.59k
  if (param_length + sizeof(struct sctp_asconf_paramhdr) != aparam_length) {
491
1.84k
    return (NULL);
492
1.84k
  }
493
7.74k
#endif
494
7.74k
  sa = &store.sa;
495
7.74k
  switch (param_type) {
496
0
#ifdef INET
497
3.54k
  case SCTP_IPV4_ADDRESS:
498
3.54k
    if (param_length != sizeof(struct sctp_ipv4addr_param)) {
499
      /* invalid param size */
500
133
      return (NULL);
501
133
    }
502
3.41k
    v4addr = (struct sctp_ipv4addr_param *)ph;
503
3.41k
    sin = &store.sin;
504
3.41k
    memset(sin, 0, sizeof(*sin));
505
3.41k
    sin->sin_family = AF_INET;
506
#ifdef HAVE_SIN_LEN
507
    sin->sin_len = sizeof(struct sockaddr_in);
508
#endif
509
3.41k
    sin->sin_addr.s_addr = v4addr->addr;
510
3.41k
    if (sin->sin_addr.s_addr == INADDR_ANY)
511
476
      zero_address = 1;
512
3.41k
    SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
513
3.41k
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
514
3.41k
    break;
515
0
#endif
516
0
#ifdef INET6
517
3.27k
  case SCTP_IPV6_ADDRESS:
518
3.27k
    if (param_length != sizeof(struct sctp_ipv6addr_param)) {
519
      /* invalid param size */
520
151
      return (NULL);
521
151
    }
522
3.12k
    v6addr = (struct sctp_ipv6addr_param *)ph;
523
3.12k
    sin6 = &store.sin6;
524
3.12k
    memset(sin6, 0, sizeof(*sin6));
525
3.12k
    sin6->sin6_family = AF_INET6;
526
#ifdef HAVE_SIN6_LEN
527
    sin6->sin6_len = sizeof(struct sockaddr_in6);
528
#endif
529
3.12k
    memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
530
3.12k
        sizeof(struct in6_addr));
531
3.12k
    if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
532
29
      zero_address = 1;
533
3.12k
    SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
534
3.12k
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
535
3.12k
    break;
536
0
#endif
537
930
  default:
538
930
    m_reply = sctp_asconf_error_response(aph->correlation_id,
539
930
        SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
540
930
        aparam_length);
541
930
    return (m_reply);
542
7.74k
  }
543
544
  /* if 0.0.0.0/::0, use the source address instead */
545
6.53k
  if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
546
505
    sa = src;
547
505
    SCTPDBG(SCTP_DEBUG_ASCONF1,
548
505
      "process_asconf_set_primary: using source addr ");
549
505
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
550
505
  }
551
  /* set the primary address */
552
6.53k
  if (sctp_set_primary_addr(stcb, sa, NULL) == 0) {
553
2.12k
    SCTPDBG(SCTP_DEBUG_ASCONF1,
554
2.12k
      "process_asconf_set_primary: primary address set\n");
555
    /* notify upper layer */
556
2.12k
    sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
557
2.12k
    if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) &&
558
2.12k
        ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF) == 0) &&
559
2.12k
        (stcb->asoc.alternate != NULL)) {
560
1
      sctp_free_remote_addr(stcb->asoc.alternate);
561
1
      stcb->asoc.alternate = NULL;
562
1
    }
563
2.12k
    if (response_required) {
564
1.47k
      m_reply = sctp_asconf_success_response(aph->correlation_id);
565
1.47k
    }
566
    /* Mobility adaptation.
567
       Ideally, when the reception of SET PRIMARY with DELETE IP
568
       ADDRESS of the previous primary destination, unacknowledged
569
       DATA are retransmitted immediately to the new primary
570
       destination for seamless handover.
571
       If the destination is UNCONFIRMED and marked to REQ_PRIM,
572
       The retransmission occur when reception of the
573
       HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
574
       sctp_input.c)
575
       Also, when change of the primary destination, it is better
576
       that all subsequent new DATA containing already queued DATA
577
       are transmitted to the new primary destination. (by micchie)
578
     */
579
2.12k
    if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
580
2.12k
                                     SCTP_MOBILITY_BASE) ||
581
2.12k
        sctp_is_mobility_feature_on(stcb->sctp_ep,
582
2.12k
                                    SCTP_MOBILITY_FASTHANDOFF)) &&
583
2.12k
        sctp_is_mobility_feature_on(stcb->sctp_ep,
584
2.12k
                                    SCTP_MOBILITY_PRIM_DELETED) &&
585
2.12k
        (stcb->asoc.primary_destination->dest_state &
586
0
         SCTP_ADDR_UNCONFIRMED) == 0) {
587
0
      sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
588
0
                      stcb->sctp_ep, stcb, NULL,
589
0
                      SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
590
0
      if (sctp_is_mobility_feature_on(stcb->sctp_ep,
591
0
          SCTP_MOBILITY_FASTHANDOFF)) {
592
0
        sctp_assoc_immediate_retrans(stcb,
593
0
            stcb->asoc.primary_destination);
594
0
      }
595
0
      if (sctp_is_mobility_feature_on(stcb->sctp_ep,
596
0
          SCTP_MOBILITY_BASE)) {
597
0
        sctp_move_chunks_from_net(stcb,
598
0
            stcb->asoc.deleted_primary);
599
0
      }
600
0
      sctp_delete_prim_timer(stcb->sctp_ep, stcb);
601
0
    }
602
4.41k
  } else {
603
    /* couldn't set the requested primary address! */
604
4.41k
    SCTPDBG(SCTP_DEBUG_ASCONF1,
605
4.41k
      "process_asconf_set_primary: set primary failed!\n");
606
    /* must have been an invalid address, so report */
607
4.41k
    m_reply = sctp_asconf_error_response(aph->correlation_id,
608
4.41k
        SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
609
4.41k
        aparam_length);
610
4.41k
  }
611
612
6.53k
  return (m_reply);
613
6.53k
}
614
615
/*
616
 * handles an ASCONF chunk.
617
 * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
618
 */
619
void
620
sctp_handle_asconf(struct mbuf *m, unsigned int offset,
621
                   struct sockaddr *src,
622
       struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb,
623
       int first)
624
6.00k
{
625
6.00k
  struct sctp_association *asoc;
626
6.00k
  uint32_t serial_num;
627
6.00k
  struct mbuf *n, *m_ack, *m_result, *m_tail;
628
6.00k
  struct sctp_asconf_ack_chunk *ack_cp;
629
6.00k
  struct sctp_asconf_paramhdr *aph;
630
6.00k
  struct sctp_ipv6addr_param *p_addr;
631
6.00k
  unsigned int asconf_limit, cnt;
632
6.00k
  int error = 0;    /* did an error occur? */
633
634
  /* asconf param buffer */
635
6.00k
  uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
636
6.00k
  struct sctp_asconf_ack *ack, *ack_next;
637
638
  /* verify minimum length */
639
6.00k
  if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_chunk)) {
640
949
    SCTPDBG(SCTP_DEBUG_ASCONF1,
641
949
      "handle_asconf: chunk too small = %xh\n",
642
949
      ntohs(cp->ch.chunk_length));
643
949
    return;
644
949
  }
645
5.05k
  asoc = &stcb->asoc;
646
5.05k
  serial_num = ntohl(cp->serial_number);
647
648
5.05k
  if (SCTP_TSN_GE(asoc->asconf_seq_in, serial_num)) {
649
    /* got a duplicate ASCONF */
650
1.09k
    SCTPDBG(SCTP_DEBUG_ASCONF1,
651
1.09k
      "handle_asconf: got duplicate serial number = %xh\n",
652
1.09k
      serial_num);
653
1.09k
    return;
654
3.96k
  } else if (serial_num != (asoc->asconf_seq_in + 1)) {
655
1.63k
    SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: incorrect serial number = %xh (expected next = %xh)\n",
656
1.63k
      serial_num, asoc->asconf_seq_in + 1);
657
1.63k
    return;
658
1.63k
  }
659
660
  /* it's the expected "next" sequence number, so process it */
661
2.32k
  asoc->asconf_seq_in = serial_num; /* update sequence */
662
  /* get length of all the param's in the ASCONF */
663
2.32k
  asconf_limit = offset + ntohs(cp->ch.chunk_length);
664
2.32k
  SCTPDBG(SCTP_DEBUG_ASCONF1,
665
2.32k
    "handle_asconf: asconf_limit=%u, sequence=%xh\n",
666
2.32k
    asconf_limit, serial_num);
667
668
2.32k
  if (first) {
669
    /* delete old cache */
670
2.20k
    SCTPDBG(SCTP_DEBUG_ASCONF1,"handle_asconf: Now processing first ASCONF. Try to delete old cache\n");
671
672
2.20k
    TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) {
673
0
      if (ack->serial_number == serial_num)
674
0
        break;
675
0
      SCTPDBG(SCTP_DEBUG_ASCONF1,"handle_asconf: delete old(%u) < first(%u)\n",
676
0
          ack->serial_number, serial_num);
677
0
      TAILQ_REMOVE(&asoc->asconf_ack_sent, ack, next);
678
0
      if (ack->data != NULL) {
679
0
        sctp_m_freem(ack->data);
680
0
      }
681
0
      SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), ack);
682
0
    }
683
2.20k
  }
684
685
2.32k
  m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
686
2.32k
              M_NOWAIT, 1, MT_DATA);
687
2.32k
  if (m_ack == NULL) {
688
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
689
0
      "handle_asconf: couldn't get mbuf!\n");
690
0
    return;
691
0
  }
692
2.32k
  m_tail = m_ack;   /* current reply chain's tail */
693
694
  /* fill in ASCONF-ACK header */
695
2.32k
  ack_cp = mtod(m_ack, struct sctp_asconf_ack_chunk *);
696
2.32k
  ack_cp->ch.chunk_type = SCTP_ASCONF_ACK;
697
2.32k
  ack_cp->ch.chunk_flags = 0;
698
2.32k
  ack_cp->serial_number = htonl(serial_num);
699
  /* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
700
2.32k
  SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
701
2.32k
  ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
702
703
  /* skip the lookup address parameter */
704
2.32k
  offset += sizeof(struct sctp_asconf_chunk);
705
2.32k
  p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), (uint8_t *)&aparam_buf);
706
2.32k
  if (p_addr == NULL) {
707
5
    SCTPDBG(SCTP_DEBUG_ASCONF1,
708
5
      "handle_asconf: couldn't get lookup addr!\n");
709
    /* respond with a missing/invalid mandatory parameter error */
710
5
    sctp_m_freem(m_ack);
711
5
    return;
712
5
  }
713
  /* skip lookup addr */
714
2.32k
  offset += SCTP_SIZE32(ntohs(p_addr->ph.param_length));
715
  /* get pointer to first asconf param in ASCONF */
716
2.32k
  aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *)&aparam_buf);
717
2.32k
  if (aph == NULL) {
718
107
    SCTPDBG(SCTP_DEBUG_ASCONF1, "Empty ASCONF received?\n");
719
107
    goto send_reply;
720
107
  }
721
  /* process through all parameters */
722
2.21k
  cnt = 0;
723
146k
  while (aph != NULL) {
724
146k
    unsigned int param_length, param_type;
725
726
146k
    param_type = ntohs(aph->ph.param_type);
727
146k
    param_length = ntohs(aph->ph.param_length);
728
146k
    if (offset + param_length > asconf_limit) {
729
      /* parameter goes beyond end of chunk! */
730
662
      sctp_m_freem(m_ack);
731
662
      return;
732
662
    }
733
145k
    m_result = NULL;
734
735
145k
    if (param_length > sizeof(aparam_buf)) {
736
19
      SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) larger than buffer size!\n", param_length);
737
19
      sctp_m_freem(m_ack);
738
19
      return;
739
19
    }
740
145k
    if (param_length < sizeof(struct sctp_asconf_paramhdr)) {
741
301
      SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
742
301
      sctp_m_freem(m_ack);
743
301
      return;
744
301
    }
745
    /* get the entire parameter */
746
145k
    aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
747
145k
    if (aph == NULL) {
748
0
      SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: couldn't get entire param\n");
749
0
      sctp_m_freem(m_ack);
750
0
      return;
751
0
    }
752
145k
    switch (param_type) {
753
90.5k
    case SCTP_ADD_IP_ADDRESS:
754
90.5k
      m_result = sctp_process_asconf_add_ip(src, aph, stcb,
755
90.5k
          (cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
756
90.5k
      cnt++;
757
90.5k
      break;
758
29.4k
    case SCTP_DEL_IP_ADDRESS:
759
29.4k
      m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
760
29.4k
          error);
761
29.4k
      break;
762
2.70k
    case SCTP_ERROR_CAUSE_IND:
763
      /* not valid in an ASCONF chunk */
764
2.70k
      break;
765
9.68k
    case SCTP_SET_PRIM_ADDR:
766
9.68k
      m_result = sctp_process_asconf_set_primary(src, aph,
767
9.68k
          stcb, error);
768
9.68k
      break;
769
102
    case SCTP_NAT_VTAGS:
770
102
            SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: sees a NAT VTAG state parameter\n");
771
102
            break;
772
1.00k
    case SCTP_SUCCESS_REPORT:
773
      /* not valid in an ASCONF chunk */
774
1.00k
      break;
775
1.83k
    case SCTP_ULP_ADAPTATION:
776
      /* FIX */
777
1.83k
      break;
778
10.2k
    default:
779
10.2k
      if ((param_type & 0x8000) == 0) {
780
        /* Been told to STOP at this param */
781
229
        asconf_limit = offset;
782
        /*
783
         * FIX FIX - We need to call
784
         * sctp_arethere_unrecognized_parameters()
785
         * to get a operr and send it for any
786
         * param's with the 0x4000 bit set OR do it
787
         * here ourselves... note we still must STOP
788
         * if the 0x8000 bit is clear.
789
         */
790
229
      }
791
      /* unknown/invalid param type */
792
10.2k
      break;
793
145k
    } /* switch */
794
795
    /* add any (error) result to the reply mbuf chain */
796
145k
    if (m_result != NULL) {
797
95.9k
      SCTP_BUF_NEXT(m_tail) = m_result;
798
95.9k
      m_tail = m_result;
799
95.9k
      ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
800
      /* set flag to force success reports */
801
95.9k
      error = 1;
802
95.9k
    }
803
145k
    offset += SCTP_SIZE32(param_length);
804
    /* update remaining ASCONF message length to process */
805
145k
    if (offset >= asconf_limit) {
806
      /* no more data in the mbuf chain */
807
1.12k
      break;
808
1.12k
    }
809
    /* get pointer to next asconf param */
810
144k
    aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
811
144k
        sizeof(struct sctp_asconf_paramhdr),
812
144k
        (uint8_t *)&aparam_buf);
813
144k
    if (aph == NULL) {
814
      /* can't get an asconf paramhdr */
815
115
      SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: can't get asconf param hdr!\n");
816
      /* FIX ME - add error here... */
817
115
    }
818
144k
  }
819
820
1.34k
 send_reply:
821
1.34k
  ack_cp->ch.chunk_length = htons(ack_cp->ch.chunk_length);
822
  /* save the ASCONF-ACK reply */
823
1.34k
  ack = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asconf_ack),
824
1.34k
      struct sctp_asconf_ack);
825
1.34k
  if (ack == NULL) {
826
0
    sctp_m_freem(m_ack);
827
0
    return;
828
0
  }
829
1.34k
  ack->serial_number = serial_num;
830
1.34k
  ack->last_sent_to = NULL;
831
1.34k
  ack->data = m_ack;
832
1.34k
  ack->len = 0;
833
39.9k
  for (n = m_ack; n != NULL; n = SCTP_BUF_NEXT(n)) {
834
38.5k
    ack->len += SCTP_BUF_LEN(n);
835
38.5k
  }
836
1.34k
  TAILQ_INSERT_TAIL(&stcb->asoc.asconf_ack_sent, ack, next);
837
838
  /* see if last_control_chunk_from is set properly (use IP src addr) */
839
1.34k
  if (stcb->asoc.last_control_chunk_from == NULL) {
840
    /*
841
     * this could happen if the source address was just newly
842
     * added
843
     */
844
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
845
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "Looking for IP source: ");
846
0
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
847
    /* look up the from address */
848
0
    stcb->asoc.last_control_chunk_from = sctp_findnet(stcb, src);
849
#ifdef SCTP_DEBUG
850
    if (stcb->asoc.last_control_chunk_from == NULL) {
851
      SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: IP source address not found?!\n");
852
    }
853
#endif
854
0
  }
855
1.34k
}
856
857
/*
858
 * does the address match? returns 0 if not, 1 if so
859
 */
860
static uint32_t
861
sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
862
0
{
863
0
  switch (sa->sa_family) {
864
0
#ifdef INET6
865
0
  case AF_INET6:
866
0
  {
867
    /* XXX scopeid */
868
0
    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
869
870
0
    if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
871
0
        (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
872
0
        sizeof(struct in6_addr)) == 0)) {
873
0
      return (1);
874
0
    }
875
0
    break;
876
0
  }
877
0
#endif
878
0
#ifdef INET
879
0
  case AF_INET:
880
0
  {
881
0
    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
882
883
0
    if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
884
0
        (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
885
0
        sizeof(struct in_addr)) == 0)) {
886
0
      return (1);
887
0
    }
888
0
    break;
889
0
  }
890
0
#endif
891
0
  default:
892
0
    break;
893
0
  }
894
0
  return (0);
895
0
}
896
897
/*
898
 * does the address match? returns 0 if not, 1 if so
899
 */
900
static uint32_t
901
sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
902
0
{
903
0
#if defined(INET) || defined(INET6)
904
0
  uint16_t param_type, param_length;
905
906
0
  param_type = ntohs(ph->param_type);
907
0
  param_length = ntohs(ph->param_length);
908
0
#endif
909
0
  switch (sa->sa_family) {
910
0
#ifdef INET6
911
0
  case AF_INET6:
912
0
  {
913
    /* XXX scopeid */
914
0
    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
915
0
    struct sctp_ipv6addr_param *v6addr;
916
917
0
    v6addr = (struct sctp_ipv6addr_param *)ph;
918
0
    if ((param_type == SCTP_IPV6_ADDRESS) &&
919
0
        (param_length == sizeof(struct sctp_ipv6addr_param)) &&
920
0
        (memcmp(&v6addr->addr, &sin6->sin6_addr,
921
0
        sizeof(struct in6_addr)) == 0)) {
922
0
      return (1);
923
0
    }
924
0
    break;
925
0
  }
926
0
#endif
927
0
#ifdef INET
928
0
  case AF_INET:
929
0
  {
930
0
    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
931
0
    struct sctp_ipv4addr_param *v4addr;
932
933
0
    v4addr = (struct sctp_ipv4addr_param *)ph;
934
0
    if ((param_type == SCTP_IPV4_ADDRESS) &&
935
0
        (param_length == sizeof(struct sctp_ipv4addr_param)) &&
936
0
        (memcmp(&v4addr->addr, &sin->sin_addr,
937
0
        sizeof(struct in_addr)) == 0)) {
938
0
      return (1);
939
0
    }
940
0
    break;
941
0
  }
942
0
#endif
943
0
  default:
944
0
    break;
945
0
  }
946
0
  return (0);
947
0
}
948
/*
949
 * Cleanup for non-responded/OP ERR'd ASCONF
950
 */
951
void
952
sctp_asconf_cleanup(struct sctp_tcb *stcb)
953
335
{
954
  /*
955
   * clear out any existing asconfs going out
956
   */
957
335
  sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, NULL,
958
335
      SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2);
959
335
  stcb->asoc.asconf_seq_out_acked = stcb->asoc.asconf_seq_out;
960
  /* remove the old ASCONF on our outbound queue */
961
335
  sctp_toss_old_asconf(stcb);
962
335
}
963
964
/*
965
 * cleanup any cached source addresses that may be topologically
966
 * incorrect after a new address has been added to this interface.
967
 */
968
static void
969
sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn)
970
0
{
971
0
  struct sctp_nets *net;
972
973
  /*
974
   * Ideally, we want to only clear cached routes and source addresses
975
   * that are topologically incorrect.  But since there is no easy way
976
   * to know whether the newly added address on the ifn would cause a
977
   * routing change (i.e. a new egress interface would be chosen)
978
   * without doing a new routing lookup and source address selection,
979
   * we will (for now) just flush any cached route using a different
980
   * ifn (and cached source addrs) and let output re-choose them during
981
   * the next send on that net.
982
   */
983
0
  TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
984
    /*
985
     * clear any cached route (and cached source address) if the
986
     * route's interface is NOT the same as the address change.
987
     * If it's the same interface, just clear the cached source
988
     * address.
989
     */
990
0
    if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) &&
991
0
        ((ifn == NULL) ||
992
0
         (SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index))) {
993
      /* clear any cached route */
994
#if defined(__FreeBSD__) && !defined(__Userspace__)
995
      RO_NHFREE(&net->ro);
996
#else
997
0
      RTFREE(net->ro.ro_rt);
998
0
      net->ro.ro_rt = NULL;
999
0
#endif
1000
0
    }
1001
    /* clear any cached source address */
1002
0
    if (net->src_addr_selected) {
1003
0
      sctp_free_ifa(net->ro._s_addr);
1004
0
      net->ro._s_addr = NULL;
1005
0
      net->src_addr_selected = 0;
1006
0
    }
1007
0
  }
1008
0
}
1009
1010
void
1011
sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
1012
0
{
1013
0
  int error;
1014
1015
0
  if (dstnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
1016
0
    return;
1017
0
  }
1018
0
  if (stcb->asoc.deleted_primary == NULL) {
1019
0
    return;
1020
0
  }
1021
1022
0
  if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
1023
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "assoc_immediate_retrans: Deleted primary is ");
1024
0
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
1025
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "Current Primary is ");
1026
0
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
1027
0
    sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
1028
0
        stcb->asoc.deleted_primary,
1029
0
        SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
1030
0
    stcb->asoc.num_send_timers_up--;
1031
0
    if (stcb->asoc.num_send_timers_up < 0) {
1032
0
      stcb->asoc.num_send_timers_up = 0;
1033
0
    }
1034
0
    SCTP_TCB_LOCK_ASSERT(stcb);
1035
0
    error = sctp_t3rxt_timer(stcb->sctp_ep, stcb,
1036
0
          stcb->asoc.deleted_primary);
1037
0
    if (error) {
1038
0
      SCTP_INP_DECR_REF(stcb->sctp_ep);
1039
0
      return;
1040
0
    }
1041
0
    SCTP_TCB_LOCK_ASSERT(stcb);
1042
#ifdef SCTP_AUDITING_ENABLED
1043
    sctp_auditing(4, stcb->sctp_ep, stcb, stcb->asoc.deleted_primary);
1044
#endif
1045
0
    sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1046
0
    if ((stcb->asoc.num_send_timers_up == 0) &&
1047
0
        (stcb->asoc.sent_queue_cnt > 0)) {
1048
0
      struct sctp_tmit_chunk *chk;
1049
1050
0
      TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1051
0
        if (chk->whoTo != NULL) {
1052
0
          break;
1053
0
        }
1054
0
      }
1055
0
      if (chk != NULL) {
1056
0
        sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, chk->whoTo);
1057
0
      }
1058
0
    }
1059
0
  }
1060
0
  return;
1061
0
}
1062
1063
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
1064
static int
1065
sctp_asconf_queue_mgmt(struct sctp_tcb *, struct sctp_ifa *, uint16_t);
1066
1067
void
1068
sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
1069
0
{
1070
0
  struct sctp_tmit_chunk *chk;
1071
1072
0
  SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
1073
0
  sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
1074
0
                  SCTP_FROM_SCTP_ASCONF + SCTP_LOC_4);
1075
0
  stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
1076
0
  net->error_count = 0;
1077
0
  TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
1078
0
    if (chk->whoTo == net) {
1079
0
      if (chk->sent < SCTP_DATAGRAM_RESEND) {
1080
0
        chk->sent = SCTP_DATAGRAM_RESEND;
1081
0
        sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
1082
0
        sctp_flight_size_decrease(chk);
1083
0
        sctp_total_flight_decrease(stcb, chk);
1084
0
        net->marked_retrans++;
1085
0
        stcb->asoc.marked_retrans++;
1086
0
      }
1087
0
    }
1088
0
  }
1089
0
  if (net->marked_retrans) {
1090
0
    sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
1091
0
  }
1092
0
}
1093
1094
static void
1095
sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
1096
0
{
1097
0
  struct sctp_nets *net;
1098
0
  int addrnum, changed;
1099
1100
  /*   If number of local valid addresses is 1, the valid address is
1101
       probably newly added address.
1102
       Several valid addresses in this association.  A source address
1103
       may not be changed.  Additionally, they can be configured on a
1104
       same interface as "alias" addresses.  (by micchie)
1105
   */
1106
0
  addrnum = sctp_local_addr_count(stcb);
1107
0
  SCTPDBG(SCTP_DEBUG_ASCONF1, "p_check_react(): %d local addresses\n",
1108
0
    addrnum);
1109
0
  if (addrnum == 1) {
1110
0
    TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1111
      /* clear any cached route and source address */
1112
#if defined(__FreeBSD__) && !defined(__Userspace__)
1113
      RO_NHFREE(&net->ro);
1114
#else
1115
0
      if (net->ro.ro_rt) {
1116
0
        RTFREE(net->ro.ro_rt);
1117
0
        net->ro.ro_rt = NULL;
1118
0
      }
1119
0
#endif
1120
0
      if (net->src_addr_selected) {
1121
0
        sctp_free_ifa(net->ro._s_addr);
1122
0
        net->ro._s_addr = NULL;
1123
0
        net->src_addr_selected = 0;
1124
0
      }
1125
      /* Retransmit unacknowledged DATA chunks immediately */
1126
0
      if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1127
0
                                      SCTP_MOBILITY_FASTHANDOFF)) {
1128
0
        sctp_net_immediate_retrans(stcb, net);
1129
0
      }
1130
      /* also, SET PRIMARY is maybe already sent */
1131
0
    }
1132
0
    return;
1133
0
  }
1134
1135
  /* Multiple local addresses exist in the association.  */
1136
0
  TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1137
    /* clear any cached route and source address */
1138
#if defined(__FreeBSD__) && !defined(__Userspace__)
1139
    RO_NHFREE(&net->ro);
1140
#else
1141
0
    if (net->ro.ro_rt) {
1142
0
      RTFREE(net->ro.ro_rt);
1143
0
      net->ro.ro_rt = NULL;
1144
0
    }
1145
0
#endif
1146
0
    if (net->src_addr_selected) {
1147
0
      sctp_free_ifa(net->ro._s_addr);
1148
0
      net->ro._s_addr = NULL;
1149
0
      net->src_addr_selected = 0;
1150
0
    }
1151
    /* Check if the nexthop is corresponding to the new address.
1152
       If the new address is corresponding to the current nexthop,
1153
       the path will be changed.
1154
       If the new address is NOT corresponding to the current
1155
       nexthop, the path will not be changed.
1156
     */
1157
0
    SCTP_RTALLOC((sctp_route_t *)&net->ro,
1158
0
           stcb->sctp_ep->def_vrf_id,
1159
0
           stcb->sctp_ep->fibnum);
1160
#if defined(__FreeBSD__) && !defined(__Userspace__)
1161
    if (net->ro.ro_nh == NULL)
1162
#else
1163
0
    if (net->ro.ro_rt == NULL)
1164
0
#endif
1165
0
      continue;
1166
1167
0
    changed = 0;
1168
0
    switch (net->ro._l_addr.sa.sa_family) {
1169
0
#ifdef INET
1170
0
    case AF_INET:
1171
0
      if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *)&net->ro)) {
1172
0
        changed = 1;
1173
0
      }
1174
0
      break;
1175
0
#endif
1176
0
#ifdef INET6
1177
0
    case AF_INET6:
1178
0
      if (sctp_v6src_match_nexthop(
1179
0
          &newifa->address.sin6, (sctp_route_t *)&net->ro)) {
1180
0
        changed = 1;
1181
0
      }
1182
0
      break;
1183
0
#endif
1184
0
    default:
1185
0
      break;
1186
0
    }
1187
    /* if the newly added address does not relate routing
1188
       information, we skip.
1189
     */
1190
0
    if (changed == 0)
1191
0
      continue;
1192
    /* Retransmit unacknowledged DATA chunks immediately */
1193
0
    if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1194
0
                                    SCTP_MOBILITY_FASTHANDOFF)) {
1195
0
      sctp_net_immediate_retrans(stcb, net);
1196
0
    }
1197
    /* Send SET PRIMARY for this new address */
1198
0
    if (net == stcb->asoc.primary_destination) {
1199
0
      (void)sctp_asconf_queue_mgmt(stcb, newifa,
1200
0
                 SCTP_SET_PRIM_ADDR);
1201
0
    }
1202
0
  }
1203
0
}
1204
#endif
1205
1206
/*
1207
 * process an ADD/DELETE IP ack from peer.
1208
 * addr: corresponding sctp_ifa to the address being added/deleted.
1209
 * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS.
1210
 * flag: 1=success, 0=failure.
1211
 */
1212
static void
1213
sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t flag)
1214
0
{
1215
  /*
1216
   * do the necessary asoc list work- if we get a failure indication,
1217
   * leave the address on the assoc's restricted list.  If we get a
1218
   * success indication, remove the address from the restricted list.
1219
   */
1220
  /*
1221
   * Note: this will only occur for ADD_IP_ADDRESS, since
1222
   * DEL_IP_ADDRESS is never actually added to the list...
1223
   */
1224
0
  if (flag) {
1225
    /* success case, so remove from the restricted list */
1226
0
    sctp_del_local_addr_restricted(stcb, addr);
1227
1228
0
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
1229
0
    if (sctp_is_mobility_feature_on(stcb->sctp_ep,
1230
0
                                    SCTP_MOBILITY_BASE) ||
1231
0
        sctp_is_mobility_feature_on(stcb->sctp_ep,
1232
0
                                    SCTP_MOBILITY_FASTHANDOFF)) {
1233
0
      sctp_path_check_and_react(stcb, addr);
1234
0
      return;
1235
0
    }
1236
0
#endif
1237
    /* clear any cached/topologically incorrect source addresses */
1238
0
    sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
1239
0
  }
1240
  /* else, leave it on the list */
1241
0
}
1242
1243
/*
1244
 * add an asconf add/delete/set primary IP address parameter to the queue.
1245
 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1246
 * returns 0 if queued, -1 if not queued/removed.
1247
 * NOTE: if adding, but a delete for the same address is already scheduled
1248
 * (and not yet sent out), simply remove it from queue.  Same for deleting
1249
 * an address already scheduled for add.  If a duplicate operation is found,
1250
 * ignore the new one.
1251
 */
1252
static int
1253
sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1254
           uint16_t type)
1255
0
{
1256
0
  struct sctp_asconf_addr *aa, *aa_next;
1257
1258
  /* make sure the request isn't already in the queue */
1259
0
  TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1260
    /* address match? */
1261
0
    if (sctp_asconf_addr_match(aa, &ifa->address.sa) == 0)
1262
0
      continue;
1263
    /* is the request already in queue but not sent?
1264
     * pass the request already sent in order to resolve the following case:
1265
     *  1. arrival of ADD, then sent
1266
     *  2. arrival of DEL. we can't remove the ADD request already sent
1267
     *  3. arrival of ADD
1268
     */
1269
0
    if (aa->ap.aph.ph.param_type == type && aa->sent == 0) {
1270
0
      return (-1);
1271
0
    }
1272
    /* is the negative request already in queue, and not sent */
1273
0
    if ((aa->sent == 0) && (type == SCTP_ADD_IP_ADDRESS) &&
1274
0
        (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS)) {
1275
      /* add requested, delete already queued */
1276
0
      TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1277
      /* remove the ifa from the restricted list */
1278
0
      sctp_del_local_addr_restricted(stcb, ifa);
1279
      /* free the asconf param */
1280
0
      SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1281
0
      SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: add removes queued entry\n");
1282
0
      return (-1);
1283
0
    }
1284
0
    if ((aa->sent == 0) && (type == SCTP_DEL_IP_ADDRESS) &&
1285
0
        (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS)) {
1286
      /* delete requested, add already queued */
1287
0
      TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1288
      /* remove the aa->ifa from the restricted list */
1289
0
      sctp_del_local_addr_restricted(stcb, aa->ifa);
1290
      /* free the asconf param */
1291
0
      SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1292
0
      SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: delete removes queued entry\n");
1293
0
      return (-1);
1294
0
    }
1295
0
  } /* for each aa */
1296
1297
  /* adding new request to the queue */
1298
0
  SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1299
0
        SCTP_M_ASC_ADDR);
1300
0
  if (aa == NULL) {
1301
    /* didn't get memory */
1302
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "asconf_queue_mgmt: failed to get memory!\n");
1303
0
    return (-1);
1304
0
  }
1305
0
  aa->special_del = 0;
1306
  /* fill in asconf address parameter fields */
1307
  /* top level elements are "networked" during send */
1308
0
  aa->ap.aph.ph.param_type = type;
1309
0
  aa->ifa = ifa;
1310
0
  atomic_add_int(&ifa->refcount, 1);
1311
  /* correlation_id filled in during send routine later... */
1312
0
  switch (ifa->address.sa.sa_family) {
1313
0
#ifdef INET6
1314
0
  case AF_INET6:
1315
0
  {
1316
0
    struct sockaddr_in6 *sin6;
1317
1318
0
    sin6 = &ifa->address.sin6;
1319
0
    aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1320
0
    aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1321
0
    aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1322
0
        sizeof(struct sctp_ipv6addr_param);
1323
0
    memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1324
0
           sizeof(struct in6_addr));
1325
0
    break;
1326
0
  }
1327
0
#endif
1328
0
#ifdef INET
1329
0
  case AF_INET:
1330
0
  {
1331
0
    struct sockaddr_in *sin;
1332
1333
0
    sin = &ifa->address.sin;
1334
0
    aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1335
0
    aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1336
0
    aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
1337
0
        sizeof(struct sctp_ipv4addr_param);
1338
0
    memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1339
0
           sizeof(struct in_addr));
1340
0
    break;
1341
0
  }
1342
0
#endif
1343
0
  default:
1344
    /* invalid family! */
1345
0
    SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1346
0
    sctp_free_ifa(ifa);
1347
0
    return (-1);
1348
0
  }
1349
0
  aa->sent = 0;   /* clear sent flag */
1350
1351
0
  TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1352
#ifdef SCTP_DEBUG
1353
  if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
1354
    if (type == SCTP_ADD_IP_ADDRESS) {
1355
      SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
1356
      SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1357
    } else if (type == SCTP_DEL_IP_ADDRESS) {
1358
      SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
1359
      SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1360
    } else {
1361
      SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
1362
      SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
1363
    }
1364
  }
1365
#endif
1366
1367
0
  return (0);
1368
0
}
1369
1370
/*
1371
 * add an asconf operation for the given ifa and type.
1372
 * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
1373
 * returns 0 if completed, -1 if not completed, 1 if immediate send is
1374
 * advisable.
1375
 */
1376
static int
1377
sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
1378
          uint16_t type)
1379
0
{
1380
0
  uint32_t status;
1381
0
  int pending_delete_queued = 0;
1382
0
  int last;
1383
1384
  /* see if peer supports ASCONF */
1385
0
  if (stcb->asoc.asconf_supported == 0) {
1386
0
    return (-1);
1387
0
  }
1388
1389
  /*
1390
   * if this is deleting the last address from the assoc, mark it as
1391
   * pending.
1392
   */
1393
0
  if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
1394
0
    if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1395
0
      last = (sctp_local_addr_count(stcb) == 0);
1396
0
    } else {
1397
0
      last = (sctp_local_addr_count(stcb) == 1);
1398
0
    }
1399
0
    if (last) {
1400
      /* set the pending delete info only */
1401
0
      stcb->asoc.asconf_del_pending = 1;
1402
0
      stcb->asoc.asconf_addr_del_pending = ifa;
1403
0
      atomic_add_int(&ifa->refcount, 1);
1404
0
      SCTPDBG(SCTP_DEBUG_ASCONF2,
1405
0
        "asconf_queue_add: mark delete last address pending\n");
1406
0
      return (-1);
1407
0
    }
1408
0
  }
1409
1410
  /* queue an asconf parameter */
1411
0
  status = sctp_asconf_queue_mgmt(stcb, ifa, type);
1412
1413
  /*
1414
   * if this is an add, and there is a delete also pending (i.e. the
1415
   * last local address is being changed), queue the pending delete too.
1416
   */
1417
0
  if ((type == SCTP_ADD_IP_ADDRESS) && stcb->asoc.asconf_del_pending && (status == 0)) {
1418
    /* queue in the pending delete */
1419
0
    if (sctp_asconf_queue_mgmt(stcb,
1420
0
             stcb->asoc.asconf_addr_del_pending,
1421
0
             SCTP_DEL_IP_ADDRESS) == 0) {
1422
0
      SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_add: queuing pending delete\n");
1423
0
      pending_delete_queued = 1;
1424
      /* clear out the pending delete info */
1425
0
      stcb->asoc.asconf_del_pending = 0;
1426
0
      sctp_free_ifa(stcb->asoc.asconf_addr_del_pending);
1427
0
      stcb->asoc.asconf_addr_del_pending = NULL;
1428
0
    }
1429
0
  }
1430
1431
0
  if (pending_delete_queued) {
1432
0
    struct sctp_nets *net;
1433
    /*
1434
     * since we know that the only/last address is now being
1435
     * changed in this case, reset the cwnd/rto on all nets to
1436
     * start as a new address and path.  Also clear the error
1437
     * counts to give the assoc the best chance to complete the
1438
     * address change.
1439
     */
1440
0
    TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1441
0
      stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb,
1442
0
                    net);
1443
0
      net->RTO = 0;
1444
0
      net->error_count = 0;
1445
0
    }
1446
0
    stcb->asoc.overall_error_count = 0;
1447
0
    if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
1448
0
      sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
1449
0
               stcb->asoc.overall_error_count,
1450
0
               0,
1451
0
               SCTP_FROM_SCTP_ASCONF,
1452
0
               __LINE__);
1453
0
    }
1454
1455
    /* queue in an advisory set primary too */
1456
0
    (void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
1457
    /* let caller know we should send this out immediately */
1458
0
    status = 1;
1459
0
  }
1460
0
  return (status);
1461
0
}
1462
1463
/*-
1464
 * add an asconf delete IP address parameter to the queue by sockaddr and
1465
 * possibly with no sctp_ifa available.  This is only called by the routine
1466
 * that checks the addresses in an INIT-ACK against the current address list.
1467
 * returns 0 if completed, non-zero if not completed.
1468
 * NOTE: if an add is already scheduled (and not yet sent out), simply
1469
 * remove it from queue.  If a duplicate operation is found, ignore the
1470
 * new one.
1471
 */
1472
static int
1473
sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
1474
0
{
1475
0
  struct sctp_ifa *ifa;
1476
0
  struct sctp_asconf_addr *aa, *aa_next;
1477
1478
0
  if (stcb == NULL) {
1479
0
    return (-1);
1480
0
  }
1481
  /* see if peer supports ASCONF */
1482
0
  if (stcb->asoc.asconf_supported == 0) {
1483
0
    return (-1);
1484
0
  }
1485
  /* make sure the request isn't already in the queue */
1486
0
  TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1487
    /* address match? */
1488
0
    if (sctp_asconf_addr_match(aa, sa) == 0)
1489
0
      continue;
1490
    /* is the request already in queue (sent or not) */
1491
0
    if (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
1492
0
      return (-1);
1493
0
    }
1494
    /* is the negative request already in queue, and not sent */
1495
0
    if (aa->sent == 1)
1496
0
      continue;
1497
0
    if (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
1498
      /* add already queued, so remove existing entry */
1499
0
      TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
1500
0
      sctp_del_local_addr_restricted(stcb, aa->ifa);
1501
      /* free the entry */
1502
0
      SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1503
0
      return (-1);
1504
0
    }
1505
0
  } /* for each aa */
1506
1507
  /* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
1508
0
  ifa = sctp_find_ifa_by_addr(sa, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
1509
1510
  /* adding new request to the queue */
1511
0
  SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
1512
0
        SCTP_M_ASC_ADDR);
1513
0
  if (aa == NULL) {
1514
    /* didn't get memory */
1515
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
1516
0
      "sctp_asconf_queue_sa_delete: failed to get memory!\n");
1517
0
    return (-1);
1518
0
  }
1519
0
  aa->special_del = 0;
1520
  /* fill in asconf address parameter fields */
1521
  /* top level elements are "networked" during send */
1522
0
  aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
1523
0
  aa->ifa = ifa;
1524
0
  if (ifa)
1525
0
    atomic_add_int(&ifa->refcount, 1);
1526
  /* correlation_id filled in during send routine later... */
1527
0
  switch (sa->sa_family) {
1528
0
#ifdef INET6
1529
0
  case AF_INET6:
1530
0
  {
1531
    /* IPv6 address */
1532
0
    struct sockaddr_in6 *sin6;
1533
1534
0
    sin6 = (struct sockaddr_in6 *)sa;
1535
0
    aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
1536
0
    aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
1537
0
    aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
1538
0
    memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
1539
0
        sizeof(struct in6_addr));
1540
0
    break;
1541
0
  }
1542
0
#endif
1543
0
#ifdef INET
1544
0
  case AF_INET:
1545
0
  {
1546
    /* IPv4 address */
1547
0
    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
1548
1549
0
    aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
1550
0
    aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
1551
0
    aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
1552
0
    memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
1553
0
        sizeof(struct in_addr));
1554
0
    break;
1555
0
  }
1556
0
#endif
1557
0
  default:
1558
    /* invalid family! */
1559
0
    SCTP_FREE(aa, SCTP_M_ASC_ADDR);
1560
0
    if (ifa)
1561
0
      sctp_free_ifa(ifa);
1562
0
    return (-1);
1563
0
  }
1564
0
  aa->sent = 0;   /* clear sent flag */
1565
1566
  /* delete goes to the back of the queue */
1567
0
  TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
1568
1569
  /* sa_ignore MEMLEAK {memory is put on the tailq} */
1570
0
  return (0);
1571
0
}
1572
1573
/*
1574
 * find a specific asconf param on our "sent" queue
1575
 */
1576
static struct sctp_asconf_addr *
1577
sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
1578
0
{
1579
0
  struct sctp_asconf_addr *aa;
1580
1581
0
  TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
1582
0
    if (aa->ap.aph.correlation_id == correlation_id &&
1583
0
        aa->sent == 1) {
1584
      /* found it */
1585
0
      return (aa);
1586
0
    }
1587
0
  }
1588
  /* didn't find it */
1589
0
  return (NULL);
1590
0
}
1591
1592
/*
1593
 * process an SCTP_ERROR_CAUSE_IND for a ASCONF-ACK parameter and do
1594
 * notifications based on the error response
1595
 */
1596
static void
1597
sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
1598
        struct sctp_asconf_paramhdr *aph)
1599
0
{
1600
0
  struct sctp_error_cause *eh;
1601
0
  struct sctp_paramhdr *ph;
1602
0
  uint16_t param_type;
1603
0
  uint16_t error_code;
1604
1605
0
  eh = (struct sctp_error_cause *)(aph + 1);
1606
0
  ph = (struct sctp_paramhdr *)(eh + 1);
1607
  /* validate lengths */
1608
0
  if (htons(eh->length) + sizeof(struct sctp_error_cause) >
1609
0
      htons(aph->ph.param_length)) {
1610
    /* invalid error cause length */
1611
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
1612
0
      "asconf_process_error: cause element too long\n");
1613
0
    return;
1614
0
  }
1615
0
  if (htons(ph->param_length) + sizeof(struct sctp_paramhdr) >
1616
0
      htons(eh->length)) {
1617
    /* invalid included TLV length */
1618
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
1619
0
      "asconf_process_error: included TLV too long\n");
1620
0
    return;
1621
0
  }
1622
  /* which error code ? */
1623
0
  error_code = ntohs(eh->code);
1624
0
  param_type = ntohs(aph->ph.param_type);
1625
  /* FIX: this should go back up the REMOTE_ERROR ULP notify */
1626
0
  switch (error_code) {
1627
0
  case SCTP_CAUSE_RESOURCE_SHORTAGE:
1628
    /* we allow ourselves to "try again" for this error */
1629
0
    break;
1630
0
  default:
1631
    /* peer can't handle it... */
1632
0
    switch (param_type) {
1633
0
    case SCTP_ADD_IP_ADDRESS:
1634
0
    case SCTP_DEL_IP_ADDRESS:
1635
0
    case SCTP_SET_PRIM_ADDR:
1636
0
      break;
1637
0
    default:
1638
0
      break;
1639
0
    }
1640
0
  }
1641
0
}
1642
1643
/*
1644
 * process an asconf queue param.
1645
 * aparam: parameter to process, will be removed from the queue.
1646
 * flag: 1=success case, 0=failure case
1647
 */
1648
static void
1649
sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
1650
            struct sctp_asconf_addr *aparam, uint32_t flag)
1651
0
{
1652
0
  uint16_t param_type;
1653
1654
  /* process this param */
1655
0
  param_type = aparam->ap.aph.ph.param_type;
1656
0
  switch (param_type) {
1657
0
  case SCTP_ADD_IP_ADDRESS:
1658
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
1659
0
      "process_param_ack: added IP address\n");
1660
0
    sctp_asconf_addr_mgmt_ack(stcb, aparam->ifa, flag);
1661
0
    break;
1662
0
  case SCTP_DEL_IP_ADDRESS:
1663
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
1664
0
      "process_param_ack: deleted IP address\n");
1665
    /* nothing really to do... lists already updated */
1666
0
    break;
1667
0
  case SCTP_SET_PRIM_ADDR:
1668
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
1669
0
      "process_param_ack: set primary IP address\n");
1670
    /* nothing to do... peer may start using this addr */
1671
0
    break;
1672
0
  default:
1673
    /* should NEVER happen */
1674
0
    break;
1675
0
  }
1676
1677
  /* remove the param and free it */
1678
0
  TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
1679
0
  if (aparam->ifa)
1680
0
    sctp_free_ifa(aparam->ifa);
1681
0
  SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
1682
0
}
1683
1684
/*
1685
 * cleanup from a bad asconf ack parameter
1686
 */
1687
static void
1688
sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
1689
0
{
1690
  /* assume peer doesn't really know how to do asconfs */
1691
  /* XXX we could free the pending queue here */
1692
1693
0
}
1694
1695
void
1696
sctp_handle_asconf_ack(struct mbuf *m, int offset,
1697
           struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb,
1698
           struct sctp_nets *net, int *abort_no_unlock)
1699
349
{
1700
349
  struct sctp_association *asoc;
1701
349
  uint32_t serial_num;
1702
349
  uint16_t ack_length;
1703
349
  struct sctp_asconf_paramhdr *aph;
1704
349
  struct sctp_asconf_addr *aa, *aa_next;
1705
349
  uint32_t last_error_id = 0; /* last error correlation id */
1706
349
  uint32_t id;
1707
349
  struct sctp_asconf_addr *ap;
1708
1709
  /* asconf param buffer */
1710
349
  uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
1711
1712
  /* verify minimum length */
1713
349
  if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_ack_chunk)) {
1714
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
1715
0
      "handle_asconf_ack: chunk too small = %xh\n",
1716
0
      ntohs(cp->ch.chunk_length));
1717
0
    return;
1718
0
  }
1719
349
  asoc = &stcb->asoc;
1720
349
  serial_num = ntohl(cp->serial_number);
1721
1722
  /*
1723
   * NOTE: we may want to handle this differently- currently, we will
1724
   * abort when we get an ack for the expected serial number + 1 (eg.
1725
   * we didn't send it), process an ack normally if it is the expected
1726
   * serial number, and re-send the previous ack for *ALL* other
1727
   * serial numbers
1728
   */
1729
1730
  /*
1731
   * if the serial number is the next expected, but I didn't send it,
1732
   * abort the asoc, since someone probably just hijacked us...
1733
   */
1734
349
  if (serial_num == (asoc->asconf_seq_out + 1)) {
1735
0
    struct mbuf *op_err;
1736
0
    char msg[SCTP_DIAG_INFO_LEN];
1737
1738
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
1739
0
    SCTP_SNPRINTF(msg, sizeof(msg), "Never sent serial number %8.8x", serial_num);
1740
0
    op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
1741
0
    sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED);
1742
0
    *abort_no_unlock = 1;
1743
0
    return;
1744
0
  }
1745
349
  if (serial_num != asoc->asconf_seq_out_acked + 1) {
1746
    /* got a duplicate/unexpected ASCONF-ACK */
1747
349
    SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
1748
349
      serial_num, asoc->asconf_seq_out_acked + 1);
1749
349
    return;
1750
349
  }
1751
1752
0
  if (serial_num == asoc->asconf_seq_out - 1) {
1753
    /* stop our timer */
1754
0
    sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, NULL,
1755
0
        SCTP_FROM_SCTP_ASCONF + SCTP_LOC_5);
1756
0
  }
1757
1758
  /* process the ASCONF-ACK contents */
1759
0
  ack_length = ntohs(cp->ch.chunk_length) -
1760
0
      sizeof(struct sctp_asconf_ack_chunk);
1761
0
  offset += sizeof(struct sctp_asconf_ack_chunk);
1762
  /* process through all parameters */
1763
0
  while (ack_length >= sizeof(struct sctp_asconf_paramhdr)) {
1764
0
    unsigned int param_length, param_type;
1765
1766
    /* get pointer to next asconf parameter */
1767
0
    aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
1768
0
        sizeof(struct sctp_asconf_paramhdr), aparam_buf);
1769
0
    if (aph == NULL) {
1770
      /* can't get an asconf paramhdr */
1771
0
      sctp_asconf_ack_clear(stcb);
1772
0
      return;
1773
0
    }
1774
0
    param_type = ntohs(aph->ph.param_type);
1775
0
    param_length = ntohs(aph->ph.param_length);
1776
0
    if (param_length > ack_length) {
1777
0
      sctp_asconf_ack_clear(stcb);
1778
0
      return;
1779
0
    }
1780
0
    if (param_length < sizeof(struct sctp_asconf_paramhdr)) {
1781
0
      sctp_asconf_ack_clear(stcb);
1782
0
      return;
1783
0
    }
1784
    /* get the complete parameter... */
1785
0
    if (param_length > sizeof(aparam_buf)) {
1786
0
      SCTPDBG(SCTP_DEBUG_ASCONF1,
1787
0
        "param length (%u) larger than buffer size!\n", param_length);
1788
0
      sctp_asconf_ack_clear(stcb);
1789
0
      return;
1790
0
    }
1791
0
    aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
1792
0
    if (aph == NULL) {
1793
0
      sctp_asconf_ack_clear(stcb);
1794
0
      return;
1795
0
    }
1796
    /* correlation_id is transparent to peer, no ntohl needed */
1797
0
    id = aph->correlation_id;
1798
1799
0
    switch (param_type) {
1800
0
    case SCTP_ERROR_CAUSE_IND:
1801
0
      last_error_id = id;
1802
      /* find the corresponding asconf param in our queue */
1803
0
      ap = sctp_asconf_find_param(stcb, id);
1804
0
      if (ap == NULL) {
1805
        /* hmm... can't find this in our queue! */
1806
0
        break;
1807
0
      }
1808
      /* process the parameter, failed flag */
1809
0
      sctp_asconf_process_param_ack(stcb, ap, 0);
1810
      /* process the error response */
1811
0
      sctp_asconf_process_error(stcb, aph);
1812
0
      break;
1813
0
    case SCTP_SUCCESS_REPORT:
1814
      /* find the corresponding asconf param in our queue */
1815
0
      ap = sctp_asconf_find_param(stcb, id);
1816
0
      if (ap == NULL) {
1817
        /* hmm... can't find this in our queue! */
1818
0
        break;
1819
0
      }
1820
      /* process the parameter, success flag */
1821
0
      sctp_asconf_process_param_ack(stcb, ap, 1);
1822
0
      break;
1823
0
    default:
1824
0
      break;
1825
0
    }   /* switch */
1826
1827
    /* update remaining ASCONF-ACK message length to process */
1828
0
    if (ack_length > SCTP_SIZE32(param_length)) {
1829
0
      ack_length -= SCTP_SIZE32(param_length);
1830
0
    } else {
1831
0
      break;
1832
0
    }
1833
0
    offset += SCTP_SIZE32(param_length);
1834
0
  } /* while */
1835
1836
  /*
1837
   * if there are any "sent" params still on the queue, these are
1838
   * implicitly "success", or "failed" (if we got an error back) ...
1839
   * so process these appropriately
1840
   *
1841
   * we assume that the correlation_id's are monotonically increasing
1842
   * beginning from 1 and that we don't have *that* many outstanding
1843
   * at any given time
1844
   */
1845
0
  if (last_error_id == 0)
1846
0
    last_error_id--; /* set to "max" value */
1847
0
  TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
1848
0
    if (aa->sent == 1) {
1849
      /*
1850
       * implicitly successful or failed if correlation_id
1851
       * < last_error_id, then success else, failure
1852
       */
1853
0
      if (aa->ap.aph.correlation_id < last_error_id)
1854
0
        sctp_asconf_process_param_ack(stcb, aa, 1);
1855
0
      else
1856
0
        sctp_asconf_process_param_ack(stcb, aa, 0);
1857
0
    } else {
1858
      /*
1859
       * since we always process in order (FIFO queue) if
1860
       * we reach one that hasn't been sent, the rest
1861
       * should not have been sent either. so, we're
1862
       * done...
1863
       */
1864
0
      break;
1865
0
    }
1866
0
  }
1867
1868
  /* update the next sequence number to use */
1869
0
  asoc->asconf_seq_out_acked++;
1870
  /* remove the old ASCONF on our outbound queue */
1871
0
  sctp_toss_old_asconf(stcb);
1872
0
  if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
1873
#ifdef SCTP_TIMER_BASED_ASCONF
1874
    /* we have more params, so restart our timer */
1875
    sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
1876
         stcb, net);
1877
#else
1878
    /* we have more params, so send out more */
1879
0
    sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
1880
0
#endif
1881
0
  }
1882
0
}
1883
1884
#ifdef INET6
1885
static uint32_t
1886
sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
1887
0
{
1888
0
  struct sockaddr_in6 *sin6, *net6;
1889
0
  struct sctp_nets *net;
1890
1891
0
  if (sa->sa_family != AF_INET6) {
1892
    /* wrong family */
1893
0
    return (0);
1894
0
  }
1895
0
  sin6 = (struct sockaddr_in6 *)sa;
1896
0
  if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) == 0) {
1897
    /* not link local address */
1898
0
    return (0);
1899
0
  }
1900
  /* hunt through our destination nets list for this scope_id */
1901
0
  TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1902
0
    if (((struct sockaddr *)(&net->ro._l_addr))->sa_family !=
1903
0
        AF_INET6)
1904
0
      continue;
1905
0
    net6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1906
0
    if (IN6_IS_ADDR_LINKLOCAL(&net6->sin6_addr) == 0)
1907
0
      continue;
1908
0
    if (sctp_is_same_scope(sin6, net6)) {
1909
      /* found one */
1910
0
      return (1);
1911
0
    }
1912
0
  }
1913
  /* didn't find one */
1914
0
  return (0);
1915
0
}
1916
#endif
1917
1918
/*
1919
 * address management functions
1920
 */
1921
static void
1922
sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
1923
         struct sctp_ifa *ifa, uint16_t type, int addr_locked)
1924
0
{
1925
0
  int status;
1926
1927
0
  if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 ||
1928
0
      sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
1929
    /* subset bound, no ASCONF allowed case, so ignore */
1930
0
    return;
1931
0
  }
1932
  /*
1933
   * note: we know this is not the subset bound, no ASCONF case eg.
1934
   * this is boundall or subset bound w/ASCONF allowed
1935
   */
1936
1937
  /* first, make sure that the address is IPv4 or IPv6 and not jailed */
1938
0
  switch (ifa->address.sa.sa_family) {
1939
0
#ifdef INET6
1940
0
  case AF_INET6:
1941
#if defined(__FreeBSD__) && !defined(__Userspace__)
1942
    if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
1943
                         &ifa->address.sin6.sin6_addr) != 0) {
1944
      return;
1945
    }
1946
#endif
1947
0
    break;
1948
0
#endif
1949
0
#ifdef INET
1950
0
  case AF_INET:
1951
#if defined(__FreeBSD__) && !defined(__Userspace__)
1952
    if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
1953
                         &ifa->address.sin.sin_addr) != 0) {
1954
      return;
1955
    }
1956
#endif
1957
0
    break;
1958
0
#endif
1959
0
  default:
1960
0
    return;
1961
0
  }
1962
0
#ifdef INET6
1963
  /* make sure we're "allowed" to add this type of addr */
1964
0
  if (ifa->address.sa.sa_family == AF_INET6) {
1965
    /* invalid if we're not a v6 endpoint */
1966
0
    if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)
1967
0
      return;
1968
    /* is the v6 addr really valid ? */
1969
0
    if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1970
0
      return;
1971
0
    }
1972
0
  }
1973
0
#endif
1974
  /* put this address on the "pending/do not use yet" list */
1975
0
  sctp_add_local_addr_restricted(stcb, ifa);
1976
  /*
1977
   * check address scope if address is out of scope, don't queue
1978
   * anything... note: this would leave the address on both inp and
1979
   * asoc lists
1980
   */
1981
0
  switch (ifa->address.sa.sa_family) {
1982
0
#ifdef INET6
1983
0
  case AF_INET6:
1984
0
  {
1985
0
    struct sockaddr_in6 *sin6;
1986
1987
0
    sin6 = &ifa->address.sin6;
1988
0
    if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1989
      /* we skip unspecified addresses */
1990
0
      return;
1991
0
    }
1992
0
    if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
1993
0
      if (stcb->asoc.scope.local_scope == 0) {
1994
0
        return;
1995
0
      }
1996
      /* is it the right link local scope? */
1997
0
      if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
1998
0
        return;
1999
0
      }
2000
0
    }
2001
0
    if (stcb->asoc.scope.site_scope == 0 &&
2002
0
        IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
2003
0
      return;
2004
0
    }
2005
0
    break;
2006
0
  }
2007
0
#endif
2008
0
#ifdef INET
2009
0
  case AF_INET:
2010
0
  {
2011
0
    struct sockaddr_in *sin;
2012
2013
    /* invalid if we are a v6 only endpoint */
2014
0
    if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2015
0
        SCTP_IPV6_V6ONLY(inp))
2016
0
      return;
2017
2018
0
    sin = &ifa->address.sin;
2019
0
    if (sin->sin_addr.s_addr == 0) {
2020
      /* we skip unspecified addresses */
2021
0
      return;
2022
0
    }
2023
0
    if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2024
0
        IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2025
0
      return;
2026
0
    }
2027
0
    break;
2028
0
  }
2029
0
#endif
2030
0
  default:
2031
    /* else, not AF_INET or AF_INET6, so skip */
2032
0
    return;
2033
0
  }
2034
2035
  /* queue an asconf for this address add/delete */
2036
0
  if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
2037
    /* does the peer do asconf? */
2038
0
    if (stcb->asoc.asconf_supported) {
2039
      /* queue an asconf for this addr */
2040
0
      status = sctp_asconf_queue_add(stcb, ifa, type);
2041
2042
      /*
2043
       * if queued ok, and in the open state, send out the
2044
       * ASCONF.  If in the non-open state, these will be
2045
       * sent when the state goes open.
2046
       */
2047
0
      if (status == 0 &&
2048
0
          ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2049
0
           (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
2050
#ifdef SCTP_TIMER_BASED_ASCONF
2051
        sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
2052
            stcb, stcb->asoc.primary_destination);
2053
#else
2054
0
        sctp_send_asconf(stcb, NULL, addr_locked);
2055
0
#endif
2056
0
      }
2057
0
    }
2058
0
  }
2059
0
}
2060
2061
int
2062
sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2063
0
{
2064
0
  struct sctp_asconf_iterator *asc;
2065
0
  struct sctp_ifa *ifa;
2066
0
  struct sctp_laddr *l;
2067
0
  int cnt_invalid = 0;
2068
2069
0
  asc = (struct sctp_asconf_iterator *)ptr;
2070
0
  LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2071
0
    ifa = l->ifa;
2072
0
    switch (ifa->address.sa.sa_family) {
2073
0
#ifdef INET6
2074
0
    case AF_INET6:
2075
      /* invalid if we're not a v6 endpoint */
2076
0
      if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2077
0
        cnt_invalid++;
2078
0
        if (asc->cnt == cnt_invalid)
2079
0
          return (1);
2080
0
      }
2081
0
      break;
2082
0
#endif
2083
0
#ifdef INET
2084
0
    case AF_INET:
2085
0
    {
2086
      /* invalid if we are a v6 only endpoint */
2087
0
      if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2088
0
          SCTP_IPV6_V6ONLY(inp)) {
2089
0
        cnt_invalid++;
2090
0
        if (asc->cnt == cnt_invalid)
2091
0
          return (1);
2092
0
      }
2093
0
      break;
2094
0
    }
2095
0
#endif
2096
0
    default:
2097
      /* invalid address family */
2098
0
      cnt_invalid++;
2099
0
      if (asc->cnt == cnt_invalid)
2100
0
        return (1);
2101
0
    }
2102
0
  }
2103
0
  return (0);
2104
0
}
2105
2106
static int
2107
sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
2108
0
{
2109
0
  struct sctp_ifa *ifa;
2110
0
  struct sctp_asconf_iterator *asc;
2111
0
  struct sctp_laddr *laddr, *nladdr, *l;
2112
2113
  /* Only for specific case not bound all */
2114
0
  asc = (struct sctp_asconf_iterator *)ptr;
2115
0
  LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2116
0
    ifa = l->ifa;
2117
0
    if (l->action == SCTP_ADD_IP_ADDRESS) {
2118
0
      LIST_FOREACH(laddr, &inp->sctp_addr_list,
2119
0
             sctp_nxt_addr) {
2120
0
        if (laddr->ifa == ifa) {
2121
0
          laddr->action = 0;
2122
0
          break;
2123
0
        }
2124
0
      }
2125
0
    } else if (l->action == SCTP_DEL_IP_ADDRESS) {
2126
0
      LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
2127
        /* remove only after all guys are done */
2128
0
        if (laddr->ifa == ifa) {
2129
0
          sctp_del_local_addr_ep(inp, ifa);
2130
0
        }
2131
0
      }
2132
0
    }
2133
0
  }
2134
0
  return (0);
2135
0
}
2136
2137
void
2138
sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
2139
        void *ptr, uint32_t val SCTP_UNUSED)
2140
0
{
2141
0
  struct sctp_asconf_iterator *asc;
2142
0
  struct sctp_ifa *ifa;
2143
0
  struct sctp_laddr *l;
2144
0
  int cnt_invalid = 0;
2145
0
  int type, status;
2146
0
  int num_queued = 0;
2147
2148
0
  asc = (struct sctp_asconf_iterator *)ptr;
2149
0
  LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
2150
0
    ifa = l->ifa;
2151
0
    type = l->action;
2152
2153
    /* address's vrf_id must be the vrf_id of the assoc */
2154
0
    if (ifa->vrf_id != stcb->asoc.vrf_id) {
2155
0
      continue;
2156
0
    }
2157
2158
    /* Same checks again for assoc */
2159
0
    switch (ifa->address.sa.sa_family) {
2160
0
#ifdef INET6
2161
0
    case AF_INET6:
2162
0
    {
2163
      /* invalid if we're not a v6 endpoint */
2164
0
      struct sockaddr_in6 *sin6;
2165
2166
0
      if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
2167
0
        cnt_invalid++;
2168
0
        if (asc->cnt == cnt_invalid)
2169
0
          return;
2170
0
        else
2171
0
          continue;
2172
0
      }
2173
0
      sin6 = &ifa->address.sin6;
2174
0
      if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2175
        /* we skip unspecified addresses */
2176
0
        continue;
2177
0
      }
2178
#if defined(__FreeBSD__) && !defined(__Userspace__)
2179
      if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
2180
                           &sin6->sin6_addr) != 0) {
2181
        continue;
2182
      }
2183
#endif
2184
0
      if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2185
0
        if (stcb->asoc.scope.local_scope == 0) {
2186
0
          continue;
2187
0
        }
2188
        /* is it the right link local scope? */
2189
0
        if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
2190
0
          continue;
2191
0
        }
2192
0
      }
2193
0
      break;
2194
0
    }
2195
0
#endif
2196
0
#ifdef INET
2197
0
    case AF_INET:
2198
0
    {
2199
      /* invalid if we are a v6 only endpoint */
2200
0
      struct sockaddr_in *sin;
2201
2202
      /* invalid if we are a v6 only endpoint */
2203
0
      if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2204
0
          SCTP_IPV6_V6ONLY(inp))
2205
0
        continue;
2206
2207
0
      sin = &ifa->address.sin;
2208
0
      if (sin->sin_addr.s_addr == 0) {
2209
        /* we skip unspecified addresses */
2210
0
        continue;
2211
0
      }
2212
#if defined(__FreeBSD__) && !defined(__Userspace__)
2213
      if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
2214
                           &sin->sin_addr) != 0) {
2215
        continue;
2216
      }
2217
#endif
2218
0
      if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2219
0
          IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
2220
0
        continue;
2221
0
      }
2222
0
      if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
2223
0
          SCTP_IPV6_V6ONLY(inp)) {
2224
0
        cnt_invalid++;
2225
0
        if (asc->cnt == cnt_invalid)
2226
0
          return;
2227
0
        else
2228
0
          continue;
2229
0
      }
2230
0
      break;
2231
0
    }
2232
0
#endif
2233
0
    default:
2234
      /* invalid address family */
2235
0
      cnt_invalid++;
2236
0
      if (asc->cnt == cnt_invalid)
2237
0
        return;
2238
0
      else
2239
0
        continue;
2240
0
    }
2241
2242
0
    if (type == SCTP_ADD_IP_ADDRESS) {
2243
      /* prevent this address from being used as a source */
2244
0
      sctp_add_local_addr_restricted(stcb, ifa);
2245
0
    } else if (type == SCTP_DEL_IP_ADDRESS) {
2246
0
      struct sctp_nets *net;
2247
0
      TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
2248
        /* delete this address if cached */
2249
0
        if (net->ro._s_addr == ifa) {
2250
0
          sctp_free_ifa(net->ro._s_addr);
2251
0
          net->ro._s_addr = NULL;
2252
0
          net->src_addr_selected = 0;
2253
#if defined(__FreeBSD__) && !defined(__Userspace__)
2254
          RO_NHFREE(&net->ro);
2255
#else
2256
0
          if (net->ro.ro_rt) {
2257
0
            RTFREE(net->ro.ro_rt);
2258
0
            net->ro.ro_rt = NULL;
2259
0
          }
2260
0
#endif
2261
          /*
2262
           * Now we deleted our src address,
2263
           * should we not also now reset the
2264
           * cwnd/rto to start as if its a new
2265
           * address?
2266
           */
2267
0
          stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
2268
0
          net->RTO = 0;
2269
0
        }
2270
0
      }
2271
0
    } else if (type == SCTP_SET_PRIM_ADDR) {
2272
0
      if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
2273
        /* must validate the ifa is in the ep */
2274
0
        if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
2275
0
          continue;
2276
0
        }
2277
0
      } else {
2278
        /* Need to check scopes for this guy */
2279
0
        if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
2280
0
          continue;
2281
0
        }
2282
0
      }
2283
0
    }
2284
    /* queue an asconf for this address add/delete */
2285
0
    if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
2286
0
        stcb->asoc.asconf_supported == 1) {
2287
      /* queue an asconf for this addr */
2288
0
      status = sctp_asconf_queue_add(stcb, ifa, type);
2289
      /*
2290
       * if queued ok, and in the open state, update the
2291
       * count of queued params.  If in the non-open state,
2292
       * these get sent when the assoc goes open.
2293
       */
2294
0
      if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2295
0
          (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2296
0
        if (status >= 0) {
2297
0
          num_queued++;
2298
0
        }
2299
0
      }
2300
0
    }
2301
0
  }
2302
  /*
2303
   * If we have queued params in the open state, send out an ASCONF.
2304
   */
2305
0
  if (num_queued > 0) {
2306
0
    sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2307
0
  }
2308
0
}
2309
2310
void
2311
sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
2312
0
{
2313
0
  struct sctp_asconf_iterator *asc;
2314
0
  struct sctp_ifa *ifa;
2315
0
  struct sctp_laddr *l, *nl;
2316
2317
0
  asc = (struct sctp_asconf_iterator *)ptr;
2318
0
  LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) {
2319
0
    ifa = l->ifa;
2320
0
    if (l->action == SCTP_ADD_IP_ADDRESS) {
2321
      /* Clear the defer use flag */
2322
0
      ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
2323
0
    }
2324
0
    sctp_free_ifa(ifa);
2325
0
    SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l);
2326
0
    SCTP_DECR_LADDR_COUNT();
2327
0
  }
2328
0
  SCTP_FREE(asc, SCTP_M_ASC_IT);
2329
0
}
2330
2331
/*
2332
 * sa is the sockaddr to ask the peer to set primary to.
2333
 * returns: 0 = completed, -1 = error
2334
 */
2335
int32_t
2336
sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
2337
0
{
2338
0
  uint32_t vrf_id;
2339
0
  struct sctp_ifa *ifa;
2340
2341
  /* find the ifa for the desired set primary */
2342
0
  vrf_id = stcb->asoc.vrf_id;
2343
0
  ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
2344
0
  if (ifa == NULL) {
2345
    /* Invalid address */
2346
0
    return (-1);
2347
0
  }
2348
2349
  /* queue an ASCONF:SET_PRIM_ADDR to be sent */
2350
0
  if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
2351
    /* set primary queuing succeeded */
2352
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
2353
0
      "set_primary_ip_address_sa: queued on tcb=%p, ",
2354
0
      (void *)stcb);
2355
0
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2356
0
    if ((SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) ||
2357
0
        (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
2358
#ifdef SCTP_TIMER_BASED_ASCONF
2359
      sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2360
           stcb->sctp_ep, stcb,
2361
           stcb->asoc.primary_destination);
2362
#else
2363
0
      sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2364
0
#endif
2365
0
    }
2366
0
  } else {
2367
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
2368
0
      (void *)stcb);
2369
0
    SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
2370
0
    return (-1);
2371
0
  }
2372
0
  return (0);
2373
0
}
2374
2375
int
2376
sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
2377
0
{
2378
0
  struct sctp_tmit_chunk *chk, *nchk;
2379
0
  unsigned int offset, asconf_limit;
2380
0
  struct sctp_asconf_chunk *acp;
2381
0
  struct sctp_asconf_paramhdr *aph;
2382
0
  uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
2383
0
  struct sctp_paramhdr *ph;
2384
0
  int add_cnt, del_cnt;
2385
0
  uint16_t last_param_type;
2386
2387
0
  add_cnt = del_cnt = 0;
2388
0
  last_param_type = 0;
2389
0
  TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) {
2390
0
    if (chk->data == NULL) {
2391
0
      SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n");
2392
0
      continue;
2393
0
    }
2394
0
    offset = 0;
2395
0
    acp = mtod(chk->data, struct sctp_asconf_chunk *);
2396
0
    offset += sizeof(struct sctp_asconf_chunk);
2397
0
    asconf_limit = ntohs(acp->ch.chunk_length);
2398
0
    ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
2399
0
    if (ph == NULL) {
2400
0
      SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
2401
0
      continue;
2402
0
    }
2403
0
    offset += ntohs(ph->param_length);
2404
2405
0
    aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2406
0
    if (aph == NULL) {
2407
0
      SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n");
2408
0
      continue;
2409
0
    }
2410
0
    while (aph != NULL) {
2411
0
      unsigned int param_length, param_type;
2412
2413
0
      param_type = ntohs(aph->ph.param_type);
2414
0
      param_length = ntohs(aph->ph.param_length);
2415
0
      if (offset + param_length > asconf_limit) {
2416
        /* parameter goes beyond end of chunk! */
2417
0
        break;
2418
0
      }
2419
0
      if (param_length > sizeof(aparam_buf)) {
2420
0
        SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length);
2421
0
        break;
2422
0
      }
2423
0
      if (param_length <= sizeof(struct sctp_paramhdr)) {
2424
0
        SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length);
2425
0
        break;
2426
0
      }
2427
2428
0
      aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf);
2429
0
      if (aph == NULL) {
2430
0
        SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
2431
0
        break;
2432
0
      }
2433
2434
0
      ph = (struct sctp_paramhdr *)(aph + 1);
2435
0
      if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
2436
0
        switch (param_type) {
2437
0
        case SCTP_ADD_IP_ADDRESS:
2438
0
          add_cnt++;
2439
0
          break;
2440
0
        case SCTP_DEL_IP_ADDRESS:
2441
0
          del_cnt++;
2442
0
          break;
2443
0
        default:
2444
0
          break;
2445
0
        }
2446
0
        last_param_type = param_type;
2447
0
      }
2448
2449
0
      offset += SCTP_SIZE32(param_length);
2450
0
      if (offset >= asconf_limit) {
2451
        /* no more data in the mbuf chain */
2452
0
        break;
2453
0
      }
2454
      /* get pointer to next asconf param */
2455
0
      aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
2456
0
    }
2457
0
  }
2458
2459
  /* we want to find the sequences which consist of ADD -> DEL -> ADD or DEL -> ADD */
2460
0
  if (add_cnt > del_cnt ||
2461
0
      (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
2462
0
    return (1);
2463
0
  }
2464
0
  return (0);
2465
0
}
2466
2467
static struct sockaddr *
2468
sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
2469
0
{
2470
0
  struct sctp_vrf *vrf = NULL;
2471
0
  struct sctp_ifn *sctp_ifn;
2472
0
  struct sctp_ifa *sctp_ifa;
2473
2474
0
  if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2475
0
    SCTP_IPI_ADDR_RLOCK();
2476
0
  vrf = sctp_find_vrf(stcb->asoc.vrf_id);
2477
0
  if (vrf == NULL) {
2478
0
    if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2479
0
      SCTP_IPI_ADDR_RUNLOCK();
2480
0
    return (NULL);
2481
0
  }
2482
0
  LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2483
0
    if (stcb->asoc.scope.loopback_scope == 0 &&
2484
0
        SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2485
      /* Skip if loopback_scope not set */
2486
0
      continue;
2487
0
    }
2488
0
    LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2489
0
      switch (sctp_ifa->address.sa.sa_family) {
2490
0
#ifdef INET
2491
0
      case AF_INET:
2492
0
        if (stcb->asoc.scope.ipv4_addr_legal) {
2493
0
          struct sockaddr_in *sin;
2494
2495
0
          sin = &sctp_ifa->address.sin;
2496
0
          if (sin->sin_addr.s_addr == 0) {
2497
            /* skip unspecified addresses */
2498
0
            continue;
2499
0
          }
2500
#if defined(__FreeBSD__) && !defined(__Userspace__)
2501
          if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
2502
                               &sin->sin_addr) != 0) {
2503
            continue;
2504
          }
2505
#endif
2506
0
          if (stcb->asoc.scope.ipv4_local_scope == 0 &&
2507
0
              IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
2508
0
            continue;
2509
2510
0
          if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2511
0
              (!sctp_is_addr_pending(stcb, sctp_ifa)))
2512
0
            continue;
2513
          /* found a valid local v4 address to use */
2514
0
          if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2515
0
            SCTP_IPI_ADDR_RUNLOCK();
2516
0
          return (&sctp_ifa->address.sa);
2517
0
        }
2518
0
        break;
2519
0
#endif
2520
0
#ifdef INET6
2521
0
      case AF_INET6:
2522
0
        if (stcb->asoc.scope.ipv6_addr_legal) {
2523
0
          struct sockaddr_in6 *sin6;
2524
2525
0
          if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2526
0
            continue;
2527
0
          }
2528
2529
0
          sin6 = &sctp_ifa->address.sin6;
2530
0
          if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2531
            /* we skip unspecified addresses */
2532
0
            continue;
2533
0
          }
2534
#if defined(__FreeBSD__) && !defined(__Userspace__)
2535
          if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
2536
                               &sin6->sin6_addr) != 0) {
2537
            continue;
2538
          }
2539
#endif
2540
0
          if (stcb->asoc.scope.local_scope == 0 &&
2541
0
              IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
2542
0
            continue;
2543
0
          if (stcb->asoc.scope.site_scope == 0 &&
2544
0
              IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
2545
0
            continue;
2546
2547
0
          if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
2548
0
              (!sctp_is_addr_pending(stcb, sctp_ifa)))
2549
0
            continue;
2550
          /* found a valid local v6 address to use */
2551
0
          if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2552
0
            SCTP_IPI_ADDR_RUNLOCK();
2553
0
          return (&sctp_ifa->address.sa);
2554
0
        }
2555
0
        break;
2556
0
#endif
2557
0
      default:
2558
0
        break;
2559
0
      }
2560
0
    }
2561
0
  }
2562
  /* no valid addresses found */
2563
0
  if (addr_locked == SCTP_ADDR_NOT_LOCKED)
2564
0
    SCTP_IPI_ADDR_RUNLOCK();
2565
0
  return (NULL);
2566
0
}
2567
2568
static struct sockaddr *
2569
sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
2570
0
{
2571
0
  struct sctp_laddr *laddr;
2572
2573
0
  LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
2574
0
    if (laddr->ifa == NULL) {
2575
0
      continue;
2576
0
    }
2577
    /* is the address restricted ? */
2578
0
    if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
2579
0
        (!sctp_is_addr_pending(stcb, laddr->ifa)))
2580
0
      continue;
2581
2582
    /* found a valid local address to use */
2583
0
    return (&laddr->ifa->address.sa);
2584
0
  }
2585
  /* no valid addresses found */
2586
0
  return (NULL);
2587
0
}
2588
2589
/*
2590
 * builds an ASCONF chunk from queued ASCONF params.
2591
 * returns NULL on error (no mbuf, no ASCONF params queued, etc).
2592
 */
2593
struct mbuf *
2594
sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
2595
0
{
2596
0
  struct mbuf *m_asconf, *m_asconf_chk;
2597
0
  struct sctp_asconf_addr *aa;
2598
0
  struct sctp_asconf_chunk *acp;
2599
0
  struct sctp_asconf_paramhdr *aph;
2600
0
  struct sctp_asconf_addr_param *aap;
2601
0
  uint32_t p_length, overhead;
2602
0
  uint32_t correlation_id = 1;  /* 0 is reserved... */
2603
0
  caddr_t ptr, lookup_ptr;
2604
0
  uint8_t lookup_used = 0;
2605
2606
  /* are there any asconf params to send? */
2607
0
  TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2608
0
    if (aa->sent == 0)
2609
0
      break;
2610
0
  }
2611
0
  if (aa == NULL)
2612
0
    return (NULL);
2613
2614
  /* Consider IP header and SCTP common header. */
2615
0
  if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
2616
0
    overhead = SCTP_MIN_OVERHEAD;
2617
0
  } else {
2618
0
    overhead = SCTP_MIN_V4_OVERHEAD;
2619
0
  }
2620
  /* Consider ASONF chunk. */
2621
0
  overhead += sizeof(struct sctp_asconf_chunk);
2622
  /* Consider AUTH chunk. */
2623
0
  overhead += sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
2624
0
  if (stcb->asoc.smallest_mtu <= overhead) {
2625
    /* MTU too small. */
2626
0
    return (NULL);
2627
0
  }
2628
  /*
2629
   * get a chunk header mbuf and a cluster for the asconf params since
2630
   * it's simpler to fill in the asconf chunk header lookup address on
2631
   * the fly
2632
   */
2633
0
  m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_NOWAIT, 1, MT_DATA);
2634
0
  if (m_asconf_chk == NULL) {
2635
    /* no mbuf's */
2636
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
2637
0
      "sctp_compose_asconf: couldn't get chunk mbuf!\n");
2638
0
    return (NULL);
2639
0
  }
2640
0
  m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
2641
0
  if (m_asconf == NULL) {
2642
    /* no mbuf's */
2643
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
2644
0
      "sctp_compose_asconf: couldn't get mbuf!\n");
2645
0
    sctp_m_freem(m_asconf_chk);
2646
0
    return (NULL);
2647
0
  }
2648
0
  SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
2649
0
  SCTP_BUF_LEN(m_asconf) = 0;
2650
0
  acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
2651
0
  memset(acp, 0, sizeof(struct sctp_asconf_chunk));
2652
  /* save pointers to lookup address and asconf params */
2653
0
  lookup_ptr = (caddr_t)(acp + 1);  /* after the header */
2654
0
  ptr = mtod(m_asconf, caddr_t);  /* beginning of cluster */
2655
2656
  /* fill in chunk header info */
2657
0
  acp->ch.chunk_type = SCTP_ASCONF;
2658
0
  acp->ch.chunk_flags = 0;
2659
0
  acp->serial_number = htonl(stcb->asoc.asconf_seq_out);
2660
0
  stcb->asoc.asconf_seq_out++;
2661
2662
  /* add parameters... up to smallest MTU allowed */
2663
0
  TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
2664
0
    if (aa->sent)
2665
0
      continue;
2666
    /* get the parameter length */
2667
0
    p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
2668
    /* will it fit in current chunk? */
2669
0
    if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu - overhead) ||
2670
0
        (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
2671
      /* won't fit, so we're done with this chunk */
2672
0
      break;
2673
0
    }
2674
    /* assign (and store) a correlation id */
2675
0
    aa->ap.aph.correlation_id = correlation_id++;
2676
2677
    /*
2678
     * fill in address if we're doing a delete this is a simple
2679
     * way for us to fill in the correlation address, which
2680
     * should only be used by the peer if we're deleting our
2681
     * source address and adding a new address (e.g. renumbering
2682
     * case)
2683
     */
2684
0
    if (lookup_used == 0 &&
2685
0
        (aa->special_del == 0) &&
2686
0
        aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
2687
0
      struct sctp_ipv6addr_param *lookup;
2688
0
      uint16_t p_size, addr_size;
2689
2690
0
      lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2691
0
      lookup->ph.param_type =
2692
0
          htons(aa->ap.addrp.ph.param_type);
2693
0
      if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) {
2694
        /* copy IPv6 address */
2695
0
        p_size = sizeof(struct sctp_ipv6addr_param);
2696
0
        addr_size = sizeof(struct in6_addr);
2697
0
      } else {
2698
        /* copy IPv4 address */
2699
0
        p_size = sizeof(struct sctp_ipv4addr_param);
2700
0
        addr_size = sizeof(struct in_addr);
2701
0
      }
2702
0
      lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2703
0
      memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
2704
0
      SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2705
0
      lookup_used = 1;
2706
0
    }
2707
    /* copy into current space */
2708
0
    memcpy(ptr, &aa->ap, p_length);
2709
2710
    /* network elements and update lengths */
2711
0
    aph = (struct sctp_asconf_paramhdr *)ptr;
2712
0
    aap = (struct sctp_asconf_addr_param *)ptr;
2713
    /* correlation_id is transparent to peer, no htonl needed */
2714
0
    aph->ph.param_type = htons(aph->ph.param_type);
2715
0
    aph->ph.param_length = htons(aph->ph.param_length);
2716
0
    aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
2717
0
    aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
2718
2719
0
    SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
2720
0
    ptr += SCTP_SIZE32(p_length);
2721
2722
    /*
2723
     * these params are removed off the pending list upon
2724
     * getting an ASCONF-ACK back from the peer, just set flag
2725
     */
2726
0
    aa->sent = 1;
2727
0
  }
2728
  /* check to see if the lookup addr has been populated yet */
2729
0
  if (lookup_used == 0) {
2730
    /* NOTE: if the address param is optional, can skip this... */
2731
    /* add any valid (existing) address... */
2732
0
    struct sctp_ipv6addr_param *lookup;
2733
0
    uint16_t p_size, addr_size;
2734
0
    struct sockaddr *found_addr;
2735
0
    caddr_t addr_ptr;
2736
2737
0
    if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
2738
0
      found_addr = sctp_find_valid_localaddr(stcb,
2739
0
                     addr_locked);
2740
0
    else
2741
0
      found_addr = sctp_find_valid_localaddr_ep(stcb);
2742
2743
0
    lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
2744
0
    if (found_addr != NULL) {
2745
0
      switch (found_addr->sa_family) {
2746
0
#ifdef INET6
2747
0
      case AF_INET6:
2748
        /* copy IPv6 address */
2749
0
        lookup->ph.param_type =
2750
0
            htons(SCTP_IPV6_ADDRESS);
2751
0
        p_size = sizeof(struct sctp_ipv6addr_param);
2752
0
        addr_size = sizeof(struct in6_addr);
2753
0
        addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
2754
0
            found_addr)->sin6_addr;
2755
0
        break;
2756
0
#endif
2757
0
#ifdef INET
2758
0
      case AF_INET:
2759
        /* copy IPv4 address */
2760
0
        lookup->ph.param_type =
2761
0
            htons(SCTP_IPV4_ADDRESS);
2762
0
        p_size = sizeof(struct sctp_ipv4addr_param);
2763
0
        addr_size = sizeof(struct in_addr);
2764
0
        addr_ptr = (caddr_t)&((struct sockaddr_in *)
2765
0
            found_addr)->sin_addr;
2766
0
        break;
2767
0
#endif
2768
0
      default:
2769
0
        SCTPDBG(SCTP_DEBUG_ASCONF1,
2770
0
          "sctp_compose_asconf: no usable lookup addr (family = %d)!\n",
2771
0
          found_addr->sa_family);
2772
0
        sctp_m_freem(m_asconf_chk);
2773
0
        sctp_m_freem(m_asconf);
2774
0
        return (NULL);
2775
0
      }
2776
0
      lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
2777
0
      memcpy(lookup->addr, addr_ptr, addr_size);
2778
0
      SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
2779
0
    } else {
2780
      /* uh oh... don't have any address?? */
2781
0
      SCTPDBG(SCTP_DEBUG_ASCONF1,
2782
0
        "sctp_compose_asconf: no lookup addr!\n");
2783
0
      sctp_m_freem(m_asconf_chk);
2784
0
      sctp_m_freem(m_asconf);
2785
0
      return (NULL);
2786
0
    }
2787
0
  }
2788
  /* chain it all together */
2789
0
  SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
2790
0
  *retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
2791
0
  acp->ch.chunk_length = htons(*retlen);
2792
2793
0
  return (m_asconf_chk);
2794
0
}
2795
2796
/*
2797
 * section to handle address changes before an association is up eg. changes
2798
 * during INIT/INIT-ACK/COOKIE-ECHO handshake
2799
 */
2800
2801
/*
2802
 * processes the (local) addresses in the INIT-ACK chunk
2803
 */
2804
static void
2805
sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
2806
    unsigned int offset, unsigned int length)
2807
0
{
2808
0
  struct sctp_paramhdr tmp_param, *ph;
2809
0
  uint16_t plen, ptype;
2810
0
  struct sctp_ifa *sctp_ifa;
2811
0
  union sctp_sockstore store;
2812
0
#ifdef INET6
2813
0
  struct sctp_ipv6addr_param addr6_store;
2814
0
#endif
2815
0
#ifdef INET
2816
0
  struct sctp_ipv4addr_param addr4_store;
2817
0
#endif
2818
2819
0
  SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
2820
0
  if (stcb == NULL) /* Un-needed check for SA */
2821
0
    return;
2822
2823
  /* convert to upper bound */
2824
0
  length += offset;
2825
2826
0
  if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2827
0
    return;
2828
0
  }
2829
  /* go through the addresses in the init-ack */
2830
0
  ph = (struct sctp_paramhdr *)
2831
0
       sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
2832
0
                     (uint8_t *)&tmp_param);
2833
0
  while (ph != NULL) {
2834
0
    ptype = ntohs(ph->param_type);
2835
0
    plen = ntohs(ph->param_length);
2836
0
    switch (ptype) {
2837
0
#ifdef INET6
2838
0
    case SCTP_IPV6_ADDRESS:
2839
0
    {
2840
0
      struct sctp_ipv6addr_param *a6p;
2841
2842
      /* get the entire IPv6 address param */
2843
0
      a6p = (struct sctp_ipv6addr_param *)
2844
0
          sctp_m_getptr(m, offset,
2845
0
          sizeof(struct sctp_ipv6addr_param),
2846
0
          (uint8_t *)&addr6_store);
2847
0
      if (plen != sizeof(struct sctp_ipv6addr_param) ||
2848
0
          a6p == NULL) {
2849
0
        return;
2850
0
      }
2851
0
      memset(&store, 0, sizeof(union sctp_sockstore));
2852
0
      store.sin6.sin6_family = AF_INET6;
2853
#ifdef HAVE_SIN6_LEN
2854
      store.sin6.sin6_len = sizeof(struct sockaddr_in6);
2855
#endif
2856
0
      store.sin6.sin6_port = stcb->rport;
2857
0
      memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
2858
0
      break;
2859
0
    }
2860
0
#endif
2861
0
#ifdef INET
2862
0
    case SCTP_IPV4_ADDRESS:
2863
0
    {
2864
0
      struct sctp_ipv4addr_param *a4p;
2865
2866
      /* get the entire IPv4 address param */
2867
0
      a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
2868
0
                    sizeof(struct sctp_ipv4addr_param),
2869
0
                    (uint8_t *)&addr4_store);
2870
0
      if (plen != sizeof(struct sctp_ipv4addr_param) ||
2871
0
          a4p == NULL) {
2872
0
        return;
2873
0
      }
2874
0
      memset(&store, 0, sizeof(union sctp_sockstore));
2875
0
      store.sin.sin_family = AF_INET;
2876
#ifdef HAVE_SIN_LEN
2877
      store.sin.sin_len = sizeof(struct sockaddr_in);
2878
#endif
2879
0
      store.sin.sin_port = stcb->rport;
2880
0
      store.sin.sin_addr.s_addr = a4p->addr;
2881
0
      break;
2882
0
    }
2883
0
#endif
2884
0
    default:
2885
0
      goto next_addr;
2886
0
    }
2887
2888
    /* see if this address really (still) exists */
2889
0
    sctp_ifa = sctp_find_ifa_by_addr(&store.sa, stcb->asoc.vrf_id,
2890
0
             SCTP_ADDR_NOT_LOCKED);
2891
0
    if (sctp_ifa == NULL) {
2892
      /* address doesn't exist anymore */
2893
0
      int status;
2894
2895
      /* are ASCONFs allowed ? */
2896
0
      if ((sctp_is_feature_on(stcb->sctp_ep,
2897
0
          SCTP_PCB_FLAGS_DO_ASCONF)) &&
2898
0
          stcb->asoc.asconf_supported) {
2899
        /* queue an ASCONF DEL_IP_ADDRESS */
2900
0
        status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
2901
        /*
2902
         * if queued ok, and in correct state, send
2903
         * out the ASCONF.
2904
         */
2905
0
        if (status == 0 &&
2906
0
            SCTP_GET_STATE(stcb) == SCTP_STATE_OPEN) {
2907
#ifdef SCTP_TIMER_BASED_ASCONF
2908
          sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
2909
               stcb->sctp_ep, stcb,
2910
               stcb->asoc.primary_destination);
2911
#else
2912
0
          sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
2913
0
#endif
2914
0
        }
2915
0
      }
2916
0
    }
2917
2918
0
next_addr:
2919
    /*
2920
     * Sanity check:  Make sure the length isn't 0, otherwise
2921
     * we'll be stuck in this loop for a long time...
2922
     */
2923
0
    if (SCTP_SIZE32(plen) == 0) {
2924
0
      SCTP_PRINTF("process_initack_addrs: bad len (%d) type=%xh\n",
2925
0
            plen, ptype);
2926
0
      return;
2927
0
    }
2928
    /* get next parameter */
2929
0
    offset += SCTP_SIZE32(plen);
2930
0
    if ((offset + sizeof(struct sctp_paramhdr)) > length)
2931
0
      return;
2932
0
    ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2933
0
        sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
2934
0
  } /* while */
2935
0
}
2936
2937
/* FIX ME: need to verify return result for v6 address type if v6 disabled */
2938
/*
2939
 * checks to see if a specific address is in the initack address list returns
2940
 * 1 if found, 0 if not
2941
 */
2942
static uint32_t
2943
sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
2944
0
{
2945
0
  struct sctp_paramhdr tmp_param, *ph;
2946
0
  uint16_t plen, ptype;
2947
0
#ifdef INET
2948
0
  struct sockaddr_in *sin;
2949
0
  struct sctp_ipv4addr_param *a4p;
2950
0
  struct sctp_ipv6addr_param addr4_store;
2951
0
#endif
2952
0
#ifdef INET6
2953
0
  struct sockaddr_in6 *sin6;
2954
0
  struct sctp_ipv6addr_param *a6p;
2955
0
  struct sctp_ipv6addr_param addr6_store;
2956
#ifdef SCTP_EMBEDDED_V6_SCOPE
2957
  struct sockaddr_in6 sin6_tmp;
2958
#endif
2959
0
#endif
2960
2961
0
  switch (sa->sa_family) {
2962
0
#ifdef INET
2963
0
  case AF_INET:
2964
0
    break;
2965
0
#endif
2966
0
#ifdef INET6
2967
0
  case AF_INET6:
2968
0
    break;
2969
0
#endif
2970
0
  default:
2971
0
    return (0);
2972
0
  }
2973
2974
0
  SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
2975
0
  SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
2976
  /* convert to upper bound */
2977
0
  length += offset;
2978
2979
0
  if ((offset + sizeof(struct sctp_paramhdr)) > length) {
2980
0
    SCTPDBG(SCTP_DEBUG_ASCONF1,
2981
0
      "find_initack_addr: invalid offset?\n");
2982
0
    return (0);
2983
0
  }
2984
  /* go through the addresses in the init-ack */
2985
0
  ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
2986
0
      sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
2987
0
  while (ph != NULL) {
2988
0
    ptype = ntohs(ph->param_type);
2989
0
    plen = ntohs(ph->param_length);
2990
0
    switch (ptype) {
2991
0
#ifdef INET6
2992
0
    case SCTP_IPV6_ADDRESS:
2993
0
      if (sa->sa_family == AF_INET6) {
2994
        /* get the entire IPv6 address param */
2995
0
        if (plen != sizeof(struct sctp_ipv6addr_param)) {
2996
0
          break;
2997
0
        }
2998
        /* get the entire IPv6 address param */
2999
0
        a6p = (struct sctp_ipv6addr_param *)
3000
0
              sctp_m_getptr(m, offset,
3001
0
                            sizeof(struct sctp_ipv6addr_param),
3002
0
                            (uint8_t *)&addr6_store);
3003
0
        if (a6p == NULL) {
3004
0
          return (0);
3005
0
        }
3006
0
        sin6 = (struct sockaddr_in6 *)sa;
3007
#ifdef SCTP_EMBEDDED_V6_SCOPE
3008
        if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
3009
          /* create a copy and clear scope */
3010
          memcpy(&sin6_tmp, sin6,
3011
                 sizeof(struct sockaddr_in6));
3012
          sin6 = &sin6_tmp;
3013
          in6_clearscope(&sin6->sin6_addr);
3014
        }
3015
#endif /* SCTP_EMBEDDED_V6_SCOPE */
3016
0
        if (memcmp(&sin6->sin6_addr, a6p->addr,
3017
0
                   sizeof(struct in6_addr)) == 0) {
3018
          /* found it */
3019
0
          return (1);
3020
0
        }
3021
0
      }
3022
0
      break;
3023
0
#endif /* INET6 */
3024
0
#ifdef INET
3025
0
    case SCTP_IPV4_ADDRESS:
3026
0
      if (sa->sa_family == AF_INET) {
3027
0
        if (plen != sizeof(struct sctp_ipv4addr_param)) {
3028
0
          break;
3029
0
        }
3030
        /* get the entire IPv4 address param */
3031
0
        a4p = (struct sctp_ipv4addr_param *)
3032
0
              sctp_m_getptr(m, offset,
3033
0
                            sizeof(struct sctp_ipv4addr_param),
3034
0
                            (uint8_t *)&addr4_store);
3035
0
        if (a4p == NULL) {
3036
0
          return (0);
3037
0
        }
3038
0
        sin = (struct sockaddr_in *)sa;
3039
0
        if (sin->sin_addr.s_addr == a4p->addr) {
3040
          /* found it */
3041
0
          return (1);
3042
0
        }
3043
0
      }
3044
0
      break;
3045
0
#endif
3046
0
    default:
3047
0
      break;
3048
0
    }
3049
    /* get next parameter */
3050
0
    offset += SCTP_SIZE32(plen);
3051
0
    if (offset + sizeof(struct sctp_paramhdr) > length) {
3052
0
      return (0);
3053
0
    }
3054
0
    ph = (struct sctp_paramhdr *)
3055
0
        sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
3056
0
        (uint8_t *) & tmp_param);
3057
0
  } /* while */
3058
  /* not found! */
3059
0
  return (0);
3060
0
}
3061
3062
/*
3063
 * makes sure that the current endpoint local addr list is consistent with
3064
 * the new association (eg. subset bound, asconf allowed) adds addresses as
3065
 * necessary
3066
 */
3067
static void
3068
sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3069
    int length, struct sockaddr *init_addr)
3070
0
{
3071
0
  struct sctp_laddr *laddr;
3072
3073
  /* go through the endpoint list */
3074
0
  LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3075
    /* be paranoid and validate the laddr */
3076
0
    if (laddr->ifa == NULL) {
3077
0
      SCTPDBG(SCTP_DEBUG_ASCONF1,
3078
0
        "check_addr_list_ep: laddr->ifa is NULL");
3079
0
      continue;
3080
0
    }
3081
    /* do i have it implicitly? */
3082
0
    if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
3083
0
      continue;
3084
0
    }
3085
    /* check to see if in the init-ack */
3086
0
    if (!sctp_addr_in_initack(m, offset, length, &laddr->ifa->address.sa)) {
3087
      /* try to add it */
3088
0
      sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
3089
0
          SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
3090
0
    }
3091
0
  }
3092
0
}
3093
3094
/*
3095
 * makes sure that the current kernel address list is consistent with the new
3096
 * association (with all addrs bound) adds addresses as necessary
3097
 */
3098
static void
3099
sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3100
    int length, struct sockaddr *init_addr,
3101
    uint16_t local_scope, uint16_t site_scope,
3102
    uint16_t ipv4_scope, uint16_t loopback_scope)
3103
0
{
3104
0
  struct sctp_vrf *vrf = NULL;
3105
0
  struct sctp_ifn *sctp_ifn;
3106
0
  struct sctp_ifa *sctp_ifa;
3107
0
  uint32_t vrf_id;
3108
0
#ifdef INET
3109
0
  struct sockaddr_in *sin;
3110
0
#endif
3111
0
#ifdef INET6
3112
0
  struct sockaddr_in6 *sin6;
3113
0
#endif
3114
3115
0
  if (stcb) {
3116
0
    vrf_id = stcb->asoc.vrf_id;
3117
0
  } else {
3118
0
    return;
3119
0
  }
3120
0
  SCTP_IPI_ADDR_RLOCK();
3121
0
  vrf = sctp_find_vrf(vrf_id);
3122
0
  if (vrf == NULL) {
3123
0
    SCTP_IPI_ADDR_RUNLOCK();
3124
0
    return;
3125
0
  }
3126
  /* go through all our known interfaces */
3127
0
  LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
3128
0
    if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
3129
      /* skip loopback interface */
3130
0
      continue;
3131
0
    }
3132
    /* go through each interface address */
3133
0
    LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
3134
      /* do i have it implicitly? */
3135
0
      if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
3136
0
        continue;
3137
0
      }
3138
0
      switch (sctp_ifa->address.sa.sa_family) {
3139
0
#ifdef INET
3140
0
      case AF_INET:
3141
0
        sin = &sctp_ifa->address.sin;
3142
#if defined(__FreeBSD__) && !defined(__Userspace__)
3143
        if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3144
                             &sin->sin_addr) != 0) {
3145
          continue;
3146
        }
3147
#endif
3148
0
        if ((ipv4_scope == 0) &&
3149
0
            (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
3150
          /* private address not in scope */
3151
0
          continue;
3152
0
        }
3153
0
        break;
3154
0
#endif
3155
0
#ifdef INET6
3156
0
      case AF_INET6:
3157
0
        sin6 = &sctp_ifa->address.sin6;
3158
#if defined(__FreeBSD__) && !defined(__Userspace__)
3159
        if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3160
                             &sin6->sin6_addr) != 0) {
3161
          continue;
3162
        }
3163
#endif
3164
0
        if ((local_scope == 0) &&
3165
0
            (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
3166
0
          continue;
3167
0
        }
3168
0
        if ((site_scope == 0) &&
3169
0
            (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
3170
0
          continue;
3171
0
        }
3172
0
        break;
3173
0
#endif
3174
0
      default:
3175
0
        break;
3176
0
      }
3177
      /* check to see if in the init-ack */
3178
0
      if (!sctp_addr_in_initack(m, offset, length, &sctp_ifa->address.sa)) {
3179
        /* try to add it */
3180
0
        sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
3181
0
            sctp_ifa, SCTP_ADD_IP_ADDRESS,
3182
0
            SCTP_ADDR_LOCKED);
3183
0
      }
3184
0
    } /* end foreach ifa */
3185
0
  } /* end foreach ifn */
3186
0
  SCTP_IPI_ADDR_RUNLOCK();
3187
0
}
3188
3189
/*
3190
 * validates an init-ack chunk (from a cookie-echo) with current addresses
3191
 * adds addresses from the init-ack into our local address list, if needed
3192
 * queues asconf adds/deletes addresses as needed and makes appropriate list
3193
 * changes for source address selection m, offset: points to the start of the
3194
 * address list in an init-ack chunk length: total length of the address
3195
 * params only init_addr: address where my INIT-ACK was sent from
3196
 */
3197
void
3198
sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset,
3199
    int length, struct sockaddr *init_addr,
3200
    uint16_t local_scope, uint16_t site_scope,
3201
    uint16_t ipv4_scope, uint16_t loopback_scope)
3202
0
{
3203
  /* process the local addresses in the initack */
3204
0
  sctp_process_initack_addresses(stcb, m, offset, length);
3205
3206
0
  if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3207
    /* bound all case */
3208
0
    sctp_check_address_list_all(stcb, m, offset, length, init_addr,
3209
0
        local_scope, site_scope, ipv4_scope, loopback_scope);
3210
0
  } else {
3211
    /* subset bound case */
3212
0
    if (sctp_is_feature_on(stcb->sctp_ep,
3213
0
        SCTP_PCB_FLAGS_DO_ASCONF)) {
3214
      /* asconf's allowed */
3215
0
      sctp_check_address_list_ep(stcb, m, offset, length,
3216
0
          init_addr);
3217
0
    }
3218
    /* else, no asconfs allowed, so what we sent is what we get */
3219
0
  }
3220
0
}
3221
3222
/*
3223
 * sctp_bindx() support
3224
 */
3225
uint32_t
3226
sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
3227
                     uint32_t type, uint32_t vrf_id)
3228
0
{
3229
0
  struct sctp_ifa *ifa;
3230
0
  struct sctp_laddr *laddr, *nladdr;
3231
3232
#ifdef HAVE_SA_LEN
3233
  if (sa->sa_len == 0) {
3234
    SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3235
    return (EINVAL);
3236
  }
3237
#endif
3238
0
  if (type == SCTP_ADD_IP_ADDRESS) {
3239
    /* For an add the address MUST be on the system */
3240
0
    ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
3241
0
  } else if (type == SCTP_DEL_IP_ADDRESS) {
3242
    /* For a delete we need to find it in the inp */
3243
0
    ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED);
3244
0
  } else {
3245
0
    ifa = NULL;
3246
0
  }
3247
0
  if (ifa != NULL) {
3248
0
    if (type == SCTP_ADD_IP_ADDRESS) {
3249
0
      sctp_add_local_addr_ep(inp, ifa, type);
3250
0
    } else if (type == SCTP_DEL_IP_ADDRESS) {
3251
0
      if (inp->laddr_count < 2) {
3252
        /* can't delete the last local address */
3253
0
        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
3254
0
        return (EINVAL);
3255
0
      }
3256
0
      LIST_FOREACH(laddr, &inp->sctp_addr_list,
3257
0
             sctp_nxt_addr) {
3258
0
        if (ifa == laddr->ifa) {
3259
          /* Mark in the delete */
3260
0
          laddr->action = type;
3261
0
        }
3262
0
      }
3263
0
    }
3264
0
    if (LIST_EMPTY(&inp->sctp_asoc_list)) {
3265
      /*
3266
       * There is no need to start the iterator if
3267
       * the inp has no associations.
3268
       */
3269
0
      if (type == SCTP_DEL_IP_ADDRESS) {
3270
0
        LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
3271
0
          if (laddr->ifa == ifa) {
3272
0
            sctp_del_local_addr_ep(inp, ifa);
3273
0
          }
3274
0
        }
3275
0
      }
3276
0
    } else {
3277
0
      struct sctp_asconf_iterator *asc;
3278
0
      struct sctp_laddr *wi;
3279
0
      int ret;
3280
3281
0
      SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
3282
0
                  sizeof(struct sctp_asconf_iterator),
3283
0
                  SCTP_M_ASC_IT);
3284
0
      if (asc == NULL) {
3285
0
        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3286
0
        return (ENOMEM);
3287
0
      }
3288
0
      wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
3289
0
      if (wi == NULL) {
3290
0
        SCTP_FREE(asc, SCTP_M_ASC_IT);
3291
0
        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
3292
0
        return (ENOMEM);
3293
0
      }
3294
0
      LIST_INIT(&asc->list_of_work);
3295
0
      asc->cnt = 1;
3296
0
      SCTP_INCR_LADDR_COUNT();
3297
0
      wi->ifa = ifa;
3298
0
      wi->action = type;
3299
0
      atomic_add_int(&ifa->refcount, 1);
3300
0
      LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
3301
0
      ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
3302
0
                                   sctp_asconf_iterator_stcb,
3303
0
                                   sctp_asconf_iterator_ep_end,
3304
0
                                   SCTP_PCB_ANY_FLAGS,
3305
0
                                   SCTP_PCB_ANY_FEATURES,
3306
0
                                   SCTP_ASOC_ANY_STATE,
3307
0
                                   (void *)asc, 0,
3308
0
                                   sctp_asconf_iterator_end, inp, 0);
3309
0
      if (ret) {
3310
0
        SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n");
3311
0
        SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT);
3312
0
                            sctp_asconf_iterator_end(asc, 0);
3313
0
        return (EFAULT);
3314
0
      }
3315
0
    }
3316
0
    return (0);
3317
0
  } else {
3318
    /* invalid address! */
3319
0
    SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
3320
0
    return (EADDRNOTAVAIL);
3321
0
  }
3322
0
}
3323
3324
void
3325
sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb, struct sctp_nets *net)
3326
280
{
3327
280
  struct sctp_asconf_addr *aa_vtag, *aa_add, *aa_del;
3328
280
  struct sctp_ifa *sctp_ifap;
3329
280
  struct sctp_asconf_tag_param *vtag;
3330
280
#ifdef INET
3331
280
  struct sockaddr_in *to;
3332
280
#endif
3333
280
#ifdef INET6
3334
280
  struct sockaddr_in6 *to6;
3335
280
#endif
3336
3337
280
  if (net == NULL) {
3338
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
3339
0
    return;
3340
0
  }
3341
280
  if (stcb == NULL) {
3342
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
3343
0
    return;
3344
0
  }
3345
  /* Need to have in the ASCONF:
3346
   * - VTAG(my_vtag/peer_vtag)
3347
   * - ADD(wildcard)
3348
   * - DEL(wildcard)
3349
   * - ADD(Any global addresses)
3350
   */
3351
280
  SCTP_MALLOC(aa_vtag, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
3352
280
  SCTP_MALLOC(aa_add, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
3353
280
  SCTP_MALLOC(aa_del, struct sctp_asconf_addr *, sizeof(struct sctp_asconf_addr), SCTP_M_ASC_ADDR);
3354
3355
280
  if ((aa_vtag == NULL) || (aa_add == NULL) || (aa_del == NULL)) {
3356
    /* Didn't get memory */
3357
0
    SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: failed to get memory!\n");
3358
280
out:
3359
280
    if (aa_vtag != NULL) {
3360
280
      SCTP_FREE(aa_vtag, SCTP_M_ASC_ADDR);
3361
280
    }
3362
280
    if (aa_add != NULL) {
3363
280
      SCTP_FREE(aa_add, SCTP_M_ASC_ADDR);
3364
280
    }
3365
280
    if (aa_del != NULL) {
3366
280
      SCTP_FREE(aa_del, SCTP_M_ASC_ADDR);
3367
280
    }
3368
280
    return;
3369
0
  }
3370
280
  memset(aa_vtag, 0, sizeof(struct sctp_asconf_addr));
3371
280
  aa_vtag->special_del = 0;
3372
  /* Fill in ASCONF address parameter fields. */
3373
  /* Top level elements are "networked" during send. */
3374
280
  aa_vtag->ifa = NULL;
3375
280
  aa_vtag->sent = 0;    /* clear sent flag */
3376
280
  vtag = (struct sctp_asconf_tag_param *)&aa_vtag->ap.aph;
3377
280
  vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
3378
280
  vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
3379
280
  vtag->local_vtag = htonl(stcb->asoc.my_vtag);
3380
280
  vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
3381
3382
280
  memset(aa_add, 0, sizeof(struct sctp_asconf_addr));
3383
280
  memset(aa_del, 0, sizeof(struct sctp_asconf_addr));
3384
280
  switch (net->ro._l_addr.sa.sa_family) {
3385
0
#ifdef INET
3386
0
  case AF_INET:
3387
0
    aa_add->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3388
0
    aa_add->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3389
0
    aa_add->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3390
0
    aa_add->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
3391
    /* No need to fill the address, we are using 0.0.0.0 */
3392
0
    aa_del->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
3393
0
    aa_del->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
3394
0
    aa_del->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
3395
0
    aa_del->ap.addrp.ph.param_length = sizeof (struct sctp_ipv4addr_param);
3396
    /* No need to fill the address, we are using 0.0.0.0 */
3397
0
    break;
3398
0
#endif
3399
0
#ifdef INET6
3400
0
  case AF_INET6:
3401
0
    aa_add->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
3402
0
    aa_add->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3403
0
    aa_add->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3404
0
    aa_add->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
3405
    /* No need to fill the address, we are using ::0 */
3406
0
    aa_del->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
3407
0
    aa_del->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
3408
0
    aa_del->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
3409
0
    aa_del->ap.addrp.ph.param_length = sizeof (struct sctp_ipv6addr_param);
3410
    /* No need to fill the address, we are using ::0 */
3411
0
    break;
3412
0
#endif
3413
280
  default:
3414
280
    SCTPDBG(SCTP_DEBUG_ASCONF1,
3415
280
            "sctp_asconf_send_nat_state_update: unknown address family %d\n",
3416
280
            net->ro._l_addr.sa.sa_family);
3417
280
    goto out;
3418
280
  }
3419
0
  TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_vtag, next);
3420
0
  TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_add, next);
3421
0
  TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa_del, next);
3422
3423
  /* Now we must hunt the addresses and add all global addresses */
3424
0
  if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3425
0
    struct sctp_vrf *vrf = NULL;
3426
0
    struct sctp_ifn *sctp_ifnp;
3427
0
    uint32_t vrf_id;
3428
3429
0
    vrf_id = stcb->sctp_ep->def_vrf_id;
3430
0
    vrf = sctp_find_vrf(vrf_id);
3431
0
    if (vrf == NULL) {
3432
0
      goto skip_rest;
3433
0
    }
3434
3435
0
    SCTP_IPI_ADDR_RLOCK();
3436
0
    LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
3437
0
      LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
3438
0
        switch (sctp_ifap->address.sa.sa_family) {
3439
0
#ifdef INET
3440
0
        case AF_INET:
3441
0
          to = &sctp_ifap->address.sin;
3442
#if defined(__FreeBSD__) && !defined(__Userspace__)
3443
          if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
3444
                               &to->sin_addr) != 0) {
3445
            continue;
3446
          }
3447
#endif
3448
0
          if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3449
0
            continue;
3450
0
          }
3451
0
          if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3452
0
            continue;
3453
0
          }
3454
0
          break;
3455
0
#endif
3456
0
#ifdef INET6
3457
0
        case AF_INET6:
3458
0
          to6 = &sctp_ifap->address.sin6;
3459
#if defined(__FreeBSD__) && !defined(__Userspace__)
3460
          if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
3461
                               &to6->sin6_addr) != 0) {
3462
            continue;
3463
          }
3464
#endif
3465
0
          if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3466
0
            continue;
3467
0
          }
3468
0
          if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3469
0
            continue;
3470
0
          }
3471
0
          break;
3472
0
#endif
3473
0
        default:
3474
0
          continue;
3475
0
        }
3476
0
        sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3477
0
      }
3478
0
    }
3479
0
    SCTP_IPI_ADDR_RUNLOCK();
3480
0
  } else {
3481
0
    struct sctp_laddr *laddr;
3482
3483
0
    LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
3484
0
      if (laddr->ifa == NULL) {
3485
0
        continue;
3486
0
      }
3487
0
      if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
3488
        /* Address being deleted by the system, dont
3489
         * list.
3490
         */
3491
0
        continue;
3492
0
      if (laddr->action == SCTP_DEL_IP_ADDRESS) {
3493
        /* Address being deleted on this ep
3494
         * don't list.
3495
         */
3496
0
        continue;
3497
0
      }
3498
0
      sctp_ifap = laddr->ifa;
3499
0
      switch (sctp_ifap->address.sa.sa_family) {
3500
0
#ifdef INET
3501
0
      case AF_INET:
3502
0
        to = &sctp_ifap->address.sin;
3503
0
        if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
3504
0
          continue;
3505
0
        }
3506
0
        if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
3507
0
          continue;
3508
0
        }
3509
0
        break;
3510
0
#endif
3511
0
#ifdef INET6
3512
0
      case AF_INET6:
3513
0
        to6 = &sctp_ifap->address.sin6;
3514
0
        if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
3515
0
          continue;
3516
0
        }
3517
0
        if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3518
0
          continue;
3519
0
        }
3520
0
        break;
3521
0
#endif
3522
0
      default:
3523
0
        continue;
3524
0
      }
3525
0
      sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
3526
0
    }
3527
0
  }
3528
0
 skip_rest:
3529
  /* Now we must send the asconf into the queue */
3530
0
  sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
3531
0
}