From owner-svn-src-stable@FreeBSD.ORG Sun Jul 7 16:04:00 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id C7D969ED; Sun, 7 Jul 2013 16:04:00 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id B907C19CF; Sun, 7 Jul 2013 16:04:00 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r67G40XG046290; Sun, 7 Jul 2013 16:04:00 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r67G3wSR046267; Sun, 7 Jul 2013 16:03:58 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201307071603.r67G3wSR046267@svn.freebsd.org> From: Michael Tuexen Date: Sun, 7 Jul 2013 16:03:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r252961 - stable/9/sys/netinet X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Jul 2013 16:04:00 -0000 Author: tuexen Date: Sun Jul 7 16:03:58 2013 New Revision: 252961 URL: http://svnweb.freebsd.org/changeset/base/252961 Log: MFC r246595: Cleanup the handling of address scopes. Announce in the INIT/INIT-ACK only the supported address types. While there, do some whitespace cleanups. Modified: stable/9/sys/netinet/sctp.h stable/9/sys/netinet/sctp_asconf.c stable/9/sys/netinet/sctp_input.c stable/9/sys/netinet/sctp_output.c stable/9/sys/netinet/sctp_output.h stable/9/sys/netinet/sctp_pcb.c stable/9/sys/netinet/sctp_structs.h stable/9/sys/netinet/sctp_sysctl.c stable/9/sys/netinet/sctp_usrreq.c stable/9/sys/netinet/sctputil.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/netinet/sctp.h ============================================================================== --- stable/9/sys/netinet/sctp.h Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp.h Sun Jul 7 16:03:58 2013 (r252961) @@ -500,12 +500,12 @@ struct sctp_error_unrecognized_chunk { #define SCTP_PCB_FLAGS_SOCKET_GONE 0x10000000 #define SCTP_PCB_FLAGS_SOCKET_ALLGONE 0x20000000 #define SCTP_PCB_FLAGS_SOCKET_CANT_READ 0x40000000 + /* flags to copy to new PCB */ #define SCTP_PCB_COPY_FLAGS (SCTP_PCB_FLAGS_BOUNDALL|\ SCTP_PCB_FLAGS_WAKEINPUT|\ SCTP_PCB_FLAGS_BOUND_V6) - /* * PCB Features (in sctp_features bitmask) */ Modified: stable/9/sys/netinet/sctp_asconf.c ============================================================================== --- stable/9/sys/netinet/sctp_asconf.c Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_asconf.c Sun Jul 7 16:03:58 2013 (r252961) @@ -1916,7 +1916,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb * return; } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - if (stcb->asoc.local_scope == 0) { + if (stcb->asoc.scope.local_scope == 0) { return; } /* is it the right link local scope? */ @@ -1924,7 +1924,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb * return; } } - if (stcb->asoc.site_scope == 0 && + if (stcb->asoc.scope.site_scope == 0 && IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { return; } @@ -1948,7 +1948,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb * /* we skip unspecifed addresses */ return; } - if (stcb->asoc.ipv4_local_scope == 0 && + if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { return; } @@ -2106,7 +2106,7 @@ sctp_asconf_iterator_stcb(struct sctp_in continue; } if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { - if (stcb->asoc.local_scope == 0) { + if (stcb->asoc.scope.local_scope == 0) { continue; } /* is it the right link local scope? */ @@ -2135,7 +2135,7 @@ sctp_asconf_iterator_stcb(struct sctp_in /* we skip unspecifed addresses */ continue; } - if (stcb->asoc.ipv4_local_scope == 0 && + if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { continue; } @@ -2198,13 +2198,7 @@ sctp_asconf_iterator_stcb(struct sctp_in } } else { /* Need to check scopes for this guy */ - if (sctp_is_address_in_scope(ifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) { continue; } } @@ -2437,7 +2431,7 @@ sctp_find_valid_localaddr(struct sctp_tc return (NULL); } LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { - if (stcb->asoc.loopback_scope == 0 && + if (stcb->asoc.scope.loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { /* Skip if loopback_scope not set */ continue; @@ -2446,7 +2440,7 @@ sctp_find_valid_localaddr(struct sctp_tc switch (sctp_ifa->address.sa.sa_family) { #ifdef INET case AF_INET: - if (stcb->asoc.ipv4_addr_legal) { + if (stcb->asoc.scope.ipv4_addr_legal) { struct sockaddr_in *sin; sin = (struct sockaddr_in *)&sctp_ifa->address.sa; @@ -2454,7 +2448,7 @@ sctp_find_valid_localaddr(struct sctp_tc /* skip unspecifed addresses */ continue; } - if (stcb->asoc.ipv4_local_scope == 0 && + if (stcb->asoc.scope.ipv4_local_scope == 0 && IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) continue; @@ -2473,7 +2467,7 @@ sctp_find_valid_localaddr(struct sctp_tc #endif #ifdef INET6 case AF_INET6: - if (stcb->asoc.ipv6_addr_legal) { + if (stcb->asoc.scope.ipv6_addr_legal) { struct sockaddr_in6 *sin6; if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { @@ -2487,10 +2481,10 @@ sctp_find_valid_localaddr(struct sctp_tc */ continue; } - if (stcb->asoc.local_scope == 0 && + if (stcb->asoc.scope.local_scope == 0 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) continue; - if (stcb->asoc.site_scope == 0 && + if (stcb->asoc.scope.site_scope == 0 && IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) continue; Modified: stable/9/sys/netinet/sctp_input.c ============================================================================== --- stable/9/sys/netinet/sctp_input.c Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_input.c Sun Jul 7 16:03:58 2013 (r252961) @@ -2130,13 +2130,13 @@ sctp_process_cookie_new(struct mbuf *m, asoc = &stcb->asoc; /* get scope variables out of cookie */ - asoc->ipv4_local_scope = cookie->ipv4_scope; - asoc->site_scope = cookie->site_scope; - asoc->local_scope = cookie->local_scope; - asoc->loopback_scope = cookie->loopback_scope; + asoc->scope.ipv4_local_scope = cookie->ipv4_scope; + asoc->scope.site_scope = cookie->site_scope; + asoc->scope.local_scope = cookie->local_scope; + asoc->scope.loopback_scope = cookie->loopback_scope; - if ((asoc->ipv4_addr_legal != cookie->ipv4_addr_legal) || - (asoc->ipv6_addr_legal != cookie->ipv6_addr_legal)) { + if ((asoc->scope.ipv4_addr_legal != cookie->ipv4_addr_legal) || + (asoc->scope.ipv6_addr_legal != cookie->ipv6_addr_legal)) { struct mbuf *op_err; /* Modified: stable/9/sys/netinet/sctp_output.c ============================================================================== --- stable/9/sys/netinet/sctp_output.c Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_output.c Sun Jul 7 16:03:58 2013 (r252961) @@ -1863,15 +1863,10 @@ struct sack_track sack_array[256] = { int sctp_is_address_in_scope(struct sctp_ifa *ifa, - int ipv4_addr_legal, - int ipv6_addr_legal, - int loopback_scope, - int ipv4_local_scope, - int local_scope SCTP_UNUSED,/* XXX */ - int site_scope, + struct sctp_scoping *scope, int do_update) { - if ((loopback_scope == 0) && + if ((scope->loopback_scope == 0) && (ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) { /* * skip loopback if not in scope * @@ -1881,7 +1876,7 @@ sctp_is_address_in_scope(struct sctp_ifa switch (ifa->address.sa.sa_family) { #ifdef INET case AF_INET: - if (ipv4_addr_legal) { + if (scope->ipv4_addr_legal) { struct sockaddr_in *sin; sin = (struct sockaddr_in *)&ifa->address.sin; @@ -1889,7 +1884,7 @@ sctp_is_address_in_scope(struct sctp_ifa /* not in scope , unspecified */ return (0); } - if ((ipv4_local_scope == 0) && + if ((scope->ipv4_local_scope == 0) && (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { /* private address not in scope */ return (0); @@ -1901,7 +1896,7 @@ sctp_is_address_in_scope(struct sctp_ifa #endif #ifdef INET6 case AF_INET6: - if (ipv6_addr_legal) { + if (scope->ipv6_addr_legal) { struct sockaddr_in6 *sin6; /* @@ -1924,7 +1919,7 @@ sctp_is_address_in_scope(struct sctp_ifa (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) { return (0); } - if ((site_scope == 0) && + if ((scope->site_scope == 0) && (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { return (0); } @@ -2063,13 +2058,7 @@ sctp_add_addresses_to_i_ia(struct sctp_i if (sctp_is_addr_restricted(stcb, sctp_ifap)) { continue; } - if (sctp_is_address_in_scope(sctp_ifap, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 1) == 0) { + if (sctp_is_address_in_scope(sctp_ifap, scope, 1) == 0) { continue; } cnt++; @@ -2099,12 +2088,7 @@ skip_count: continue; } if (sctp_is_address_in_scope(sctp_ifap, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 0) == 0) { + scope, 0) == 0) { continue; } if ((chunk_len != NULL) && @@ -2157,12 +2141,7 @@ skip_count: continue; } if (sctp_is_address_in_scope(laddr->ifa, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 1) == 0) { + scope, 1) == 0) { continue; } cnt++; @@ -2182,12 +2161,7 @@ skip_count: continue; } if (sctp_is_address_in_scope(laddr->ifa, - scope->ipv4_addr_legal, - scope->ipv6_addr_legal, - scope->loopback_scope, - scope->ipv4_local_scope, - scope->local_scope, - scope->site_scope, 0) == 0) { + scope, 0) == 0) { continue; } if ((chunk_len != NULL) && @@ -2801,13 +2775,7 @@ sctp_select_nth_preferred_addr_from_ifn_ } #endif if (stcb) { - if (sctp_is_address_in_scope(ifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) { continue; } if (((non_asoc_addr_ok == 0) && @@ -2853,13 +2821,7 @@ sctp_count_num_preferred_boundall(struct continue; } if (stcb) { - if (sctp_is_address_in_scope(ifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) { continue; } if (((non_asoc_addr_ok == 0) && @@ -3055,13 +3017,7 @@ again_with_private_addresses_allowed: continue; } if (stcb) { - if (sctp_is_address_in_scope(sifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) { SCTPDBG(SCTP_DEBUG_OUTPUT2, "NOT in scope\n"); sifa = NULL; continue; @@ -3108,13 +3064,7 @@ plan_d: if (sifa == NULL) continue; if (stcb) { - if (sctp_is_address_in_scope(sifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + if (sctp_is_address_in_scope(sifa, &stcb->asoc.scope, 0) == 0) { sifa = NULL; continue; } @@ -3135,12 +3085,12 @@ plan_d: } } #ifdef INET - if ((retried == 0) && (stcb->asoc.ipv4_local_scope == 0)) { - stcb->asoc.ipv4_local_scope = 1; + if ((retried == 0) && (stcb->asoc.scope.ipv4_local_scope == 0)) { + stcb->asoc.scope.ipv4_local_scope = 1; retried = 1; goto again_with_private_addresses_allowed; } else if (retried == 1) { - stcb->asoc.ipv4_local_scope = 0; + stcb->asoc.scope.ipv4_local_scope = 0; } #endif out: @@ -3169,12 +3119,7 @@ out: } if (stcb) { if (sctp_is_address_in_scope(tmp_sifa, - stcb->asoc.ipv4_addr_legal, - stcb->asoc.ipv6_addr_legal, - stcb->asoc.loopback_scope, - stcb->asoc.ipv4_local_scope, - stcb->asoc.local_scope, - stcb->asoc.site_scope, 0) == 0) { + &stcb->asoc.scope, 0) == 0) { continue; } if (((non_asoc_addr_ok == 0) && @@ -4595,7 +4540,6 @@ sctp_send_initiate(struct sctp_inpcb *in #endif ) { - struct sctp_scoping scp; struct mbuf *m; struct sctp_nets *net; struct sctp_init_chunk *init; @@ -4675,37 +4619,29 @@ sctp_send_initiate(struct sctp_inpcb *in init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams); init->init.initial_tsn = htonl(stcb->asoc.init_seq_number); -#if defined(INET) || defined(INET6) - /* now the address restriction */ - /* XXX Should we take the address family of the socket into account? */ - sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len); - sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE); -#ifdef INET6 -#ifdef INET - /* we support 2 types: IPv4/IPv6 */ - parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + 2 * sizeof(uint16_t)); - sup_addr->ph.param_length = htons(parameter_len); - sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS); - sup_addr->addr_type[1] = htons(SCTP_IPV6_ADDRESS); - padding_len = 0; -#else - /* we support 1 type: IPv6 */ - parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t)); - sup_addr->ph.param_length = htons(parameter_len); - sup_addr->addr_type[0] = htons(SCTP_IPV6_ADDRESS); - sup_addr->addr_type[1] = htons(0); /* this is the padding */ - padding_len = (uint16_t) sizeof(uint16_t); -#endif -#else - /* we support 1 type: IPv4 */ - parameter_len = (uint16_t) (sizeof(struct sctp_paramhdr) + sizeof(uint16_t)); - sup_addr->ph.param_length = htons(parameter_len); - sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS); - sup_addr->addr_type[1] = htons(0); /* this is the padding */ - padding_len = (uint16_t) sizeof(uint16_t); -#endif - chunk_len += parameter_len; -#endif + if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) { + uint8_t i; + + parameter_len = (uint16_t) sizeof(struct sctp_paramhdr); + if (stcb->asoc.scope.ipv4_addr_legal) { + parameter_len += (uint16_t) sizeof(uint16_t); + } + if (stcb->asoc.scope.ipv6_addr_legal) { + parameter_len += (uint16_t) sizeof(uint16_t); + } + sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t)+chunk_len); + sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE); + sup_addr->ph.param_length = htons(parameter_len); + i = 0; + if (stcb->asoc.scope.ipv4_addr_legal) { + sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS); + } + if (stcb->asoc.scope.ipv6_addr_legal) { + sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS); + } + padding_len = 4 - 2 * i; + chunk_len += parameter_len; + } /* Adaptation layer indication parameter */ /* XXX: Should we include this always? */ if (padding_len > 0) { @@ -4860,13 +4796,7 @@ sctp_send_initiate(struct sctp_inpcb *in * we could just sifa in the address within the stcb. But for now * this is a quick hack to get the address stuff teased apart. */ - scp.ipv4_addr_legal = stcb->asoc.ipv4_addr_legal; - scp.ipv6_addr_legal = stcb->asoc.ipv6_addr_legal; - scp.loopback_scope = stcb->asoc.loopback_scope; - scp.ipv4_local_scope = stcb->asoc.ipv4_local_scope; - scp.local_scope = stcb->asoc.local_scope; - scp.site_scope = stcb->asoc.site_scope; - sctp_add_addresses_to_i_ia(inp, stcb, &scp, m, cnt_inits_to, &padding_len, &chunk_len); + sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope, m, cnt_inits_to, &padding_len, &chunk_len); init->ch.chunk_length = htons(chunk_len); if (padding_len > 0) { @@ -5507,24 +5437,16 @@ do_a_abort: */ stc.site_scope = stc.local_scope = stc.loopback_scope = 0; if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - struct inpcb *in_inp; - - /* Its a V6 socket */ - in_inp = (struct inpcb *)inp; stc.ipv6_addr_legal = 1; - /* Now look at the binding flag to see if V4 will be legal */ - if (SCTP_IPV6_V6ONLY(in_inp) == 0) { - stc.ipv4_addr_legal = 1; - } else { - /* V4 addresses are NOT legal on the association */ + if (SCTP_IPV6_V6ONLY(inp)) { stc.ipv4_addr_legal = 0; + } else { + stc.ipv4_addr_legal = 1; } } else { - /* Its a V4 socket, no - V6 */ - stc.ipv4_addr_legal = 1; stc.ipv6_addr_legal = 0; + stc.ipv4_addr_legal = 1; } - #ifdef SCTP_DONT_DO_PRIVADDR_SCOPE stc.ipv4_scope = 1; #else @@ -5629,10 +5551,10 @@ do_a_abort: #endif - stc.loopback_scope = asoc->loopback_scope; - stc.ipv4_scope = asoc->ipv4_local_scope; - stc.site_scope = asoc->site_scope; - stc.local_scope = asoc->local_scope; + stc.loopback_scope = asoc->scope.loopback_scope; + stc.ipv4_scope = asoc->scope.ipv4_local_scope; + stc.site_scope = asoc->scope.site_scope; + stc.local_scope = asoc->scope.local_scope; #ifdef INET6 /* Why do we not consider IPv4 LL addresses? */ TAILQ_FOREACH(lnet, &asoc->nets, sctp_next) { Modified: stable/9/sys/netinet/sctp_output.h ============================================================================== --- stable/9/sys/netinet/sctp_output.h Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_output.h Sun Jul 7 16:03:58 2013 (r252961) @@ -55,13 +55,9 @@ int sctp_is_addr_restricted(struct sctp_ int sctp_is_address_in_scope(struct sctp_ifa *ifa, - int ipv4_addr_legal, - int ipv6_addr_legal, - int loopback_scope, - int ipv4_local_scope, - int local_scope, - int site_scope, + struct sctp_scoping *scope, int do_update); + int sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa); Modified: stable/9/sys/netinet/sctp_pcb.c ============================================================================== --- stable/9/sys/netinet/sctp_pcb.c Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_pcb.c Sun Jul 7 16:03:58 2013 (r252961) @@ -94,11 +94,10 @@ sctp_fill_pcbinfo(struct sctp_pcbinfo *s spcb->readq_count = SCTP_BASE_INFO(ipi_count_readq); spcb->stream_oque = SCTP_BASE_INFO(ipi_count_strmoq); spcb->free_chunks = SCTP_BASE_INFO(ipi_free_chunks); - SCTP_INP_INFO_RUNLOCK(); } -/* +/*- * Addresses are added to VRF's (Virtual Router's). For BSD we * have only the default VRF 0. We maintain a hash list of * VRF's. Each VRF has its own list of sctp_ifn's. Each of @@ -214,7 +213,6 @@ sctp_find_ifn(void *ifn, uint32_t ifn_in } - struct sctp_vrf * sctp_find_vrf(uint32_t vrf_id) { @@ -230,6 +228,7 @@ sctp_find_vrf(uint32_t vrf_id) return (NULL); } + void sctp_free_vrf(struct sctp_vrf *vrf) { @@ -245,6 +244,7 @@ sctp_free_vrf(struct sctp_vrf *vrf) } } + void sctp_free_ifn(struct sctp_ifn *sctp_ifnp) { @@ -258,6 +258,7 @@ sctp_free_ifn(struct sctp_ifn *sctp_ifnp } } + void sctp_update_ifn_mtu(uint32_t ifn_index, uint32_t mtu) { @@ -283,6 +284,7 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap } } + static void sctp_delete_ifn(struct sctp_ifn *sctp_ifnp, int hold_addr_lock) { @@ -305,12 +307,13 @@ sctp_delete_ifn(struct sctp_ifn *sctp_if sctp_free_ifn(sctp_ifnp); } + void sctp_mark_ifa_addr_down(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index) { struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap = NULL; + struct sctp_ifa *sctp_ifap; SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(vrf_id); @@ -348,12 +351,13 @@ out: SCTP_IPI_ADDR_RUNLOCK(); } + void sctp_mark_ifa_addr_up(uint32_t vrf_id, struct sockaddr *addr, const char *if_name, uint32_t ifn_index) { struct sctp_vrf *vrf; - struct sctp_ifa *sctp_ifap = NULL; + struct sctp_ifa *sctp_ifap; SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(vrf_id); @@ -391,6 +395,7 @@ out: SCTP_IPI_ADDR_RUNLOCK(); } + /*- * Add an ifa to an ifn. * Register the interface as necessary. @@ -428,6 +433,7 @@ sctp_add_ifa_to_ifn(struct sctp_ifn *sct } } + /*- * Remove an ifa from its ifn. * If no more addresses exist, remove the ifn too. Otherwise, re-register @@ -479,6 +485,7 @@ sctp_remove_ifa_from_ifn(struct sctp_ifa } } + struct sctp_ifa * sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, uint32_t ifn_type, const char *if_name, void *ifa, @@ -1027,6 +1034,7 @@ sctp_tcb_special_locate(struct sctp_inpc return (NULL); } + static int sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) { @@ -1036,19 +1044,12 @@ sctp_does_stcb_own_this_addr(struct sctp struct sctp_ifn *sctp_ifn; struct sctp_ifa *sctp_ifa; - loopback_scope = stcb->asoc.loopback_scope; - ipv4_local_scope = stcb->asoc.ipv4_local_scope; - local_scope = stcb->asoc.local_scope; - site_scope = stcb->asoc.site_scope; - ipv4_addr_legal = ipv6_addr_legal = 0; - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - ipv6_addr_legal = 1; - if (SCTP_IPV6_V6ONLY(stcb->sctp_ep) == 0) { - ipv4_addr_legal = 1; - } - } else { - ipv4_addr_legal = 1; - } + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; SCTP_IPI_ADDR_RLOCK(); vrf = sctp_find_vrf(stcb->asoc.vrf_id); @@ -1183,6 +1184,7 @@ sctp_does_stcb_own_this_addr(struct sctp return (0); } + /* * rules for use * @@ -1471,11 +1473,11 @@ null_return: return (NULL); } + /* * Find an association for a specific endpoint using the association id given * out in the COMM_UP notification */ - struct sctp_tcb * sctp_findasoc_ep_asocid_locked(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock) { @@ -1536,6 +1538,9 @@ sctp_findassociation_ep_asocid(struct sc } +/* + * Endpoint probe expects that the INP_INFO is locked. + */ static struct sctp_inpcb * sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, uint16_t lport, uint32_t vrf_id) @@ -1552,12 +1557,8 @@ sctp_endpoint_probe(struct sockaddr *nam struct sockaddr_in6 *intf_addr6; #endif - int fnd; - /* - * Endpoint probe expects that the INP_INFO is locked. - */ #ifdef INET sin = NULL; #endif @@ -1893,6 +1894,7 @@ sctp_pcb_findep(struct sockaddr *nam, in return (inp); } + /* * Find an association for an endpoint with the pointer to whom you want to * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may @@ -2144,6 +2146,7 @@ sctp_findassoc_by_vtag(struct sockaddr * return (NULL); } + /* * Find an association with the pointer to the inbound IP packet. This can be * a IPv4 or IPv6 packet. @@ -3743,13 +3746,13 @@ sctp_add_remote_addr(struct sctp_tcb *st stcb->ipv4_local_scope = 1; #else if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { - stcb->asoc.ipv4_local_scope = 1; + stcb->asoc.scope.ipv4_local_scope = 1; } #endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */ } else { /* Validate the address is in scope */ if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) && - (stcb->asoc.ipv4_local_scope == 0)) { + (stcb->asoc.scope.ipv4_local_scope == 0)) { addr_inscope = 0; } } @@ -3770,10 +3773,10 @@ sctp_add_remote_addr(struct sctp_tcb *st sin6->sin6_len = sizeof(struct sockaddr_in6); if (set_scope) { if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) { - stcb->asoc.loopback_scope = 1; - stcb->asoc.local_scope = 0; - stcb->asoc.ipv4_local_scope = 1; - stcb->asoc.site_scope = 1; + stcb->asoc.scope.loopback_scope = 1; + stcb->asoc.scope.local_scope = 0; + stcb->asoc.scope.ipv4_local_scope = 1; + stcb->asoc.scope.site_scope = 1; } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { /* * If the new destination is a @@ -3785,26 +3788,26 @@ sctp_add_remote_addr(struct sctp_tcb *st * also be on our private network * for v4 too. */ - stcb->asoc.ipv4_local_scope = 1; - stcb->asoc.site_scope = 1; + stcb->asoc.scope.ipv4_local_scope = 1; + stcb->asoc.scope.site_scope = 1; } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { /* * If the new destination is * SITE_LOCAL then we must have site * scope in common. */ - stcb->asoc.site_scope = 1; + stcb->asoc.scope.site_scope = 1; } } else { /* Validate the address is in scope */ if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && - (stcb->asoc.loopback_scope == 0)) { + (stcb->asoc.scope.loopback_scope == 0)) { addr_inscope = 0; } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && - (stcb->asoc.local_scope == 0)) { + (stcb->asoc.scope.local_scope == 0)) { addr_inscope = 0; } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && - (stcb->asoc.site_scope == 0)) { + (stcb->asoc.scope.site_scope == 0)) { addr_inscope = 0; } } @@ -3839,10 +3842,10 @@ sctp_add_remote_addr(struct sctp_tcb *st } net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id); if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) { - stcb->asoc.loopback_scope = 1; - stcb->asoc.ipv4_local_scope = 1; - stcb->asoc.local_scope = 0; - stcb->asoc.site_scope = 1; + stcb->asoc.scope.loopback_scope = 1; + stcb->asoc.scope.ipv4_local_scope = 1; + stcb->asoc.scope.local_scope = 0; + stcb->asoc.scope.site_scope = 1; addr_inscope = 1; } net->failure_threshold = stcb->asoc.def_net_failure; @@ -6071,7 +6074,7 @@ sctp_load_addresses_from_init(struct sct switch (sa->sa_family) { #ifdef INET case AF_INET: - if (stcb->asoc.ipv4_addr_legal) { + if (stcb->asoc.scope.ipv4_addr_legal) { if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) { return (-1); } @@ -6080,7 +6083,7 @@ sctp_load_addresses_from_init(struct sct #endif #ifdef INET6 case AF_INET6: - if (stcb->asoc.ipv6_addr_legal) { + if (stcb->asoc.scope.ipv6_addr_legal) { if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) { return (-2); } @@ -6127,7 +6130,7 @@ sctp_load_addresses_from_init(struct sct } #ifdef INET if (ptype == SCTP_IPV4_ADDRESS) { - if (stcb->asoc.ipv4_addr_legal) { + if (stcb->asoc.scope.ipv4_addr_legal) { struct sctp_ipv4addr_param *p4, p4_buf; /* ok get the v4 address and check/add */ @@ -6213,7 +6216,7 @@ sctp_load_addresses_from_init(struct sct #endif #ifdef INET6 if (ptype == SCTP_IPV6_ADDRESS) { - if (stcb->asoc.ipv6_addr_legal) { + if (stcb->asoc.scope.ipv6_addr_legal) { /* ok get the v6 address and check/add */ struct sctp_ipv6addr_param *p6, p6_buf; Modified: stable/9/sys/netinet/sctp_structs.h ============================================================================== --- stable/9/sys/netinet/sctp_structs.h Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_structs.h Sun Jul 7 16:03:58 2013 (r252961) @@ -1177,17 +1177,7 @@ struct sctp_association { */ uint8_t peer_supports_pktdrop; - /* Do we allow V6/V4? */ - uint8_t ipv4_addr_legal; - uint8_t ipv6_addr_legal; - /* Address scoping flags */ - /* scope value for IPv4 */ - uint8_t ipv4_local_scope; - /* scope values for IPv6 */ - uint8_t local_scope; - uint8_t site_scope; - /* loopback scope */ - uint8_t loopback_scope; + struct sctp_scoping scope; /* flags to handle send alternate net tracking */ uint8_t used_alt_onsack; uint8_t used_alt_asconfack; Modified: stable/9/sys/netinet/sctp_sysctl.c ============================================================================== --- stable/9/sys/netinet/sctp_sysctl.c Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_sysctl.c Sun Jul 7 16:03:58 2013 (r252961) @@ -197,29 +197,29 @@ copy_out_local_addresses(struct sctp_inp /* Turn on all the appropriate scope */ if (stcb) { /* use association specific values */ - loopback_scope = stcb->asoc.loopback_scope; - ipv4_local_scope = stcb->asoc.ipv4_local_scope; - local_scope = stcb->asoc.local_scope; - site_scope = stcb->asoc.site_scope; + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; } else { - /* use generic values for endpoints */ + /* Use generic values for endpoints. */ loopback_scope = 1; ipv4_local_scope = 1; local_scope = 1; site_scope = 1; - } - - /* use only address families of interest */ - if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - ipv6_addr_legal = 1; - if (SCTP_IPV6_V6ONLY(inp)) { - ipv4_addr_legal = 0; + if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { + ipv6_addr_legal = 1; + if (SCTP_IPV6_V6ONLY(inp)) { + ipv4_addr_legal = 0; + } else { + ipv4_addr_legal = 1; + } } else { + ipv6_addr_legal = 0; ipv4_addr_legal = 1; } - } else { - ipv4_addr_legal = 1; - ipv6_addr_legal = 0; } /* neither Mac OS X nor FreeBSD support mulitple routing functions */ Modified: stable/9/sys/netinet/sctp_usrreq.c ============================================================================== --- stable/9/sys/netinet/sctp_usrreq.c Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctp_usrreq.c Sun Jul 7 16:03:58 2013 (r252961) @@ -1143,23 +1143,29 @@ sctp_fill_up_addresses_vrf(struct sctp_i if (stcb) { /* Turn on all the appropriate scope */ - loopback_scope = stcb->asoc.loopback_scope; - ipv4_local_scope = stcb->asoc.ipv4_local_scope; - local_scope = stcb->asoc.local_scope; - site_scope = stcb->asoc.site_scope; + loopback_scope = stcb->asoc.scope.loopback_scope; + ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; + local_scope = stcb->asoc.scope.local_scope; + site_scope = stcb->asoc.scope.site_scope; + ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; + ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; } else { - /* Turn on ALL scope, since we look at the EP */ - loopback_scope = ipv4_local_scope = local_scope = - site_scope = 1; - } - ipv4_addr_legal = ipv6_addr_legal = 0; - if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - ipv6_addr_legal = 1; - if (SCTP_IPV6_V6ONLY(inp) == 0) { + /* Use generic values for endpoints. */ + loopback_scope = 1; + ipv4_local_scope = 1; + local_scope = 1; + site_scope = 1; + if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { + ipv6_addr_legal = 1; + if (SCTP_IPV6_V6ONLY(inp)) { + ipv4_addr_legal = 0; + } else { + ipv4_addr_legal = 1; + } + } else { + ipv6_addr_legal = 0; ipv4_addr_legal = 1; } - } else { - ipv4_addr_legal = 1; } vrf = sctp_find_vrf(vrf_id); if (vrf == NULL) { @@ -1298,8 +1304,21 @@ sctp_fill_up_addresses_vrf(struct sctp_i } if (sctp_fill_user_address(sas, &laddr->ifa->address.sa)) continue; - - ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; + switch (laddr->ifa->address.sa.sa_family) { +#ifdef INET + case AF_INET: + ((struct sockaddr_in *)sas)->sin_port = inp->sctp_lport; + break; +#endif +#ifdef INET6 + case AF_INET6: + ((struct sockaddr_in6 *)sas)->sin6_port = inp->sctp_lport; + break; +#endif + default: + /* TSNH */ + break; + } sas = (struct sockaddr_storage *)((caddr_t)sas + laddr->ifa->address.sa.sa_len); actual += laddr->ifa->address.sa.sa_len; @@ -5948,7 +5967,7 @@ sctp_connect(struct socket *so, struct s error = EINVAL; goto out_now; } -#endif /* INET6 */ +#endif if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == SCTP_PCB_FLAGS_UNBOUND) { /* Bind a ephemeral port */ @@ -6242,8 +6261,8 @@ sctp_accept(struct socket *so, struct so return (ENOMEM); sin->sin_family = AF_INET; sin->sin_len = sizeof(*sin); - sin->sin_port = ((struct sockaddr_in *)&store)->sin_port; - sin->sin_addr = ((struct sockaddr_in *)&store)->sin_addr; + sin->sin_port = store.sin.sin_port; + sin->sin_addr = store.sin.sin_addr; *addr = (struct sockaddr *)sin; break; } @@ -6258,9 +6277,8 @@ sctp_accept(struct socket *so, struct so return (ENOMEM); sin6->sin6_family = AF_INET6; sin6->sin6_len = sizeof(*sin6); - sin6->sin6_port = ((struct sockaddr_in6 *)&store)->sin6_port; - - sin6->sin6_addr = ((struct sockaddr_in6 *)&store)->sin6_addr; + sin6->sin6_port = store.sin6.sin6_port; + sin6->sin6_addr = store.sin6.sin6_addr; if ((error = sa6_recoverscope(sin6)) != 0) { SCTP_FREE_SONAME(sin6); return (error); Modified: stable/9/sys/netinet/sctputil.c ============================================================================== --- stable/9/sys/netinet/sctputil.c Sun Jul 7 16:01:00 2013 (r252960) +++ stable/9/sys/netinet/sctputil.c Sun Jul 7 16:03:58 2013 (r252961) @@ -878,7 +878,7 @@ sctp_select_a_tag(struct sctp_inpcb *inp } int -sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb, +sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint32_t override_tag, uint32_t vrf_id) { struct sctp_association *asoc; @@ -899,23 +899,23 @@ sctp_init_asoc(struct sctp_inpcb *m, str asoc = &stcb->asoc; /* init all variables to a known value. */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***