sctp_pcb.c (170138) | sctp_pcb.c (170181) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, by 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, by 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 170138 2007-05-30 17:39:45Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 170181 2007-06-01 11:19:54Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_pcb.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp.h> --- 233 unchanged lines hidden (view full) --- 276 if (found == NULL) { 277 /* Not in the list.. sorry */ 278 return; 279 } 280 if (hold_addr_lock == 0) 281 SCTP_IPI_ADDR_LOCK(); 282 LIST_REMOVE(sctp_ifnp, next_bucket); 283 LIST_REMOVE(sctp_ifnp, next_ifn); | 35 36#include <netinet/sctp_os.h> 37#include <sys/proc.h> 38#include <netinet/sctp_var.h> 39#include <netinet/sctp_sysctl.h> 40#include <netinet/sctp_pcb.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp.h> --- 233 unchanged lines hidden (view full) --- 276 if (found == NULL) { 277 /* Not in the list.. sorry */ 278 return; 279 } 280 if (hold_addr_lock == 0) 281 SCTP_IPI_ADDR_LOCK(); 282 LIST_REMOVE(sctp_ifnp, next_bucket); 283 LIST_REMOVE(sctp_ifnp, next_ifn); |
284 SCTP_DEREGISTER_INTERFACE(sctp_ifnp->ifn_index, 285 sctp_ifnp->registered_af); |
|
284 if (hold_addr_lock == 0) 285 SCTP_IPI_ADDR_UNLOCK(); 286 /* Take away the reference, and possibly free it */ 287 sctp_free_ifn(sctp_ifnp); 288} 289 290 291struct sctp_ifa * 292sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, 293 uint32_t ifn_type, const char *if_name, 294 void *ifa, struct sockaddr *addr, uint32_t ifa_flags, 295 int dynamic_add) 296{ 297 struct sctp_vrf *vrf; 298 struct sctp_ifn *sctp_ifnp = NULL; 299 struct sctp_ifa *sctp_ifap = NULL; 300 struct sctp_ifalist *hash_addr_head; 301 struct sctp_ifnlist *hash_ifn_head; 302 uint32_t hash_of_addr; | 286 if (hold_addr_lock == 0) 287 SCTP_IPI_ADDR_UNLOCK(); 288 /* Take away the reference, and possibly free it */ 289 sctp_free_ifn(sctp_ifnp); 290} 291 292 293struct sctp_ifa * 294sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index, 295 uint32_t ifn_type, const char *if_name, 296 void *ifa, struct sockaddr *addr, uint32_t ifa_flags, 297 int dynamic_add) 298{ 299 struct sctp_vrf *vrf; 300 struct sctp_ifn *sctp_ifnp = NULL; 301 struct sctp_ifa *sctp_ifap = NULL; 302 struct sctp_ifalist *hash_addr_head; 303 struct sctp_ifnlist *hash_ifn_head; 304 uint32_t hash_of_addr; |
305 int new_ifn_af = 0; |
|
303 304 /* How granular do we need the locks to be here? */ 305 SCTP_IPI_ADDR_LOCK(); 306 vrf = sctp_find_vrf(vrf_id); 307 if (vrf == NULL) { 308 vrf = sctp_allocate_vrf(vrf_id); 309 if (vrf == NULL) { 310 SCTP_IPI_ADDR_UNLOCK(); --- 15 unchanged lines hidden (view full) --- 326 return (NULL); 327 } 328 sctp_ifnp->ifn_index = ifn_index; 329 sctp_ifnp->ifn_p = ifn; 330 sctp_ifnp->ifn_type = ifn_type; 331 sctp_ifnp->ifa_count = 0; 332 sctp_ifnp->refcount = 1; 333 sctp_ifnp->vrf = vrf; | 306 307 /* How granular do we need the locks to be here? */ 308 SCTP_IPI_ADDR_LOCK(); 309 vrf = sctp_find_vrf(vrf_id); 310 if (vrf == NULL) { 311 vrf = sctp_allocate_vrf(vrf_id); 312 if (vrf == NULL) { 313 SCTP_IPI_ADDR_UNLOCK(); --- 15 unchanged lines hidden (view full) --- 329 return (NULL); 330 } 331 sctp_ifnp->ifn_index = ifn_index; 332 sctp_ifnp->ifn_p = ifn; 333 sctp_ifnp->ifn_type = ifn_type; 334 sctp_ifnp->ifa_count = 0; 335 sctp_ifnp->refcount = 1; 336 sctp_ifnp->vrf = vrf; |
334 sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index); | 337 sctp_ifnp->ifn_mtu = SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, addr->sa_family); |
335 if (if_name != NULL) { 336 memcpy(sctp_ifnp->ifn_name, if_name, SCTP_IFNAMSIZ); 337 } else { 338 memcpy(sctp_ifnp->ifn_name, "unknown", min(7, SCTP_IFNAMSIZ)); 339 } 340 hash_ifn_head = &vrf->vrf_ifn_hash[(ifn_index & vrf->vrf_ifn_hashmark)]; 341 LIST_INIT(&sctp_ifnp->ifalist); 342 SCTP_IPI_ADDR_LOCK(); 343 LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket); 344 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn); 345 atomic_add_int(&sctppcbinfo.ipi_count_ifns, 1); | 338 if (if_name != NULL) { 339 memcpy(sctp_ifnp->ifn_name, if_name, SCTP_IFNAMSIZ); 340 } else { 341 memcpy(sctp_ifnp->ifn_name, "unknown", min(7, SCTP_IFNAMSIZ)); 342 } 343 hash_ifn_head = &vrf->vrf_ifn_hash[(ifn_index & vrf->vrf_ifn_hashmark)]; 344 LIST_INIT(&sctp_ifnp->ifalist); 345 SCTP_IPI_ADDR_LOCK(); 346 LIST_INSERT_HEAD(hash_ifn_head, sctp_ifnp, next_bucket); 347 LIST_INSERT_HEAD(&vrf->ifnlist, sctp_ifnp, next_ifn); 348 atomic_add_int(&sctppcbinfo.ipi_count_ifns, 1); |
349 new_ifn_af = 1; |
|
346 } 347 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1); 348 if (sctp_ifap) { 349 /* Hmm, it already exists? */ 350 if ((sctp_ifap->ifn_p) && 351 (sctp_ifap->ifn_p->ifn_index == ifn_index)) { 352 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { 353 /* easy to solve, just switch back to active */ --- 44 unchanged lines hidden (view full) --- 398 sin = (struct sockaddr_in *)&sctp_ifap->address.sin; 399 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || 400 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) { 401 sctp_ifap->src_is_loop = 1; 402 } 403 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 404 sctp_ifap->src_is_priv = 1; 405 } | 350 } 351 sctp_ifap = sctp_find_ifa_by_addr(addr, vrf->vrf_id, 1); 352 if (sctp_ifap) { 353 /* Hmm, it already exists? */ 354 if ((sctp_ifap->ifn_p) && 355 (sctp_ifap->ifn_p->ifn_index == ifn_index)) { 356 if (sctp_ifap->localifa_flags & SCTP_BEING_DELETED) { 357 /* easy to solve, just switch back to active */ --- 44 unchanged lines hidden (view full) --- 402 sin = (struct sockaddr_in *)&sctp_ifap->address.sin; 403 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || 404 (IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) { 405 sctp_ifap->src_is_loop = 1; 406 } 407 if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) { 408 sctp_ifap->src_is_priv = 1; 409 } |
410 sctp_ifnp->num_v4++; 411 if (new_ifn_af) 412 new_ifn_af = AF_INET; |
|
406 } else if (sctp_ifap->address.sa.sa_family == AF_INET6) { 407 /* ok to use deprecated addresses? */ 408 struct sockaddr_in6 *sin6; 409 410 sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6; 411 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || 412 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) { 413 sctp_ifap->src_is_loop = 1; 414 } 415 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 416 sctp_ifap->src_is_priv = 1; 417 } | 413 } else if (sctp_ifap->address.sa.sa_family == AF_INET6) { 414 /* ok to use deprecated addresses? */ 415 struct sockaddr_in6 *sin6; 416 417 sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6; 418 if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) || 419 (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) { 420 sctp_ifap->src_is_loop = 1; 421 } 422 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 423 sctp_ifap->src_is_priv = 1; 424 } |
425 sctp_ifnp->num_v6++; 426 if (new_ifn_af) 427 new_ifn_af = AF_INET6; 428 } else { 429 new_ifn_af = 0; |
|
418 } 419 hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa); 420 421 if ((sctp_ifap->src_is_priv == 0) && 422 (sctp_ifap->src_is_loop == 0)) { 423 sctp_ifap->src_is_glob = 1; 424 } 425 SCTP_IPI_ADDR_LOCK(); 426 hash_addr_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)]; 427 LIST_INSERT_HEAD(hash_addr_head, sctp_ifap, next_bucket); 428 sctp_ifap->refcount = 1; 429 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); 430 sctp_ifnp->ifa_count++; 431 vrf->total_ifa_count++; 432 atomic_add_int(&sctppcbinfo.ipi_count_ifas, 1); | 430 } 431 hash_of_addr = sctp_get_ifa_hash_val(&sctp_ifap->address.sa); 432 433 if ((sctp_ifap->src_is_priv == 0) && 434 (sctp_ifap->src_is_loop == 0)) { 435 sctp_ifap->src_is_glob = 1; 436 } 437 SCTP_IPI_ADDR_LOCK(); 438 hash_addr_head = &vrf->vrf_addr_hash[(hash_of_addr & vrf->vrf_addr_hashmark)]; 439 LIST_INSERT_HEAD(hash_addr_head, sctp_ifap, next_bucket); 440 sctp_ifap->refcount = 1; 441 LIST_INSERT_HEAD(&sctp_ifnp->ifalist, sctp_ifap, next_ifa); 442 sctp_ifnp->ifa_count++; 443 vrf->total_ifa_count++; 444 atomic_add_int(&sctppcbinfo.ipi_count_ifas, 1); |
445 if (new_ifn_af) { 446 SCTP_REGISTER_INTERFACE(ifn_index, new_ifn_af); 447 sctp_ifnp->registered_af = new_ifn_af; 448 } |
|
433 SCTP_IPI_ADDR_UNLOCK(); 434 if (dynamic_add) { 435 /* 436 * Bump up the refcount so that when the timer completes it 437 * will drop back down. 438 */ 439 struct sctp_laddr *wi; 440 --- 50 unchanged lines hidden (view full) --- 491 if (sctp_ifap) { 492 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID; 493 sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; 494 vrf->total_ifa_count--; 495 LIST_REMOVE(sctp_ifap, next_bucket); 496 LIST_REMOVE(sctp_ifap, next_ifa); 497 if (sctp_ifap->ifn_p) { 498 sctp_ifap->ifn_p->ifa_count--; | 449 SCTP_IPI_ADDR_UNLOCK(); 450 if (dynamic_add) { 451 /* 452 * Bump up the refcount so that when the timer completes it 453 * will drop back down. 454 */ 455 struct sctp_laddr *wi; 456 --- 50 unchanged lines hidden (view full) --- 507 if (sctp_ifap) { 508 sctp_ifap->localifa_flags &= SCTP_ADDR_VALID; 509 sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; 510 vrf->total_ifa_count--; 511 LIST_REMOVE(sctp_ifap, next_bucket); 512 LIST_REMOVE(sctp_ifap, next_ifa); 513 if (sctp_ifap->ifn_p) { 514 sctp_ifap->ifn_p->ifa_count--; |
515 if (sctp_ifap->address.sa.sa_family == AF_INET6) 516 sctp_ifap->ifn_p->num_v6--; 517 else if (sctp_ifap->address.sa.sa_family == AF_INET) 518 sctp_ifap->ifn_p->num_v4--; |
|
499 if (SCTP_LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) { 500 sctp_delete_ifn(sctp_ifap->ifn_p, 1); | 519 if (SCTP_LIST_EMPTY(&sctp_ifap->ifn_p->ifalist)) { 520 sctp_delete_ifn(sctp_ifap->ifn_p, 1); |
521 } else { 522 if ((sctp_ifap->ifn_p->num_v6 == 0) && 523 (sctp_ifap->ifn_p->registered_af == AF_INET6)) { 524 SCTP_DEREGISTER_INTERFACE(ifn_index, 525 AF_INET6); 526 SCTP_REGISTER_INTERFACE(ifn_index, 527 AF_INET); 528 sctp_ifap->ifn_p->registered_af = AF_INET; 529 } else if ((sctp_ifap->ifn_p->num_v4 == 0) && 530 (sctp_ifap->ifn_p->registered_af == AF_INET)) { 531 SCTP_DEREGISTER_INTERFACE(ifn_index, 532 AF_INET); 533 SCTP_REGISTER_INTERFACE(ifn_index, 534 AF_INET6); 535 sctp_ifap->ifn_p->registered_af = AF_INET6; 536 } |
|
501 } 502 sctp_free_ifn(sctp_ifap->ifn_p); 503 sctp_ifap->ifn_p = NULL; 504 } 505 } 506#ifdef SCTP_DEBUG 507 else { 508 SCTPDBG(SCTP_DEBUG_PCB1, "Del Addr-ifn:%d Could not find address:", --- 1279 unchanged lines hidden (view full) --- 1788 inp->sctp_tcbhash = SCTP_HASH_INIT(sctp_pcbtblsize, 1789 &inp->sctp_hashmark); 1790 if (inp->sctp_tcbhash == NULL) { 1791 SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n"); 1792 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp); 1793 return (ENOBUFS); 1794 } 1795 inp->def_vrf_id = SCTP_DEFAULT_VRFID; | 537 } 538 sctp_free_ifn(sctp_ifap->ifn_p); 539 sctp_ifap->ifn_p = NULL; 540 } 541 } 542#ifdef SCTP_DEBUG 543 else { 544 SCTPDBG(SCTP_DEBUG_PCB1, "Del Addr-ifn:%d Could not find address:", --- 1279 unchanged lines hidden (view full) --- 1824 inp->sctp_tcbhash = SCTP_HASH_INIT(sctp_pcbtblsize, 1825 &inp->sctp_hashmark); 1826 if (inp->sctp_tcbhash == NULL) { 1827 SCTP_PRINTF("Out of SCTP-INPCB->hashinit - no resources\n"); 1828 SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_ep, inp); 1829 return (ENOBUFS); 1830 } 1831 inp->def_vrf_id = SCTP_DEFAULT_VRFID; |
1796 inp->def_table_id = SCTP_DEFAULT_TABLEID; | |
1797 1798 SCTP_INP_INFO_WLOCK(); 1799 SCTP_INP_LOCK_INIT(inp); 1800 SCTP_INP_READ_INIT(inp); 1801 SCTP_ASOC_CREATE_LOCK_INIT(inp); 1802 /* lock the new ep */ 1803 SCTP_INP_WLOCK(inp); 1804 --- 1258 unchanged lines hidden (view full) --- 3063 /* KAME hack: embed scopeid */ 3064 if (newaddr->sa_family == AF_INET6) { 3065 struct sockaddr_in6 *sin6; 3066 3067 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; 3068 (void)sa6_embedscope(sin6, ip6_use_defzone); 3069 sin6->sin6_scope_id = 0; 3070 } | 1832 1833 SCTP_INP_INFO_WLOCK(); 1834 SCTP_INP_LOCK_INIT(inp); 1835 SCTP_INP_READ_INIT(inp); 1836 SCTP_ASOC_CREATE_LOCK_INIT(inp); 1837 /* lock the new ep */ 1838 SCTP_INP_WLOCK(inp); 1839 --- 1258 unchanged lines hidden (view full) --- 3098 /* KAME hack: embed scopeid */ 3099 if (newaddr->sa_family == AF_INET6) { 3100 struct sockaddr_in6 *sin6; 3101 3102 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; 3103 (void)sa6_embedscope(sin6, ip6_use_defzone); 3104 sin6->sin6_scope_id = 0; 3105 } |
3071 SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id, 3072 stcb->asoc.table_id); | 3106 SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id); |
3073 3074 if (newaddr->sa_family == AF_INET6) { 3075 struct sockaddr_in6 *sin6; 3076 3077 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; 3078 (void)sa6_recoverscope(sin6); 3079 } 3080 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) { --- 2540 unchanged lines hidden --- | 3107 3108 if (newaddr->sa_family == AF_INET6) { 3109 struct sockaddr_in6 *sin6; 3110 3111 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; 3112 (void)sa6_recoverscope(sin6); 3113 } 3114 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) { --- 2540 unchanged lines hidden --- |