sctp_pcb.c (166675) | sctp_pcb.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_pcb.c,v 1.38 2005/03/06 16:04:18 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_pcb.c,v 1.38 2005/03/06 16:04:18 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 166675 2007-02-12 23:24:31Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.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_pcb.h> 40#include <netinet/sctputil.h> 41#include <netinet/sctp.h> 42#include <netinet/sctp_header.h> 43#include <netinet/sctp_asconf.h> 44#include <netinet/sctp_output.h> 45#include <netinet/sctp_timer.h> | 40#include <netinet/sctp_pcb.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp.h> 43#include <netinet/sctp_header.h> 44#include <netinet/sctp_asconf.h> 45#include <netinet/sctp_output.h> 46#include <netinet/sctp_timer.h> |
47#include <netinet/sctp_bsd_addr.h> |
|
46 47 | 48 49 |
48#ifdef SCTP_DEBUG 49uint32_t sctp_debug_on = 0; 50 51#endif /* SCTP_DEBUG */ 52 53 54extern int sctp_pcbtblsize; 55extern int sctp_hashtblsize; 56extern int sctp_chunkscale; 57 | |
58struct sctp_epinfo sctppcbinfo; 59 60/* FIX: we don't handle multiple link local scopes */ 61/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */ 62int 63SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b) 64{ 65 struct in6_addr tmp_a, tmp_b; 66 67 /* use a copy of a and b */ 68 tmp_a = *a; 69 tmp_b = *b; 70 in6_clearscope(&tmp_a); 71 in6_clearscope(&tmp_b); 72 return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b)); 73} 74 | 50struct sctp_epinfo sctppcbinfo; 51 52/* FIX: we don't handle multiple link local scopes */ 53/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */ 54int 55SCTP6_ARE_ADDR_EQUAL(struct in6_addr *a, struct in6_addr *b) 56{ 57 struct in6_addr tmp_a, tmp_b; 58 59 /* use a copy of a and b */ 60 tmp_a = *a; 61 tmp_b = *b; 62 in6_clearscope(&tmp_a); 63 in6_clearscope(&tmp_b); 64 return (IN6_ARE_ADDR_EQUAL(&tmp_a, &tmp_b)); 65} 66 |
75 | |
76void 77sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb) 78{ 79 /* 80 * We really don't need to lock this, but I will just because it 81 * does not hurt. 82 */ 83 SCTP_INP_INFO_RLOCK(); --- 4 unchanged lines hidden (view full) --- 88 spcb->chk_count = sctppcbinfo.ipi_count_chunk; 89 spcb->readq_count = sctppcbinfo.ipi_count_readq; 90 spcb->stream_oque = sctppcbinfo.ipi_count_strmoq; 91 spcb->free_chunks = sctppcbinfo.ipi_free_chunks; 92 93 SCTP_INP_INFO_RUNLOCK(); 94} 95 | 67void 68sctp_fill_pcbinfo(struct sctp_pcbinfo *spcb) 69{ 70 /* 71 * We really don't need to lock this, but I will just because it 72 * does not hurt. 73 */ 74 SCTP_INP_INFO_RLOCK(); --- 4 unchanged lines hidden (view full) --- 79 spcb->chk_count = sctppcbinfo.ipi_count_chunk; 80 spcb->readq_count = sctppcbinfo.ipi_count_readq; 81 spcb->stream_oque = sctppcbinfo.ipi_count_strmoq; 82 spcb->free_chunks = sctppcbinfo.ipi_free_chunks; 83 84 SCTP_INP_INFO_RUNLOCK(); 85} 86 |
87/* 88 * Addresses are added to VRF's (Virtual Router's). For BSD we 89 * have only the default VRF 0. We maintain a hash list of 90 * VRF's. Each VRF has its own list of sctp_ifn's. Each of 91 * these has a list of addresses. When we add a new address 92 * to a VRF we lookup the ifn/ifn_index, if the ifn does 93 * not exist we create it and add it to the list of IFN's 94 * within the VRF. Once we have the sctp_ifn, we add the 95 * address to the list. So we look something like: 96 * 97 * hash-vrf-table 98 * vrf-> ifn-> ifn -> ifn 99 * vrf | 100 * ... +--ifa-> ifa -> ifa 101 * vrf 102 * 103 * We keep these seperate lists since the SCTP subsystem will 104 * point to these from its source address selection nets structure. 105 * When an address is deleted it does not happen right away on 106 * the SCTP side, it gets scheduled. What we do when a 107 * delete happens is immediately remove the address from 108 * the master list and decrement the refcount. As our 109 * addip iterator works through and frees the src address 110 * selection pointing to the sctp_ifa, eventually the refcount 111 * will reach 0 and we will delete it. Note that it is assumed 112 * that any locking on system level ifn/ifa is done at the 113 * caller of these functions and these routines will only 114 * lock the SCTP structures as they add or delete things. 115 * 116 * Other notes on VRF concepts. 117 * - An endpoint can be in multiple VRF's 118 * - An association lives within a VRF and only one VRF. 119 * - Any incoming packet we can deduce the VRF for by 120 * looking at the mbuf/pak inbound (for BSD its VRF=0 :D) 121 * - Any downward send call or connect call must supply the 122 * VRF via ancillary data or via some sort of set default 123 * VRF socket option call (again for BSD no brainer since 124 * the VRF is always 0). 125 * - An endpoint may add multiple VRF's to it. 126 * - Listening sockets can accept associations in any 127 * of the VRF's they are in but the assoc will end up 128 * in only one VRF (gotten from the packet or connect/send). 129 * 130 */ |
|
96 | 131 |
132struct sctp_vrf * 133sctp_allocate_vrf(int vrfid) 134{ 135 struct sctp_vrf *vrf = NULL; 136 struct sctp_vrflist *bucket; 137 138 /* First allocate the VRF structure */ 139 vrf = sctp_find_vrf(vrfid); 140 if (vrf) { 141 /* Already allocated */ 142 return (vrf); 143 } 144 SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf), 145 "SCTP_VRF"); 146 if (vrf == NULL) { 147 /* No memory */ 148#ifdef INVARIANTS 149 panic("No memory for VRF:%d", vrfid); 150#endif 151 return (NULL); 152 } 153 /* setup the VRF */ 154 memset(vrf, 0, sizeof(struct sctp_vrf)); 155 vrf->vrf_id = vrfid; 156 LIST_INIT(&vrf->ifnlist); 157 vrf->total_ifa_count = 0; 158 /* Add it to the hash table */ 159 bucket = &sctppcbinfo.sctp_vrfhash[(vrfid & sctppcbinfo.hashvrfmark)]; 160 LIST_INSERT_HEAD(bucket, vrf, next_vrf); 161 return (vrf); 162} 163 164 165struct sctp_ifn * 166sctp_find_ifn(struct sctp_vrf *vrf, void *ifn, uint32_t ifn_index) 167{ 168 struct sctp_ifn *sctp_ifnp; 169 170 /* 171 * We assume the lock is held for the addresses if thats wrong 172 * problems could occur :-) 173 */ 174 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) { 175 if (sctp_ifnp->ifn_index == ifn_index) { 176 return (sctp_ifnp); 177 } 178 if (sctp_ifnp->ifn_p && ifn && (sctp_ifnp->ifn_p == ifn)) { 179 return (sctp_ifnp); 180 } 181 } 182 return (NULL); 183} 184 185struct sctp_vrf * 186sctp_find_vrf(uint32_t vrfid) 187{ 188 struct sctp_vrflist *bucket; 189 struct sctp_vrf *liste; 190 191 bucket = &sctppcbinfo.sctp_vrfhash[(vrfid & sctppcbinfo.hashvrfmark)]; 192 LIST_FOREACH(liste, bucket, next_vrf) { 193 if (vrfid == liste->vrf_id) { 194 return (liste); 195 } 196 } 197 return (NULL); 198} 199 200void 201sctp_free_ifa(struct sctp_ifa *sctp_ifap) 202{ 203 int ret; 204 205 ret = atomic_fetchadd_int(&sctp_ifap->refcount, -1); 206 if (ret == 1) { 207 /* We zero'd the count */ 208 SCTP_FREE(sctp_ifap); 209 } 210} 211 212struct sctp_ifa * 213sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index, 214 uint32_t ifn_type, const char *if_name, 215 void *ifa, struct sockaddr *addr, uint32_t ifa_flags) 216{ 217 struct sctp_vrf *vrf; 218 struct sctp_ifn *sctp_ifnp = NULL; 219 struct sctp_ifa *sctp_ifap = NULL; 220 221 /* How granular do we need the locks to be here? */ 222 SCTP_IPI_ADDR_LOCK(); 223 vrf = sctp_find_vrf(vrfid); 224 if (vrf == NULL) { 225 vrf = sctp_allocate_vrf(vrfid); 226 if (vrf == NULL) { 227 SCTP_IPI_ADDR_UNLOCK(); 228 return (NULL); 229 } 230 } 231 sctp_ifnp = sctp_find_ifn(vrf, ifn, ifn_index); 232 if (sctp_ifnp == NULL) { 233 /* 234 * build one and add it, can't hold lock until after malloc 235 * done though. 236 */ 237 SCTP_IPI_ADDR_UNLOCK(); 238 SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *, sizeof(struct sctp_ifn), "SCTP_IFN"); 239 if (sctp_ifnp == NULL) { 240#ifdef INVARIANTS 241 panic("No memory for IFN:%u", sctp_ifnp->ifn_index); 242#endif 243 return (NULL); 244 } 245 sctp_ifnp->ifn_index = ifn_index; 246 sctp_ifnp->ifn_p = ifn; 247 sctp_ifnp->ifn_type = ifn_type; 248 sctp_ifnp->ifa_count = 0; 249 sctp_ifnp->refcount = 0; 250 sctp_ifnp->vrf = vrf; 251 memcpy(sctp_ifnp->ifn_name, if_name, SCTP_IFNAMSIZ); 252 LIST_INIT(&sctp_ifnp->ifalist); 253 SCTP_IPI_ADDR_LOCK(); 254 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn); 255 } 256 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1); 257 if (sctp_ifap) { 258 /* Hmm, it already exists? */ 259 if ((sctp_ifap->ifn_p) && 260 (sctp_ifap->ifn_p->ifn_index == ifn_index)) { 261 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { 262 /* easy to solve, just switch back to active */ 263 sctp_ifap->localifa_flags = SCTP_ADDR_VALID; 264 sctp_ifap->ifn_p = sctp_ifnp; 265 exit_stage_left: 266 SCTP_IPI_ADDR_UNLOCK(); 267 return (sctp_ifap); 268 } else { 269 goto exit_stage_left; 270 } 271 } else { 272 if (sctp_ifap->ifn_p) { 273 /* 274 * The first IFN gets the address, 275 * duplicates are ignored. 276 */ 277 goto exit_stage_left; 278 } else { 279 /* repair ifnp which was NULL ? */ 280 sctp_ifap->localifa_flags = SCTP_ADDR_VALID; 281 sctp_ifap->ifn_p = sctp_ifnp; 282 atomic_add_int(&sctp_ifnp->refcount, 1); 283 } 284 goto exit_stage_left; 285 } 286 } 287 SCTP_IPI_ADDR_UNLOCK(); 288 SCTP_MALLOC(sctp_ifap, struct sctp_ifa *, sizeof(struct sctp_ifa), "SCTP_IFA"); 289 if (sctp_ifap == NULL) { 290#ifdef INVARIANTS 291 panic("No memory for IFA"); 292#endif 293 return (NULL); 294 } 295 memset(sctp_ifap, 0, sizeof(sctp_ifap)); 296 sctp_ifap->ifn_p = sctp_ifnp; 297 atomic_add_int(&sctp_ifnp->refcount, 1); 298 299 sctp_ifap->ifa = ifa; 300 memcpy(&sctp_ifap->address, addr, addr->sa_len); 301 sctp_ifap->localifa_flags = SCTP_ADDR_VALID | SCTP_ADDR_DEFER_USE; 302 sctp_ifap->flags = ifa_flags; 303 /* Set scope */ 304 if (sctp_ifap->address.sa.sa_family == AF_INET) { 305 struct sockaddr_in *sin; 306 307 sin = (struct sockaddr_in *)&sctp_ifap->address.sin; 308 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || 309 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) { 310 sctp_ifap->src_is_loop = 1; 311 } 312 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 313 sctp_ifap->src_is_priv = 1; 314 } 315 } else if (sctp_ifap->address.sa.sa_family == AF_INET6) { 316 /* ok to use deprecated addresses? */ 317 struct sockaddr_in6 *sin6; 318 319 sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6; 320 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || 321 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) { 322 sctp_ifap->src_is_loop = 1; 323 } 324 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 325 sctp_ifap->src_is_priv = 1; 326 } 327 } 328 if ((sctp_ifap->src_is_priv == 0) && 329 (sctp_ifap->src_is_loop == 0)) { 330 sctp_ifap->src_is_glob = 1; 331 } 332 SCTP_IPI_ADDR_LOCK(); 333 sctp_ifap->refcount = 1; 334 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); 335 sctp_ifnp->ifa_count++; 336 vrf->total_ifa_count++; 337 SCTP_IPI_ADDR_UNLOCK(); 338 return (sctp_ifap); 339} 340 341struct sctp_ifa * 342sctp_del_addr_from_vrf(uint32_t vrfid, struct sockaddr *addr, 343 uint32_t ifn_index) 344{ 345 struct sctp_vrf *vrf; 346 struct sctp_ifa *sctp_ifap = NULL; 347 struct sctp_ifn *sctp_ifnp = NULL; 348 349 SCTP_IPI_ADDR_LOCK(); 350 351 vrf = sctp_find_vrf(vrfid); 352 if (vrf == NULL) { 353 printf("Can't find vrfid:%d\n", vrfid); 354 goto out_now; 355 } 356 sctp_ifnp = sctp_find_ifn(vrf, (void *)NULL, ifn_index); 357 if (sctp_ifnp == NULL) { 358 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1); 359 } else { 360 sctp_ifap = sctp_find_ifa_in_ifn(sctp_ifnp, addr, 1); 361 } 362 363 if (sctp_ifap) { 364 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID; 365 sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; 366 sctp_ifnp->ifa_count--; 367 vrf->total_ifa_count--; 368 LIST_REMOVE(sctp_ifap, next_ifa); 369 atomic_add_int(&sctp_ifnp->refcount, -1); 370 } else { 371 printf("Del Addr-ifn:%d Could not find address:", 372 ifn_index); 373 sctp_print_address(addr); 374 } 375out_now: 376 SCTP_IPI_ADDR_UNLOCK(); 377 return (sctp_ifap); 378} 379 |
|
97/* 98 * Notes on locks for FreeBSD 5 and up. All association lookups that have a 99 * definte ep, the INP structure is assumed to be locked for reading. If we 100 * need to go find the INP (ususally when a **inp is passed) then we must 101 * lock the INFO structure first and if needed lock the INP too. Note that if 102 * we lock it we must 103 * 104 */ --- 67 unchanged lines hidden (view full) --- 172 if (laddr->ifa == NULL) { 173#ifdef SCTP_DEBUG 174 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 175 printf("An ounce of prevention is worth a pound of cure\n"); 176 } 177#endif 178 continue; 179 } | 380/* 381 * Notes on locks for FreeBSD 5 and up. All association lookups that have a 382 * definte ep, the INP structure is assumed to be locked for reading. If we 383 * need to go find the INP (ususally when a **inp is passed) then we must 384 * lock the INFO structure first and if needed lock the INP too. Note that if 385 * we lock it we must 386 * 387 */ --- 67 unchanged lines hidden (view full) --- 455 if (laddr->ifa == NULL) { 456#ifdef SCTP_DEBUG 457 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 458 printf("An ounce of prevention is worth a pound of cure\n"); 459 } 460#endif 461 continue; 462 } |
180 if (laddr->ifa->ifa_addr == NULL) { | 463 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { |
181#ifdef SCTP_DEBUG 182 if (sctp_debug_on & SCTP_DEBUG_PCB1) { | 464#ifdef SCTP_DEBUG 465 if (sctp_debug_on & SCTP_DEBUG_PCB1) { |
183 printf("ifa with a NULL address\n"); | 466 printf("ifa being deleted\n"); |
184 } 185#endif 186 continue; 187 } | 467 } 468#endif 469 continue; 470 } |
188 if (laddr->ifa->ifa_addr->sa_family == | 471 if (laddr->ifa->address.sa.sa_family == |
189 to->sa_family) { 190 /* see if it matches */ 191 struct sockaddr_in *intf_addr, *sin; 192 | 472 to->sa_family) { 473 /* see if it matches */ 474 struct sockaddr_in *intf_addr, *sin; 475 |
193 intf_addr = (struct sockaddr_in *) 194 laddr->ifa->ifa_addr; | 476 intf_addr = &laddr->ifa->address.sin; |
195 sin = (struct sockaddr_in *)to; 196 if (from->sa_family == AF_INET) { 197 if (sin->sin_addr.s_addr == 198 intf_addr->sin_addr.s_addr) { 199 match = 1; 200 break; 201 } 202 } else { 203 struct sockaddr_in6 *intf_addr6; 204 struct sockaddr_in6 *sin6; 205 206 sin6 = (struct sockaddr_in6 *) 207 to; | 477 sin = (struct sockaddr_in *)to; 478 if (from->sa_family == AF_INET) { 479 if (sin->sin_addr.s_addr == 480 intf_addr->sin_addr.s_addr) { 481 match = 1; 482 break; 483 } 484 } else { 485 struct sockaddr_in6 *intf_addr6; 486 struct sockaddr_in6 *sin6; 487 488 sin6 = (struct sockaddr_in6 *) 489 to; |
208 intf_addr6 = (struct sockaddr_in6 *) 209 laddr->ifa->ifa_addr; | 490 intf_addr6 = &laddr->ifa->address.sin6; |
210 211 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 212 &intf_addr6->sin6_addr)) { 213 match = 1; 214 break; 215 } 216 } 217 } --- 372 unchanged lines hidden (view full) --- 590 } 591 SCTP_INP_INFO_RUNLOCK(); 592 return (NULL); 593} 594 595 596static struct sctp_inpcb * 597sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, | 491 492 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 493 &intf_addr6->sin6_addr)) { 494 match = 1; 495 break; 496 } 497 } 498 } --- 372 unchanged lines hidden (view full) --- 871 } 872 SCTP_INP_INFO_RUNLOCK(); 873 return (NULL); 874} 875 876 877static struct sctp_inpcb * 878sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, |
598 uint16_t lport) | 879 uint16_t lport, uint32_t vrf_id) |
599{ 600 struct sctp_inpcb *inp; 601 struct sockaddr_in *sin; 602 struct sockaddr_in6 *sin6; 603 struct sctp_laddr *laddr; | 880{ 881 struct sctp_inpcb *inp; 882 struct sockaddr_in *sin; 883 struct sockaddr_in6 *sin6; 884 struct sctp_laddr *laddr; |
885 int fnd; |
|
604 605 /* 606 * Endpoing probe expects that the INP_INFO is locked. 607 */ 608 if (nam->sa_family == AF_INET) { 609 sin = (struct sockaddr_in *)nam; 610 sin6 = NULL; 611 } else if (nam->sa_family == AF_INET6) { --- 22 unchanged lines hidden (view full) --- 634 continue; 635 } 636 /* A V6 address and the endpoint is NOT bound V6 */ 637 if (nam->sa_family == AF_INET6 && 638 (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 639 SCTP_INP_RUNLOCK(inp); 640 continue; 641 } | 886 887 /* 888 * Endpoing probe expects that the INP_INFO is locked. 889 */ 890 if (nam->sa_family == AF_INET) { 891 sin = (struct sockaddr_in *)nam; 892 sin6 = NULL; 893 } else if (nam->sa_family == AF_INET6) { --- 22 unchanged lines hidden (view full) --- 916 continue; 917 } 918 /* A V6 address and the endpoint is NOT bound V6 */ 919 if (nam->sa_family == AF_INET6 && 920 (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { 921 SCTP_INP_RUNLOCK(inp); 922 continue; 923 } |
924 /* does a VRF id match? */ 925 fnd = 0; 926 if (inp->def_vrf_id == vrf_id) 927 fnd = 1; 928 |
|
642 SCTP_INP_RUNLOCK(inp); | 929 SCTP_INP_RUNLOCK(inp); |
930 if (!fnd) 931 continue; |
|
643 return (inp); 644 } 645 SCTP_INP_RUNLOCK(inp); 646 } 647 648 if ((nam->sa_family == AF_INET) && 649 (sin->sin_addr.s_addr == INADDR_ANY)) { 650 /* Can't hunt for one that has no address specified */ --- 20 unchanged lines hidden (view full) --- 671 /* 672 * Ok this could be a likely candidate, look at all of its 673 * addresses 674 */ 675 if (inp->sctp_lport != lport) { 676 SCTP_INP_RUNLOCK(inp); 677 continue; 678 } | 932 return (inp); 933 } 934 SCTP_INP_RUNLOCK(inp); 935 } 936 937 if ((nam->sa_family == AF_INET) && 938 (sin->sin_addr.s_addr == INADDR_ANY)) { 939 /* Can't hunt for one that has no address specified */ --- 20 unchanged lines hidden (view full) --- 960 /* 961 * Ok this could be a likely candidate, look at all of its 962 * addresses 963 */ 964 if (inp->sctp_lport != lport) { 965 SCTP_INP_RUNLOCK(inp); 966 continue; 967 } |
968 /* does a VRF id match? */ 969 fnd = 0; 970 if (inp->def_vrf_id == vrf_id) 971 fnd = 1; 972 973 if (!fnd) { 974 SCTP_INP_RUNLOCK(inp); 975 continue; 976 } |
|
679 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 680 if (laddr->ifa == NULL) { 681#ifdef SCTP_DEBUG 682 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 683 printf("An ounce of prevention is worth a pound of cure\n"); 684 } 685#endif 686 continue; 687 } 688#ifdef SCTP_DEBUG 689 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 690 printf("Ok laddr->ifa:%p is possible, ", 691 laddr->ifa); 692 } 693#endif | 977 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 978 if (laddr->ifa == NULL) { 979#ifdef SCTP_DEBUG 980 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 981 printf("An ounce of prevention is worth a pound of cure\n"); 982 } 983#endif 984 continue; 985 } 986#ifdef SCTP_DEBUG 987 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 988 printf("Ok laddr->ifa:%p is possible, ", 989 laddr->ifa); 990 } 991#endif |
694 if (laddr->ifa->ifa_addr == NULL) { | 992 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { |
695#ifdef SCTP_DEBUG 696 if (sctp_debug_on & SCTP_DEBUG_PCB1) { | 993#ifdef SCTP_DEBUG 994 if (sctp_debug_on & SCTP_DEBUG_PCB1) { |
697 printf("Huh IFA as an ifa_addr=NULL, "); | 995 printf("Huh IFA being deleted\n"); |
698 } 699#endif 700 continue; 701 } | 996 } 997#endif 998 continue; 999 } |
702 if (laddr->ifa->ifa_addr->sa_family == nam->sa_family) { | 1000 if (laddr->ifa->address.sa.sa_family == nam->sa_family) { |
703 /* possible, see if it matches */ 704 struct sockaddr_in *intf_addr; 705 | 1001 /* possible, see if it matches */ 1002 struct sockaddr_in *intf_addr; 1003 |
706 intf_addr = (struct sockaddr_in *) 707 laddr->ifa->ifa_addr; | 1004 intf_addr = &laddr->ifa->address.sin; |
708 if (nam->sa_family == AF_INET) { 709 if (sin->sin_addr.s_addr == 710 intf_addr->sin_addr.s_addr) { 711 SCTP_INP_RUNLOCK(inp); 712 return (inp); 713 } 714 } else if (nam->sa_family == AF_INET6) { 715 struct sockaddr_in6 *intf_addr6; 716 | 1005 if (nam->sa_family == AF_INET) { 1006 if (sin->sin_addr.s_addr == 1007 intf_addr->sin_addr.s_addr) { 1008 SCTP_INP_RUNLOCK(inp); 1009 return (inp); 1010 } 1011 } else if (nam->sa_family == AF_INET6) { 1012 struct sockaddr_in6 *intf_addr6; 1013 |
717 intf_addr6 = (struct sockaddr_in6 *) 718 laddr->ifa->ifa_addr; | 1014 intf_addr6 = &laddr->ifa->address.sin6; |
719 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 720 &intf_addr6->sin6_addr)) { 721 SCTP_INP_RUNLOCK(inp); 722 return (inp); 723 } 724 } 725 } 726 } 727 SCTP_INP_RUNLOCK(inp); 728 } 729 return (NULL); 730} 731 732 733struct sctp_inpcb * | 1015 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 1016 &intf_addr6->sin6_addr)) { 1017 SCTP_INP_RUNLOCK(inp); 1018 return (inp); 1019 } 1020 } 1021 } 1022 } 1023 SCTP_INP_RUNLOCK(inp); 1024 } 1025 return (NULL); 1026} 1027 1028 1029struct sctp_inpcb * |
734sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock) | 1030sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock, uint32_t vrf_id) |
735{ 736 /* 737 * First we check the hash table to see if someone has this port 738 * bound with just the port. 739 */ 740 struct sctp_inpcb *inp; 741 struct sctppcbhead *head; 742 struct sockaddr_in *sin; --- 17 unchanged lines hidden (view full) --- 760 */ 761 /* Find the head of the ALLADDR chain */ 762 if (have_lock == 0) { 763 SCTP_INP_INFO_RLOCK(); 764 765 } 766 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport, 767 sctppcbinfo.hashmark)]; | 1031{ 1032 /* 1033 * First we check the hash table to see if someone has this port 1034 * bound with just the port. 1035 */ 1036 struct sctp_inpcb *inp; 1037 struct sctppcbhead *head; 1038 struct sockaddr_in *sin; --- 17 unchanged lines hidden (view full) --- 1056 */ 1057 /* Find the head of the ALLADDR chain */ 1058 if (have_lock == 0) { 1059 SCTP_INP_INFO_RLOCK(); 1060 1061 } 1062 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport, 1063 sctppcbinfo.hashmark)]; |
768 inp = sctp_endpoint_probe(nam, head, lport); | 1064 inp = sctp_endpoint_probe(nam, head, lport, vrf_id); |
769 770 /* 771 * If the TCP model exists it could be that the main listening 772 * endpoint is gone but there exists a connected socket for this guy 773 * yet. If so we can return the first one that we find. This may NOT 774 * be the correct one but the sctp_findassociation_ep_addr has 775 * further code to look at all TCP models. 776 */ --- 4 unchanged lines hidden (view full) --- 781 /* 782 * This is real gross, but we do NOT have a remote 783 * port at this point depending on who is calling. 784 * We must therefore look for ANY one that matches 785 * our local port :/ 786 */ 787 head = &sctppcbinfo.sctp_tcpephash[i]; 788 if (LIST_FIRST(head)) { | 1065 1066 /* 1067 * If the TCP model exists it could be that the main listening 1068 * endpoint is gone but there exists a connected socket for this guy 1069 * yet. If so we can return the first one that we find. This may NOT 1070 * be the correct one but the sctp_findassociation_ep_addr has 1071 * further code to look at all TCP models. 1072 */ --- 4 unchanged lines hidden (view full) --- 1077 /* 1078 * This is real gross, but we do NOT have a remote 1079 * port at this point depending on who is calling. 1080 * We must therefore look for ANY one that matches 1081 * our local port :/ 1082 */ 1083 head = &sctppcbinfo.sctp_tcpephash[i]; 1084 if (LIST_FIRST(head)) { |
789 inp = sctp_endpoint_probe(nam, head, lport); | 1085 inp = sctp_endpoint_probe(nam, head, lport, vrf_id); |
790 if (inp) { 791 /* Found one */ 792 break; 793 } 794 } 795 } 796 } 797 if (inp) { --- 7 unchanged lines hidden (view full) --- 805 806/* 807 * Find an association for an endpoint with the pointer to whom you want to 808 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may 809 * need to change the *to to some other struct like a mbuf... 810 */ 811struct sctp_tcb * 812sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from, | 1086 if (inp) { 1087 /* Found one */ 1088 break; 1089 } 1090 } 1091 } 1092 } 1093 if (inp) { --- 7 unchanged lines hidden (view full) --- 1101 1102/* 1103 * Find an association for an endpoint with the pointer to whom you want to 1104 * send to and the endpoint pointer. The address can be IPv4 or IPv6. We may 1105 * need to change the *to to some other struct like a mbuf... 1106 */ 1107struct sctp_tcb * 1108sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from, |
813 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool) | 1109 struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool, uint32_t vrf_id) |
814{ 815 struct sctp_inpcb *inp; 816 struct sctp_tcb *retval; 817 818 SCTP_INP_INFO_RLOCK(); 819 if (find_tcp_pool) { 820 if (inp_p != NULL) { 821 retval = sctp_tcb_special_locate(inp_p, from, to, netp); 822 } else { 823 retval = sctp_tcb_special_locate(&inp, from, to, netp); 824 } 825 if (retval != NULL) { 826 SCTP_INP_INFO_RUNLOCK(); 827 return (retval); 828 } 829 } | 1110{ 1111 struct sctp_inpcb *inp; 1112 struct sctp_tcb *retval; 1113 1114 SCTP_INP_INFO_RLOCK(); 1115 if (find_tcp_pool) { 1116 if (inp_p != NULL) { 1117 retval = sctp_tcb_special_locate(inp_p, from, to, netp); 1118 } else { 1119 retval = sctp_tcb_special_locate(&inp, from, to, netp); 1120 } 1121 if (retval != NULL) { 1122 SCTP_INP_INFO_RUNLOCK(); 1123 return (retval); 1124 } 1125 } |
830 inp = sctp_pcb_findep(to, 0, 1); | 1126 inp = sctp_pcb_findep(to, 0, 1, vrf_id); |
831 if (inp_p != NULL) { 832 *inp_p = inp; 833 } 834 SCTP_INP_INFO_RUNLOCK(); 835 836 if (inp == NULL) { 837 return (NULL); 838 } --- 183 unchanged lines hidden (view full) --- 1022{ 1023 int find_tcp_pool; 1024 struct ip *iph; 1025 struct sctp_tcb *retval; 1026 struct sockaddr_storage to_store, from_store; 1027 struct sockaddr *to = (struct sockaddr *)&to_store; 1028 struct sockaddr *from = (struct sockaddr *)&from_store; 1029 struct sctp_inpcb *inp; | 1127 if (inp_p != NULL) { 1128 *inp_p = inp; 1129 } 1130 SCTP_INP_INFO_RUNLOCK(); 1131 1132 if (inp == NULL) { 1133 return (NULL); 1134 } --- 183 unchanged lines hidden (view full) --- 1318{ 1319 int find_tcp_pool; 1320 struct ip *iph; 1321 struct sctp_tcb *retval; 1322 struct sockaddr_storage to_store, from_store; 1323 struct sockaddr *to = (struct sockaddr *)&to_store; 1324 struct sockaddr *from = (struct sockaddr *)&from_store; 1325 struct sctp_inpcb *inp; |
1326 uint32_t vrf_id; |
|
1030 | 1327 |
1031 | 1328 vrf_id = SCTP_DEFAULT_VRFID; |
1032 iph = mtod(m, struct ip *); 1033 if (iph->ip_v == IPVERSION) { 1034 /* its IPv4 */ 1035 struct sockaddr_in *from4; 1036 1037 from4 = (struct sockaddr_in *)&from_store; 1038 bzero(from4, sizeof(*from4)); 1039 from4->sin_family = AF_INET; --- 66 unchanged lines hidden (view full) --- 1106 (ch->chunk_type != SCTP_INITIATION_ACK) && 1107 (ch->chunk_type != SCTP_COOKIE_ACK) && 1108 (ch->chunk_type != SCTP_COOKIE_ECHO)) { 1109 /* Other chunk types go to the tcp pool. */ 1110 find_tcp_pool = 1; 1111 } 1112 if (inp_p) { 1113 retval = sctp_findassociation_addr_sa(to, from, inp_p, netp, | 1329 iph = mtod(m, struct ip *); 1330 if (iph->ip_v == IPVERSION) { 1331 /* its IPv4 */ 1332 struct sockaddr_in *from4; 1333 1334 from4 = (struct sockaddr_in *)&from_store; 1335 bzero(from4, sizeof(*from4)); 1336 from4->sin_family = AF_INET; --- 66 unchanged lines hidden (view full) --- 1403 (ch->chunk_type != SCTP_INITIATION_ACK) && 1404 (ch->chunk_type != SCTP_COOKIE_ACK) && 1405 (ch->chunk_type != SCTP_COOKIE_ECHO)) { 1406 /* Other chunk types go to the tcp pool. */ 1407 find_tcp_pool = 1; 1408 } 1409 if (inp_p) { 1410 retval = sctp_findassociation_addr_sa(to, from, inp_p, netp, |
1114 find_tcp_pool); | 1411 find_tcp_pool, vrf_id); |
1115 inp = *inp_p; 1116 } else { 1117 retval = sctp_findassociation_addr_sa(to, from, &inp, netp, | 1412 inp = *inp_p; 1413 } else { 1414 retval = sctp_findassociation_addr_sa(to, from, &inp, netp, |
1118 find_tcp_pool); | 1415 find_tcp_pool, vrf_id); |
1119 } 1120#ifdef SCTP_DEBUG 1121 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 1122 printf("retval:%p inp:%p\n", retval, inp); 1123 } 1124#endif 1125 if (retval == NULL && inp) { 1126 /* Found a EP but not this address */ --- 150 unchanged lines hidden (view full) --- 1277 stcb = sctp_findassociation_ep_addr(inp_p, 1278 (struct sockaddr *)&remote_store, netp, 1279 (struct sockaddr *)&local_store, NULL); 1280 } 1281 return (stcb); 1282} 1283 1284 | 1416 } 1417#ifdef SCTP_DEBUG 1418 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 1419 printf("retval:%p inp:%p\n", retval, inp); 1420 } 1421#endif 1422 if (retval == NULL && inp) { 1423 /* Found a EP but not this address */ --- 150 unchanged lines hidden (view full) --- 1574 stcb = sctp_findassociation_ep_addr(inp_p, 1575 (struct sockaddr *)&remote_store, netp, 1576 (struct sockaddr *)&local_store, NULL); 1577 } 1578 return (stcb); 1579} 1580 1581 |
1285extern int sctp_max_burst_default; 1286 1287extern unsigned int sctp_delayed_sack_time_default; 1288extern unsigned int sctp_heartbeat_interval_default; 1289extern unsigned int sctp_pmtu_raise_time_default; 1290extern unsigned int sctp_shutdown_guard_time_default; 1291extern unsigned int sctp_secret_lifetime_default; 1292 1293extern unsigned int sctp_rto_max_default; 1294extern unsigned int sctp_rto_min_default; 1295extern unsigned int sctp_rto_initial_default; 1296extern unsigned int sctp_init_rto_max_default; 1297extern unsigned int sctp_valid_cookie_life_default; 1298extern unsigned int sctp_init_rtx_max_default; 1299extern unsigned int sctp_assoc_rtx_max_default; 1300extern unsigned int sctp_path_rtx_max_default; 1301extern unsigned int sctp_nr_outgoing_streams_default; 1302 | |
1303/* 1304 * allocate a sctp_inpcb and setup a temporary binding to a port/all 1305 * addresses. This way if we don't get a bind we by default pick a ephemeral 1306 * port with all addresses bound. 1307 */ 1308int 1309sctp_inpcb_alloc(struct socket *so) 1310{ --- 48 unchanged lines hidden (view full) --- 1359 } 1360#endif /* IPSEC */ 1361 SCTP_INCR_EP_COUNT(); 1362 inp->ip_inp.inp.inp_ip_ttl = ip_defttl; 1363 SCTP_INP_INFO_WUNLOCK(); 1364 1365 so->so_pcb = (caddr_t)inp; 1366 | 1582/* 1583 * allocate a sctp_inpcb and setup a temporary binding to a port/all 1584 * addresses. This way if we don't get a bind we by default pick a ephemeral 1585 * port with all addresses bound. 1586 */ 1587int 1588sctp_inpcb_alloc(struct socket *so) 1589{ --- 48 unchanged lines hidden (view full) --- 1638 } 1639#endif /* IPSEC */ 1640 SCTP_INCR_EP_COUNT(); 1641 inp->ip_inp.inp.inp_ip_ttl = ip_defttl; 1642 SCTP_INP_INFO_WUNLOCK(); 1643 1644 so->so_pcb = (caddr_t)inp; 1645 |
1367 if ((so->so_type == SOCK_DGRAM) || 1368 (so->so_type == SOCK_SEQPACKET)) { | 1646 if ((SCTP_SO_TYPE(so) == SOCK_DGRAM) || 1647 (SCTP_SO_TYPE(so) == SOCK_SEQPACKET)) { |
1369 /* UDP style socket */ 1370 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE | 1371 SCTP_PCB_FLAGS_UNBOUND); 1372 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 1373 /* Be sure it is NON-BLOCKING IO for UDP */ | 1648 /* UDP style socket */ 1649 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE | 1650 SCTP_PCB_FLAGS_UNBOUND); 1651 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 1652 /* Be sure it is NON-BLOCKING IO for UDP */ |
1374 /* so->so_state |= SS_NBIO; */ 1375 } else if (so->so_type == SOCK_STREAM) { | 1653 /* SCTP_SET_SO_NBIO(so); */ 1654 } else if (SCTP_SO_TYPE(so) == SOCK_STREAM) { |
1376 /* TCP style socket */ 1377 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE | 1378 SCTP_PCB_FLAGS_UNBOUND); 1379 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 1380 /* Be sure we have blocking IO by default */ | 1655 /* TCP style socket */ 1656 inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE | 1657 SCTP_PCB_FLAGS_UNBOUND); 1658 sctp_feature_on(inp, SCTP_PCB_FLAGS_RECVDATAIOEVNT); 1659 /* Be sure we have blocking IO by default */ |
1381 so->so_state &= ~SS_NBIO; | 1660 SCTP_CLEAR_SO_NBIO(so); |
1382 } else { 1383 /* 1384 * unsupported socket type (RAW, etc)- in case we missed it 1385 * in protosw 1386 */ 1387 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp); 1388 return (EOPNOTSUPP); 1389 } 1390 inp->sctp_tcbhash = SCTP_HASH_INIT(sctp_pcbtblsize, 1391 &inp->sctp_hashmark); 1392 if (inp->sctp_tcbhash == NULL) { 1393 printf("Out of SCTP-INPCB->hashinit - no resources\n"); 1394 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp); 1395 return (ENOBUFS); 1396 } | 1661 } else { 1662 /* 1663 * unsupported socket type (RAW, etc)- in case we missed it 1664 * in protosw 1665 */ 1666 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp); 1667 return (EOPNOTSUPP); 1668 } 1669 inp->sctp_tcbhash = SCTP_HASH_INIT(sctp_pcbtblsize, 1670 &inp->sctp_hashmark); 1671 if (inp->sctp_tcbhash == NULL) { 1672 printf("Out of SCTP-INPCB->hashinit - no resources\n"); 1673 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp); 1674 return (ENOBUFS); 1675 } |
1676 inp->def_vrf_id = SCTP_DEFAULT_VRFID; 1677 |
|
1397 SCTP_INP_INFO_WLOCK(); 1398 SCTP_INP_LOCK_INIT(inp); 1399 SCTP_INP_READ_INIT(inp); 1400 SCTP_ASOC_CREATE_LOCK_INIT(inp); 1401 /* lock the new ep */ 1402 SCTP_INP_WLOCK(inp); 1403 1404 /* add it to the info area */ 1405 LIST_INSERT_HEAD(&sctppcbinfo.listhead, inp, sctp_list); 1406 SCTP_INP_INFO_WUNLOCK(); 1407 1408 TAILQ_INIT(&inp->read_queue); 1409 LIST_INIT(&inp->sctp_addr_list); | 1678 SCTP_INP_INFO_WLOCK(); 1679 SCTP_INP_LOCK_INIT(inp); 1680 SCTP_INP_READ_INIT(inp); 1681 SCTP_ASOC_CREATE_LOCK_INIT(inp); 1682 /* lock the new ep */ 1683 SCTP_INP_WLOCK(inp); 1684 1685 /* add it to the info area */ 1686 LIST_INSERT_HEAD(&sctppcbinfo.listhead, inp, sctp_list); 1687 SCTP_INP_INFO_WUNLOCK(); 1688 1689 TAILQ_INIT(&inp->read_queue); 1690 LIST_INIT(&inp->sctp_addr_list); |
1691 |
|
1410 LIST_INIT(&inp->sctp_asoc_list); 1411 1412#ifdef SCTP_TRACK_FREED_ASOCS 1413 /* TEMP CODE */ 1414 LIST_INIT(&inp->sctp_asoc_free_list); 1415#endif 1416 /* Init the timer structure for signature change */ 1417 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer); --- 10 unchanged lines hidden (view full) --- 1428 m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(sctp_pmtu_raise_time_default); 1429 m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(sctp_shutdown_guard_time_default); 1430 m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(sctp_secret_lifetime_default); 1431 /* all max/min max are in ms */ 1432 m->sctp_maxrto = sctp_rto_max_default; 1433 m->sctp_minrto = sctp_rto_min_default; 1434 m->initial_rto = sctp_rto_initial_default; 1435 m->initial_init_rto_max = sctp_init_rto_max_default; | 1692 LIST_INIT(&inp->sctp_asoc_list); 1693 1694#ifdef SCTP_TRACK_FREED_ASOCS 1695 /* TEMP CODE */ 1696 LIST_INIT(&inp->sctp_asoc_free_list); 1697#endif 1698 /* Init the timer structure for signature change */ 1699 SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer); --- 10 unchanged lines hidden (view full) --- 1710 m->sctp_timeoutticks[SCTP_TIMER_PMTU] = SEC_TO_TICKS(sctp_pmtu_raise_time_default); 1711 m->sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN] = SEC_TO_TICKS(sctp_shutdown_guard_time_default); 1712 m->sctp_timeoutticks[SCTP_TIMER_SIGNATURE] = SEC_TO_TICKS(sctp_secret_lifetime_default); 1713 /* all max/min max are in ms */ 1714 m->sctp_maxrto = sctp_rto_max_default; 1715 m->sctp_minrto = sctp_rto_min_default; 1716 m->initial_rto = sctp_rto_initial_default; 1717 m->initial_init_rto_max = sctp_init_rto_max_default; |
1718 m->sctp_sack_freq = sctp_sack_freq_default; |
|
1436 1437 m->max_open_streams_intome = MAX_SCTP_STREAMS; 1438 1439 m->max_init_times = sctp_init_rtx_max_default; 1440 m->max_send_times = sctp_assoc_rtx_max_default; 1441 m->def_net_failure = sctp_path_rtx_max_default; 1442 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF; 1443 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF; --- 21 unchanged lines hidden (view full) --- 1465 1466 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) { 1467 m->secret_key[0][i] = sctp_select_initial_TSN(m); 1468 } 1469 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL); 1470 1471 /* How long is a cookie good for ? */ 1472 m->def_cookie_life = sctp_valid_cookie_life_default; | 1719 1720 m->max_open_streams_intome = MAX_SCTP_STREAMS; 1721 1722 m->max_init_times = sctp_init_rtx_max_default; 1723 m->max_send_times = sctp_assoc_rtx_max_default; 1724 m->def_net_failure = sctp_path_rtx_max_default; 1725 m->sctp_sws_sender = SCTP_SWS_SENDER_DEF; 1726 m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF; --- 21 unchanged lines hidden (view full) --- 1748 1749 for (i = 0; i < SCTP_NUMBER_OF_SECRETS; i++) { 1750 m->secret_key[0][i] = sctp_select_initial_TSN(m); 1751 } 1752 sctp_timer_start(SCTP_TIMER_TYPE_NEWCOOKIE, inp, NULL, NULL); 1753 1754 /* How long is a cookie good for ? */ 1755 m->def_cookie_life = sctp_valid_cookie_life_default; |
1473 | |
1474 /* 1475 * Initialize authentication parameters 1476 */ 1477 m->local_hmacs = sctp_default_supported_hmaclist(); 1478 m->local_auth_chunks = sctp_alloc_chunklist(); 1479 sctp_auth_set_default_chunks(m->local_auth_chunks); 1480 LIST_INIT(&m->shared_keys); 1481 /* add default NULL key as key id 0 */ --- 114 unchanged lines hidden (view full) --- 1596 net->rxt_timer.ep = (void *)new_inp; 1597 net->fr_timer.ep = (void *)new_inp; 1598 } 1599 SCTP_INP_WUNLOCK(new_inp); 1600 SCTP_INP_WUNLOCK(old_inp); 1601} 1602 1603static int | 1756 /* 1757 * Initialize authentication parameters 1758 */ 1759 m->local_hmacs = sctp_default_supported_hmaclist(); 1760 m->local_auth_chunks = sctp_alloc_chunklist(); 1761 sctp_auth_set_default_chunks(m->local_auth_chunks); 1762 LIST_INIT(&m->shared_keys); 1763 /* add default NULL key as key id 0 */ --- 114 unchanged lines hidden (view full) --- 1878 net->rxt_timer.ep = (void *)new_inp; 1879 net->fr_timer.ep = (void *)new_inp; 1880 } 1881 SCTP_INP_WUNLOCK(new_inp); 1882 SCTP_INP_WUNLOCK(old_inp); 1883} 1884 1885static int |
1604sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport) | 1886sctp_isport_inuse(struct sctp_inpcb *inp, uint16_t lport, uint32_t vrf_id) |
1605{ 1606 struct sctppcbhead *head; 1607 struct sctp_inpcb *t_inp; | 1887{ 1888 struct sctppcbhead *head; 1889 struct sctp_inpcb *t_inp; |
1890 int fnd; |
|
1608 1609 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport, 1610 sctppcbinfo.hashmark)]; 1611 1612 LIST_FOREACH(t_inp, head, sctp_hash) { 1613 if (t_inp->sctp_lport != lport) { 1614 continue; 1615 } | 1891 1892 head = &sctppcbinfo.sctp_ephash[SCTP_PCBHASH_ALLADDR(lport, 1893 sctppcbinfo.hashmark)]; 1894 1895 LIST_FOREACH(t_inp, head, sctp_hash) { 1896 if (t_inp->sctp_lport != lport) { 1897 continue; 1898 } |
1899 /* is it in the VRF in question */ 1900 fnd = 0; 1901 if (t_inp->def_vrf_id == vrf_id) 1902 fnd = 1; 1903 if (!fnd) 1904 continue; 1905 |
|
1616 /* This one is in use. */ 1617 /* check the v6/v4 binding issue */ 1618 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 1619 SCTP_IPV6_V6ONLY(t_inp)) { 1620 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1621 /* collision in V6 space */ 1622 return (1); 1623 } else { --- 24 unchanged lines hidden (view full) --- 1648{ 1649 /* bind a ep to a socket address */ 1650 struct sctppcbhead *head; 1651 struct sctp_inpcb *inp, *inp_tmp; 1652 struct inpcb *ip_inp; 1653 int bindall; 1654 uint16_t lport; 1655 int error; | 1906 /* This one is in use. */ 1907 /* check the v6/v4 binding issue */ 1908 if ((t_inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && 1909 SCTP_IPV6_V6ONLY(t_inp)) { 1910 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1911 /* collision in V6 space */ 1912 return (1); 1913 } else { --- 24 unchanged lines hidden (view full) --- 1938{ 1939 /* bind a ep to a socket address */ 1940 struct sctppcbhead *head; 1941 struct sctp_inpcb *inp, *inp_tmp; 1942 struct inpcb *ip_inp; 1943 int bindall; 1944 uint16_t lport; 1945 int error; |
1946 uint32_t vrf_id; |
|
1656 1657 lport = 0; 1658 error = 0; 1659 bindall = 1; 1660 inp = (struct sctp_inpcb *)so->so_pcb; 1661 ip_inp = (struct inpcb *)so->so_pcb; 1662#ifdef SCTP_DEBUG 1663 if (sctp_debug_on & SCTP_DEBUG_PCB1) { --- 43 unchanged lines hidden (view full) --- 1707 return (EINVAL); 1708 } 1709 /* this must be cleared for ifa_ifwithaddr() */ 1710 sin6->sin6_scope_id = 0; 1711 } else { 1712 return (EAFNOSUPPORT); 1713 } 1714 } | 1947 1948 lport = 0; 1949 error = 0; 1950 bindall = 1; 1951 inp = (struct sctp_inpcb *)so->so_pcb; 1952 ip_inp = (struct inpcb *)so->so_pcb; 1953#ifdef SCTP_DEBUG 1954 if (sctp_debug_on & SCTP_DEBUG_PCB1) { --- 43 unchanged lines hidden (view full) --- 1998 return (EINVAL); 1999 } 2000 /* this must be cleared for ifa_ifwithaddr() */ 2001 sin6->sin6_scope_id = 0; 2002 } else { 2003 return (EAFNOSUPPORT); 2004 } 2005 } |
2006 /* 2007 * Setup a vrf_id to be the default for the non-bind-all case. 2008 */ 2009 vrf_id = inp->def_vrf_id; 2010 |
|
1715 SCTP_INP_INFO_WLOCK(); 1716 SCTP_INP_WLOCK(inp); 1717 /* increase our count due to the unlock we do */ 1718 SCTP_INP_INCR_REF(inp); 1719 if (lport) { 1720 /* 1721 * Did the caller specify a port? if so we must see if a ep 1722 * already has this one bound. 1723 */ 1724 /* got to be root to get at low ports */ 1725 if (ntohs(lport) < IPPORT_RESERVED) { 1726 if (p && (error = | 2011 SCTP_INP_INFO_WLOCK(); 2012 SCTP_INP_WLOCK(inp); 2013 /* increase our count due to the unlock we do */ 2014 SCTP_INP_INCR_REF(inp); 2015 if (lport) { 2016 /* 2017 * Did the caller specify a port? if so we must see if a ep 2018 * already has this one bound. 2019 */ 2020 /* got to be root to get at low ports */ 2021 if (ntohs(lport) < IPPORT_RESERVED) { 2022 if (p && (error = |
1727 priv_check(p, 1728 PRIV_NETINET_RESERVEDPORT) | 2023 priv_check_cred(p->td_ucred, 2024 PRIV_NETINET_RESERVEDPORT, 2025 SUSER_ALLOWJAIL 2026 ) |
1729 )) { 1730 SCTP_INP_DECR_REF(inp); 1731 SCTP_INP_WUNLOCK(inp); 1732 SCTP_INP_INFO_WUNLOCK(); 1733 return (error); 1734 } 1735 } 1736 if (p == NULL) { 1737 SCTP_INP_DECR_REF(inp); 1738 SCTP_INP_WUNLOCK(inp); 1739 SCTP_INP_INFO_WUNLOCK(); 1740 return (error); 1741 } 1742 SCTP_INP_WUNLOCK(inp); | 2027 )) { 2028 SCTP_INP_DECR_REF(inp); 2029 SCTP_INP_WUNLOCK(inp); 2030 SCTP_INP_INFO_WUNLOCK(); 2031 return (error); 2032 } 2033 } 2034 if (p == NULL) { 2035 SCTP_INP_DECR_REF(inp); 2036 SCTP_INP_WUNLOCK(inp); 2037 SCTP_INP_INFO_WUNLOCK(); 2038 return (error); 2039 } 2040 SCTP_INP_WUNLOCK(inp); |
1743 inp_tmp = sctp_pcb_findep(addr, 0, 1); 1744 if (inp_tmp != NULL) { 1745 /* 1746 * lock guy returned and lower count note that we 1747 * are not bound so inp_tmp should NEVER be inp. And 1748 * it is this inp (inp_tmp) that gets the reference 1749 * bump, so we must lower it. 1750 */ 1751 SCTP_INP_DECR_REF(inp_tmp); 1752 SCTP_INP_DECR_REF(inp); 1753 /* unlock info */ 1754 SCTP_INP_INFO_WUNLOCK(); 1755 return (EADDRNOTAVAIL); | 2041 if (bindall) { 2042 vrf_id = inp->def_vrf_id; 2043 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id); 2044 if (inp_tmp != NULL) { 2045 /* 2046 * lock guy returned and lower count note 2047 * that we are not bound so inp_tmp should 2048 * NEVER be inp. And it is this inp 2049 * (inp_tmp) that gets the reference bump, 2050 * so we must lower it. 2051 */ 2052 SCTP_INP_DECR_REF(inp_tmp); 2053 SCTP_INP_DECR_REF(inp); 2054 /* unlock info */ 2055 SCTP_INP_INFO_WUNLOCK(); 2056 return (EADDRNOTAVAIL); 2057 } 2058 } else { 2059 inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id); 2060 if (inp_tmp != NULL) { 2061 /* 2062 * lock guy returned and lower count note 2063 * that we are not bound so inp_tmp should 2064 * NEVER be inp. And it is this inp 2065 * (inp_tmp) that gets the reference bump, 2066 * so we must lower it. 2067 */ 2068 SCTP_INP_DECR_REF(inp_tmp); 2069 SCTP_INP_DECR_REF(inp); 2070 /* unlock info */ 2071 SCTP_INP_INFO_WUNLOCK(); 2072 return (EADDRNOTAVAIL); 2073 } |
1756 } 1757 SCTP_INP_WLOCK(inp); 1758 if (bindall) { 1759 /* verify that no lport is not used by a singleton */ | 2074 } 2075 SCTP_INP_WLOCK(inp); 2076 if (bindall) { 2077 /* verify that no lport is not used by a singleton */ |
1760 if (sctp_isport_inuse(inp, lport)) { | 2078 if (sctp_isport_inuse(inp, lport, vrf_id)) { |
1761 /* Sorry someone already has this one bound */ 1762 SCTP_INP_DECR_REF(inp); 1763 SCTP_INP_WUNLOCK(inp); 1764 SCTP_INP_INFO_WUNLOCK(); 1765 return (EADDRNOTAVAIL); 1766 } 1767 } 1768 } else { --- 4 unchanged lines hidden (view full) --- 1773 1774 /* 1775 * setup the inp to the top (I could use the union but this 1776 * is just as easy 1777 */ 1778 uint32_t port_guess; 1779 uint16_t port_attempt; 1780 int not_done = 1; | 2079 /* Sorry someone already has this one bound */ 2080 SCTP_INP_DECR_REF(inp); 2081 SCTP_INP_WUNLOCK(inp); 2082 SCTP_INP_INFO_WUNLOCK(); 2083 return (EADDRNOTAVAIL); 2084 } 2085 } 2086 } else { --- 4 unchanged lines hidden (view full) --- 2091 2092 /* 2093 * setup the inp to the top (I could use the union but this 2094 * is just as easy 2095 */ 2096 uint32_t port_guess; 2097 uint16_t port_attempt; 2098 int not_done = 1; |
2099 int not_found = 1; |
|
1781 1782 while (not_done) { 1783 port_guess = sctp_select_initial_TSN(&inp->sctp_ep); 1784 port_attempt = (port_guess & 0x0000ffff); 1785 if (port_attempt == 0) { 1786 goto next_half; 1787 } 1788 if (port_attempt < IPPORT_RESERVED) { 1789 port_attempt += IPPORT_RESERVED; 1790 } | 2100 2101 while (not_done) { 2102 port_guess = sctp_select_initial_TSN(&inp->sctp_ep); 2103 port_attempt = (port_guess & 0x0000ffff); 2104 if (port_attempt == 0) { 2105 goto next_half; 2106 } 2107 if (port_attempt < IPPORT_RESERVED) { 2108 port_attempt += IPPORT_RESERVED; 2109 } |
1791 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) { | 2110 vrf_id = inp->def_vrf_id; 2111 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) { |
1792 /* got a port we can use */ | 2112 /* got a port we can use */ |
2113 not_found = 0; 2114 break; 2115 } 2116 if (not_found == 1) { 2117 /* We can use this port */ |
|
1793 not_done = 0; 1794 continue; 1795 } 1796 /* try upper half */ 1797 next_half: 1798 port_attempt = ((port_guess >> 16) & 0x0000ffff); 1799 if (port_attempt == 0) { 1800 goto last_try; 1801 } 1802 if (port_attempt < IPPORT_RESERVED) { 1803 port_attempt += IPPORT_RESERVED; 1804 } | 2118 not_done = 0; 2119 continue; 2120 } 2121 /* try upper half */ 2122 next_half: 2123 port_attempt = ((port_guess >> 16) & 0x0000ffff); 2124 if (port_attempt == 0) { 2125 goto last_try; 2126 } 2127 if (port_attempt < IPPORT_RESERVED) { 2128 port_attempt += IPPORT_RESERVED; 2129 } |
1805 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) { | 2130 vrf_id = inp->def_vrf_id; 2131 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) { |
1806 /* got a port we can use */ | 2132 /* got a port we can use */ |
2133 not_found = 0; 2134 break; 2135 } 2136 if (not_found == 1) { 2137 /* We can use this port */ |
|
1807 not_done = 0; 1808 continue; 1809 } 1810 /* try two half's added together */ 1811 last_try: 1812 port_attempt = (((port_guess >> 16) & 0x0000ffff) + 1813 (port_guess & 0x0000ffff)); 1814 if (port_attempt == 0) { 1815 /* get a new random number */ 1816 continue; 1817 } 1818 if (port_attempt < IPPORT_RESERVED) { 1819 port_attempt += IPPORT_RESERVED; 1820 } | 2138 not_done = 0; 2139 continue; 2140 } 2141 /* try two half's added together */ 2142 last_try: 2143 port_attempt = (((port_guess >> 16) & 0x0000ffff) + 2144 (port_guess & 0x0000ffff)); 2145 if (port_attempt == 0) { 2146 /* get a new random number */ 2147 continue; 2148 } 2149 if (port_attempt < IPPORT_RESERVED) { 2150 port_attempt += IPPORT_RESERVED; 2151 } |
1821 if (sctp_isport_inuse(inp, htons(port_attempt)) == 0) { | 2152 vrf_id = inp->def_vrf_id; 2153 if (sctp_isport_inuse(inp, htons(port_attempt), vrf_id) == 1) { |
1822 /* got a port we can use */ | 2154 /* got a port we can use */ |
2155 not_found = 0; 2156 break; 2157 } 2158 if (not_found == 1) { 2159 /* We can use this port */ |
|
1823 not_done = 0; 1824 continue; 1825 } 1826 } 1827 /* we don't get out of the loop until we have a port */ 1828 lport = htons(port_attempt); 1829 } 1830 SCTP_INP_DECR_REF(inp); --- 24 unchanged lines hidden (view full) --- 1855 * address structure to the sctp_addr_list inside the ep 1856 * structure. 1857 * 1858 * We will need to allocate one and insert it at the head. The 1859 * socketopt call can just insert new addresses in there as 1860 * well. It will also have to do the embed scope kame hack 1861 * too (before adding). 1862 */ | 2160 not_done = 0; 2161 continue; 2162 } 2163 } 2164 /* we don't get out of the loop until we have a port */ 2165 lport = htons(port_attempt); 2166 } 2167 SCTP_INP_DECR_REF(inp); --- 24 unchanged lines hidden (view full) --- 2192 * address structure to the sctp_addr_list inside the ep 2193 * structure. 2194 * 2195 * We will need to allocate one and insert it at the head. The 2196 * socketopt call can just insert new addresses in there as 2197 * well. It will also have to do the embed scope kame hack 2198 * too (before adding). 2199 */ |
1863 struct ifaddr *ifa; | 2200 struct sctp_ifa *ifa; |
1864 struct sockaddr_storage store_sa; 1865 1866 memset(&store_sa, 0, sizeof(store_sa)); 1867 if (addr->sa_family == AF_INET) { 1868 struct sockaddr_in *sin; 1869 1870 sin = (struct sockaddr_in *)&store_sa; 1871 memcpy(sin, addr, sizeof(struct sockaddr_in)); --- 5 unchanged lines hidden (view full) --- 1877 memcpy(sin6, addr, sizeof(struct sockaddr_in6)); 1878 sin6->sin6_port = 0; 1879 } 1880 /* 1881 * first find the interface with the bound address need to 1882 * zero out the port to find the address! yuck! can't do 1883 * this earlier since need port for sctp_pcb_findep() 1884 */ | 2201 struct sockaddr_storage store_sa; 2202 2203 memset(&store_sa, 0, sizeof(store_sa)); 2204 if (addr->sa_family == AF_INET) { 2205 struct sockaddr_in *sin; 2206 2207 sin = (struct sockaddr_in *)&store_sa; 2208 memcpy(sin, addr, sizeof(struct sockaddr_in)); --- 5 unchanged lines hidden (view full) --- 2214 memcpy(sin6, addr, sizeof(struct sockaddr_in6)); 2215 sin6->sin6_port = 0; 2216 } 2217 /* 2218 * first find the interface with the bound address need to 2219 * zero out the port to find the address! yuck! can't do 2220 * this earlier since need port for sctp_pcb_findep() 2221 */ |
1885 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa); | 2222 ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa, vrf_id, 0); |
1886 if (ifa == NULL) { 1887 /* Can't find an interface with that address */ 1888 SCTP_INP_WUNLOCK(inp); 1889 SCTP_INP_INFO_WUNLOCK(); 1890 return (EADDRNOTAVAIL); 1891 } 1892 if (addr->sa_family == AF_INET6) { | 2223 if (ifa == NULL) { 2224 /* Can't find an interface with that address */ 2225 SCTP_INP_WUNLOCK(inp); 2226 SCTP_INP_INFO_WUNLOCK(); 2227 return (EADDRNOTAVAIL); 2228 } 2229 if (addr->sa_family == AF_INET6) { |
1893 struct in6_ifaddr *ifa6; 1894 1895 ifa6 = (struct in6_ifaddr *)ifa; 1896 /* 1897 * allow binding of deprecated addresses as per RFC 1898 * 2462 and ipng discussion 1899 */ 1900 if (ifa6->ia6_flags & (IN6_IFF_DETACHED | 1901 IN6_IFF_ANYCAST | 1902 IN6_IFF_NOTREADY)) { | 2230 /* GAK, more FIXME IFA lock? */ 2231 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { |
1903 /* Can't bind a non-existent addr. */ 1904 SCTP_INP_WUNLOCK(inp); 1905 SCTP_INP_INFO_WUNLOCK(); 1906 return (EINVAL); 1907 } 1908 } 1909 /* we're not bound all */ 1910 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL; 1911 /* set the automatic addr changes from kernel flag */ | 2232 /* Can't bind a non-existent addr. */ 2233 SCTP_INP_WUNLOCK(inp); 2234 SCTP_INP_INFO_WUNLOCK(); 2235 return (EINVAL); 2236 } 2237 } 2238 /* we're not bound all */ 2239 inp->sctp_flags &= ~SCTP_PCB_FLAGS_BOUNDALL; 2240 /* set the automatic addr changes from kernel flag */ |
2241 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF); |
|
1912 if (sctp_auto_asconf == 0) { 1913 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 1914 } else { | 2242 if (sctp_auto_asconf == 0) { 2243 sctp_feature_off(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 2244 } else { |
2245 /* 2246 * allow bindx() to send ASCONF's for binding 2247 * changes 2248 */ |
|
1915 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 1916 } | 2249 sctp_feature_on(inp, SCTP_PCB_FLAGS_AUTO_ASCONF); 2250 } |
1917 /* allow bindx() to send ASCONF's for binding changes */ 1918 sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF); | 2251 |
1919 /* add this address to the endpoint list */ | 2252 /* add this address to the endpoint list */ |
1920 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa); | 2253 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, 0); |
1921 if (error != 0) { 1922 SCTP_INP_WUNLOCK(inp); 1923 SCTP_INP_INFO_WUNLOCK(); 1924 return (error); 1925 } 1926 inp->laddr_count++; 1927 } 1928 /* find the bucket */ --- 30 unchanged lines hidden (view full) --- 1959 /* 1960 * Go through all iterators, we must do this since it is possible 1961 * that some iterator does NOT have the lock, but is waiting for it. 1962 * And the one that had the lock has either moved in the last 1963 * iteration or we just cleared it above. We need to find all of 1964 * those guys. The list of iterators should never be very big 1965 * though. 1966 */ | 2254 if (error != 0) { 2255 SCTP_INP_WUNLOCK(inp); 2256 SCTP_INP_INFO_WUNLOCK(); 2257 return (error); 2258 } 2259 inp->laddr_count++; 2260 } 2261 /* find the bucket */ --- 30 unchanged lines hidden (view full) --- 2292 /* 2293 * Go through all iterators, we must do this since it is possible 2294 * that some iterator does NOT have the lock, but is waiting for it. 2295 * And the one that had the lock has either moved in the last 2296 * iteration or we just cleared it above. We need to find all of 2297 * those guys. The list of iterators should never be very big 2298 * though. 2299 */ |
1967 LIST_FOREACH(it, &sctppcbinfo.iteratorhead, sctp_nxt_itr) { | 2300 TAILQ_FOREACH(it, &sctppcbinfo.iteratorhead, sctp_nxt_itr) { |
1968 if (it == inp->inp_starting_point_for_iterator) 1969 /* skip this guy, he's special */ 1970 continue; 1971 if (it->inp == inp) { 1972 /* 1973 * This is tricky and we DON'T lock the iterator. 1974 * Reason is he's running but waiting for me since 1975 * inp->inp_starting_point_for_iterator has the lock --- 412 unchanged lines hidden (view full) --- 2388 /* 2389 * if we have an address list the following will free the list of 2390 * ifaddr's that are set into this ep. Again macro limitations here, 2391 * since the LIST_FOREACH could be a bad idea. 2392 */ 2393 for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL; 2394 laddr = nladdr) { 2395 nladdr = LIST_NEXT(laddr, sctp_nxt_addr); | 2301 if (it == inp->inp_starting_point_for_iterator) 2302 /* skip this guy, he's special */ 2303 continue; 2304 if (it->inp == inp) { 2305 /* 2306 * This is tricky and we DON'T lock the iterator. 2307 * Reason is he's running but waiting for me since 2308 * inp->inp_starting_point_for_iterator has the lock --- 412 unchanged lines hidden (view full) --- 2721 /* 2722 * if we have an address list the following will free the list of 2723 * ifaddr's that are set into this ep. Again macro limitations here, 2724 * since the LIST_FOREACH could be a bad idea. 2725 */ 2726 for ((laddr = LIST_FIRST(&inp->sctp_addr_list)); laddr != NULL; 2727 laddr = nladdr) { 2728 nladdr = LIST_NEXT(laddr, sctp_nxt_addr); |
2396 LIST_REMOVE(laddr, sctp_nxt_addr); 2397 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr); 2398 SCTP_DECR_LADDR_COUNT(); | 2729 sctp_remove_laddr(laddr); |
2399 } 2400 2401#ifdef SCTP_TRACK_FREED_ASOCS 2402 /* TEMP CODE */ 2403 for ((asoc = LIST_FIRST(&inp->sctp_asoc_free_list)); asoc != NULL; 2404 asoc = nasoc) { 2405 nasoc = LIST_NEXT(asoc, sctp_tcblist); 2406 LIST_REMOVE(asoc, sctp_tcblist); --- 36 unchanged lines hidden (view full) --- 2443 2444 2445/* 2446 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as 2447 * when a ASCONF arrives that adds it. It will also initialize all the cwnd 2448 * stats of stuff. 2449 */ 2450int | 2730 } 2731 2732#ifdef SCTP_TRACK_FREED_ASOCS 2733 /* TEMP CODE */ 2734 for ((asoc = LIST_FIRST(&inp->sctp_asoc_free_list)); asoc != NULL; 2735 asoc = nasoc) { 2736 nasoc = LIST_NEXT(asoc, sctp_tcblist); 2737 LIST_REMOVE(asoc, sctp_tcblist); --- 36 unchanged lines hidden (view full) --- 2774 2775 2776/* 2777 * add's a remote endpoint address, done with the INIT/INIT-ACK as well as 2778 * when a ASCONF arrives that adds it. It will also initialize all the cwnd 2779 * stats of stuff. 2780 */ 2781int |
2451sctp_is_address_on_local_host(struct sockaddr *addr) | 2782sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id) |
2452{ | 2783{ |
2453 struct ifnet *ifn; 2454 struct ifaddr *ifa; | 2784 struct sctp_ifa *sctp_ifa; |
2455 | 2785 |
2456 TAILQ_FOREACH(ifn, &ifnet, if_list) { 2457 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { 2458 if (addr->sa_family == ifa->ifa_addr->sa_family) { 2459 /* same family */ 2460 if (addr->sa_family == AF_INET) { 2461 struct sockaddr_in *sin, *sin_c; | 2786 sctp_ifa = sctp_find_ifa_by_addr(addr, vrf_id, 0); 2787 if (sctp_ifa) { 2788 return (1); 2789 } else { 2790 return (0); 2791 } 2792} |
2462 | 2793 |
2463 sin = (struct sockaddr_in *)addr; 2464 sin_c = (struct sockaddr_in *) 2465 ifa->ifa_addr; 2466 if (sin->sin_addr.s_addr == 2467 sin_c->sin_addr.s_addr) { 2468 /* 2469 * we are on the same 2470 * machine 2471 */ 2472 return (1); 2473 } 2474 } else if (addr->sa_family == AF_INET6) { 2475 struct sockaddr_in6 *sin6, *sin_c6; 2476 2477 sin6 = (struct sockaddr_in6 *)addr; 2478 sin_c6 = (struct sockaddr_in6 *) 2479 ifa->ifa_addr; 2480 if (SCTP6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 2481 &sin_c6->sin6_addr)) { 2482 /* 2483 * we are on the same 2484 * machine 2485 */ 2486 return (1); 2487 } 2488 } 2489 } 2490 } | 2794void 2795sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net) 2796{ 2797 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND)); 2798 /* we always get at LEAST 2 MTU's */ 2799 if (net->cwnd < (2 * net->mtu)) { 2800 net->cwnd = 2 * net->mtu; |
2491 } | 2801 } |
2492 return (0); | 2802 net->ssthresh = stcb->asoc.peers_rwnd; |
2493} 2494 2495int 2496sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, 2497 int set_scope, int from) 2498{ 2499 /* 2500 * The following is redundant to the same lines in the --- 48 unchanged lines hidden (view full) --- 2549 if (set_scope) { 2550#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE 2551 stcb->ipv4_local_scope = 1; 2552#else 2553 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { 2554 stcb->asoc.ipv4_local_scope = 1; 2555 } 2556#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */ | 2803} 2804 2805int 2806sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, 2807 int set_scope, int from) 2808{ 2809 /* 2810 * The following is redundant to the same lines in the --- 48 unchanged lines hidden (view full) --- 2859 if (set_scope) { 2860#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE 2861 stcb->ipv4_local_scope = 1; 2862#else 2863 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) { 2864 stcb->asoc.ipv4_local_scope = 1; 2865 } 2866#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */ |
2557 2558 if (sctp_is_address_on_local_host(newaddr)) { 2559 stcb->asoc.loopback_scope = 1; 2560 stcb->asoc.ipv4_local_scope = 1; 2561 stcb->asoc.local_scope = 1; 2562 stcb->asoc.site_scope = 1; 2563 } | |
2564 } else { | 2867 } else { |
2565 if (from == SCTP_ADDR_IS_CONFIRMED) { 2566 /* From connectx */ 2567 if (sctp_is_address_on_local_host(newaddr)) { 2568 stcb->asoc.loopback_scope = 1; 2569 stcb->asoc.ipv4_local_scope = 1; 2570 stcb->asoc.local_scope = 1; 2571 stcb->asoc.site_scope = 1; 2572 } 2573 } | |
2574 /* Validate the address is in scope */ 2575 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) && 2576 (stcb->asoc.ipv4_local_scope == 0)) { 2577 addr_inscope = 0; 2578 } 2579 } 2580 } else if (newaddr->sa_family == AF_INET6) { 2581 struct sockaddr_in6 *sin6; 2582 2583 sin6 = (struct sockaddr_in6 *)newaddr; 2584 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 2585 /* Invalid address */ 2586 return (-1); 2587 } 2588 /* assure len is set */ 2589 sin6->sin6_len = sizeof(struct sockaddr_in6); 2590 if (set_scope) { | 2868 /* Validate the address is in scope */ 2869 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) && 2870 (stcb->asoc.ipv4_local_scope == 0)) { 2871 addr_inscope = 0; 2872 } 2873 } 2874 } else if (newaddr->sa_family == AF_INET6) { 2875 struct sockaddr_in6 *sin6; 2876 2877 sin6 = (struct sockaddr_in6 *)newaddr; 2878 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 2879 /* Invalid address */ 2880 return (-1); 2881 } 2882 /* assure len is set */ 2883 sin6->sin6_len = sizeof(struct sockaddr_in6); 2884 if (set_scope) { |
2591 if (sctp_is_address_on_local_host(newaddr)) { | 2885 if (sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id)) { |
2592 stcb->asoc.loopback_scope = 1; | 2886 stcb->asoc.loopback_scope = 1; |
2593 stcb->asoc.local_scope = 1; | 2887 stcb->asoc.local_scope = 0; |
2594 stcb->asoc.ipv4_local_scope = 1; 2595 stcb->asoc.site_scope = 1; 2596 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 2597 /* 2598 * If the new destination is a LINK_LOCAL we 2599 * must have common site scope. Don't set 2600 * the local scope since we may not share 2601 * all links, only loopback can do this. --- 5 unchanged lines hidden (view full) --- 2607 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 2608 /* 2609 * If the new destination is SITE_LOCAL then 2610 * we must have site scope in common. 2611 */ 2612 stcb->asoc.site_scope = 1; 2613 } 2614 } else { | 2888 stcb->asoc.ipv4_local_scope = 1; 2889 stcb->asoc.site_scope = 1; 2890 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 2891 /* 2892 * If the new destination is a LINK_LOCAL we 2893 * must have common site scope. Don't set 2894 * the local scope since we may not share 2895 * all links, only loopback can do this. --- 5 unchanged lines hidden (view full) --- 2901 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { 2902 /* 2903 * If the new destination is SITE_LOCAL then 2904 * we must have site scope in common. 2905 */ 2906 stcb->asoc.site_scope = 1; 2907 } 2908 } else { |
2615 if (from == SCTP_ADDR_IS_CONFIRMED) { 2616 /* From connectx so we check for localhost. */ 2617 if (sctp_is_address_on_local_host(newaddr)) { 2618 stcb->asoc.loopback_scope = 1; 2619 stcb->asoc.ipv4_local_scope = 1; 2620 stcb->asoc.local_scope = 1; 2621 stcb->asoc.site_scope = 1; 2622 } 2623 } | |
2624 /* Validate the address is in scope */ 2625 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && 2626 (stcb->asoc.loopback_scope == 0)) { 2627 addr_inscope = 0; 2628 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && 2629 (stcb->asoc.local_scope == 0)) { 2630 addr_inscope = 0; 2631 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && --- 13 unchanged lines hidden (view full) --- 2645 bzero(net, sizeof(*net)); 2646 SCTP_GETTIME_TIMEVAL(&net->start_time); 2647 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len); 2648 if (newaddr->sa_family == AF_INET) { 2649 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport; 2650 } else if (newaddr->sa_family == AF_INET6) { 2651 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport; 2652 } | 2909 /* Validate the address is in scope */ 2910 if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) && 2911 (stcb->asoc.loopback_scope == 0)) { 2912 addr_inscope = 0; 2913 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && 2914 (stcb->asoc.local_scope == 0)) { 2915 addr_inscope = 0; 2916 } else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) && --- 13 unchanged lines hidden (view full) --- 2930 bzero(net, sizeof(*net)); 2931 SCTP_GETTIME_TIMEVAL(&net->start_time); 2932 memcpy(&net->ro._l_addr, newaddr, newaddr->sa_len); 2933 if (newaddr->sa_family == AF_INET) { 2934 ((struct sockaddr_in *)&net->ro._l_addr)->sin_port = stcb->rport; 2935 } else if (newaddr->sa_family == AF_INET6) { 2936 ((struct sockaddr_in6 *)&net->ro._l_addr)->sin6_port = stcb->rport; 2937 } |
2653 net->addr_is_local = sctp_is_address_on_local_host(newaddr); | 2938 net->addr_is_local = sctp_is_address_on_local_host(newaddr, stcb->asoc.vrf_id); 2939 if (net->addr_is_local && ((set_scope || (from == SCTP_ADDR_IS_CONFIRMED)))) { 2940 stcb->asoc.loopback_scope = 1; 2941 stcb->asoc.ipv4_local_scope = 1; 2942 stcb->asoc.local_scope = 0; 2943 stcb->asoc.site_scope = 1; 2944 addr_inscope = 1; 2945 } |
2654 net->failure_threshold = stcb->asoc.def_net_failure; 2655 if (addr_inscope == 0) { 2656 net->dest_state = (SCTP_ADDR_REACHABLE | 2657 SCTP_ADDR_OUT_OF_SCOPE); 2658 } else { 2659 if (from == SCTP_ADDR_IS_CONFIRMED) 2660 /* SCTP_ADDR_IS_CONFIRMED is passed by connect_x */ 2661 net->dest_state = SCTP_ADDR_REACHABLE; 2662 else 2663 net->dest_state = SCTP_ADDR_REACHABLE | 2664 SCTP_ADDR_UNCONFIRMED; 2665 } 2666 net->RTO = stcb->asoc.initial_rto; 2667 stcb->asoc.numnets++; 2668 *(&net->ref_count) = 1; 2669 net->tos_flowlabel = 0; | 2946 net->failure_threshold = stcb->asoc.def_net_failure; 2947 if (addr_inscope == 0) { 2948 net->dest_state = (SCTP_ADDR_REACHABLE | 2949 SCTP_ADDR_OUT_OF_SCOPE); 2950 } else { 2951 if (from == SCTP_ADDR_IS_CONFIRMED) 2952 /* SCTP_ADDR_IS_CONFIRMED is passed by connect_x */ 2953 net->dest_state = SCTP_ADDR_REACHABLE; 2954 else 2955 net->dest_state = SCTP_ADDR_REACHABLE | 2956 SCTP_ADDR_UNCONFIRMED; 2957 } 2958 net->RTO = stcb->asoc.initial_rto; 2959 stcb->asoc.numnets++; 2960 *(&net->ref_count) = 1; 2961 net->tos_flowlabel = 0; |
2670#ifdef AF_INET | 2962#ifdef INET |
2671 if (newaddr->sa_family == AF_INET) 2672 net->tos_flowlabel = stcb->asoc.default_tos; 2673#endif | 2963 if (newaddr->sa_family == AF_INET) 2964 net->tos_flowlabel = stcb->asoc.default_tos; 2965#endif |
2674#ifdef AF_INET6 | 2966#ifdef INET6 |
2675 if (newaddr->sa_family == AF_INET6) 2676 net->tos_flowlabel = stcb->asoc.default_flowlabel; 2677#endif 2678 /* Init the timer structure */ 2679 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer); 2680 SCTP_OS_TIMER_INIT(&net->fr_timer.timer); 2681 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer); 2682 --- 27 unchanged lines hidden (view full) --- 2710 2711 if (stcb->asoc.smallest_mtu > net->mtu) { 2712 stcb->asoc.smallest_mtu = net->mtu; 2713 } 2714 /* 2715 * We take the max of the burst limit times a MTU or the 2716 * INITIAL_CWND. We then limit this to 4 MTU's of sending. 2717 */ | 2967 if (newaddr->sa_family == AF_INET6) 2968 net->tos_flowlabel = stcb->asoc.default_flowlabel; 2969#endif 2970 /* Init the timer structure */ 2971 SCTP_OS_TIMER_INIT(&net->rxt_timer.timer); 2972 SCTP_OS_TIMER_INIT(&net->fr_timer.timer); 2973 SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer); 2974 --- 27 unchanged lines hidden (view full) --- 3002 3003 if (stcb->asoc.smallest_mtu > net->mtu) { 3004 stcb->asoc.smallest_mtu = net->mtu; 3005 } 3006 /* 3007 * We take the max of the burst limit times a MTU or the 3008 * INITIAL_CWND. We then limit this to 4 MTU's of sending. 3009 */ |
2718 net->cwnd = min((net->mtu * 4), max((2 * net->mtu), SCTP_INITIAL_CWND)); | 3010 sctp_set_initial_cc_param(stcb, net); |
2719 | 3011 |
2720 /* we always get at LEAST 2 MTU's */ 2721 if (net->cwnd < (2 * net->mtu)) { 2722 net->cwnd = 2 * net->mtu; 2723 } 2724 net->ssthresh = stcb->asoc.peers_rwnd; | |
2725 2726#if defined(SCTP_CWND_MONITOR) || defined(SCTP_CWND_LOGGING) 2727 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION); 2728#endif 2729 2730 /* 2731 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning 2732 * of assoc (2005/06/27, iyengar@cis.udel.edu) --- 82 unchanged lines hidden (view full) --- 2815 2816/* 2817 * allocate an association and add it to the endpoint. The caller must be 2818 * careful to add all additional addresses once they are know right away or 2819 * else the assoc will be may experience a blackout scenario. 2820 */ 2821struct sctp_tcb * 2822sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr, | 3012 3013#if defined(SCTP_CWND_MONITOR) || defined(SCTP_CWND_LOGGING) 3014 sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION); 3015#endif 3016 3017 /* 3018 * CMT: CUC algo - set find_pseudo_cumack to TRUE (1) at beginning 3019 * of assoc (2005/06/27, iyengar@cis.udel.edu) --- 82 unchanged lines hidden (view full) --- 3102 3103/* 3104 * allocate an association and add it to the endpoint. The caller must be 3105 * careful to add all additional addresses once they are know right away or 3106 * else the assoc will be may experience a blackout scenario. 3107 */ 3108struct sctp_tcb * 3109sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr, |
2823 int for_a_init, int *error, uint32_t override_tag) | 3110 int for_a_init, int *error, uint32_t override_tag, uint32_t vrf) |
2824{ 2825 struct sctp_tcb *stcb; 2826 struct sctp_association *asoc; 2827 struct sctpasochead *head; 2828 uint16_t rport; 2829 int err; 2830 2831 /* --- 83 unchanged lines hidden (view full) --- 2915 2916 bzero(stcb, sizeof(*stcb)); 2917 asoc = &stcb->asoc; 2918 SCTP_TCB_LOCK_INIT(stcb); 2919 SCTP_TCB_SEND_LOCK_INIT(stcb); 2920 /* setup back pointer's */ 2921 stcb->sctp_ep = inp; 2922 stcb->sctp_socket = inp->sctp_socket; | 3111{ 3112 struct sctp_tcb *stcb; 3113 struct sctp_association *asoc; 3114 struct sctpasochead *head; 3115 uint16_t rport; 3116 int err; 3117 3118 /* --- 83 unchanged lines hidden (view full) --- 3202 3203 bzero(stcb, sizeof(*stcb)); 3204 asoc = &stcb->asoc; 3205 SCTP_TCB_LOCK_INIT(stcb); 3206 SCTP_TCB_SEND_LOCK_INIT(stcb); 3207 /* setup back pointer's */ 3208 stcb->sctp_ep = inp; 3209 stcb->sctp_socket = inp->sctp_socket; |
2923 if ((err = sctp_init_asoc(inp, asoc, for_a_init, override_tag))) { | 3210 if ((err = sctp_init_asoc(inp, asoc, for_a_init, override_tag, vrf))) { |
2924 /* failed */ 2925 SCTP_TCB_LOCK_DESTROY(stcb); 2926 SCTP_TCB_SEND_LOCK_DESTROY(stcb); 2927 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb); 2928 SCTP_DECR_ASOC_COUNT(); 2929 *error = err; 2930 return (NULL); 2931 } --- 64 unchanged lines hidden (view full) --- 2996void 2997sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net) 2998{ 2999 struct sctp_association *asoc; 3000 3001 asoc = &stcb->asoc; 3002 asoc->numnets--; 3003 TAILQ_REMOVE(&asoc->nets, net, sctp_next); | 3211 /* failed */ 3212 SCTP_TCB_LOCK_DESTROY(stcb); 3213 SCTP_TCB_SEND_LOCK_DESTROY(stcb); 3214 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb); 3215 SCTP_DECR_ASOC_COUNT(); 3216 *error = err; 3217 return (NULL); 3218 } --- 64 unchanged lines hidden (view full) --- 3283void 3284sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net) 3285{ 3286 struct sctp_association *asoc; 3287 3288 asoc = &stcb->asoc; 3289 asoc->numnets--; 3290 TAILQ_REMOVE(&asoc->nets, net, sctp_next); |
3004 sctp_free_remote_addr(net); | |
3005 if (net == asoc->primary_destination) { 3006 /* Reset primary */ 3007 struct sctp_nets *lnet; 3008 3009 lnet = TAILQ_FIRST(&asoc->nets); 3010 /* Try to find a confirmed primary */ | 3291 if (net == asoc->primary_destination) { 3292 /* Reset primary */ 3293 struct sctp_nets *lnet; 3294 3295 lnet = TAILQ_FIRST(&asoc->nets); 3296 /* Try to find a confirmed primary */ |
3011 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 3012 0); | 3297 asoc->primary_destination = sctp_find_alternate_net(stcb, lnet, 0); |
3013 } 3014 if (net == asoc->last_data_chunk_from) { 3015 /* Reset primary */ 3016 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets); 3017 } 3018 if (net == asoc->last_control_chunk_from) { 3019 /* Clear net */ 3020 asoc->last_control_chunk_from = NULL; 3021 } | 3298 } 3299 if (net == asoc->last_data_chunk_from) { 3300 /* Reset primary */ 3301 asoc->last_data_chunk_from = TAILQ_FIRST(&asoc->nets); 3302 } 3303 if (net == asoc->last_control_chunk_from) { 3304 /* Clear net */ 3305 asoc->last_control_chunk_from = NULL; 3306 } |
3022/* if (net == asoc->asconf_last_sent_to) {*/ 3023 /* Reset primary */ 3024/* asoc->asconf_last_sent_to = TAILQ_FIRST(&asoc->nets);*/ 3025/* }*/ | 3307 sctp_free_remote_addr(net); |
3026} 3027 3028/* 3029 * remove a remote endpoint address from an association, it will fail if the 3030 * address does not exist. 3031 */ 3032int 3033sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr) --- 592 unchanged lines hidden (view full) --- 3626#endif 3627 break; 3628 } 3629 prev = net; 3630 TAILQ_REMOVE(&asoc->nets, net, sctp_next); 3631 sctp_free_remote_addr(net); 3632 } 3633 | 3308} 3309 3310/* 3311 * remove a remote endpoint address from an association, it will fail if the 3312 * address does not exist. 3313 */ 3314int 3315sctp_del_remote_addr(struct sctp_tcb *stcb, struct sockaddr *remaddr) --- 592 unchanged lines hidden (view full) --- 3908#endif 3909 break; 3910 } 3911 prev = net; 3912 TAILQ_REMOVE(&asoc->nets, net, sctp_next); 3913 sctp_free_remote_addr(net); 3914 } 3915 |
3634 /* local addresses, if any */ 3635 while (!SCTP_LIST_EMPTY(&asoc->sctp_local_addr_list)) { 3636 laddr = LIST_FIRST(&asoc->sctp_local_addr_list); 3637 LIST_REMOVE(laddr, sctp_nxt_addr); 3638 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr); 3639 SCTP_DECR_LADDR_COUNT(); | 3916 while (!SCTP_LIST_EMPTY(&asoc->sctp_restricted_addrs)) { 3917 laddr = LIST_FIRST(&asoc->sctp_restricted_addrs); 3918 sctp_remove_laddr(laddr); |
3640 } | 3919 } |
3920 |
|
3641 /* pending asconf (address) parameters */ 3642 while (!TAILQ_EMPTY(&asoc->asconf_queue)) { 3643 aparam = TAILQ_FIRST(&asoc->asconf_queue); 3644 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next); 3645 SCTP_FREE(aparam); 3646 } 3647 if (asoc->last_asconf_ack_sent != NULL) { 3648 sctp_m_freem(asoc->last_asconf_ack_sent); --- 137 unchanged lines hidden (view full) --- 3786 if (laddr->ifa == NULL) { 3787#ifdef SCTP_DEBUG 3788 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 3789 printf("An ounce of prevention is worth a pound of cure\n"); 3790 } 3791#endif /* SCTP_DEBUG */ 3792 continue; 3793 } | 3921 /* pending asconf (address) parameters */ 3922 while (!TAILQ_EMPTY(&asoc->asconf_queue)) { 3923 aparam = TAILQ_FIRST(&asoc->asconf_queue); 3924 TAILQ_REMOVE(&asoc->asconf_queue, aparam, next); 3925 SCTP_FREE(aparam); 3926 } 3927 if (asoc->last_asconf_ack_sent != NULL) { 3928 sctp_m_freem(asoc->last_asconf_ack_sent); --- 137 unchanged lines hidden (view full) --- 4066 if (laddr->ifa == NULL) { 4067#ifdef SCTP_DEBUG 4068 if (sctp_debug_on & SCTP_DEBUG_PCB1) { 4069 printf("An ounce of prevention is worth a pound of cure\n"); 4070 } 4071#endif /* SCTP_DEBUG */ 4072 continue; 4073 } |
3794 if (laddr->ifa->ifa_addr) { | 4074 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED) { |
3795 continue; 3796 } | 4075 continue; 4076 } |
3797 if (laddr->ifa->ifa_addr->sa_family == AF_INET6) { | 4077 if (laddr->ifa->address.sa.sa_family == AF_INET6) { |
3798 inp->ip_inp.inp.inp_vflag |= INP_IPV6; | 4078 inp->ip_inp.inp.inp_vflag |= INP_IPV6; |
3799 } else if (laddr->ifa->ifa_addr->sa_family == AF_INET) { | 4079 } else if (laddr->ifa->address.sa.sa_family == AF_INET) { |
3800 inp->ip_inp.inp.inp_vflag |= INP_IPV4; 3801 } 3802 } 3803} 3804 3805/* 3806 * Add the address to the endpoint local address list There is nothing to be 3807 * done if we are bound to all addresses 3808 */ 3809int | 4080 inp->ip_inp.inp.inp_vflag |= INP_IPV4; 4081 } 4082 } 4083} 4084 4085/* 4086 * Add the address to the endpoint local address list There is nothing to be 4087 * done if we are bound to all addresses 4088 */ 4089int |
3810sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa) | 4090sctp_add_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa, uint32_t action) |
3811{ 3812 struct sctp_laddr *laddr; 3813 int fnd, error; 3814 3815 fnd = 0; 3816 3817 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 3818 /* You are already bound to all. You have it already */ 3819 return (0); 3820 } | 4091{ 4092 struct sctp_laddr *laddr; 4093 int fnd, error; 4094 4095 fnd = 0; 4096 4097 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 4098 /* You are already bound to all. You have it already */ 4099 return (0); 4100 } |
3821 if (ifa->ifa_addr->sa_family == AF_INET6) { 3822 struct in6_ifaddr *ifa6; 3823 3824 ifa6 = (struct in6_ifaddr *)ifa; 3825 if (ifa6->ia6_flags & (IN6_IFF_DETACHED | 3826 IN6_IFF_DEPRECATED | IN6_IFF_ANYCAST | IN6_IFF_NOTREADY)) 3827 /* Can't bind a non-existent addr. */ | 4101 if (ifa->address.sa.sa_family == AF_INET6) { 4102 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { 4103 /* Can't bind a non-useable addr. */ |
3828 return (-1); | 4104 return (-1); |
4105 } |
|
3829 } 3830 /* first, is it already present? */ 3831 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 3832 if (laddr->ifa == ifa) { 3833 fnd = 1; 3834 break; 3835 } 3836 } 3837 | 4106 } 4107 /* first, is it already present? */ 4108 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 4109 if (laddr->ifa == ifa) { 4110 fnd = 1; 4111 break; 4112 } 4113 } 4114 |
3838 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd == 0)) { 3839 /* Not bound to all */ 3840 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa); | 4115 if (fnd == 0) { 4116 /* Not in the ep list */ 4117 error = sctp_insert_laddr(&inp->sctp_addr_list, ifa, action); |
3841 if (error != 0) 3842 return (error); 3843 inp->laddr_count++; 3844 /* update inp_vflag flags */ | 4118 if (error != 0) 4119 return (error); 4120 inp->laddr_count++; 4121 /* update inp_vflag flags */ |
3845 if (ifa->ifa_addr->sa_family == AF_INET6) { | 4122 if (ifa->address.sa.sa_family == AF_INET6) { |
3846 inp->ip_inp.inp.inp_vflag |= INP_IPV6; | 4123 inp->ip_inp.inp.inp_vflag |= INP_IPV6; |
3847 } else if (ifa->ifa_addr->sa_family == AF_INET) { | 4124 } else if (ifa->address.sa.sa_family == AF_INET) { |
3848 inp->ip_inp.inp.inp_vflag |= INP_IPV4; 3849 } 3850 } 3851 return (0); 3852} 3853 3854 3855/* --- 20 unchanged lines hidden (view full) --- 3876} 3877 3878 3879/* 3880 * Delete the address from the endpoint local address list There is nothing 3881 * to be done if we are bound to all addresses 3882 */ 3883int | 4125 inp->ip_inp.inp.inp_vflag |= INP_IPV4; 4126 } 4127 } 4128 return (0); 4129} 4130 4131 4132/* --- 20 unchanged lines hidden (view full) --- 4153} 4154 4155 4156/* 4157 * Delete the address from the endpoint local address list There is nothing 4158 * to be done if we are bound to all addresses 4159 */ 4160int |
3884sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct ifaddr *ifa) | 4161sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa) |
3885{ 3886 struct sctp_laddr *laddr; 3887 int fnd; 3888 3889 fnd = 0; 3890 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 3891 /* You are already bound to all. You have it already */ 3892 return (EINVAL); 3893 } 3894 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 3895 if (laddr->ifa == ifa) { 3896 fnd = 1; 3897 break; 3898 } 3899 } 3900 if (fnd && (inp->laddr_count < 2)) { 3901 /* can't delete unless there are at LEAST 2 addresses */ 3902 return (-1); 3903 } | 4162{ 4163 struct sctp_laddr *laddr; 4164 int fnd; 4165 4166 fnd = 0; 4167 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 4168 /* You are already bound to all. You have it already */ 4169 return (EINVAL); 4170 } 4171 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 4172 if (laddr->ifa == ifa) { 4173 fnd = 1; 4174 break; 4175 } 4176 } 4177 if (fnd && (inp->laddr_count < 2)) { 4178 /* can't delete unless there are at LEAST 2 addresses */ 4179 return (-1); 4180 } |
3904 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && (fnd)) { | 4181 if (fnd) { |
3905 /* 3906 * clean up any use of this address go through our 3907 * associations and clear any last_used_address that match 3908 * this one for each assoc, see if a new primary_destination 3909 * is needed 3910 */ 3911 struct sctp_tcb *stcb; 3912 3913 /* clean up "next_addr_touse" */ 3914 if (inp->next_addr_touse == laddr) 3915 /* delete this address */ 3916 inp->next_addr_touse = NULL; 3917 3918 /* clean up "last_used_address" */ 3919 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { | 4182 /* 4183 * clean up any use of this address go through our 4184 * associations and clear any last_used_address that match 4185 * this one for each assoc, see if a new primary_destination 4186 * is needed 4187 */ 4188 struct sctp_tcb *stcb; 4189 4190 /* clean up "next_addr_touse" */ 4191 if (inp->next_addr_touse == laddr) 4192 /* delete this address */ 4193 inp->next_addr_touse = NULL; 4194 4195 /* clean up "last_used_address" */ 4196 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { |
4197 struct sctp_nets *net; 4198 4199 SCTP_TCB_LOCK(stcb); |
|
3920 if (stcb->asoc.last_used_address == laddr) 3921 /* delete this address */ 3922 stcb->asoc.last_used_address = NULL; | 4200 if (stcb->asoc.last_used_address == laddr) 4201 /* delete this address */ 4202 stcb->asoc.last_used_address = NULL; |
3923 } /* for each tcb */ | 4203 /* 4204 * Now spin through all the nets and purge any ref 4205 * to laddr 4206 */ 4207 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 4208 if (net->ro._s_addr && 4209 (net->ro._s_addr->ifa == laddr->ifa)) { 4210 /* Yep, purge src address selected */ 4211 struct rtentry *rt; |
3924 | 4212 |
4213 /* delete this address if cached */ 4214 rt = net->ro.ro_rt; 4215 if (rt != NULL) { 4216 RTFREE(rt); 4217 net->ro.ro_rt = NULL; 4218 } 4219 sctp_free_ifa(net->ro._s_addr); 4220 net->ro._s_addr = NULL; 4221 net->src_addr_selected = 0; 4222 } 4223 } 4224 SCTP_TCB_UNLOCK(stcb); 4225 } /* for each tcb */ |
|
3925 /* remove it from the ep list */ 3926 sctp_remove_laddr(laddr); 3927 inp->laddr_count--; 3928 /* update inp_vflag flags */ 3929 sctp_update_ep_vflag(inp); | 4226 /* remove it from the ep list */ 4227 sctp_remove_laddr(laddr); 4228 inp->laddr_count--; 4229 /* update inp_vflag flags */ 4230 sctp_update_ep_vflag(inp); |
3930 /* select a new primary destination if needed */ 3931 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) { 3932 /* 3933 * presume caller (sctp_asconf.c) already owns INP 3934 * lock 3935 */ 3936 SCTP_TCB_LOCK(stcb); 3937 if (sctp_destination_is_reachable(stcb, 3938 (struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr) == 0) { 3939 sctp_select_primary_destination(stcb); 3940 } 3941 SCTP_TCB_UNLOCK(stcb); 3942 } /* for each tcb */ | |
3943 } 3944 return (0); 3945} 3946 3947/* 3948 * Add the addr to the TCB local address list For the BOUNDALL or dynamic 3949 * case, this is a "pending" address list (eg. addresses waiting for an 3950 * ASCONF-ACK response) For the subset binding, static case, this is a 3951 * "valid" address list 3952 */ 3953int | 4231 } 4232 return (0); 4233} 4234 4235/* 4236 * Add the addr to the TCB local address list For the BOUNDALL or dynamic 4237 * case, this is a "pending" address list (eg. addresses waiting for an 4238 * ASCONF-ACK response) For the subset binding, static case, this is a 4239 * "valid" address list 4240 */ 4241int |
3954sctp_add_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa) | 4242sctp_add_local_addr_assoc(struct sctp_tcb *stcb, struct sctp_ifa *ifa, int restricted_list) |
3955{ 3956 struct sctp_inpcb *inp; 3957 struct sctp_laddr *laddr; | 4243{ 4244 struct sctp_inpcb *inp; 4245 struct sctp_laddr *laddr; |
4246 struct sctpladdr *list; |
|
3958 int error; 3959 3960 /* | 4247 int error; 4248 4249 /* |
3961 * Assumes TCP is locked.. and possiblye the INP. May need to | 4250 * Assumes TCB is locked.. and possibly the INP. May need to |
3962 * confirm/fix that if we need it and is not the case. 3963 */ | 4251 * confirm/fix that if we need it and is not the case. 4252 */ |
3964 inp = stcb->sctp_ep; 3965 if (ifa->ifa_addr->sa_family == AF_INET6) { 3966 struct in6_ifaddr *ifa6; | 4253 list = &stcb->asoc.sctp_restricted_addrs; |
3967 | 4254 |
3968 ifa6 = (struct in6_ifaddr *)ifa; 3969 if (ifa6->ia6_flags & (IN6_IFF_DETACHED | 3970 /* IN6_IFF_DEPRECATED | */ 3971 IN6_IFF_ANYCAST | 3972 IN6_IFF_NOTREADY)) | 4255 inp = stcb->sctp_ep; 4256 if (ifa->address.sa.sa_family == AF_INET6) { 4257 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) { |
3973 /* Can't bind a non-existent addr. */ 3974 return (-1); | 4258 /* Can't bind a non-existent addr. */ 4259 return (-1); |
4260 } |
|
3975 } 3976 /* does the address already exist? */ | 4261 } 4262 /* does the address already exist? */ |
3977 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) { | 4263 LIST_FOREACH(laddr, list, sctp_nxt_addr) { |
3978 if (laddr->ifa == ifa) { 3979 return (-1); 3980 } 3981 } 3982 3983 /* add to the list */ | 4264 if (laddr->ifa == ifa) { 4265 return (-1); 4266 } 4267 } 4268 4269 /* add to the list */ |
3984 error = sctp_insert_laddr(&stcb->asoc.sctp_local_addr_list, ifa); | 4270 error = sctp_insert_laddr(list, ifa, 0); |
3985 if (error != 0) 3986 return (error); 3987 return (0); 3988} 3989 3990/* 3991 * insert an laddr entry with the given ifa for the desired list 3992 */ 3993int | 4271 if (error != 0) 4272 return (error); 4273 return (0); 4274} 4275 4276/* 4277 * insert an laddr entry with the given ifa for the desired list 4278 */ 4279int |
3994sctp_insert_laddr(struct sctpladdr *list, struct ifaddr *ifa) | 4280sctp_insert_laddr(struct sctpladdr *list, struct sctp_ifa *ifa, uint32_t act) |
3995{ 3996 struct sctp_laddr *laddr; 3997 3998 laddr = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr); 3999 if (laddr == NULL) { 4000 /* out of memory? */ 4001 return (EINVAL); 4002 } 4003 SCTP_INCR_LADDR_COUNT(); 4004 bzero(laddr, sizeof(*laddr)); 4005 laddr->ifa = ifa; | 4281{ 4282 struct sctp_laddr *laddr; 4283 4284 laddr = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr); 4285 if (laddr == NULL) { 4286 /* out of memory? */ 4287 return (EINVAL); 4288 } 4289 SCTP_INCR_LADDR_COUNT(); 4290 bzero(laddr, sizeof(*laddr)); 4291 laddr->ifa = ifa; |
4292 laddr->action = act; 4293 atomic_add_int(&ifa->refcount, 1); |
|
4006 /* insert it */ 4007 LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr); 4008 4009 return (0); 4010} 4011 4012/* 4013 * Remove an laddr entry from the local address list (on an assoc) 4014 */ 4015void 4016sctp_remove_laddr(struct sctp_laddr *laddr) 4017{ 4018 4019 /* remove from the list */ 4020 LIST_REMOVE(laddr, sctp_nxt_addr); | 4294 /* insert it */ 4295 LIST_INSERT_HEAD(list, laddr, sctp_nxt_addr); 4296 4297 return (0); 4298} 4299 4300/* 4301 * Remove an laddr entry from the local address list (on an assoc) 4302 */ 4303void 4304sctp_remove_laddr(struct sctp_laddr *laddr) 4305{ 4306 4307 /* remove from the list */ 4308 LIST_REMOVE(laddr, sctp_nxt_addr); |
4309 sctp_free_ifa(laddr->ifa); |
|
4021 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr); 4022 SCTP_DECR_LADDR_COUNT(); 4023} 4024 4025/* 4026 * Remove an address from the TCB local address list 4027 */ 4028int | 4310 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_laddr, laddr); 4311 SCTP_DECR_LADDR_COUNT(); 4312} 4313 4314/* 4315 * Remove an address from the TCB local address list 4316 */ 4317int |
4029sctp_del_local_addr_assoc(struct sctp_tcb *stcb, struct ifaddr *ifa) | 4318sctp_del_local_addr_assoc(struct sctp_tcb *stcb, struct sctp_ifa *ifa) |
4030{ 4031 struct sctp_inpcb *inp; 4032 struct sctp_laddr *laddr; 4033 4034 /* 4035 * This is called by asconf work. It is assumed that a) The TCB is 4036 * locked and b) The INP is locked. This is true in as much as I can 4037 * trace through the entry asconf code where I did these locks. --- 7 unchanged lines hidden (view full) --- 4045 /* if subset bound and don't allow ASCONF's, can't delete last */ 4046 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && 4047 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) { 4048 if (stcb->asoc.numnets < 2) { 4049 /* can't delete last address */ 4050 return (-1); 4051 } 4052 } | 4319{ 4320 struct sctp_inpcb *inp; 4321 struct sctp_laddr *laddr; 4322 4323 /* 4324 * This is called by asconf work. It is assumed that a) The TCB is 4325 * locked and b) The INP is locked. This is true in as much as I can 4326 * trace through the entry asconf code where I did these locks. --- 7 unchanged lines hidden (view full) --- 4334 /* if subset bound and don't allow ASCONF's, can't delete last */ 4335 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && 4336 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) { 4337 if (stcb->asoc.numnets < 2) { 4338 /* can't delete last address */ 4339 return (-1); 4340 } 4341 } |
4053 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) { | 4342 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) { |
4054 /* remove the address if it exists */ 4055 if (laddr->ifa == NULL) 4056 continue; 4057 if (laddr->ifa == ifa) { 4058 sctp_remove_laddr(laddr); 4059 return (0); 4060 } 4061 } 4062 4063 /* address not found! */ 4064 return (-1); 4065} 4066 | 4343 /* remove the address if it exists */ 4344 if (laddr->ifa == NULL) 4345 continue; 4346 if (laddr->ifa == ifa) { 4347 sctp_remove_laddr(laddr); 4348 return (0); 4349 } 4350 } 4351 4352 /* address not found! */ 4353 return (-1); 4354} 4355 |
4067/* 4068 * Remove an address from the TCB local address list lookup using a sockaddr 4069 * addr 4070 */ 4071int 4072sctp_del_local_addr_assoc_sa(struct sctp_tcb *stcb, struct sockaddr *sa) 4073{ 4074 struct sctp_inpcb *inp; 4075 struct sctp_laddr *laddr; 4076 struct sockaddr *l_sa; 4077 4078 /* 4079 * This function I find does not seem to have a caller. As such we 4080 * NEED TO DELETE this code. If we do find a caller, the caller MUST 4081 * have locked the TCB at the least and probably the INP as well. 4082 */ 4083 inp = stcb->sctp_ep; 4084 /* if subset bound and don't allow ASCONF's, can't delete last */ 4085 if (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) && 4086 (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF) == 0)) { 4087 if (stcb->asoc.numnets < 2) { 4088 /* can't delete last address */ 4089 return (-1); 4090 } 4091 } 4092 LIST_FOREACH(laddr, &stcb->asoc.sctp_local_addr_list, sctp_nxt_addr) { 4093 /* make sure the address exists */ 4094 if (laddr->ifa == NULL) 4095 continue; 4096 if (laddr->ifa->ifa_addr == NULL) 4097 continue; 4098 4099 l_sa = laddr->ifa->ifa_addr; 4100 if (l_sa->sa_family == AF_INET6) { 4101 /* IPv6 address */ 4102 struct sockaddr_in6 *sin1, *sin2; 4103 4104 sin1 = (struct sockaddr_in6 *)l_sa; 4105 sin2 = (struct sockaddr_in6 *)sa; 4106 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, 4107 sizeof(struct in6_addr)) == 0) { 4108 /* matched */ 4109 sctp_remove_laddr(laddr); 4110 return (0); 4111 } 4112 } else if (l_sa->sa_family == AF_INET) { 4113 /* IPv4 address */ 4114 struct sockaddr_in *sin1, *sin2; 4115 4116 sin1 = (struct sockaddr_in *)l_sa; 4117 sin2 = (struct sockaddr_in *)sa; 4118 if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) { 4119 /* matched */ 4120 sctp_remove_laddr(laddr); 4121 return (0); 4122 } 4123 } else { 4124 /* invalid family */ 4125 return (-1); 4126 } 4127 } /* end foreach */ 4128 /* address not found! */ 4129 return (-1); 4130} 4131 | |
4132static char sctp_pcb_initialized = 0; 4133 4134/* 4135 * Temporarily remove for __APPLE__ until we use the Tiger equivalents 4136 */ 4137/* sysctl */ 4138static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC; 4139static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR; --- 14 unchanged lines hidden (view full) --- 4154 sctp_pcb_initialized = 1; 4155 4156 bzero(&sctpstat, sizeof(struct sctpstat)); 4157 SCTP_GETTIME_TIMEVAL(&sctpstat.sctps_discontinuitytime); 4158 /* init the empty list of (All) Endpoints */ 4159 LIST_INIT(&sctppcbinfo.listhead); 4160 4161 /* init the iterator head */ | 4356static char sctp_pcb_initialized = 0; 4357 4358/* 4359 * Temporarily remove for __APPLE__ until we use the Tiger equivalents 4360 */ 4361/* sysctl */ 4362static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC; 4363static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR; --- 14 unchanged lines hidden (view full) --- 4378 sctp_pcb_initialized = 1; 4379 4380 bzero(&sctpstat, sizeof(struct sctpstat)); 4381 SCTP_GETTIME_TIMEVAL(&sctpstat.sctps_discontinuitytime); 4382 /* init the empty list of (All) Endpoints */ 4383 LIST_INIT(&sctppcbinfo.listhead); 4384 4385 /* init the iterator head */ |
4162 LIST_INIT(&sctppcbinfo.iteratorhead); | 4386 TAILQ_INIT(&sctppcbinfo.iteratorhead); |
4163 4164 /* init the hash table of endpoints */ 4165 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &sctp_hashtblsize); 4166 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &sctp_pcbtblsize); 4167 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &sctp_chunkscale); 4168 sctppcbinfo.sctp_asochash = SCTP_HASH_INIT((sctp_hashtblsize * 31), 4169 &sctppcbinfo.hashasocmark); 4170 sctppcbinfo.sctp_ephash = SCTP_HASH_INIT(sctp_hashtblsize, 4171 &sctppcbinfo.hashmark); 4172 sctppcbinfo.sctp_tcpephash = SCTP_HASH_INIT(sctp_hashtblsize, 4173 &sctppcbinfo.hashtcpmark); 4174 sctppcbinfo.hashtblsize = sctp_hashtblsize; 4175 4176 /* init the small hash table we use to track restarted asoc's */ 4177 sctppcbinfo.sctp_restarthash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, 4178 &sctppcbinfo.hashrestartmark); 4179 | 4387 4388 /* init the hash table of endpoints */ 4389 TUNABLE_INT_FETCH("net.inet.sctp.tcbhashsize", &sctp_hashtblsize); 4390 TUNABLE_INT_FETCH("net.inet.sctp.pcbhashsize", &sctp_pcbtblsize); 4391 TUNABLE_INT_FETCH("net.inet.sctp.chunkscale", &sctp_chunkscale); 4392 sctppcbinfo.sctp_asochash = SCTP_HASH_INIT((sctp_hashtblsize * 31), 4393 &sctppcbinfo.hashasocmark); 4394 sctppcbinfo.sctp_ephash = SCTP_HASH_INIT(sctp_hashtblsize, 4395 &sctppcbinfo.hashmark); 4396 sctppcbinfo.sctp_tcpephash = SCTP_HASH_INIT(sctp_hashtblsize, 4397 &sctppcbinfo.hashtcpmark); 4398 sctppcbinfo.hashtblsize = sctp_hashtblsize; 4399 4400 /* init the small hash table we use to track restarted asoc's */ 4401 sctppcbinfo.sctp_restarthash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, 4402 &sctppcbinfo.hashrestartmark); 4403 |
4404 4405 sctppcbinfo.sctp_vrfhash = SCTP_HASH_INIT(SCTP_SIZE_OF_VRF_HASH, 4406 &sctppcbinfo.hashvrfmark); 4407 |
|
4180 /* init the zones */ 4181 /* 4182 * FIX ME: Should check for NULL returns, but if it does fail we are 4183 * doomed to panic anyways... add later maybe. 4184 */ 4185 SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_ep, "sctp_ep", 4186 sizeof(struct sctp_inpcb), maxsockets); 4187 --- 22 unchanged lines hidden (view full) --- 4210 4211 /* Master Lock INIT for info structure */ 4212 SCTP_INP_INFO_LOCK_INIT(); 4213 SCTP_STATLOG_INIT_LOCK(); 4214 SCTP_ITERATOR_LOCK_INIT(); 4215 4216 SCTP_IPI_COUNT_INIT(); 4217 SCTP_IPI_ADDR_INIT(); | 4408 /* init the zones */ 4409 /* 4410 * FIX ME: Should check for NULL returns, but if it does fail we are 4411 * doomed to panic anyways... add later maybe. 4412 */ 4413 SCTP_ZONE_INIT(sctppcbinfo.ipi_zone_ep, "sctp_ep", 4414 sizeof(struct sctp_inpcb), maxsockets); 4415 --- 22 unchanged lines hidden (view full) --- 4438 4439 /* Master Lock INIT for info structure */ 4440 SCTP_INP_INFO_LOCK_INIT(); 4441 SCTP_STATLOG_INIT_LOCK(); 4442 SCTP_ITERATOR_LOCK_INIT(); 4443 4444 SCTP_IPI_COUNT_INIT(); 4445 SCTP_IPI_ADDR_INIT(); |
4446 SCTP_IPI_ITERATOR_WQ_INIT(); 4447 |
|
4218 LIST_INIT(&sctppcbinfo.addr_wq); 4219 4220 /* not sure if we need all the counts */ 4221 sctppcbinfo.ipi_count_ep = 0; 4222 /* assoc/tcb zone info */ 4223 sctppcbinfo.ipi_count_asoc = 0; 4224 /* local addrlist zone info */ 4225 sctppcbinfo.ipi_count_laddr = 0; --- 13 unchanged lines hidden (view full) --- 4239 4240 SCTP_OS_TIMER_INIT(&sctppcbinfo.addr_wq_timer.timer); 4241 4242 /* Init the TIMEWAIT list */ 4243 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) { 4244 LIST_INIT(&sctppcbinfo.vtag_timewait[i]); 4245 } 4246 | 4448 LIST_INIT(&sctppcbinfo.addr_wq); 4449 4450 /* not sure if we need all the counts */ 4451 sctppcbinfo.ipi_count_ep = 0; 4452 /* assoc/tcb zone info */ 4453 sctppcbinfo.ipi_count_asoc = 0; 4454 /* local addrlist zone info */ 4455 sctppcbinfo.ipi_count_laddr = 0; --- 13 unchanged lines hidden (view full) --- 4469 4470 SCTP_OS_TIMER_INIT(&sctppcbinfo.addr_wq_timer.timer); 4471 4472 /* Init the TIMEWAIT list */ 4473 for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) { 4474 LIST_INIT(&sctppcbinfo.vtag_timewait[i]); 4475 } 4476 |
4477#if defined(SCTP_USE_THREAD_BASED_ITERATOR) 4478 sctppcbinfo.iterator_running = 0; 4479 sctp_startup_iterator(); 4480#endif 4481 4482 /* 4483 * INIT the default VRF which for BSD is the only one, other O/S's 4484 * may have more. But initially they must start with one and then 4485 * add the VRF's as addresses are added. 4486 */ 4487 sctp_init_vrf_list(SCTP_DEFAULT_VRF); 4488 |
|
4247} 4248 4249 4250int 4251sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, 4252 int iphlen, int offset, int limit, struct sctphdr *sh, 4253 struct sockaddr *altsa) 4254{ --- 554 unchanged lines hidden (view full) --- 4809 net = sctp_findnet(stcb, sa); 4810 4811 if (net == NULL) { 4812 /* didn't find the requested primary address! */ 4813 return (-1); 4814 } else { 4815 /* set the primary address */ 4816 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { | 4489} 4490 4491 4492int 4493sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, 4494 int iphlen, int offset, int limit, struct sctphdr *sh, 4495 struct sockaddr *altsa) 4496{ --- 554 unchanged lines hidden (view full) --- 5051 net = sctp_findnet(stcb, sa); 5052 5053 if (net == NULL) { 5054 /* didn't find the requested primary address! */ 5055 return (-1); 5056 } else { 5057 /* set the primary address */ 5058 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) { |
4817 /* Must be confirmed */ 4818 return (-1); | 5059 /* Must be confirmed, so queue to set */ 5060 net->dest_state |= SCTP_ADDR_REQ_PRIMARY; 5061 return (0); |
4819 } 4820 stcb->asoc.primary_destination = net; 4821 net->dest_state &= ~SCTP_ADDR_WAS_PRIMARY; 4822 net = TAILQ_FIRST(&stcb->asoc.nets); 4823 if (net != stcb->asoc.primary_destination) { 4824 /* 4825 * first one on the list is NOT the primary 4826 * sctp_cmpaddr() is much more efficent if the --- 90 unchanged lines hidden (view full) --- 4917 } 4918 } 4919 /* Not found, ok to use the tag */ 4920 SCTP_INP_INFO_WUNLOCK(); 4921 return (1); 4922} 4923 4924 | 5062 } 5063 stcb->asoc.primary_destination = net; 5064 net->dest_state &= ~SCTP_ADDR_WAS_PRIMARY; 5065 net = TAILQ_FIRST(&stcb->asoc.nets); 5066 if (net != stcb->asoc.primary_destination) { 5067 /* 5068 * first one on the list is NOT the primary 5069 * sctp_cmpaddr() is much more efficent if the --- 90 unchanged lines hidden (view full) --- 5160 } 5161 } 5162 /* Not found, ok to use the tag */ 5163 SCTP_INP_INFO_WUNLOCK(); 5164 return (1); 5165} 5166 5167 |
4925/* 4926 * Delete the address from the endpoint local address list Lookup using a 4927 * sockaddr address (ie. not an ifaddr) 4928 */ 4929int 4930sctp_del_local_addr_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa) 4931{ 4932 struct sctp_laddr *laddr; 4933 struct sockaddr *l_sa; 4934 int found = 0; 4935 4936 /* 4937 * Here is another function I cannot find a caller for. As such we 4938 * SHOULD delete it if we have no users. If we find a user that user 4939 * MUST have the INP locked. 4940 * 4941 */ 4942 4943 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 4944 /* You are already bound to all. You have it already */ 4945 return (EINVAL); 4946 } 4947 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 4948 /* make sure the address exists */ 4949 if (laddr->ifa == NULL) 4950 continue; 4951 if (laddr->ifa->ifa_addr == NULL) 4952 continue; 4953 4954 l_sa = laddr->ifa->ifa_addr; 4955 if (l_sa->sa_family == AF_INET6) { 4956 /* IPv6 address */ 4957 struct sockaddr_in6 *sin1, *sin2; 4958 4959 sin1 = (struct sockaddr_in6 *)l_sa; 4960 sin2 = (struct sockaddr_in6 *)sa; 4961 if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, 4962 sizeof(struct in6_addr)) == 0) { 4963 /* matched */ 4964 found = 1; 4965 break; 4966 } 4967 } else if (l_sa->sa_family == AF_INET) { 4968 /* IPv4 address */ 4969 struct sockaddr_in *sin1, *sin2; 4970 4971 sin1 = (struct sockaddr_in *)l_sa; 4972 sin2 = (struct sockaddr_in *)sa; 4973 if (sin1->sin_addr.s_addr == sin2->sin_addr.s_addr) { 4974 /* matched */ 4975 found = 1; 4976 break; 4977 } 4978 } else { 4979 /* invalid family */ 4980 return (-1); 4981 } 4982 } 4983 4984 if (found && inp->laddr_count < 2) { 4985 /* can't delete unless there are at LEAST 2 addresses */ 4986 return (-1); 4987 } 4988 if (found && (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) { 4989 /* 4990 * remove it from the ep list, this should NOT be done until 4991 * its really gone from the interface list and we won't be 4992 * receiving more of these. Probably right away. If we do 4993 * allow a removal of an address from an association 4994 * (sub-set bind) than this should NOT be called until the 4995 * all ASCONF come back from this association. 4996 */ 4997 sctp_remove_laddr(laddr); 4998 return (0); 4999 } else { 5000 return (-1); 5001 } 5002} 5003 | |
5004static sctp_assoc_t reneged_asoc_ids[256]; 5005static uint8_t reneged_at = 0; 5006 | 5168static sctp_assoc_t reneged_asoc_ids[256]; 5169static uint8_t reneged_at = 0; 5170 |
5007extern int sctp_do_drain; | |
5008 5009static void 5010sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb) 5011{ 5012 /* 5013 * We must hunt this association for MBUF's past the cumack (i.e. 5014 * out of order data that we can renege on). 5015 */ --- 139 unchanged lines hidden (view full) --- 5155 /* Nothing left in map */ 5156 memset(asoc->mapping_array, 0, asoc->mapping_array_size); 5157 asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1; 5158 asoc->highest_tsn_inside_map = asoc->cumulative_tsn; 5159 } 5160 asoc->last_revoke_count = cnt; 5161 SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer); 5162 sctp_send_sack(stcb); | 5171 5172static void 5173sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb) 5174{ 5175 /* 5176 * We must hunt this association for MBUF's past the cumack (i.e. 5177 * out of order data that we can renege on). 5178 */ --- 139 unchanged lines hidden (view full) --- 5318 /* Nothing left in map */ 5319 memset(asoc->mapping_array, 0, asoc->mapping_array_size); 5320 asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1; 5321 asoc->highest_tsn_inside_map = asoc->cumulative_tsn; 5322 } 5323 asoc->last_revoke_count = cnt; 5324 SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer); 5325 sctp_send_sack(stcb); |
5326 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN); |
|
5163 reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb); 5164 reneged_at++; 5165 } 5166 /* 5167 * Another issue, in un-setting the TSN's in the mapping array we 5168 * DID NOT adjust the higest_tsn marker. This will cause one of two 5169 * things to occur. It may cause us to do extra work in checking for 5170 * our mapping array movement. More importantly it may cause us to --- 33 unchanged lines hidden (view full) --- 5204 * start a new iterator 5205 * iterates through all endpoints and associations based on the pcb_state 5206 * flags and asoc_state. "af" (mandatory) is executed for all matching 5207 * assocs and "ef" (optional) is executed when the iterator completes. 5208 * "inpf" (optional) is executed for each new endpoint as it is being 5209 * iterated through. 5210 */ 5211int | 5327 reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb); 5328 reneged_at++; 5329 } 5330 /* 5331 * Another issue, in un-setting the TSN's in the mapping array we 5332 * DID NOT adjust the higest_tsn marker. This will cause one of two 5333 * things to occur. It may cause us to do extra work in checking for 5334 * our mapping array movement. More importantly it may cause us to --- 33 unchanged lines hidden (view full) --- 5368 * start a new iterator 5369 * iterates through all endpoints and associations based on the pcb_state 5370 * flags and asoc_state. "af" (mandatory) is executed for all matching 5371 * assocs and "ef" (optional) is executed when the iterator completes. 5372 * "inpf" (optional) is executed for each new endpoint as it is being 5373 * iterated through. 5374 */ 5375int |
5212sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t pcb_state, 5213 uint32_t pcb_features, uint32_t asoc_state, void *argp, uint32_t argi, 5214 end_func ef, struct sctp_inpcb *s_inp, uint8_t chunk_output_off) | 5376sctp_initiate_iterator(inp_func inpf, 5377 asoc_func af, 5378 inp_func inpe, 5379 uint32_t pcb_state, 5380 uint32_t pcb_features, 5381 uint32_t asoc_state, 5382 void *argp, 5383 uint32_t argi, 5384 end_func ef, 5385 struct sctp_inpcb *s_inp, 5386 uint8_t chunk_output_off) |
5215{ 5216 struct sctp_iterator *it = NULL; 5217 5218 if (af == NULL) { 5219 return (-1); 5220 } 5221 SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator), 5222 "Iterator"); 5223 if (it == NULL) { 5224 return (ENOMEM); 5225 } 5226 memset(it, 0, sizeof(*it)); 5227 it->function_assoc = af; 5228 it->function_inp = inpf; | 5387{ 5388 struct sctp_iterator *it = NULL; 5389 5390 if (af == NULL) { 5391 return (-1); 5392 } 5393 SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator), 5394 "Iterator"); 5395 if (it == NULL) { 5396 return (ENOMEM); 5397 } 5398 memset(it, 0, sizeof(*it)); 5399 it->function_assoc = af; 5400 it->function_inp = inpf; |
5401 if (inpf) 5402 it->done_current_ep = 0; 5403 else 5404 it->done_current_ep = 1; |
|
5229 it->function_atend = ef; 5230 it->pointer = argp; 5231 it->val = argi; 5232 it->pcb_flags = pcb_state; 5233 it->pcb_features = pcb_features; 5234 it->asoc_state = asoc_state; | 5405 it->function_atend = ef; 5406 it->pointer = argp; 5407 it->val = argi; 5408 it->pcb_flags = pcb_state; 5409 it->pcb_features = pcb_features; 5410 it->asoc_state = asoc_state; |
5411 it->function_inp_end = inpe; |
|
5235 it->no_chunk_output = chunk_output_off; 5236 if (s_inp) { 5237 it->inp = s_inp; 5238 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP; 5239 } else { 5240 SCTP_INP_INFO_RLOCK(); 5241 it->inp = LIST_FIRST(&sctppcbinfo.listhead); | 5412 it->no_chunk_output = chunk_output_off; 5413 if (s_inp) { 5414 it->inp = s_inp; 5415 it->iterator_flags = SCTP_ITERATOR_DO_SINGLE_INP; 5416 } else { 5417 SCTP_INP_INFO_RLOCK(); 5418 it->inp = LIST_FIRST(&sctppcbinfo.listhead); |
5419 |
|
5242 SCTP_INP_INFO_RUNLOCK(); 5243 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP; 5244 5245 } | 5420 SCTP_INP_INFO_RUNLOCK(); 5421 it->iterator_flags = SCTP_ITERATOR_DO_ALL_INP; 5422 5423 } |
5424 SCTP_IPI_ITERATOR_WQ_LOCK(); 5425 if (it->inp) 5426 SCTP_INP_INCR_REF(it->inp); 5427 TAILQ_INSERT_TAIL(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr); 5428#if defined(SCTP_USE_THREAD_BASED_ITERATOR) 5429 if (sctppcbinfo.iterator_running == 0) { 5430 sctp_wakeup_iterator(); 5431 } 5432 SCTP_IPI_ITERATOR_WQ_UNLOCK(); 5433#else 5434 if (it->inp) 5435 SCTP_INP_DECR_REF(it->inp); 5436 SCTP_IPI_ITERATOR_WQ_UNLOCK(); |
|
5246 /* Init the timer */ 5247 SCTP_OS_TIMER_INIT(&it->tmr.timer); 5248 /* add to the list of all iterators */ | 5437 /* Init the timer */ 5438 SCTP_OS_TIMER_INIT(&it->tmr.timer); 5439 /* add to the list of all iterators */ |
5249 SCTP_INP_INFO_WLOCK(); 5250 LIST_INSERT_HEAD(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr); 5251 SCTP_INP_INFO_WUNLOCK(); | |
5252 sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it, 5253 NULL, NULL); | 5440 sctp_timer_start(SCTP_TIMER_TYPE_ITERATOR, (struct sctp_inpcb *)it, 5441 NULL, NULL); |
5442#endif |
|
5254 return (0); 5255} | 5443 return (0); 5444} |