summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet/sctp_bsd_addr.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet/sctp_bsd_addr.c')
-rw-r--r--freebsd/sys/netinet/sctp_bsd_addr.c146
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),