sctp_output.c (166675) | sctp_output.c (167598) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, Cisco Systems, Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * a) Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 166675 2007-02-12 23:24:31Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 167598 2007-03-15 11:27:14Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> | 35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> |
39#include <netinet/sctp_sysctl.h> |
|
39#include <netinet/sctp_header.h> 40#include <netinet/sctp_pcb.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp_output.h> 43#include <netinet/sctp_uio.h> 44#include <netinet/sctputil.h> 45#include <netinet/sctp_auth.h> 46#include <netinet/sctp_timer.h> 47#include <netinet/sctp_asconf.h> 48#include <netinet/sctp_indata.h> 49#include <netinet/sctp_bsd_addr.h> 50 | 40#include <netinet/sctp_header.h> 41#include <netinet/sctp_pcb.h> 42#include <netinet/sctputil.h> 43#include <netinet/sctp_output.h> 44#include <netinet/sctp_uio.h> 45#include <netinet/sctputil.h> 46#include <netinet/sctp_auth.h> 47#include <netinet/sctp_timer.h> 48#include <netinet/sctp_asconf.h> 49#include <netinet/sctp_indata.h> 50#include <netinet/sctp_bsd_addr.h> 51 |
51#ifdef SCTP_DEBUG 52extern uint32_t sctp_debug_on; | |
53 | 52 |
54#endif | |
55 | 53 |
56 57 | |
58#define SCTP_MAX_GAPS_INARRAY 4 59struct sack_track { 60 uint8_t right_edge; /* mergable on the right edge */ 61 uint8_t left_edge; /* mergable on the left edge */ 62 uint8_t num_entries; 63 uint8_t spare; 64 struct sctp_gap_ack_block gaps[SCTP_MAX_GAPS_INARRAY]; 65}; --- 1789 unchanged lines hidden (view full) --- 1855 {0, 0}, 1856 {0, 0}, 1857 {0, 0} 1858 } 1859 } 1860}; 1861 1862 | 54#define SCTP_MAX_GAPS_INARRAY 4 55struct sack_track { 56 uint8_t right_edge; /* mergable on the right edge */ 57 uint8_t left_edge; /* mergable on the left edge */ 58 uint8_t num_entries; 59 uint8_t spare; 60 struct sctp_gap_ack_block gaps[SCTP_MAX_GAPS_INARRAY]; 61}; --- 1789 unchanged lines hidden (view full) --- 1851 {0, 0}, 1852 {0, 0}, 1853 {0, 0} 1854 } 1855 } 1856}; 1857 1858 |
1859int 1860sctp_is_address_in_scope(struct sctp_ifa *ifa, 1861 int ipv4_addr_legal, 1862 int ipv6_addr_legal, 1863 int loopback_scope, 1864 int ipv4_local_scope, 1865 int local_scope, 1866 int site_scope, 1867 int do_update) 1868{ 1869 if ((loopback_scope == 0) && 1870 (ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) { 1871 /* 1872 * skip loopback if not in scope * 1873 */ 1874 return (0); 1875 } 1876 if ((ifa->address.sa.sa_family == AF_INET) && ipv4_addr_legal) { 1877 struct sockaddr_in *sin; |
|
1863 | 1878 |
1879 sin = (struct sockaddr_in *)&ifa->address.sin; 1880 if (sin->sin_addr.s_addr == 0) { 1881 /* not in scope , unspecified */ 1882 return (0); 1883 } 1884 if ((ipv4_local_scope == 0) && 1885 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 1886 /* private address not in scope */ 1887 return (0); 1888 } 1889 } else if ((ifa->address.sa.sa_family == AF_INET6) && ipv6_addr_legal) { 1890 struct sockaddr_in6 *sin6; |
|
1864 | 1891 |
1865extern int sctp_peer_chunk_oh; | 1892 /* 1893 * Must update the flags, bummer, which means any IFA locks 1894 * must now be applied HERE <-> 1895 */ 1896 if (do_update) { 1897 sctp_gather_internal_ifa_flags(ifa); 1898 } 1899 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { 1900 return (0); 1901 } 1902 /* ok to use deprecated addresses? */ 1903 sin6 = (struct sockaddr_in6 *)&ifa->address.sin6; 1904 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 1905 /* skip unspecifed addresses */ 1906 return (0); 1907 } 1908 if ( /* (local_scope == 0) && */ 1909 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) { 1910 return (0); 1911 } 1912 if ((site_scope == 0) && 1913 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) { 1914 return (0); 1915 } 1916 } else { 1917 return (0); 1918 } 1919 return (1); 1920} |
1866 | 1921 |
1922static struct mbuf * 1923sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa) 1924{ 1925 struct sctp_paramhdr *parmh; 1926 struct mbuf *mret; 1927 int len; 1928 1929 if (ifa->address.sa.sa_family == AF_INET) { 1930 len = sizeof(struct sctp_ipv4addr_param); 1931 } else if (ifa->address.sa.sa_family == AF_INET6) { 1932 len = sizeof(struct sctp_ipv6addr_param); 1933 } else { 1934 /* unknown type */ 1935 return (m); 1936 } 1937 if (M_TRAILINGSPACE(m) >= len) { 1938 /* easy side we just drop it on the end */ 1939 parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m))); 1940 mret = m; 1941 } else { 1942 /* Need more space */ 1943 mret = m; 1944 while (SCTP_BUF_NEXT(mret) != NULL) { 1945 mret = SCTP_BUF_NEXT(mret); 1946 } 1947 SCTP_BUF_NEXT(mret) = sctp_get_mbuf_for_msg(len, 0, M_DONTWAIT, 1, MT_DATA); 1948 if (SCTP_BUF_NEXT(mret) == NULL) { 1949 /* We are hosed, can't add more addresses */ 1950 return (m); 1951 } 1952 mret = SCTP_BUF_NEXT(mret); 1953 parmh = mtod(mret, struct sctp_paramhdr *); 1954 } 1955 /* now add the parameter */ 1956 if (ifa->address.sa.sa_family == AF_INET) { 1957 struct sctp_ipv4addr_param *ipv4p; 1958 struct sockaddr_in *sin; 1959 1960 sin = (struct sockaddr_in *)&ifa->address.sin; 1961 ipv4p = (struct sctp_ipv4addr_param *)parmh; 1962 parmh->param_type = htons(SCTP_IPV4_ADDRESS); 1963 parmh->param_length = htons(len); 1964 ipv4p->addr = sin->sin_addr.s_addr; 1965 SCTP_BUF_LEN(mret) += len; 1966 } else if (ifa->address.sa.sa_family == AF_INET6) { 1967 struct sctp_ipv6addr_param *ipv6p; 1968 struct sockaddr_in6 *sin6; 1969 1970 sin6 = (struct sockaddr_in6 *)&ifa->address.sin6; 1971 ipv6p = (struct sctp_ipv6addr_param *)parmh; 1972 parmh->param_type = htons(SCTP_IPV6_ADDRESS); 1973 parmh->param_length = htons(len); 1974 memcpy(ipv6p->addr, &sin6->sin6_addr, 1975 sizeof(ipv6p->addr)); 1976 /* clear embedded scope in the address */ 1977 in6_clearscope((struct in6_addr *)ipv6p->addr); 1978 SCTP_BUF_LEN(mret) += len; 1979 } else { 1980 return (m); 1981 } 1982 return (mret); 1983} 1984 1985 1986struct mbuf * 1987sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_scoping *scope, 1988 struct mbuf *m_at, int cnt_inits_to) 1989{ 1990 struct sctp_vrf *vrf = NULL; 1991 int cnt, limit_out = 0, total_count; 1992 uint32_t vrf_id; 1993 1994 vrf_id = SCTP_DEFAULT_VRFID; 1995 SCTP_IPI_ADDR_LOCK(); 1996 vrf = sctp_find_vrf(vrf_id); 1997 if (vrf == NULL) { 1998 SCTP_IPI_ADDR_UNLOCK(); 1999 return (m_at); 2000 } 2001 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 2002 struct sctp_ifa *sctp_ifap; 2003 struct sctp_ifn *sctp_ifnp; 2004 2005 cnt = cnt_inits_to; 2006 if (vrf->total_ifa_count > SCTP_COUNT_LIMIT) { 2007 limit_out = 1; 2008 cnt = SCTP_ADDRESS_LIMIT; 2009 goto skip_count; 2010 } 2011 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) { 2012 if ((scope->loopback_scope == 0) && 2013 SCTP_IFN_IS_IFT_LOOP(sctp_ifnp)) { 2014 /* 2015 * Skip loopback devices if loopback_scope 2016 * not set 2017 */ 2018 continue; 2019 } 2020 LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) { 2021 if (sctp_is_address_in_scope(sctp_ifap, 2022 scope->ipv4_addr_legal, 2023 scope->ipv6_addr_legal, 2024 scope->loopback_scope, 2025 scope->ipv4_local_scope, 2026 scope->local_scope, 2027 scope->site_scope, 1) == 0) { 2028 continue; 2029 } 2030 cnt++; 2031 if (cnt > SCTP_ADDRESS_LIMIT) { 2032 break; 2033 } 2034 } 2035 if (cnt > SCTP_ADDRESS_LIMIT) { 2036 break; 2037 } 2038 } 2039skip_count: 2040 if (cnt > 1) { 2041 total_count = 0; 2042 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) { 2043 cnt = 0; 2044 if ((scope->loopback_scope == 0) && 2045 SCTP_IFN_IS_IFT_LOOP(sctp_ifnp)) { 2046 /* 2047 * Skip loopback devices if 2048 * loopback_scope not set 2049 */ 2050 continue; 2051 } 2052 LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) { 2053 if (sctp_is_address_in_scope(sctp_ifap, 2054 scope->ipv4_addr_legal, 2055 scope->ipv6_addr_legal, 2056 scope->loopback_scope, 2057 scope->ipv4_local_scope, 2058 scope->local_scope, 2059 scope->site_scope, 0) == 0) { 2060 continue; 2061 } 2062 m_at = sctp_add_addr_to_mbuf(m_at, sctp_ifap); 2063 if (limit_out) { 2064 cnt++; 2065 total_count++; 2066 if (cnt >= 2) { 2067 /* 2068 * two from each 2069 * address 2070 */ 2071 break; 2072 } 2073 if (total_count > SCTP_ADDRESS_LIMIT) { 2074 /* No more addresses */ 2075 break; 2076 } 2077 } 2078 } 2079 } 2080 } 2081 } else { 2082 struct sctp_laddr *laddr; 2083 2084 cnt = cnt_inits_to; 2085 /* First, how many ? */ 2086 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 2087 if (laddr->ifa == NULL) { 2088 continue; 2089 } 2090 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) 2091 /* 2092 * Address being deleted by the system, dont 2093 * list. 2094 */ 2095 continue; 2096 if (laddr->action == SCTP_DEL_IP_ADDRESS) { 2097 /* 2098 * Address being deleted on this ep don't 2099 * list. 2100 */ 2101 continue; 2102 } 2103 if (sctp_is_address_in_scope(laddr->ifa, 2104 scope->ipv4_addr_legal, 2105 scope->ipv6_addr_legal, 2106 scope->loopback_scope, 2107 scope->ipv4_local_scope, 2108 scope->local_scope, 2109 scope->site_scope, 1) == 0) { 2110 continue; 2111 } 2112 cnt++; 2113 } 2114 if (cnt > SCTP_ADDRESS_LIMIT) { 2115 limit_out = 1; 2116 } 2117 /* 2118 * To get through a NAT we only list addresses if we have 2119 * more than one. That way if you just bind a single address 2120 * we let the source of the init dictate our address. 2121 */ 2122 if (cnt > 1) { 2123 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 2124 cnt = 0; 2125 if (laddr->ifa == NULL) { 2126 continue; 2127 } 2128 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) 2129 continue; 2130 2131 if (sctp_is_address_in_scope(laddr->ifa, 2132 scope->ipv4_addr_legal, 2133 scope->ipv6_addr_legal, 2134 scope->loopback_scope, 2135 scope->ipv4_local_scope, 2136 scope->local_scope, 2137 scope->site_scope, 0) == 0) { 2138 continue; 2139 } 2140 m_at = sctp_add_addr_to_mbuf(m_at, laddr->ifa); 2141 cnt++; 2142 if (cnt >= SCTP_ADDRESS_LIMIT) { 2143 break; 2144 } 2145 } 2146 } 2147 } 2148 SCTP_IPI_ADDR_UNLOCK(); 2149 return (m_at); 2150} 2151 2152static struct sctp_ifa * 2153sctp_is_ifa_addr_prefered(struct sctp_ifa *ifa, 2154 uint8_t dest_is_loop, 2155 uint8_t dest_is_priv, 2156 sa_family_t fam) 2157{ 2158 uint8_t dest_is_global = 0; 2159 2160 /* 2161 * is_scope -> dest_is_priv is true if destination is a private 2162 * address 2163 */ 2164 /* dest_is_loop is true if destination is a loopback addresses */ 2165 2166 /* 2167 * Here we determine if its a prefered address. A prefered address 2168 * means it is the same scope or higher scope then the destination. 2169 * L = loopback, P = private, G = global 2170 * ----------------------------------------- src | dest | result 2171 * ---------------------------------------- L | L | yes 2172 * ----------------------------------------- P | L | 2173 * yes-v4 no-v6 ----------------------------------------- G | 2174 * L | yes-v4 no-v6 ----------------------------------------- L 2175 * | P | no ----------------------------------------- P | 2176 * P | yes ----------------------------------------- G | 2177 * P | no ----------------------------------------- L | G 2178 * | no ----------------------------------------- P | G | 2179 * no ----------------------------------------- G | G | 2180 * yes ----------------------------------------- 2181 */ 2182 2183 if (ifa->address.sa.sa_family != fam) { 2184 /* forget mis-matched family */ 2185 return (NULL); 2186 } 2187 if ((dest_is_priv == 0) && (dest_is_loop == 0)) { 2188 dest_is_global = 1; 2189 } 2190 /* Ok the address may be ok */ 2191 if (fam == AF_INET6) { 2192 /* ok to use deprecated addresses? */ 2193 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { 2194 return (NULL); 2195 } 2196 if (ifa->src_is_priv) { 2197 if (dest_is_loop) { 2198 return (NULL); 2199 } 2200 } 2201 if (ifa->src_is_glob) { 2202 2203 if (dest_is_loop) { 2204 return (NULL); 2205 } 2206 } 2207 } 2208 /* 2209 * Now that we know what is what, implement or table this could in 2210 * theory be done slicker (it used to be), but this is 2211 * straightforward and easier to validate :-) 2212 */ 2213 if ((ifa->src_is_loop) && (dest_is_priv)) { 2214 return (NULL); 2215 } 2216 if ((ifa->src_is_glob) && (dest_is_priv)) { 2217 return (NULL); 2218 } 2219 if ((ifa->src_is_loop) && (dest_is_global)) { 2220 return (NULL); 2221 } 2222 if ((ifa->src_is_priv) && (dest_is_global)) { 2223 return (NULL); 2224 } 2225 /* its a prefered address */ 2226 return (ifa); 2227} 2228 2229static struct sctp_ifa * 2230sctp_is_ifa_addr_acceptable(struct sctp_ifa *ifa, 2231 uint8_t dest_is_loop, 2232 uint8_t dest_is_priv, 2233 sa_family_t fam) 2234{ 2235 uint8_t dest_is_global = 0; 2236 2237 2238 /* 2239 * Here we determine if its a acceptable address. A acceptable 2240 * address means it is the same scope or higher scope but we can 2241 * allow for NAT which means its ok to have a global dest and a 2242 * private src. 2243 * 2244 * L = loopback, P = private, G = global 2245 * ----------------------------------------- src | dest | result 2246 * ----------------------------------------- L | L | yes 2247 * ----------------------------------------- P | L | 2248 * yes-v4 no-v6 ----------------------------------------- G | 2249 * L | yes ----------------------------------------- L | 2250 * P | no ----------------------------------------- P | P 2251 * | yes ----------------------------------------- G | P 2252 * | yes - May not work ----------------------------------------- 2253 * L | G | no ----------------------------------------- P 2254 * | G | yes - May not work 2255 * ----------------------------------------- G | G | yes 2256 * ----------------------------------------- 2257 */ 2258 2259 if (ifa->address.sa.sa_family != fam) { 2260 /* forget non matching family */ 2261 return (NULL); 2262 } 2263 /* Ok the address may be ok */ 2264 if ((dest_is_loop == 0) && (dest_is_priv == 0)) { 2265 dest_is_global = 1; 2266 } 2267 if (fam == AF_INET6) { 2268 /* ok to use deprecated addresses? */ 2269 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { 2270 return (NULL); 2271 } 2272 if (ifa->src_is_priv) { 2273 /* Special case, linklocal to loop */ 2274 if (dest_is_loop) 2275 return (NULL); 2276 } 2277 } 2278 /* 2279 * Now that we know what is what, implement or table this could in 2280 * theory be done slicker (it used to be), but this is 2281 * straightforward and easier to validate :-) 2282 */ 2283 2284 if ((ifa->src_is_loop == 0) && (dest_is_priv)) { 2285 return (NULL); 2286 } 2287 if ((ifa->src_is_loop == 0) && (dest_is_global)) { 2288 return (NULL); 2289 } 2290 /* its an acceptable address */ 2291 return (ifa); 2292} 2293 2294int 2295sctp_is_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa) 2296{ 2297 struct sctp_laddr *laddr; 2298 2299 if (stcb == NULL) { 2300 /* There are no restrictions, no TCB :-) */ 2301 return (0); 2302 } 2303 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) { 2304 if (laddr->ifa == NULL) { 2305#ifdef SCTP_DEBUG 2306 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 2307 printf("Help I have fallen and I can't get up!\n"); 2308 } 2309#endif 2310 continue; 2311 } 2312 if (laddr->ifa == ifa) { 2313 /* Yes it is on the list */ 2314 return (1); 2315 } 2316 } 2317 return (0); 2318} 2319 2320 2321int 2322sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa) 2323{ 2324 struct sctp_laddr *laddr; 2325 2326 if (ifa == NULL) 2327 return (0); 2328 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 2329 if (laddr->ifa == NULL) { 2330#ifdef SCTP_DEBUG 2331 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 2332 printf("Help I have fallen and I can't get up!\n"); 2333 } 2334#endif 2335 continue; 2336 } 2337 if ((laddr->ifa == ifa) && laddr->action == 0) 2338 /* same pointer */ 2339 return (1); 2340 } 2341 return (0); 2342} 2343 2344 2345 2346static struct sctp_ifa * 2347sctp_choose_boundspecific_inp(struct sctp_inpcb *inp, 2348 struct route *ro, 2349 uint32_t vrf_id, 2350 int non_asoc_addr_ok, 2351 uint8_t dest_is_priv, 2352 uint8_t dest_is_loop, 2353 sa_family_t fam) 2354{ 2355 struct sctp_laddr *laddr, *starting_point; 2356 void *ifn; 2357 int resettotop = 0; 2358 struct sctp_ifn *sctp_ifn; 2359 struct sctp_ifa *sctp_ifa, *pass; 2360 struct sctp_vrf *vrf; 2361 uint32_t ifn_index; 2362 2363 vrf = sctp_find_vrf(vrf_id); 2364 if (vrf == NULL) 2365 return (NULL); 2366 2367 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro); 2368 ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro); 2369 sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index); 2370 /* 2371 * first question, is the ifn we will emit on in our list, if so, we 2372 * want such an address. Note that we first looked for a prefered 2373 * address. 2374 */ 2375 if (sctp_ifn) { 2376 /* is a prefered one on the interface we route out? */ 2377 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2378 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2379 continue; 2380 pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2381 if (pass == NULL) 2382 continue; 2383 if (sctp_is_addr_in_ep(inp, pass)) { 2384 atomic_add_int(&pass->refcount, 1); 2385 return (pass); 2386 } 2387 } 2388 } 2389 /* 2390 * ok, now we now need to find one on the list of the addresses. We 2391 * can't get one on the emitting interface so lets find first a 2392 * prefered one. If not that a acceptable one otherwise... we return 2393 * NULL. 2394 */ 2395 starting_point = inp->next_addr_touse; 2396once_again: 2397 if (inp->next_addr_touse == NULL) { 2398 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list); 2399 resettotop = 1; 2400 } 2401 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2402 if (laddr->ifa == NULL) { 2403 /* address has been removed */ 2404 continue; 2405 } 2406 pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2407 if (pass == NULL) 2408 continue; 2409 atomic_add_int(&pass->refcount, 1); 2410 return (pass); 2411 } 2412 if (resettotop == 0) { 2413 inp->next_addr_touse = NULL; 2414 goto once_again; 2415 } 2416 inp->next_addr_touse = starting_point; 2417 resettotop = 0; 2418once_again_too: 2419 if (inp->next_addr_touse == NULL) { 2420 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list); 2421 resettotop = 1; 2422 } 2423 /* ok, what about an acceptable address in the inp */ 2424 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2425 if (laddr->ifa == NULL) { 2426 /* address has been removed */ 2427 continue; 2428 } 2429 pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2430 if (pass == NULL) 2431 continue; 2432 atomic_add_int(&pass->refcount, 1); 2433 return (pass); 2434 } 2435 if (resettotop == 0) { 2436 inp->next_addr_touse = NULL; 2437 goto once_again_too; 2438 } 2439 /* 2440 * no address bound can be a source for the destination we are in 2441 * trouble 2442 */ 2443 return (NULL); 2444} 2445 2446 2447 2448static struct sctp_ifa * 2449sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, 2450 struct sctp_tcb *stcb, 2451 struct sctp_nets *net, 2452 struct route *ro, 2453 uint32_t vrf_id, 2454 uint8_t dest_is_priv, 2455 uint8_t dest_is_loop, 2456 int non_asoc_addr_ok, 2457 sa_family_t fam) 2458{ 2459 struct sctp_laddr *laddr, *starting_point; 2460 void *ifn; 2461 struct sctp_ifn *sctp_ifn; 2462 struct sctp_ifa *sctp_ifa, *pass; 2463 uint8_t start_at_beginning = 0; 2464 struct sctp_vrf *vrf; 2465 uint32_t ifn_index; 2466 2467 /* 2468 * first question, is the ifn we will emit on in our list, if so, we 2469 * want that one. 2470 */ 2471 vrf = sctp_find_vrf(vrf_id); 2472 if (vrf == NULL) 2473 return (NULL); 2474 2475 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro); 2476 ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro); 2477 sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index); 2478 2479 /* 2480 * first question, is the ifn we will emit on in our list, if so, we 2481 * want that one.. First we look for a prefered. Second we go for an 2482 * acceptable. 2483 */ 2484 if (sctp_ifn) { 2485 /* first try for an prefered address on the ep */ 2486 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2487 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2488 continue; 2489 if (sctp_is_addr_in_ep(inp, sctp_ifa)) { 2490 pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2491 if (pass == NULL) 2492 continue; 2493 if ((non_asoc_addr_ok == 0) && 2494 (sctp_is_addr_restricted(stcb, pass))) { 2495 /* on the no-no list */ 2496 continue; 2497 } 2498 atomic_add_int(&pass->refcount, 1); 2499 return (pass); 2500 } 2501 } 2502 /* next try for an acceptable address on the ep */ 2503 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2504 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2505 continue; 2506 if (sctp_is_addr_in_ep(inp, sctp_ifa)) { 2507 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2508 if (pass == NULL) 2509 continue; 2510 if ((non_asoc_addr_ok == 0) && 2511 (sctp_is_addr_restricted(stcb, pass))) { 2512 /* on the no-no list */ 2513 continue; 2514 } 2515 atomic_add_int(&pass->refcount, 1); 2516 return (pass); 2517 } 2518 } 2519 2520 } 2521 /* 2522 * if we can't find one like that then we must look at all addresses 2523 * bound to pick one at first prefereable then secondly acceptable. 2524 */ 2525 starting_point = stcb->asoc.last_used_address; 2526sctp_from_the_top: 2527 if (stcb->asoc.last_used_address == NULL) { 2528 start_at_beginning = 1; 2529 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list); 2530 } 2531 /* search beginning with the last used address */ 2532 for (laddr = stcb->asoc.last_used_address; laddr; 2533 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2534 if (laddr->ifa == NULL) { 2535 /* address has been removed */ 2536 continue; 2537 } 2538 pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2539 if (pass == NULL) 2540 continue; 2541 if ((non_asoc_addr_ok == 0) && 2542 (sctp_is_addr_restricted(stcb, pass))) { 2543 /* on the no-no list */ 2544 continue; 2545 } 2546 stcb->asoc.last_used_address = laddr; 2547 atomic_add_int(&pass->refcount, 1); 2548 return (pass); 2549 2550 } 2551 if (start_at_beginning == 0) { 2552 stcb->asoc.last_used_address = NULL; 2553 goto sctp_from_the_top; 2554 } 2555 /* now try for any higher scope than the destination */ 2556 stcb->asoc.last_used_address = starting_point; 2557 start_at_beginning = 0; 2558sctp_from_the_top2: 2559 if (stcb->asoc.last_used_address == NULL) { 2560 start_at_beginning = 1; 2561 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list); 2562 } 2563 /* search beginning with the last used address */ 2564 for (laddr = stcb->asoc.last_used_address; laddr; 2565 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) { 2566 if (laddr->ifa == NULL) { 2567 /* address has been removed */ 2568 continue; 2569 } 2570 pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam); 2571 if (pass == NULL) 2572 continue; 2573 if ((non_asoc_addr_ok == 0) && 2574 (sctp_is_addr_restricted(stcb, pass))) { 2575 /* on the no-no list */ 2576 continue; 2577 } 2578 stcb->asoc.last_used_address = laddr; 2579 atomic_add_int(&pass->refcount, 1); 2580 return (pass); 2581 } 2582 if (start_at_beginning == 0) { 2583 stcb->asoc.last_used_address = NULL; 2584 goto sctp_from_the_top2; 2585 } 2586 return (NULL); 2587} 2588 2589static struct sctp_ifa * 2590sctp_select_nth_prefered_addr_from_ifn_boundall(struct sctp_ifn *ifn, 2591 struct sctp_tcb *stcb, 2592 int non_asoc_addr_ok, 2593 uint8_t dest_is_loop, 2594 uint8_t dest_is_priv, 2595 int addr_wanted, 2596 sa_family_t fam) 2597{ 2598 struct sctp_ifa *ifa, *pass; 2599 int num_eligible_addr = 0; 2600 2601 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { 2602 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2603 continue; 2604 pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam); 2605 if (pass == NULL) 2606 continue; 2607 if (stcb) { 2608 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { 2609 /* 2610 * It is restricted for some reason.. 2611 * probably not yet added. 2612 */ 2613 continue; 2614 } 2615 } 2616 if (num_eligible_addr >= addr_wanted) { 2617 return (pass); 2618 } 2619 num_eligible_addr++; 2620 } 2621 return (NULL); 2622} 2623 2624 |
|
1867static int | 2625static int |
2626sctp_count_num_prefered_boundall(struct sctp_ifn *ifn, 2627 struct sctp_tcb *stcb, 2628 int non_asoc_addr_ok, 2629 uint8_t dest_is_loop, 2630 uint8_t dest_is_priv, 2631 sa_family_t fam) 2632{ 2633 struct sctp_ifa *ifa, *pass; 2634 int num_eligible_addr = 0; 2635 2636 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) { 2637 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) { 2638 continue; 2639 } 2640 pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam); 2641 if (pass == NULL) { 2642 continue; 2643 } 2644 if (stcb) { 2645 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { 2646 /* 2647 * It is restricted for some reason.. 2648 * probably not yet added. 2649 */ 2650 continue; 2651 } 2652 } 2653 num_eligible_addr++; 2654 } 2655 return (num_eligible_addr); 2656} 2657 2658static struct sctp_ifa * 2659sctp_choose_boundall(struct sctp_inpcb *inp, 2660 struct sctp_tcb *stcb, 2661 struct sctp_nets *net, 2662 struct route *ro, 2663 uint32_t vrf_id, 2664 uint8_t dest_is_priv, 2665 uint8_t dest_is_loop, 2666 int non_asoc_addr_ok, 2667 sa_family_t fam) 2668{ 2669 int cur_addr_num = 0, num_prefered = 0; 2670 void *ifn; 2671 struct sctp_ifn *sctp_ifn, *looked_at = NULL, *emit_ifn; 2672 struct sctp_ifa *sctp_ifa, *pass; 2673 uint32_t ifn_index; 2674 struct sctp_vrf *vrf; 2675 2676 /* 2677 * For boundall we can use any address in the association. If 2678 * non_asoc_addr_ok is set we can use any address (at least in 2679 * theory). So we look for prefered addresses first. If we find one, 2680 * we use it. Otherwise we next try to get an address on the 2681 * interface, which we should be able to do (unless non_asoc_addr_ok 2682 * is false and we are routed out that way). In these cases where we 2683 * can't use the address of the interface we go through all the 2684 * ifn's looking for an address we can use and fill that in. Punting 2685 * means we send back address 0, which will probably cause problems 2686 * actually since then IP will fill in the address of the route ifn, 2687 * which means we probably already rejected it.. i.e. here comes an 2688 * abort :-<. 2689 */ 2690 vrf = sctp_find_vrf(vrf_id); 2691 if (vrf == NULL) 2692 return (NULL); 2693 2694 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro); 2695 ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro); 2696 2697 emit_ifn = looked_at = sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index); 2698 if (sctp_ifn == NULL) { 2699 /* ?? We don't have this guy ?? */ 2700 goto bound_all_plan_b; 2701 } 2702 if (net) { 2703 cur_addr_num = net->indx_of_eligible_next_to_use; 2704 } 2705 num_prefered = sctp_count_num_prefered_boundall(sctp_ifn, 2706 stcb, 2707 non_asoc_addr_ok, 2708 dest_is_loop, 2709 dest_is_priv, fam); 2710#ifdef SCTP_DEBUG 2711 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 2712 printf("Found %d prefered source addresses\n", num_prefered); 2713 } 2714#endif 2715 if (num_prefered == 0) { 2716 /* 2717 * no eligible addresses, we must use some other interface 2718 * address if we can find one. 2719 */ 2720 goto bound_all_plan_b; 2721 } 2722 /* 2723 * Ok we have num_eligible_addr set with how many we can use, this 2724 * may vary from call to call due to addresses being deprecated 2725 * etc.. 2726 */ 2727 if (cur_addr_num >= num_prefered) { 2728 cur_addr_num = 0; 2729 } 2730 /* 2731 * select the nth address from the list (where cur_addr_num is the 2732 * nth) and 0 is the first one, 1 is the second one etc... 2733 */ 2734#ifdef SCTP_DEBUG 2735 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 2736 printf("cur_addr_num:%d\n", cur_addr_num); 2737 } 2738#endif 2739 sctp_ifa = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, 2740 dest_is_priv, cur_addr_num, fam); 2741 2742 /* if sctp_ifa is NULL something changed??, fall to plan b. */ 2743 if (sctp_ifa) { 2744 atomic_add_int(&sctp_ifa->refcount, 1); 2745 if (net) { 2746 /* save off where the next one we will want */ 2747 net->indx_of_eligible_next_to_use = cur_addr_num + 1; 2748 } 2749 return (sctp_ifa); 2750 } 2751 /* 2752 * plan_b: Look at all interfaces and find a prefered address. If no 2753 * prefered fall through to plan_c. 2754 */ 2755bound_all_plan_b: 2756 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 2757 if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { 2758 /* wrong base scope */ 2759 continue; 2760 } 2761 if ((sctp_ifn == looked_at) && looked_at) 2762 /* already looked at this guy */ 2763 continue; 2764 num_prefered = sctp_count_num_prefered_boundall(sctp_ifn, stcb, non_asoc_addr_ok, 2765 dest_is_loop, dest_is_priv, fam); 2766#ifdef SCTP_DEBUG 2767 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 2768 printf("Found ifn:%p %d prefered source addresses\n", ifn, num_prefered); 2769 } 2770#endif 2771 if (num_prefered == 0) { 2772 /* 2773 * None on this interface. 2774 */ 2775 continue; 2776 } 2777#ifdef SCTP_DEBUG 2778 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 2779 printf("num prefered:%d on interface:%p cur_addr_num:%d\n", 2780 num_prefered, 2781 sctp_ifn, 2782 cur_addr_num); 2783 } 2784#endif 2785 2786 /* 2787 * Ok we have num_eligible_addr set with how many we can 2788 * use, this may vary from call to call due to addresses 2789 * being deprecated etc.. 2790 */ 2791 if (cur_addr_num >= num_prefered) { 2792 cur_addr_num = 0; 2793 } 2794 pass = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop, 2795 dest_is_priv, cur_addr_num, fam); 2796 if (pass == NULL) 2797 continue; 2798 if (net) { 2799 net->indx_of_eligible_next_to_use = cur_addr_num + 1; 2800#ifdef SCTP_DEBUG 2801 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 2802 printf("we selected %d\n", cur_addr_num); 2803 printf("Source:"); 2804 sctp_print_address(&pass->address.sa); 2805 printf("Dest:"); 2806 sctp_print_address(&net->ro._l_addr.sa); 2807 } 2808#endif 2809 } 2810 atomic_add_int(&pass->refcount, 1); 2811 return (pass); 2812 2813 } 2814 2815 /* 2816 * plan_c: See if we have an acceptable address on the emit 2817 * interface 2818 */ 2819#ifdef SCTP_DEBUG 2820 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) { 2821 if (net) { 2822 printf("Plan C no prefered for Dest:"); 2823 sctp_print_address(&net->ro._l_addr.sa); 2824 } 2825 } 2826#endif 2827 2828 LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) { 2829 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2830 continue; 2831 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2832 if (pass == NULL) 2833 continue; 2834 if (stcb) { 2835 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { 2836 /* 2837 * It is restricted for some reason.. 2838 * probably not yet added. 2839 */ 2840 continue; 2841 } 2842 } 2843 atomic_add_int(&pass->refcount, 1); 2844 return (pass); 2845 } 2846 2847 /* 2848 * plan_d: We are in trouble. No prefered address on the emit 2849 * interface. And not even a perfered address on all interfaces. Go 2850 * out and see if we can find an acceptable address somewhere 2851 * amongst all interfaces. 2852 */ 2853 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { 2854 if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { 2855 /* wrong base scope */ 2856 continue; 2857 } 2858 if ((sctp_ifn == looked_at) && looked_at) 2859 /* already looked at this guy */ 2860 continue; 2861 2862 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { 2863 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) 2864 continue; 2865 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam); 2866 if (pass == NULL) 2867 continue; 2868 if (stcb) { 2869 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) { 2870 /* 2871 * It is restricted for some 2872 * reason.. probably not yet added. 2873 */ 2874 continue; 2875 } 2876 } 2877 atomic_add_int(&pass->refcount, 1); 2878 return (pass); 2879 } 2880 } 2881 /* 2882 * Ok we can find NO address to source from that is not on our 2883 * negative list and non_asoc_address is NOT ok, or its on our 2884 * negative list. We cant source to it :-( 2885 */ 2886 return (NULL); 2887} 2888 2889 2890 2891/* tcb may be NULL */ 2892struct sctp_ifa * 2893sctp_source_address_selection(struct sctp_inpcb *inp, 2894 struct sctp_tcb *stcb, 2895 struct route *ro, 2896 struct sctp_nets *net, 2897 int non_asoc_addr_ok, uint32_t vrf_id) 2898{ 2899 2900 struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst; 2901 struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst; 2902 struct sctp_ifa *answer; 2903 uint8_t dest_is_priv, dest_is_loop; 2904 int did_rtalloc = 0; 2905 sa_family_t fam; 2906 2907 /* 2908 * Rules: - Find the route if needed, cache if I can. - Look at 2909 * interface address in route, Is it in the bound list. If so we 2910 * have the best source. - If not we must rotate amongst the 2911 * addresses. 2912 * 2913 * Cavets and issues 2914 * 2915 * Do we need to pay attention to scope. We can have a private address 2916 * or a global address we are sourcing or sending to. So if we draw 2917 * it out zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 2918 * For V4 ------------------------------------------ source * 2919 * dest * result ----------------------------------------- <a> 2920 * Private * Global * NAT 2921 * ----------------------------------------- <b> Private * 2922 * Private * No problem ----------------------------------------- 2923 * <c> Global * Private * Huh, How will this work? 2924 * ----------------------------------------- <d> Global * 2925 * Global * No Problem ------------------------------------------ 2926 * zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz For V6 2927 * ------------------------------------------ source * dest * 2928 * result ----------------------------------------- <a> Linklocal * 2929 * Global * ----------------------------------------- <b> 2930 * Linklocal * Linklocal * No problem 2931 * ----------------------------------------- <c> Global * 2932 * Linklocal * Huh, How will this work? 2933 * ----------------------------------------- <d> Global * 2934 * Global * No Problem ------------------------------------------ 2935 * zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 2936 * 2937 * And then we add to that what happens if there are multiple addresses 2938 * assigned to an interface. Remember the ifa on a ifn is a linked 2939 * list of addresses. So one interface can have more than one IP 2940 * address. What happens if we have both a private and a global 2941 * address? Do we then use context of destination to sort out which 2942 * one is best? And what about NAT's sending P->G may get you a NAT 2943 * translation, or should you select the G thats on the interface in 2944 * preference. 2945 * 2946 * Decisions: 2947 * 2948 * - count the number of addresses on the interface. - if its one, no 2949 * problem except case <c>. For <a> we will assume a NAT out there. 2950 * - if there are more than one, then we need to worry about scope P 2951 * or G. We should prefer G -> G and P -> P if possible. Then as a 2952 * secondary fall back to mixed types G->P being a last ditch one. - 2953 * The above all works for bound all, but bound specific we need to 2954 * use the same concept but instead only consider the bound 2955 * addresses. If the bound set is NOT assigned to the interface then 2956 * we must use rotation amongst the bound addresses.. 2957 * 2958 */ 2959 if (ro->ro_rt == NULL) { 2960 /* 2961 * Need a route to cache. 2962 * 2963 */ 2964 rtalloc_ign(ro, 0UL); 2965 did_rtalloc = 1; 2966 } 2967 if (ro->ro_rt == NULL) { 2968 return (NULL); 2969 } 2970 fam = to->sin_family; 2971 dest_is_priv = dest_is_loop = 0; 2972 /* Setup our scopes for the destination */ 2973 if (fam == AF_INET) { 2974 /* Scope based on outbound address */ 2975 if ((IN4_ISPRIVATE_ADDRESS(&to->sin_addr))) { 2976 dest_is_priv = 1; 2977 } else if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) { 2978 dest_is_loop = 1; 2979 if (net != NULL) { 2980 /* mark it as local */ 2981 net->addr_is_local = 1; 2982 } 2983 } 2984 } else if (fam == AF_INET6) { 2985 /* Scope based on outbound address */ 2986 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) { 2987 /* 2988 * If the route goes to the loopback address OR the 2989 * address is a loopback address, we are loopback 2990 * scope. But we don't use dest_is_priv (link local 2991 * addresses). 2992 */ 2993 dest_is_loop = 1; 2994 if (net != NULL) { 2995 /* mark it as local */ 2996 net->addr_is_local = 1; 2997 } 2998 } else if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) { 2999 dest_is_priv = 1; 3000 } 3001 } 3002 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 3003 /* 3004 * When bound to all if the address list is set it is a 3005 * negative list. Addresses being added by asconf. 3006 */ 3007 answer = sctp_choose_boundall(inp, stcb, net, ro, vrf_id, 3008 dest_is_priv, 3009 dest_is_loop, 3010 non_asoc_addr_ok, 3011 fam); 3012 return (answer); 3013 } 3014 /* 3015 * Three possiblities here: 3016 * 3017 * a) stcb is NULL, which means we operate only from the list of 3018 * addresses (ifa's) bound to the endpoint and we care not about the 3019 * list. b) stcb is NOT-NULL, which means we have an assoc structure 3020 * and auto-asconf is on. This means that the list of addresses is a 3021 * NOT list. We use the list from the inp, but any listed address in 3022 * our list is NOT yet added. However if the non_asoc_addr_ok is set 3023 * we CAN use an address NOT available (i.e. being added). Its a 3024 * negative list. c) stcb is NOT-NULL, which means we have an assoc 3025 * structure and auto-asconf is off. This means that the list of 3026 * addresses is the ONLY addresses I can use.. its positive. 3027 * 3028 * Note we collapse b & c into the same function just like in the v6 3029 * address selection. 3030 */ 3031 if (stcb) { 3032 answer = sctp_choose_boundspecific_stcb(inp, stcb, net, ro, vrf_id, 3033 dest_is_priv, dest_is_loop, non_asoc_addr_ok, fam); 3034 3035 } else { 3036 answer = sctp_choose_boundspecific_inp(inp, ro, vrf_id, non_asoc_addr_ok, dest_is_priv, dest_is_loop, fam); 3037 3038 } 3039 return (answer); 3040} 3041 3042static int |
|
1868sctp_find_cmsg(int c_type, void *data, struct mbuf *control, int cpsize) 1869{ 1870 struct cmsghdr cmh; 1871 int tlen, at; 1872 1873 tlen = SCTP_BUF_LEN(control); 1874 at = 0; 1875 /* --- 33 unchanged lines hidden (view full) --- 1909 } 1910 } 1911 } 1912 /* not found */ 1913 return (0); 1914} 1915 1916 | 3043sctp_find_cmsg(int c_type, void *data, struct mbuf *control, int cpsize) 3044{ 3045 struct cmsghdr cmh; 3046 int tlen, at; 3047 3048 tlen = SCTP_BUF_LEN(control); 3049 at = 0; 3050 /* --- 33 unchanged lines hidden (view full) --- 3084 } 3085 } 3086 } 3087 /* not found */ 3088 return (0); 3089} 3090 3091 |
1917extern int sctp_mbuf_threshold_count; 1918 1919 1920__inline struct mbuf * | 3092struct mbuf * |
1921sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, 1922 int how, int allonebuf, int type) 1923{ 1924 struct mbuf *m = NULL; 1925 int aloc_size; 1926 int index = 0; 1927 int mbuf_threshold; 1928 --- 187 unchanged lines hidden (view full) --- 2116 stcb->asoc.hb_ect_randombit++; 2117 return (SCTP_ECT1_BIT); 2118 } else { 2119 stcb->asoc.hb_ect_randombit++; 2120 return (SCTP_ECT0_BIT); 2121 } 2122} 2123 | 3093sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, 3094 int how, int allonebuf, int type) 3095{ 3096 struct mbuf *m = NULL; 3097 int aloc_size; 3098 int index = 0; 3099 int mbuf_threshold; 3100 --- 187 unchanged lines hidden (view full) --- 3288 stcb->asoc.hb_ect_randombit++; 3289 return (SCTP_ECT1_BIT); 3290 } else { 3291 stcb->asoc.hb_ect_randombit++; 3292 return (SCTP_ECT0_BIT); 3293 } 3294} 3295 |
2124extern int sctp_no_csum_on_loopback; 2125 | |
2126static int 2127sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, 2128 struct sctp_tcb *stcb, /* may be NULL */ 2129 struct sctp_nets *net, 2130 struct sockaddr *to, 2131 struct mbuf *m, 2132 uint32_t auth_offset, 2133 struct sctp_auth_chunk *auth, --- 17 unchanged lines hidden (view full) --- 2151 struct mbuf *o_pak; 2152 2153 struct sctphdr *sctphdr; 2154 int packet_length; 2155 int o_flgs; 2156 uint32_t csum; 2157 int ret; 2158 unsigned int have_mtu; | 3296static int 3297sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, 3298 struct sctp_tcb *stcb, /* may be NULL */ 3299 struct sctp_nets *net, 3300 struct sockaddr *to, 3301 struct mbuf *m, 3302 uint32_t auth_offset, 3303 struct sctp_auth_chunk *auth, --- 17 unchanged lines hidden (view full) --- 3321 struct mbuf *o_pak; 3322 3323 struct sctphdr *sctphdr; 3324 int packet_length; 3325 int o_flgs; 3326 uint32_t csum; 3327 int ret; 3328 unsigned int have_mtu; |
3329 uint32_t vrf_id; |
|
2159 struct route *ro; 2160 | 3330 struct route *ro; 3331 |
3332 |
|
2161 if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) { 2162 sctp_m_freem(m); 2163 return (EFAULT); 2164 } | 3333 if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) { 3334 sctp_m_freem(m); 3335 return (EFAULT); 3336 } |
3337 if (stcb == NULL) { 3338 vrf_id = SCTP_DEFAULT_VRFID; 3339 } else { 3340 vrf_id = stcb->asoc.vrf_id; 3341 } 3342 |
|
2165 /* fill in the HMAC digest for any AUTH chunk in the packet */ 2166 if ((auth != NULL) && (stcb != NULL)) { 2167 sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb); 2168 } 2169 /* Calculate the csum and fill in the length of the packet */ 2170 sctphdr = mtod(m, struct sctphdr *); 2171 have_mtu = 0; 2172 if (sctp_no_csum_on_loopback && --- 8 unchanged lines hidden (view full) --- 2181 packet_length = sctp_calculate_len(m); 2182 } else { 2183 sctphdr->checksum = 0; 2184 csum = sctp_calculate_sum(m, &packet_length, 0); 2185 sctphdr->checksum = csum; 2186 } 2187 2188 if (to->sa_family == AF_INET) { | 3343 /* fill in the HMAC digest for any AUTH chunk in the packet */ 3344 if ((auth != NULL) && (stcb != NULL)) { 3345 sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb); 3346 } 3347 /* Calculate the csum and fill in the length of the packet */ 3348 sctphdr = mtod(m, struct sctphdr *); 3349 have_mtu = 0; 3350 if (sctp_no_csum_on_loopback && --- 8 unchanged lines hidden (view full) --- 3359 packet_length = sctp_calculate_len(m); 3360 } else { 3361 sctphdr->checksum = 0; 3362 csum = sctp_calculate_sum(m, &packet_length, 0); 3363 sctphdr->checksum = csum; 3364 } 3365 3366 if (to->sa_family == AF_INET) { |
2189 struct ip *ip; | 3367 struct ip *ip = NULL; |
2190 struct route iproute; 2191 uint8_t tos_value; 2192 2193 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip)); 2194 if (o_pak == NULL) { 2195 /* failed to prepend data, give up */ 2196 sctp_m_freem(m); 2197 return (ENOMEM); --- 47 unchanged lines hidden (view full) --- 2245 } 2246 /* Now the address selection part */ 2247 ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; 2248 2249 /* call the routine to select the src address */ 2250 if (net) { 2251 if (net->src_addr_selected == 0) { 2252 /* Cache the source address */ | 3368 struct route iproute; 3369 uint8_t tos_value; 3370 3371 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip)); 3372 if (o_pak == NULL) { 3373 /* failed to prepend data, give up */ 3374 sctp_m_freem(m); 3375 return (ENOMEM); --- 47 unchanged lines hidden (view full) --- 3423 } 3424 /* Now the address selection part */ 3425 ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; 3426 3427 /* call the routine to select the src address */ 3428 if (net) { 3429 if (net->src_addr_selected == 0) { 3430 /* Cache the source address */ |
2253 ((struct sockaddr_in *)&net->ro._s_addr)->sin_addr = sctp_ipv4_source_address_selection(inp, 2254 stcb, 2255 ro, net, out_of_asoc_ok); 2256 if (ro->ro_rt) 2257 net->src_addr_selected = 1; | 3431 net->ro._s_addr = sctp_source_address_selection(inp, stcb, 3432 ro, net, out_of_asoc_ok, vrf_id); 3433 if (net->ro._s_addr == NULL) { 3434 /* No route to host */ 3435 goto no_route; 3436 } 3437 net->src_addr_selected = 1; |
2258 } | 3438 } |
2259 ip->ip_src = ((struct sockaddr_in *)&net->ro._s_addr)->sin_addr; | 3439 ip->ip_src = net->ro._s_addr->address.sin.sin_addr; |
2260 } else { | 3440 } else { |
2261 ip->ip_src = sctp_ipv4_source_address_selection(inp, 2262 stcb, ro, net, out_of_asoc_ok); | 3441 struct sctp_ifa *_lsrc; 3442 3443 _lsrc = sctp_source_address_selection(inp, 3444 stcb, ro, net, out_of_asoc_ok, vrf_id); 3445 if (_lsrc == NULL) { 3446 goto no_route; 3447 } 3448 ip->ip_src = _lsrc->address.sin.sin_addr; 3449 sctp_free_ifa(_lsrc); |
2263 } 2264 2265 /* 2266 * If source address selection fails and we find no route 2267 * then the ip_output should fail as well with a 2268 * NO_ROUTE_TO_HOST type error. We probably should catch 2269 * that somewhere and abort the association right away 2270 * (assuming this is an INIT being sent). 2271 */ 2272 if ((ro->ro_rt == NULL)) { 2273 /* 2274 * src addr selection failed to find a route (or 2275 * valid source addr), so we can't get there from | 3450 } 3451 3452 /* 3453 * If source address selection fails and we find no route 3454 * then the ip_output should fail as well with a 3455 * NO_ROUTE_TO_HOST type error. We probably should catch 3456 * that somewhere and abort the association right away 3457 * (assuming this is an INIT being sent). 3458 */ 3459 if ((ro->ro_rt == NULL)) { 3460 /* 3461 * src addr selection failed to find a route (or 3462 * valid source addr), so we can't get there from |
2276 * here! | 3463 * here (yet)! |
2277 */ | 3464 */ |
3465 no_route: |
|
2278#ifdef SCTP_DEBUG 2279 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { | 3466#ifdef SCTP_DEBUG 3467 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { |
2280 printf("low_level_output: dropped v4 packet- no valid source addr\n"); 2281 printf("Destination was %x\n", (uint32_t) (ntohl(ip->ip_dst.s_addr))); | 3468 printf("low_level_output: dropped packet - no valid source addr\n"); 3469 if (net) { 3470 printf("Destination was "); 3471 sctp_print_address(&net->ro._l_addr.sa); 3472 } |
2282 } 2283#endif /* SCTP_DEBUG */ 2284 if (net) { | 3473 } 3474#endif /* SCTP_DEBUG */ 3475 if (net) { |
2285 if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb) 2286 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 2287 stcb, 2288 SCTP_FAILED_THRESHOLD, 2289 (void *)net); 2290 net->dest_state &= ~SCTP_ADDR_REACHABLE; 2291 net->dest_state |= SCTP_ADDR_NOT_REACHABLE; | 3476 if (net->dest_state & SCTP_ADDR_CONFIRMED) { 3477 if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb) { 3478 printf("no route takes interface %p down\n", net); 3479 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 3480 stcb, 3481 SCTP_FAILED_THRESHOLD, 3482 (void *)net); 3483 net->dest_state &= ~SCTP_ADDR_REACHABLE; 3484 net->dest_state |= SCTP_ADDR_NOT_REACHABLE; 3485 } 3486 } |
2292 if (stcb) { 2293 if (net == stcb->asoc.primary_destination) { 2294 /* need a new primary */ 2295 struct sctp_nets *alt; 2296 2297 alt = sctp_find_alternate_net(stcb, net, 0); 2298 if (alt != net) { 2299 if (sctp_set_primary_addr(stcb, 2300 (struct sockaddr *)NULL, 2301 alt) == 0) { 2302 net->dest_state |= SCTP_ADDR_WAS_PRIMARY; | 3487 if (stcb) { 3488 if (net == stcb->asoc.primary_destination) { 3489 /* need a new primary */ 3490 struct sctp_nets *alt; 3491 3492 alt = sctp_find_alternate_net(stcb, net, 0); 3493 if (alt != net) { 3494 if (sctp_set_primary_addr(stcb, 3495 (struct sockaddr *)NULL, 3496 alt) == 0) { 3497 net->dest_state |= SCTP_ADDR_WAS_PRIMARY; |
3498 if (net->ro._s_addr) { 3499 sctp_free_ifa(net->ro._s_addr); 3500 net->ro._s_addr = NULL; 3501 } |
|
2303 net->src_addr_selected = 0; 2304 } 2305 } 2306 } 2307 } 2308 } 2309 sctp_m_freem(o_pak); 2310 return (EHOSTUNREACH); --- 33 unchanged lines hidden (view full) --- 2344 SCTP_STAT_INCR(sctps_senderrors); 2345#ifdef SCTP_DEBUG 2346 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) { 2347 printf("Ip output returns %d\n", ret); 2348 } 2349#endif 2350 if (net == NULL) { 2351 /* free tempy routes */ | 3502 net->src_addr_selected = 0; 3503 } 3504 } 3505 } 3506 } 3507 } 3508 sctp_m_freem(o_pak); 3509 return (EHOSTUNREACH); --- 33 unchanged lines hidden (view full) --- 3543 SCTP_STAT_INCR(sctps_senderrors); 3544#ifdef SCTP_DEBUG 3545 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) { 3546 printf("Ip output returns %d\n", ret); 3547 } 3548#endif 3549 if (net == NULL) { 3550 /* free tempy routes */ |
2352 if (ro->ro_rt) | 3551 if (ro->ro_rt) { |
2353 RTFREE(ro->ro_rt); | 3552 RTFREE(ro->ro_rt); |
3553 ro->ro_rt = NULL; 3554 } |
|
2354 } else { 2355 /* PMTU check versus smallest asoc MTU goes here */ 2356 if (ro->ro_rt != NULL) { 2357 if (ro->ro_rt->rt_rmx.rmx_mtu && 2358 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) { 2359 sctp_mtu_size_reset(inp, &stcb->asoc, 2360 ro->ro_rt->rt_rmx.rmx_mtu); 2361 } 2362 } else { 2363 /* route was freed */ | 3555 } else { 3556 /* PMTU check versus smallest asoc MTU goes here */ 3557 if (ro->ro_rt != NULL) { 3558 if (ro->ro_rt->rt_rmx.rmx_mtu && 3559 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) { 3560 sctp_mtu_size_reset(inp, &stcb->asoc, 3561 ro->ro_rt->rt_rmx.rmx_mtu); 3562 } 3563 } else { 3564 /* route was freed */ |
3565 if (net->ro._s_addr && 3566 net->src_addr_selected) { 3567 sctp_free_ifa(net->ro._s_addr); 3568 net->ro._s_addr = NULL; 3569 } |
|
2364 net->src_addr_selected = 0; 2365 } 2366 } 2367 return (ret); 2368 } 2369#ifdef INET6 2370 else if (to->sa_family == AF_INET6) { 2371 uint32_t flowlabel; --- 71 unchanged lines hidden (view full) --- 2443 */ 2444 bzero(&lsa6_tmp, sizeof(lsa6_tmp)); 2445 lsa6_tmp.sin6_family = AF_INET6; 2446 lsa6_tmp.sin6_len = sizeof(lsa6_tmp); 2447 lsa6 = &lsa6_tmp; 2448 if (net) { 2449 if (net->src_addr_selected == 0) { 2450 /* Cache the source address */ | 3570 net->src_addr_selected = 0; 3571 } 3572 } 3573 return (ret); 3574 } 3575#ifdef INET6 3576 else if (to->sa_family == AF_INET6) { 3577 uint32_t flowlabel; --- 71 unchanged lines hidden (view full) --- 3649 */ 3650 bzero(&lsa6_tmp, sizeof(lsa6_tmp)); 3651 lsa6_tmp.sin6_family = AF_INET6; 3652 lsa6_tmp.sin6_len = sizeof(lsa6_tmp); 3653 lsa6 = &lsa6_tmp; 3654 if (net) { 3655 if (net->src_addr_selected == 0) { 3656 /* Cache the source address */ |
2451 ((struct sockaddr_in6 *)&net->ro._s_addr)->sin6_addr = sctp_ipv6_source_address_selection(inp, 2452 stcb, ro, net, out_of_asoc_ok); 2453 2454 if (ro->ro_rt) 2455 net->src_addr_selected = 1; | 3657 net->ro._s_addr = sctp_source_address_selection(inp, 3658 stcb, 3659 ro, 3660 net, 3661 out_of_asoc_ok, 3662 vrf_id); 3663 if (net->ro._s_addr == NULL) { 3664#ifdef SCTP_DEBUG 3665 printf("V6:No route to host\n"); 3666#endif 3667 goto no_route; 3668 } 3669 net->src_addr_selected = 1; |
2456 } | 3670 } |
2457 lsa6->sin6_addr = ((struct sockaddr_in6 *)&net->ro._s_addr)->sin6_addr; | 3671 lsa6->sin6_addr = net->ro._s_addr->address.sin6.sin6_addr; |
2458 } else { | 3672 } else { |
2459 lsa6->sin6_addr = sctp_ipv6_source_address_selection( 2460 inp, stcb, ro, net, out_of_asoc_ok); | 3673 struct sctp_ifa *_lsrc; 3674 3675 _lsrc = sctp_source_address_selection(inp, stcb, ro, net, out_of_asoc_ok, vrf_id); 3676 if (_lsrc == NULL) { 3677 goto no_route; 3678 } 3679 lsa6->sin6_addr = _lsrc->address.sin6.sin6_addr; 3680 sctp_free_ifa(_lsrc); |
2461 } 2462 lsa6->sin6_port = inp->sctp_lport; 2463 2464 if ((ro->ro_rt == NULL)) { 2465 /* 2466 * src addr selection failed to find a route (or 2467 * valid source addr), so we can't get there from 2468 * here! 2469 */ | 3681 } 3682 lsa6->sin6_port = inp->sctp_lport; 3683 3684 if ((ro->ro_rt == NULL)) { 3685 /* 3686 * src addr selection failed to find a route (or 3687 * valid source addr), so we can't get there from 3688 * here! 3689 */ |
2470#ifdef SCTP_DEBUG 2471 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) { 2472 printf("low_level_output: dropped v6 pkt- no valid source addr\n"); 2473 } 2474#endif 2475 sctp_m_freem(o_pak); 2476 if (net) { 2477 if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb) 2478 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 2479 stcb, 2480 SCTP_FAILED_THRESHOLD, 2481 (void *)net); 2482 net->dest_state &= ~SCTP_ADDR_REACHABLE; 2483 net->dest_state |= SCTP_ADDR_NOT_REACHABLE; 2484 if (stcb) { 2485 if (net == stcb->asoc.primary_destination) { 2486 /* need a new primary */ 2487 struct sctp_nets *alt; 2488 2489 alt = sctp_find_alternate_net(stcb, net, 0); 2490 if (alt != net) { 2491 if (sctp_set_primary_addr(stcb, 2492 (struct sockaddr *)NULL, 2493 alt) == 0) { 2494 net->dest_state |= SCTP_ADDR_WAS_PRIMARY; 2495 net->src_addr_selected = 0; 2496 } 2497 } 2498 } 2499 } 2500 } 2501 return (EHOSTUNREACH); | 3690 goto no_route; |
2502 } 2503 /* 2504 * XXX: sa6 may not have a valid sin6_scope_id in the 2505 * non-SCOPEDROUTING case. 2506 */ 2507 bzero(&lsa6_storage, sizeof(lsa6_storage)); 2508 lsa6_storage.sin6_family = AF_INET6; 2509 lsa6_storage.sin6_len = sizeof(lsa6_storage); --- 50 unchanged lines hidden (view full) --- 2560 } 2561#ifdef SCTP_DEBUG 2562 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) { 2563 printf("return from send is %d\n", ret); 2564 } 2565#endif /* SCTP_DEBUG_OUTPUT */ 2566 SCTP_STAT_INCR(sctps_sendpackets); 2567 SCTP_STAT_INCR_COUNTER64(sctps_outpackets); | 3691 } 3692 /* 3693 * XXX: sa6 may not have a valid sin6_scope_id in the 3694 * non-SCOPEDROUTING case. 3695 */ 3696 bzero(&lsa6_storage, sizeof(lsa6_storage)); 3697 lsa6_storage.sin6_family = AF_INET6; 3698 lsa6_storage.sin6_len = sizeof(lsa6_storage); --- 50 unchanged lines hidden (view full) --- 3749 } 3750#ifdef SCTP_DEBUG 3751 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) { 3752 printf("return from send is %d\n", ret); 3753 } 3754#endif /* SCTP_DEBUG_OUTPUT */ 3755 SCTP_STAT_INCR(sctps_sendpackets); 3756 SCTP_STAT_INCR_COUNTER64(sctps_outpackets); |
2568 if (ret) | 3757 if (ret) { |
2569 SCTP_STAT_INCR(sctps_senderrors); | 3758 SCTP_STAT_INCR(sctps_senderrors); |
3759 } |
|
2570 if (net == NULL) { 2571 /* Now if we had a temp route free it */ 2572 if (ro->ro_rt) { 2573 RTFREE(ro->ro_rt); 2574 } 2575 } else { 2576 /* PMTU check versus smallest asoc MTU goes here */ 2577 if (ro->ro_rt == NULL) { 2578 /* Route was freed */ | 3760 if (net == NULL) { 3761 /* Now if we had a temp route free it */ 3762 if (ro->ro_rt) { 3763 RTFREE(ro->ro_rt); 3764 } 3765 } else { 3766 /* PMTU check versus smallest asoc MTU goes here */ 3767 if (ro->ro_rt == NULL) { 3768 /* Route was freed */ |
3769 3770 if (net->ro._s_addr && 3771 net->src_addr_selected) { 3772 sctp_free_ifa(net->ro._s_addr); 3773 net->ro._s_addr = NULL; 3774 } |
|
2579 net->src_addr_selected = 0; 2580 } 2581 if (ro->ro_rt != NULL) { 2582 if (ro->ro_rt->rt_rmx.rmx_mtu && 2583 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) { 2584 sctp_mtu_size_reset(inp, 2585 &stcb->asoc, 2586 ro->ro_rt->rt_rmx.rmx_mtu); --- 672 unchanged lines hidden (view full) --- 3259 struct sockaddr *to; 3260 struct sctp_state_cookie stc; 3261 struct sctp_nets *net = NULL; 3262 int cnt_inits_to = 0; 3263 uint16_t his_limit, i_want; 3264 int abort_flag, padval, sz_of; 3265 int num_ext; 3266 int p_len; | 3775 net->src_addr_selected = 0; 3776 } 3777 if (ro->ro_rt != NULL) { 3778 if (ro->ro_rt->rt_rmx.rmx_mtu && 3779 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) { 3780 sctp_mtu_size_reset(inp, 3781 &stcb->asoc, 3782 ro->ro_rt->rt_rmx.rmx_mtu); --- 672 unchanged lines hidden (view full) --- 4455 struct sockaddr *to; 4456 struct sctp_state_cookie stc; 4457 struct sctp_nets *net = NULL; 4458 int cnt_inits_to = 0; 4459 uint16_t his_limit, i_want; 4460 int abort_flag, padval, sz_of; 4461 int num_ext; 4462 int p_len; |
4463 uint32_t vrf_id; |
|
3267 | 4464 |
4465 vrf_id = SCTP_DEFAULT_VRFID; |
|
3268 if (stcb) { 3269 asoc = &stcb->asoc; 3270 } else { 3271 asoc = NULL; 3272 } 3273 m_last = NULL; 3274 if ((asoc != NULL) && 3275 (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) && --- 77 unchanged lines hidden (view full) --- 3353 /* now for scope setup */ 3354 memset((caddr_t)&store, 0, sizeof(store)); 3355 sin = (struct sockaddr_in *)&store; 3356 sin6 = (struct sockaddr_in6 *)&store; 3357 if (net == NULL) { 3358 to = (struct sockaddr *)&store; 3359 iph = mtod(init_pkt, struct ip *); 3360 if (iph->ip_v == IPVERSION) { | 4466 if (stcb) { 4467 asoc = &stcb->asoc; 4468 } else { 4469 asoc = NULL; 4470 } 4471 m_last = NULL; 4472 if ((asoc != NULL) && 4473 (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) && --- 77 unchanged lines hidden (view full) --- 4551 /* now for scope setup */ 4552 memset((caddr_t)&store, 0, sizeof(store)); 4553 sin = (struct sockaddr_in *)&store; 4554 sin6 = (struct sockaddr_in6 *)&store; 4555 if (net == NULL) { 4556 to = (struct sockaddr *)&store; 4557 iph = mtod(init_pkt, struct ip *); 4558 if (iph->ip_v == IPVERSION) { |
3361 struct in_addr addr; | 4559 struct sctp_ifa *addr; |
3362 struct route iproute; 3363 3364 sin->sin_family = AF_INET; 3365 sin->sin_len = sizeof(struct sockaddr_in); 3366 sin->sin_port = sh->src_port; 3367 sin->sin_addr = iph->ip_src; 3368 /* lookup address */ 3369 stc.address[0] = sin->sin_addr.s_addr; 3370 stc.address[1] = 0; 3371 stc.address[2] = 0; 3372 stc.address[3] = 0; 3373 stc.addr_type = SCTP_IPV4_ADDRESS; 3374 /* local from address */ 3375 memset(&iproute, 0, sizeof(iproute)); 3376 ro = &iproute; 3377 memcpy(&ro->ro_dst, sin, sizeof(*sin)); | 4560 struct route iproute; 4561 4562 sin->sin_family = AF_INET; 4563 sin->sin_len = sizeof(struct sockaddr_in); 4564 sin->sin_port = sh->src_port; 4565 sin->sin_addr = iph->ip_src; 4566 /* lookup address */ 4567 stc.address[0] = sin->sin_addr.s_addr; 4568 stc.address[1] = 0; 4569 stc.address[2] = 0; 4570 stc.address[3] = 0; 4571 stc.addr_type = SCTP_IPV4_ADDRESS; 4572 /* local from address */ 4573 memset(&iproute, 0, sizeof(iproute)); 4574 ro = &iproute; 4575 memcpy(&ro->ro_dst, sin, sizeof(*sin)); |
3378 addr = sctp_ipv4_source_address_selection(inp, NULL, 3379 ro, NULL, 0); | 4576 addr = sctp_source_address_selection(inp, NULL, 4577 ro, NULL, 0, vrf_id); 4578 if (addr == NULL) 4579 return; 4580 |
3380 if (ro->ro_rt) { 3381 RTFREE(ro->ro_rt); | 4581 if (ro->ro_rt) { 4582 RTFREE(ro->ro_rt); |
4583 ro->ro_rt = NULL; |
|
3382 } | 4584 } |
3383 stc.laddress[0] = addr.s_addr; | 4585 stc.laddress[0] = addr->address.sin.sin_addr.s_addr; |
3384 stc.laddress[1] = 0; 3385 stc.laddress[2] = 0; 3386 stc.laddress[3] = 0; 3387 stc.laddr_type = SCTP_IPV4_ADDRESS; 3388 /* scope_id is only for v6 */ 3389 stc.scope_id = 0; 3390#ifndef SCTP_DONT_DO_PRIVADDR_SCOPE 3391 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { 3392 stc.ipv4_scope = 1; 3393 } 3394#else 3395 stc.ipv4_scope = 1; 3396#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */ 3397 /* Must use the address in this case */ | 4586 stc.laddress[1] = 0; 4587 stc.laddress[2] = 0; 4588 stc.laddress[3] = 0; 4589 stc.laddr_type = SCTP_IPV4_ADDRESS; 4590 /* scope_id is only for v6 */ 4591 stc.scope_id = 0; 4592#ifndef SCTP_DONT_DO_PRIVADDR_SCOPE 4593 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { 4594 stc.ipv4_scope = 1; 4595 } 4596#else 4597 stc.ipv4_scope = 1; 4598#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */ 4599 /* Must use the address in this case */ |
3398 if (sctp_is_address_on_local_host((struct sockaddr *)sin)) { | 4600 if (sctp_is_address_on_local_host((struct sockaddr *)sin, vrf_id)) { |
3399 stc.loopback_scope = 1; 3400 stc.ipv4_scope = 1; 3401 stc.site_scope = 1; | 4601 stc.loopback_scope = 1; 4602 stc.ipv4_scope = 1; 4603 stc.site_scope = 1; |
3402 stc.local_scope = 1; | 4604 stc.local_scope = 0; |
3403 } 3404 } else if (iph->ip_v == (IPV6_VERSION >> 4)) { | 4605 } 4606 } else if (iph->ip_v == (IPV6_VERSION >> 4)) { |
3405 struct in6_addr addr; | 4607 struct sctp_ifa *addr; |
3406 3407 struct route_in6 iproute6; 3408 3409 ip6 = mtod(init_pkt, struct ip6_hdr *); 3410 sin6->sin6_family = AF_INET6; 3411 sin6->sin6_len = sizeof(struct sockaddr_in6); 3412 sin6->sin6_port = sh->src_port; 3413 sin6->sin6_addr = ip6->ip6_src; 3414 /* lookup address */ 3415 memcpy(&stc.address, &sin6->sin6_addr, 3416 sizeof(struct in6_addr)); 3417 sin6->sin6_scope_id = 0; 3418 stc.addr_type = SCTP_IPV6_ADDRESS; 3419 stc.scope_id = 0; | 4608 4609 struct route_in6 iproute6; 4610 4611 ip6 = mtod(init_pkt, struct ip6_hdr *); 4612 sin6->sin6_family = AF_INET6; 4613 sin6->sin6_len = sizeof(struct sockaddr_in6); 4614 sin6->sin6_port = sh->src_port; 4615 sin6->sin6_addr = ip6->ip6_src; 4616 /* lookup address */ 4617 memcpy(&stc.address, &sin6->sin6_addr, 4618 sizeof(struct in6_addr)); 4619 sin6->sin6_scope_id = 0; 4620 stc.addr_type = SCTP_IPV6_ADDRESS; 4621 stc.scope_id = 0; |
3420 if (sctp_is_address_on_local_host((struct sockaddr *)sin6)) { | 4622 if (sctp_is_address_on_local_host((struct sockaddr *)sin6, vrf_id)) { |
3421 stc.loopback_scope = 1; | 4623 stc.loopback_scope = 1; |
3422 stc.local_scope = 1; | 4624 stc.local_scope = 0; |
3423 stc.site_scope = 1; 3424 stc.ipv4_scope = 1; 3425 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 3426 /* 3427 * If the new destination is a LINK_LOCAL we 3428 * must have common both site and local 3429 * scope. Don't set local scope though since 3430 * we must depend on the source to be added --- 23 unchanged lines hidden (view full) --- 3454 * we must have site scope in common. 3455 */ 3456 stc.site_scope = 1; 3457 } 3458 /* local from address */ 3459 memset(&iproute6, 0, sizeof(iproute6)); 3460 ro = (struct route *)&iproute6; 3461 memcpy(&ro->ro_dst, sin6, sizeof(*sin6)); | 4625 stc.site_scope = 1; 4626 stc.ipv4_scope = 1; 4627 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 4628 /* 4629 * If the new destination is a LINK_LOCAL we 4630 * must have common both site and local 4631 * scope. Don't set local scope though since 4632 * we must depend on the source to be added --- 23 unchanged lines hidden (view full) --- 4656 * we must have site scope in common. 4657 */ 4658 stc.site_scope = 1; 4659 } 4660 /* local from address */ 4661 memset(&iproute6, 0, sizeof(iproute6)); 4662 ro = (struct route *)&iproute6; 4663 memcpy(&ro->ro_dst, sin6, sizeof(*sin6)); |
3462 addr = sctp_ipv6_source_address_selection(inp, NULL, 3463 ro, NULL, 0); | 4664 addr = sctp_source_address_selection(inp, NULL, 4665 ro, NULL, 0, vrf_id); 4666 if (addr == NULL) 4667 return; 4668 |
3464 if (ro->ro_rt) { 3465 RTFREE(ro->ro_rt); | 4669 if (ro->ro_rt) { 4670 RTFREE(ro->ro_rt); |
4671 ro->ro_rt = NULL; |
|
3466 } | 4672 } |
3467 memcpy(&stc.laddress, &addr, sizeof(struct in6_addr)); | 4673 memcpy(&stc.laddress, &addr->address.sin6.sin6_addr, sizeof(struct in6_addr)); |
3468 stc.laddr_type = SCTP_IPV6_ADDRESS; 3469 } 3470 } else { 3471 /* set the scope per the existing tcb */ 3472 struct sctp_nets *lnet; 3473 3474 stc.loopback_scope = asoc->loopback_scope; 3475 stc.ipv4_scope = asoc->ipv4_local_scope; --- 20 unchanged lines hidden (view full) --- 3496 stc.address[2] = 0; 3497 stc.address[3] = 0; 3498 stc.addr_type = SCTP_IPV4_ADDRESS; 3499 if (net->src_addr_selected == 0) { 3500 /* 3501 * strange case here, the INIT should have 3502 * did the selection. 3503 */ | 4674 stc.laddr_type = SCTP_IPV6_ADDRESS; 4675 } 4676 } else { 4677 /* set the scope per the existing tcb */ 4678 struct sctp_nets *lnet; 4679 4680 stc.loopback_scope = asoc->loopback_scope; 4681 stc.ipv4_scope = asoc->ipv4_local_scope; --- 20 unchanged lines hidden (view full) --- 4702 stc.address[2] = 0; 4703 stc.address[3] = 0; 4704 stc.addr_type = SCTP_IPV4_ADDRESS; 4705 if (net->src_addr_selected == 0) { 4706 /* 4707 * strange case here, the INIT should have 4708 * did the selection. 4709 */ |
3504 net->ro._s_addr.sin.sin_addr = 3505 sctp_ipv4_source_address_selection(inp, 3506 stcb, (struct route *)&net->ro, net, 0); | 4710 net->ro._s_addr = sctp_source_address_selection(inp, 4711 stcb, (struct route *)&net->ro, 4712 net, 0, vrf_id); 4713 if (net->ro._s_addr == NULL) 4714 return; 4715 |
3507 net->src_addr_selected = 1; 3508 3509 } | 4716 net->src_addr_selected = 1; 4717 4718 } |
3510 stc.laddress[0] = net->ro._s_addr.sin.sin_addr.s_addr; | 4719 stc.laddress[0] = net->ro._s_addr->address.sin.sin_addr.s_addr; |
3511 stc.laddress[1] = 0; 3512 stc.laddress[2] = 0; 3513 stc.laddress[3] = 0; 3514 stc.laddr_type = SCTP_IPV4_ADDRESS; 3515 } else if (to->sa_family == AF_INET6) { 3516 sin6 = (struct sockaddr_in6 *)to; 3517 memcpy(&stc.address, &sin6->sin6_addr, 3518 sizeof(struct in6_addr)); 3519 stc.addr_type = SCTP_IPV6_ADDRESS; 3520 if (net->src_addr_selected == 0) { 3521 /* 3522 * strange case here, the INIT should have 3523 * did the selection. 3524 */ | 4720 stc.laddress[1] = 0; 4721 stc.laddress[2] = 0; 4722 stc.laddress[3] = 0; 4723 stc.laddr_type = SCTP_IPV4_ADDRESS; 4724 } else if (to->sa_family == AF_INET6) { 4725 sin6 = (struct sockaddr_in6 *)to; 4726 memcpy(&stc.address, &sin6->sin6_addr, 4727 sizeof(struct in6_addr)); 4728 stc.addr_type = SCTP_IPV6_ADDRESS; 4729 if (net->src_addr_selected == 0) { 4730 /* 4731 * strange case here, the INIT should have 4732 * did the selection. 4733 */ |
3525 net->ro._s_addr.sin6.sin6_addr = 3526 sctp_ipv6_source_address_selection(inp, 3527 stcb, (struct route *)&net->ro, net, 0); | 4734 net->ro._s_addr = sctp_source_address_selection(inp, 4735 stcb, (struct route *)&net->ro, 4736 net, 0, vrf_id); 4737 if (net->ro._s_addr == NULL) 4738 return; 4739 |
3528 net->src_addr_selected = 1; 3529 } | 4740 net->src_addr_selected = 1; 4741 } |
3530 memcpy(&stc.laddress, &net->ro._l_addr.sin6.sin6_addr, | 4742 memcpy(&stc.laddress, &net->ro._s_addr->address.sin6.sin6_addr, |
3531 sizeof(struct in6_addr)); 3532 stc.laddr_type = SCTP_IPV6_ADDRESS; 3533 } 3534 } 3535 /* Now lets put the SCTP header in place */ 3536 initackm_out = mtod(m, struct sctp_init_msg *); 3537 initackm_out->sh.src_port = inp->sctp_lport; 3538 initackm_out->sh.dest_port = sh->src_port; --- 126 unchanged lines hidden (view full) --- 3665 /* add authentication parameters */ 3666 if (!sctp_auth_disable) { 3667 struct sctp_auth_random *random; 3668 struct sctp_auth_hmac_algo *hmacs; 3669 struct sctp_auth_chunk_list *chunks; 3670 uint16_t random_len; 3671 3672 /* generate and add RANDOM parameter */ | 4743 sizeof(struct in6_addr)); 4744 stc.laddr_type = SCTP_IPV6_ADDRESS; 4745 } 4746 } 4747 /* Now lets put the SCTP header in place */ 4748 initackm_out = mtod(m, struct sctp_init_msg *); 4749 initackm_out->sh.src_port = inp->sctp_lport; 4750 initackm_out->sh.dest_port = sh->src_port; --- 126 unchanged lines hidden (view full) --- 4877 /* add authentication parameters */ 4878 if (!sctp_auth_disable) { 4879 struct sctp_auth_random *random; 4880 struct sctp_auth_hmac_algo *hmacs; 4881 struct sctp_auth_chunk_list *chunks; 4882 uint16_t random_len; 4883 4884 /* generate and add RANDOM parameter */ |
3673 random_len = sctp_auth_random_len; | 4885 random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT; |
3674 random = (struct sctp_auth_random *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m)); 3675 random->ph.param_type = htons(SCTP_RANDOM); 3676 p_len = sizeof(*random) + random_len; 3677 random->ph.param_length = htons(p_len); 3678 SCTP_READ_RANDOM(random->random_data, random_len); 3679 /* zero out any padding required */ 3680 bzero((caddr_t)random + p_len, SCTP_SIZE32(p_len) - p_len); 3681 SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len); --- 324 unchanged lines hidden (view full) --- 4006 siz -= sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id); 4007 4008 if (siz % 4) { 4009 /* make it an even word boundary please */ 4010 siz -= (siz % 4); 4011 } 4012 return (siz); 4013} | 4886 random = (struct sctp_auth_random *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m)); 4887 random->ph.param_type = htons(SCTP_RANDOM); 4888 p_len = sizeof(*random) + random_len; 4889 random->ph.param_length = htons(p_len); 4890 SCTP_READ_RANDOM(random->random_data, random_len); 4891 /* zero out any padding required */ 4892 bzero((caddr_t)random + p_len, SCTP_SIZE32(p_len) - p_len); 4893 SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len); --- 324 unchanged lines hidden (view full) --- 5218 siz -= sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id); 5219 5220 if (siz % 4) { 5221 /* make it an even word boundary please */ 5222 siz -= (siz % 4); 5223 } 5224 return (siz); 5225} |
4014extern unsigned int sctp_max_chunks_on_queue; | |
4015 4016static void 4017sctp_set_prsctp_policy(struct sctp_tcb *stcb, 4018 struct sctp_stream_queue_pending *sp) 4019{ 4020 sp->pr_sctp_on = 0; 4021 if (stcb->asoc.peer_supports_prsctp) { 4022 /* --- 584 unchanged lines hidden (view full) --- 4607 mat = m; 4608 ca->sndlen = 0; 4609 while (m) { 4610 ca->sndlen += SCTP_BUF_LEN(m); 4611 m = SCTP_BUF_NEXT(m); 4612 } 4613 ca->m = m; 4614 } | 5226 5227static void 5228sctp_set_prsctp_policy(struct sctp_tcb *stcb, 5229 struct sctp_stream_queue_pending *sp) 5230{ 5231 sp->pr_sctp_on = 0; 5232 if (stcb->asoc.peer_supports_prsctp) { 5233 /* --- 584 unchanged lines hidden (view full) --- 5818 mat = m; 5819 ca->sndlen = 0; 5820 while (m) { 5821 ca->sndlen += SCTP_BUF_LEN(m); 5822 m = SCTP_BUF_NEXT(m); 5823 } 5824 ca->m = m; 5825 } |
4615 ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, | 5826 ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL, |
4616 SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES, SCTP_ASOC_ANY_STATE, 4617 (void *)ca, 0, 4618 sctp_sendall_completes, inp, 1); 4619 if (ret) { 4620#ifdef SCTP_DEBUG 4621 printf("Failed to initiate iterator for sendall\n"); 4622#endif 4623 SCTP_FREE(ca); --- 178 unchanged lines hidden (view full) --- 4802 /* special handling, we must look into the param */ 4803 if (chk != asoc->str_reset) { 4804 goto clean_up_anyway; 4805 } 4806 } 4807 } 4808} 4809 | 5827 SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES, SCTP_ASOC_ANY_STATE, 5828 (void *)ca, 0, 5829 sctp_sendall_completes, inp, 1); 5830 if (ret) { 5831#ifdef SCTP_DEBUG 5832 printf("Failed to initiate iterator for sendall\n"); 5833#endif 5834 SCTP_FREE(ca); --- 178 unchanged lines hidden (view full) --- 6013 /* special handling, we must look into the param */ 6014 if (chk != asoc->str_reset) { 6015 goto clean_up_anyway; 6016 } 6017 } 6018 } 6019} 6020 |
4810extern int sctp_min_split_point; | |
4811 4812static __inline int 4813sctp_can_we_split_this(struct sctp_tcb *stcb, 4814 struct sctp_stream_queue_pending *sp, 4815 int goal_mtu, int frag_point, int eeor_on) 4816{ 4817 /* 4818 * Make a decision on if I should split a msg into multiple parts. --- 370 unchanged lines hidden (view full) --- 5189 5190} 5191 5192static void 5193sctp_fill_outqueue(struct sctp_tcb *stcb, 5194 struct sctp_nets *net, int frag_point, int eeor_mode) 5195{ 5196 struct sctp_association *asoc; | 6021 6022static __inline int 6023sctp_can_we_split_this(struct sctp_tcb *stcb, 6024 struct sctp_stream_queue_pending *sp, 6025 int goal_mtu, int frag_point, int eeor_on) 6026{ 6027 /* 6028 * Make a decision on if I should split a msg into multiple parts. --- 370 unchanged lines hidden (view full) --- 6399 6400} 6401 6402static void 6403sctp_fill_outqueue(struct sctp_tcb *stcb, 6404 struct sctp_nets *net, int frag_point, int eeor_mode) 6405{ 6406 struct sctp_association *asoc; |
5197 struct sctp_stream_out *strq, *strqn; | 6407 struct sctp_stream_out *strq, *strqn, *strqt; |
5198 int goal_mtu, moved_how_much, total_moved = 0; 5199 int locked, giveup; 5200 struct sctp_stream_queue_pending *sp; 5201 5202 SCTP_TCB_LOCK_ASSERT(stcb); 5203 asoc = &stcb->asoc; | 6408 int goal_mtu, moved_how_much, total_moved = 0; 6409 int locked, giveup; 6410 struct sctp_stream_queue_pending *sp; 6411 6412 SCTP_TCB_LOCK_ASSERT(stcb); 6413 asoc = &stcb->asoc; |
5204#ifdef AF_INET6 | 6414#ifdef INET6 |
5205 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) { 5206 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD; 5207 } else { 5208 /* ?? not sure what else to do */ 5209 goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; 5210 } 5211#else 5212 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD; --- 50 unchanged lines hidden (view full) --- 5263 asoc->last_out_stream = strq; 5264 if (locked) { 5265 asoc->locked_on_sending = strq; 5266 if ((moved_how_much == 0) || (giveup)) 5267 /* no more to move for now */ 5268 break; 5269 } else { 5270 asoc->locked_on_sending = NULL; | 6415 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) { 6416 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD; 6417 } else { 6418 /* ?? not sure what else to do */ 6419 goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; 6420 } 6421#else 6422 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD; --- 50 unchanged lines hidden (view full) --- 6473 asoc->last_out_stream = strq; 6474 if (locked) { 6475 asoc->locked_on_sending = strq; 6476 if ((moved_how_much == 0) || (giveup)) 6477 /* no more to move for now */ 6478 break; 6479 } else { 6480 asoc->locked_on_sending = NULL; |
6481 strqt = sctp_select_a_stream(stcb, asoc); |
|
5271 if (TAILQ_FIRST(&strq->outqueue) == NULL) { 5272 sctp_remove_from_wheel(stcb, asoc, strq); 5273 } 5274 if (giveup) { 5275 break; 5276 } | 6482 if (TAILQ_FIRST(&strq->outqueue) == NULL) { 6483 sctp_remove_from_wheel(stcb, asoc, strq); 6484 } 6485 if (giveup) { 6486 break; 6487 } |
5277 strq = sctp_select_a_stream(stcb, asoc); | 6488 strq = strqt; |
5278 if (strq == NULL) { 5279 break; 5280 } 5281 } 5282 total_moved += moved_how_much; 5283 goal_mtu -= moved_how_much; 5284 goal_mtu &= 0xfffffffc; 5285 } --- 45 unchanged lines hidden (view full) --- 5331 sctp_free_remote_addr(chk->whoTo); 5332 chk->whoTo = a_net; 5333 atomic_add_int(&a_net->ref_count, 1); 5334 } 5335 } 5336 } 5337} 5338 | 6489 if (strq == NULL) { 6490 break; 6491 } 6492 } 6493 total_moved += moved_how_much; 6494 goal_mtu -= moved_how_much; 6495 goal_mtu &= 0xfffffffc; 6496 } --- 45 unchanged lines hidden (view full) --- 6542 sctp_free_remote_addr(chk->whoTo); 6543 chk->whoTo = a_net; 6544 atomic_add_int(&a_net->ref_count, 1); 6545 } 6546 } 6547 } 6548} 6549 |
5339extern int sctp_early_fr; 5340 | |
5341int 5342sctp_med_chunk_output(struct sctp_inpcb *inp, 5343 struct sctp_tcb *stcb, 5344 struct sctp_association *asoc, 5345 int *num_out, 5346 int *reason_code, 5347 int control_only, int *cwnd_full, int from_where, 5348 struct timeval *now, int *now_filled, int frag_point) --- 10 unchanged lines hidden (view full) --- 5359 struct sctp_nets *net; 5360 struct mbuf *outchain, *endoutchain; 5361 struct sctp_tmit_chunk *chk, *nchk; 5362 struct sctphdr *shdr; 5363 5364 /* temp arrays for unlinking */ 5365 struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING]; 5366 int no_fragmentflg, error; | 6550int 6551sctp_med_chunk_output(struct sctp_inpcb *inp, 6552 struct sctp_tcb *stcb, 6553 struct sctp_association *asoc, 6554 int *num_out, 6555 int *reason_code, 6556 int control_only, int *cwnd_full, int from_where, 6557 struct timeval *now, int *now_filled, int frag_point) --- 10 unchanged lines hidden (view full) --- 6568 struct sctp_nets *net; 6569 struct mbuf *outchain, *endoutchain; 6570 struct sctp_tmit_chunk *chk, *nchk; 6571 struct sctphdr *shdr; 6572 6573 /* temp arrays for unlinking */ 6574 struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING]; 6575 int no_fragmentflg, error; |
5367 int one_chunk, hbflag; | 6576 int one_chunk, hbflag, skip_data_for_this_net; |
5368 int asconf, cookie, no_out_cnt; 5369 int bundle_at, ctl_cnt, no_data_chunks, cwnd_full_ind, eeor_mode; 5370 unsigned int mtu, r_mtu, omtu, mx_mtu, to_out; 5371 struct sctp_nets *start_at, *old_startat = NULL, *send_start_at; 5372 int tsns_sent = 0; 5373 uint32_t auth_offset = 0; 5374 struct sctp_auth_chunk *auth = NULL; 5375 --- 134 unchanged lines hidden (view full) --- 5510 * queued to this address. Skip it. 5511 */ 5512 continue; 5513 } 5514 ctl_cnt = bundle_at = 0; 5515 endoutchain = outchain = NULL; 5516 no_fragmentflg = 1; 5517 one_chunk = 0; | 6577 int asconf, cookie, no_out_cnt; 6578 int bundle_at, ctl_cnt, no_data_chunks, cwnd_full_ind, eeor_mode; 6579 unsigned int mtu, r_mtu, omtu, mx_mtu, to_out; 6580 struct sctp_nets *start_at, *old_startat = NULL, *send_start_at; 6581 int tsns_sent = 0; 6582 uint32_t auth_offset = 0; 6583 struct sctp_auth_chunk *auth = NULL; 6584 --- 134 unchanged lines hidden (view full) --- 6719 * queued to this address. Skip it. 6720 */ 6721 continue; 6722 } 6723 ctl_cnt = bundle_at = 0; 6724 endoutchain = outchain = NULL; 6725 no_fragmentflg = 1; 6726 one_chunk = 0; |
5518 | 6727 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { 6728 skip_data_for_this_net = 1; 6729 } else { 6730 skip_data_for_this_net = 0; 6731 } |
5519 if ((net->ro.ro_rt) && (net->ro.ro_rt->rt_ifp)) { 5520 /* 5521 * if we have a route and an ifp check to see if we 5522 * have room to send to this guy 5523 */ 5524 struct ifnet *ifp; 5525 5526 ifp = net->ro.ro_rt->rt_ifp; --- 209 unchanged lines hidden (view full) --- 5736 if (error == EHOSTUNREACH) { 5737 /* 5738 * Destination went 5739 * unreachable 5740 * during this send 5741 */ 5742 sctp_move_to_an_alt(stcb, asoc, net); 5743 } | 6732 if ((net->ro.ro_rt) && (net->ro.ro_rt->rt_ifp)) { 6733 /* 6734 * if we have a route and an ifp check to see if we 6735 * have room to send to this guy 6736 */ 6737 struct ifnet *ifp; 6738 6739 ifp = net->ro.ro_rt->rt_ifp; --- 209 unchanged lines hidden (view full) --- 6949 if (error == EHOSTUNREACH) { 6950 /* 6951 * Destination went 6952 * unreachable 6953 * during this send 6954 */ 6955 sctp_move_to_an_alt(stcb, asoc, net); 6956 } |
5744 sctp_clean_up_ctl(stcb, asoc); | |
5745 *reason_code = 7; | 6957 *reason_code = 7; |
5746 return (error); | 6958 continue; |
5747 } else 5748 asoc->ifp_had_enobuf = 0; 5749 /* Only HB or ASCONF advances time */ 5750 if (hbflag) { 5751 if (*now_filled == 0) { 5752 SCTP_GETTIME_TIMEVAL(&net->last_sent_time); 5753 *now_filled = 1; 5754 *now = net->last_sent_time; --- 44 unchanged lines hidden (view full) --- 5799 else 5800 omtu = 0; 5801 } else { 5802 if (net->mtu > (sizeof(struct ip6_hdr) + sizeof(struct sctphdr))) 5803 omtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr)); 5804 else 5805 omtu = 0; 5806 } | 6959 } else 6960 asoc->ifp_had_enobuf = 0; 6961 /* Only HB or ASCONF advances time */ 6962 if (hbflag) { 6963 if (*now_filled == 0) { 6964 SCTP_GETTIME_TIMEVAL(&net->last_sent_time); 6965 *now_filled = 1; 6966 *now = net->last_sent_time; --- 44 unchanged lines hidden (view full) --- 7011 else 7012 omtu = 0; 7013 } else { 7014 if (net->mtu > (sizeof(struct ip6_hdr) + sizeof(struct sctphdr))) 7015 omtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr)); 7016 else 7017 omtu = 0; 7018 } |
5807 if (((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) || | 7019 if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) && (skip_data_for_this_net == 0)) || |
5808 (cookie)) { 5809 for (chk = TAILQ_FIRST(&asoc->send_queue); chk; chk = nchk) { 5810 if (no_data_chunks) { 5811 /* let only control go out */ 5812 *reason_code = 1; 5813 break; 5814 } 5815 if (net->flight_size >= net->cwnd) { --- 188 unchanged lines hidden (view full) --- 6004 } 6005 if (error == EHOSTUNREACH) { 6006 /* 6007 * Destination went unreachable 6008 * during this send 6009 */ 6010 sctp_move_to_an_alt(stcb, asoc, net); 6011 } | 7020 (cookie)) { 7021 for (chk = TAILQ_FIRST(&asoc->send_queue); chk; chk = nchk) { 7022 if (no_data_chunks) { 7023 /* let only control go out */ 7024 *reason_code = 1; 7025 break; 7026 } 7027 if (net->flight_size >= net->cwnd) { --- 188 unchanged lines hidden (view full) --- 7216 } 7217 if (error == EHOSTUNREACH) { 7218 /* 7219 * Destination went unreachable 7220 * during this send 7221 */ 7222 sctp_move_to_an_alt(stcb, asoc, net); 7223 } |
6012 sctp_clean_up_ctl(stcb, asoc); | |
6013 *reason_code = 6; | 7224 *reason_code = 6; |
6014 return (error); | 7225 continue; |
6015 } else { 6016 asoc->ifp_had_enobuf = 0; 6017 } 6018 outchain = endoutchain = NULL; 6019 auth = NULL; 6020 auth_offset = 0; 6021 if (bundle_at || hbflag) { 6022 /* For data/asconf and hb set time */ --- 879 unchanged lines hidden (view full) --- 6902 SCTP_STAT_INCR(sctps_sendretransdata); 6903 data_list[i]->sent = SCTP_DATAGRAM_SENT; 6904 /* 6905 * When we have a revoked data, and we 6906 * retransmit it, then we clear the revoked 6907 * flag since this flag dictates if we 6908 * subtracted from the fs 6909 */ | 7226 } else { 7227 asoc->ifp_had_enobuf = 0; 7228 } 7229 outchain = endoutchain = NULL; 7230 auth = NULL; 7231 auth_offset = 0; 7232 if (bundle_at || hbflag) { 7233 /* For data/asconf and hb set time */ --- 879 unchanged lines hidden (view full) --- 8113 SCTP_STAT_INCR(sctps_sendretransdata); 8114 data_list[i]->sent = SCTP_DATAGRAM_SENT; 8115 /* 8116 * When we have a revoked data, and we 8117 * retransmit it, then we clear the revoked 8118 * flag since this flag dictates if we 8119 * subtracted from the fs 8120 */ |
6910 data_list[i]->rec.data.chunk_was_revoked = 0; | 8121 if (data_list[i]->rec.data.chunk_was_revoked) { 8122 /* Deflate the cwnd */ 8123 data_list[i]->whoTo->cwnd -= data_list[i]->book_size; 8124 data_list[i]->rec.data.chunk_was_revoked = 0; 8125 } |
6911 data_list[i]->snd_count++; 6912 sctp_ucount_decr(asoc->sent_queue_retran_cnt); 6913 /* record the time */ 6914 data_list[i]->sent_rcv_time = asoc->time_last_sent; 6915 if (asoc->sent_queue_retran_cnt < 0) { 6916 asoc->sent_queue_retran_cnt = 0; 6917 } 6918 if (data_list[i]->book_size_scale) { --- 602 unchanged lines hidden (view full) --- 7521 a_chk->whoTo = NULL; 7522 break; 7523 } 7524 } 7525 if (a_chk == NULL) { 7526 sctp_alloc_a_chunk(stcb, a_chk); 7527 if (a_chk == NULL) { 7528 /* No memory so we drop the idea, and set a timer */ | 8126 data_list[i]->snd_count++; 8127 sctp_ucount_decr(asoc->sent_queue_retran_cnt); 8128 /* record the time */ 8129 data_list[i]->sent_rcv_time = asoc->time_last_sent; 8130 if (asoc->sent_queue_retran_cnt < 0) { 8131 asoc->sent_queue_retran_cnt = 0; 8132 } 8133 if (data_list[i]->book_size_scale) { --- 602 unchanged lines hidden (view full) --- 8736 a_chk->whoTo = NULL; 8737 break; 8738 } 8739 } 8740 if (a_chk == NULL) { 8741 sctp_alloc_a_chunk(stcb, a_chk); 8742 if (a_chk == NULL) { 8743 /* No memory so we drop the idea, and set a timer */ |
7529 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, 7530 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5); 7531 sctp_timer_start(SCTP_TIMER_TYPE_RECV, 7532 stcb->sctp_ep, stcb, NULL); | 8744 if (stcb->asoc.delayed_ack) { 8745 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, 8746 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5); 8747 sctp_timer_start(SCTP_TIMER_TYPE_RECV, 8748 stcb->sctp_ep, stcb, NULL); 8749 } else { 8750 stcb->asoc.send_sack = 1; 8751 } |
7533 return; 7534 } 7535 a_chk->copy_by_ref = 0; 7536 /* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */ 7537 a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; 7538 a_chk->rec.chunk_id.can_take_data = 1; 7539 } | 8752 return; 8753 } 8754 a_chk->copy_by_ref = 0; 8755 /* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */ 8756 a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; 8757 a_chk->rec.chunk_id.can_take_data = 1; 8758 } |
8759 /* Clear our pkt counts */ 8760 asoc->data_pkts_seen = 0; 8761 |
|
7540 a_chk->asoc = asoc; 7541 a_chk->snd_count = 0; 7542 a_chk->send_size = 0; /* fill in later */ 7543 a_chk->sent = SCTP_DATAGRAM_UNSENT; 7544 7545 if ((asoc->numduptsns) || 7546 (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE) 7547 ) { --- 42 unchanged lines hidden (view full) --- 7590 if (a_chk->data) { 7591 /* was a problem with the destination */ 7592 sctp_m_freem(a_chk->data); 7593 a_chk->data = NULL; 7594 } 7595 if (a_chk->whoTo) 7596 atomic_subtract_int(&a_chk->whoTo->ref_count, 1); 7597 sctp_free_a_chunk(stcb, a_chk); | 8762 a_chk->asoc = asoc; 8763 a_chk->snd_count = 0; 8764 a_chk->send_size = 0; /* fill in later */ 8765 a_chk->sent = SCTP_DATAGRAM_UNSENT; 8766 8767 if ((asoc->numduptsns) || 8768 (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE) 8769 ) { --- 42 unchanged lines hidden (view full) --- 8812 if (a_chk->data) { 8813 /* was a problem with the destination */ 8814 sctp_m_freem(a_chk->data); 8815 a_chk->data = NULL; 8816 } 8817 if (a_chk->whoTo) 8818 atomic_subtract_int(&a_chk->whoTo->ref_count, 1); 8819 sctp_free_a_chunk(stcb, a_chk); |
7598 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, 7599 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6); 7600 sctp_timer_start(SCTP_TIMER_TYPE_RECV, 7601 stcb->sctp_ep, stcb, NULL); | 8820 if (stcb->asoc.delayed_ack) { 8821 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, 8822 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6); 8823 sctp_timer_start(SCTP_TIMER_TYPE_RECV, 8824 stcb->sctp_ep, stcb, NULL); 8825 } else { 8826 stcb->asoc.send_sack = 1; 8827 } |
7602 return; 7603 } 7604 /* ok, lets go through and fill it in */ 7605 SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD); 7606 space = M_TRAILINGSPACE(a_chk->data); 7607 if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) { 7608 space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD); 7609 } --- 122 unchanged lines hidden (view full) --- 7732 (num_gap_blocks * sizeof(struct sctp_gap_ack_block)) + 7733 (num_dups * sizeof(int32_t))); 7734 SCTP_BUF_LEN(a_chk->data) = a_chk->send_size; 7735 sack->sack.num_gap_ack_blks = htons(num_gap_blocks); 7736 sack->sack.num_dup_tsns = htons(num_dups); 7737 sack->ch.chunk_length = htons(a_chk->send_size); 7738 TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next); 7739 asoc->ctrl_queue_cnt++; | 8828 return; 8829 } 8830 /* ok, lets go through and fill it in */ 8831 SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD); 8832 space = M_TRAILINGSPACE(a_chk->data); 8833 if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) { 8834 space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD); 8835 } --- 122 unchanged lines hidden (view full) --- 8958 (num_gap_blocks * sizeof(struct sctp_gap_ack_block)) + 8959 (num_dups * sizeof(int32_t))); 8960 SCTP_BUF_LEN(a_chk->data) = a_chk->send_size; 8961 sack->sack.num_gap_ack_blks = htons(num_gap_blocks); 8962 sack->sack.num_dup_tsns = htons(num_dups); 8963 sack->ch.chunk_length = htons(a_chk->send_size); 8964 TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next); 8965 asoc->ctrl_queue_cnt++; |
8966 asoc->send_sack = 0; |
|
7740 SCTP_STAT_INCR(sctps_sendsacks); 7741 return; 7742} 7743 7744 7745void 7746sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr) 7747{ --- 1461 unchanged lines hidden (view full) --- 9209 } 9210 } 9211 error = sctp_lower_sosend(so, addr, uio, top, control, flags, 9212 use_rcvinfo, &srcv, p); 9213 return (error); 9214} 9215 9216 | 8967 SCTP_STAT_INCR(sctps_sendsacks); 8968 return; 8969} 8970 8971 8972void 8973sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr) 8974{ --- 1461 unchanged lines hidden (view full) --- 10436 } 10437 } 10438 error = sctp_lower_sosend(so, addr, uio, top, control, flags, 10439 use_rcvinfo, &srcv, p); 10440 return (error); 10441} 10442 10443 |
9217extern unsigned int sctp_add_more_threshold; | |
9218int 9219sctp_lower_sosend(struct socket *so, 9220 struct sockaddr *addr, 9221 struct uio *uio, 9222 struct mbuf *i_pak, 9223 struct mbuf *control, 9224 int flags, 9225 int use_rcvinfo, --- 150 unchanged lines hidden (view full) --- 9376 } else if (addr == NULL) { 9377 error = ENOENT; 9378 goto out_unlocked; 9379 } else { 9380 /* 9381 * UDP style, we must go ahead and start the INIT 9382 * process 9383 */ | 10444int 10445sctp_lower_sosend(struct socket *so, 10446 struct sockaddr *addr, 10447 struct uio *uio, 10448 struct mbuf *i_pak, 10449 struct mbuf *control, 10450 int flags, 10451 int use_rcvinfo, --- 150 unchanged lines hidden (view full) --- 10602 } else if (addr == NULL) { 10603 error = ENOENT; 10604 goto out_unlocked; 10605 } else { 10606 /* 10607 * UDP style, we must go ahead and start the INIT 10608 * process 10609 */ |
10610 uint32_t vrf; 10611 |
|
9384 if ((use_rcvinfo) && (srcv) && 9385 ((srcv->sinfo_flags & SCTP_ABORT) || 9386 ((srcv->sinfo_flags & SCTP_EOF) && 9387 (uio->uio_resid == 0)))) { 9388 /* 9389 * User asks to abort a non-existant assoc, 9390 * or EOF a non-existant assoc with no data 9391 */ 9392 error = ENOENT; 9393 goto out_unlocked; 9394 } 9395 /* get an asoc/stcb struct */ | 10612 if ((use_rcvinfo) && (srcv) && 10613 ((srcv->sinfo_flags & SCTP_ABORT) || 10614 ((srcv->sinfo_flags & SCTP_EOF) && 10615 (uio->uio_resid == 0)))) { 10616 /* 10617 * User asks to abort a non-existant assoc, 10618 * or EOF a non-existant assoc with no data 10619 */ 10620 error = ENOENT; 10621 goto out_unlocked; 10622 } 10623 /* get an asoc/stcb struct */ |
9396 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0); | 10624 vrf = SCTP_DEFAULT_VRFID; 10625 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf); |
9397 if (stcb == NULL) { 9398 /* Error is setup for us in the call */ 9399 goto out_unlocked; 9400 } 9401 if (create_lock_applied) { 9402 SCTP_ASOC_CREATE_UNLOCK(inp); 9403 create_lock_applied = 0; 9404 } else { --- 112 unchanged lines hidden (view full) --- 9517 * but the ro structure may now have an update and 9518 * thus we may need to change it BEFORE we append 9519 * the message. 9520 */ 9521 net = stcb->asoc.primary_destination; 9522 asoc = &stcb->asoc; 9523 } 9524 } | 10626 if (stcb == NULL) { 10627 /* Error is setup for us in the call */ 10628 goto out_unlocked; 10629 } 10630 if (create_lock_applied) { 10631 SCTP_ASOC_CREATE_UNLOCK(inp); 10632 create_lock_applied = 0; 10633 } else { --- 112 unchanged lines hidden (view full) --- 10746 * but the ro structure may now have an update and 10747 * thus we may need to change it BEFORE we append 10748 * the message. 10749 */ 10750 net = stcb->asoc.primary_destination; 10751 asoc = &stcb->asoc; 10752 } 10753 } |
9525 if (((so->so_state & SS_NBIO) | 10754 if ((SCTP_SO_IS_NBIO(so) |
9526 || (flags & MSG_NBIO) 9527 )) { 9528 non_blocking = 1; 9529 } 9530 asoc = &stcb->asoc; 9531 /* would we block? */ 9532 if (non_blocking) { 9533 if ((so->so_snd.sb_hiwat < --- 858 unchanged lines hidden --- | 10755 || (flags & MSG_NBIO) 10756 )) { 10757 non_blocking = 1; 10758 } 10759 asoc = &stcb->asoc; 10760 /* would we block? */ 10761 if (non_blocking) { 10762 if ((so->so_snd.sb_hiwat < --- 858 unchanged lines hidden --- |