diff options
Diffstat (limited to 'freebsd/sys/netinet/sctp_bsd_addr.c')
-rw-r--r-- | freebsd/sys/netinet/sctp_bsd_addr.c | 146 |
1 files changed, 76 insertions, 70 deletions
diff --git a/freebsd/sys/netinet/sctp_bsd_addr.c b/freebsd/sys/netinet/sctp_bsd_addr.c index 8612adc9..49549d15 100644 --- a/freebsd/sys/netinet/sctp_bsd_addr.c +++ b/freebsd/sys/netinet/sctp_bsd_addr.c @@ -2,16 +2,18 @@ /*- * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. + * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * a) Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions and the following disclaimer. * * b) Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. + * the documentation and/or other materials provided with the distribution. * * c) Neither the name of Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived @@ -30,8 +32,6 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -/* $KAME: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */ - #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -70,25 +70,10 @@ MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", "sctp time block"); MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list"); MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control"); MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option"); +MALLOC_DEFINE(SCTP_M_MCORE, "sctp_mcore", "sctp mcore queue"); /* Global NON-VNET structure that controls the iterator */ struct iterator_control sctp_it_ctl; -static int __sctp_thread_based_iterator_started = 0; - - -static void -sctp_cleanup_itqueue(void) -{ - struct sctp_iterator *it; - - while ((it = TAILQ_FIRST(&sctp_it_ctl.iteratorhead)) != NULL) { - if (it->function_atend != NULL) { - (*it->function_atend) (it->pointer, it->val); - } - TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr); - SCTP_FREE(it, SCTP_M_ITER); - } -} void @@ -98,20 +83,14 @@ sctp_wakeup_iterator(void) } static void -sctp_iterator_thread(void *v) +sctp_iterator_thread(void *v SCTP_UNUSED) { SCTP_IPI_ITERATOR_WQ_LOCK(); - while (1) { + /* In FreeBSD this thread never terminates. */ + for (;;) { msleep(&sctp_it_ctl.iterator_running, &sctp_it_ctl.ipi_iterator_wq_mtx, 0, "waiting_for_work", 0); - if (sctp_it_ctl.iterator_flags & SCTP_ITERATOR_MUST_EXIT) { - SCTP_IPI_ITERATOR_WQ_DESTROY(); - SCTP_ITERATOR_LOCK_DESTROY(); - sctp_cleanup_itqueue(); - __sctp_thread_based_iterator_started = 0; - kthread_exit(); - } sctp_iterator_worker(); } } @@ -119,21 +98,21 @@ sctp_iterator_thread(void *v) void sctp_startup_iterator(void) { - if (__sctp_thread_based_iterator_started) { + static int called = 0; + int ret; + + if (called) { /* You only get one */ return; } /* init the iterator head */ - __sctp_thread_based_iterator_started = 1; + called = 1; sctp_it_ctl.iterator_running = 0; sctp_it_ctl.iterator_flags = 0; sctp_it_ctl.cur_it = NULL; SCTP_ITERATOR_LOCK_INIT(); SCTP_IPI_ITERATOR_WQ_INIT(); TAILQ_INIT(&sctp_it_ctl.iteratorhead); - - int ret; - ret = kproc_create(sctp_iterator_thread, (void *)NULL, &sctp_it_ctl.thread_proc, @@ -175,12 +154,12 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa) static uint32_t -sctp_is_desired_interface_type(struct ifaddr *ifa) +sctp_is_desired_interface_type(struct ifnet *ifn) { int result; /* check the interface type to see if it's one we care about */ - switch (ifa->ifa_ifp->if_type) { + switch (ifn->if_type) { case IFT_ETHER: case IFT_ISO88023: case IFT_ISO88024: @@ -201,9 +180,11 @@ sctp_is_desired_interface_type(struct ifaddr *ifa) case IFT_SLIP: case IFT_GIF: case IFT_L2VLAN: + case IFT_STF: case IFT_IP: case IFT_IPOVERCDLC: case IFT_IPOVERCLAW: + case IFT_PROPVIRTUAL: /* NetGraph Virtual too */ case IFT_VIRTUALIPADDRESS: result = 1; break; @@ -227,40 +208,59 @@ sctp_init_ifns_for_vrf(int vrfid) */ struct ifnet *ifn; struct ifaddr *ifa; - struct in6_ifaddr *ifa6; struct sctp_ifa *sctp_ifa; uint32_t ifa_flags; +#ifdef INET6 + struct in6_ifaddr *ifa6; + +#endif + IFNET_RLOCK(); TAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_list) { - IF_ADDR_LOCK(ifn); + if (sctp_is_desired_interface_type(ifn) == 0) { + /* non desired type */ + continue; + } + IF_ADDR_RLOCK(ifn); TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) { if (ifa->ifa_addr == NULL) { continue; } - if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) { - /* non inet/inet6 skip */ - continue; - } - if (ifa->ifa_addr->sa_family == AF_INET6) { - if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) { - /* skip unspecifed addresses */ + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) { continue; } - } else { - if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) { + break; +#endif +#ifdef INET6 + case AF_INET6: + if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) { + /* skip unspecifed addresses */ continue; } - } - if (sctp_is_desired_interface_type(ifa) == 0) { - /* non desired type */ + break; +#endif + default: continue; } - if (ifa->ifa_addr->sa_family == AF_INET6) { + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + ifa_flags = 0; + break; +#endif +#ifdef INET6 + case AF_INET6: ifa6 = (struct in6_ifaddr *)ifa; ifa_flags = ifa6->ia6_flags; - } else { + break; +#endif + default: ifa_flags = 0; + break; } sctp_ifa = sctp_add_addr_to_vrf(vrfid, (void *)ifn, @@ -275,7 +275,7 @@ sctp_init_ifns_for_vrf(int vrfid) sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE; } } - IF_ADDR_UNLOCK(ifn); + IF_ADDR_RUNLOCK(ifn); } IFNET_RUNLOCK(); } @@ -319,37 +319,41 @@ sctp_addr_change(struct ifaddr *ifa, int cmd) if (ifa->ifa_addr == NULL) { return; } - if ((ifa->ifa_addr->sa_family != AF_INET) && (ifa->ifa_addr->sa_family != AF_INET6)) { - /* non inet/inet6 skip */ + if (sctp_is_desired_interface_type(ifa->ifa_ifp) == 0) { + /* non desired type */ return; } - if (ifa->ifa_addr->sa_family == AF_INET6) { + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) { + return; + } + break; +#endif +#ifdef INET6 + case AF_INET6: ifa_flags = ((struct in6_ifaddr *)ifa)->ia6_flags; if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) { /* skip unspecifed addresses */ return; } - } else { - if (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr == 0) { - return; - } - } - - if (sctp_is_desired_interface_type(ifa) == 0) { - /* non desired type */ + break; +#endif + default: + /* non inet/inet6 skip */ return; } if (cmd == RTM_ADD) { (void)sctp_add_addr_to_vrf(SCTP_DEFAULT_VRFID, (void *)ifa->ifa_ifp, - ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, - ifa->ifa_ifp->if_xname, + ifa->ifa_ifp->if_index, ifa->ifa_ifp->if_type, ifa->ifa_ifp->if_xname, (void *)ifa, ifa->ifa_addr, ifa_flags, 1); } else { sctp_del_addr_from_vrf(SCTP_DEFAULT_VRFID, ifa->ifa_addr, ifa->ifa_ifp->if_index, - ifa->ifa_ifp->if_xname - ); + ifa->ifa_ifp->if_xname); + /* * We don't bump refcount here so when it completes the * final delete will happen. @@ -418,11 +422,12 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, #ifdef SCTP_PACKET_LOGGING void -sctp_packet_log(struct mbuf *m, int length) +sctp_packet_log(struct mbuf *m) { int *lenat, thisone; void *copyto; uint32_t *tick_tock; + int length; int total_len; int grabbed_lock = 0; int value, newval, thisend, thisbegin; @@ -432,6 +437,7 @@ sctp_packet_log(struct mbuf *m, int length) * (value) -ticks of log (ticks) o -ip packet o -as logged - * where this started (thisbegin) x <--end points here */ + length = SCTP_HEADER_LEN(m); total_len = SCTP_SIZE32((length + (4 * sizeof(int)))); /* Log a packet to the buffer. */ if (total_len > SCTP_PACKET_LOG_SIZE) { @@ -477,7 +483,7 @@ again_locked: } /* Sanity check */ if (thisend >= SCTP_PACKET_LOG_SIZE) { - printf("Insanity stops a log thisbegin:%d thisend:%d writers:%d lock:%d end:%d\n", + SCTP_PRINTF("Insanity stops a log thisbegin:%d thisend:%d writers:%d lock:%d end:%d\n", thisbegin, thisend, SCTP_BASE_VAR(packet_log_writers), |