The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/sctp_asconf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 3cbe1c02c179c544de3dc5ed8ff73296


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.