Coverage Report

Created: 2025-07-11 06:39

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