/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000,2007 Apple Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
+ * $FreeBSD: src/sys/netinet/ip_flow.c,v 1.9.2.1 2001/08/08 08:20:35 ru Exp $
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <libkern/OSAtomic.h>
#include <net/if.h>
#include <net/route.h>
static int ipflow_inuse;
#define IPFLOW_MAX 256
-#if ISFB31
-#else
+#ifdef __APPLE__
#define M_IPFLOW M_TEMP
#endif
static int ipflow_active = 0;
SYSCTL_INT(_net_inet_ip, IPCTL_FASTFORWARDING, fastforwarding, CTLFLAG_RW,
- &ipflow_active, 0, "");
+ &ipflow_active, 0, "Enable flow-based IP forwarding");
-MALLOC_DEFINE(M_IPFLOW, "ip_flow", "IP flow");
+#ifndef __APPLE__
+static MALLOC_DEFINE(M_IPFLOW, "ip_flow", "IP flow");
+#endif
static unsigned
ipflow_hash(
struct ip *ip;
struct ipflow *ipf;
struct rtentry *rt;
+ struct sockaddr *dst;
int error;
/*
ipf->ipf_uses++;
ipf->ipf_timer = IPFLOW_TIMER;
+ if (rt->rt_flags & RTF_GATEWAY)
+ dst = rt->rt_gateway;
+ else
+ dst = &ipf->ipf_ro.ro_dst;
+#ifdef __APPLE__
/* Not sure the rt_dlt is valid here !! XXX */
- if ((error = dlil_output((u_long)rt->rt_dlt, m, (caddr_t) rt, &ipf->ipf_ro.ro_dst, 0)) != 0) {
+ if ((error = dlil_output(rt->rt_ifp, PF_INET, m, (caddr_t) rt, dst, 0)) != 0) {
+
+#else
+ if ((error = (*rt->rt_ifp->if_output)(rt->rt_ifp, m, dst, rt)) != 0) {
+#endif
if (error == ENOBUFS)
ipf->ipf_dropped++;
else
struct ipflow *ipf)
{
ipf->ipf_ro.ro_rt->rt_use += ipf->ipf_uses;
- ipstat.ips_cantforward += ipf->ipf_errors + ipf->ipf_dropped;
- ipstat.ips_forward += ipf->ipf_uses;
- ipstat.ips_fastforward += ipf->ipf_uses;
+ OSAddAtomic(ipf->ipf_errors + ipf->ipf_dropped, (SInt32*)&ipstat.ips_cantforward);
+ OSAddAtomic(ipf->ipf_uses, (SInt32*)&ipstat.ips_forward);
+ OSAddAtomic(ipf->ipf_uses, (SInt32*)&ipstat.ips_fastforward);
}
static void
ipflow_free(
struct ipflow *ipf)
{
- int s;
/*
* Remove the flow from the hash table (at elevated IPL).
* Once it's off the list, we can deal with it at normal
* network IPL.
*/
- s = splimp();
LIST_REMOVE(ipf, ipf_next);
- splx(s);
ipflow_addstats(ipf);
- RTFREE(ipf->ipf_ro.ro_rt);
+ rtfree(ipf->ipf_ro.ro_rt);
ipflow_inuse--;
FREE(ipf, M_IPFLOW);
}
{
struct ipflow *ipf, *maybe_ipf = NULL;
int idx;
- int s;
for (idx = 0; idx < IPFLOW_HASHSIZE; idx++) {
ipf = LIST_FIRST(&ipflows[idx]);
/*
* Remove the entry from the flow table.
*/
- s = splimp();
LIST_REMOVE(ipf, ipf_next);
- splx(s);
ipflow_addstats(ipf);
- RTFREE(ipf->ipf_ro.ro_rt);
+ rtfree(ipf->ipf_ro.ro_rt);
+ ipf->ipf_ro.ro_rt = NULL;
return ipf;
}
-
+/* note: called under the ip_mutex lock */
void
ipflow_slowtimo(
void)
} else {
ipf->ipf_last_uses = ipf->ipf_uses;
ipf->ipf_ro.ro_rt->rt_use += ipf->ipf_uses;
+ OSAddAtomic(ipf->ipf_uses, (SInt32*)&ipstat.ips_forward);
+ OSAddAtomic(ipf->ipf_uses, (SInt32*)&ipstat.ips_fastforward);
ipstat.ips_forward += ipf->ipf_uses;
ipstat.ips_fastforward += ipf->ipf_uses;
ipf->ipf_uses = 0;
const struct ip *const ip = mtod(m, struct ip *);
struct ipflow *ipf;
unsigned hash;
- int s;
/*
* Don't create cache entries for ICMP messages.
}
bzero((caddr_t) ipf, sizeof(*ipf));
} else {
- s = splimp();
LIST_REMOVE(ipf, ipf_next);
- splx(s);
ipflow_addstats(ipf);
- RTFREE(ipf->ipf_ro.ro_rt);
+ rtfree(ipf->ipf_ro.ro_rt);
+ ipf->ipf_ro.ro_rt = NULL;
ipf->ipf_uses = ipf->ipf_last_uses = 0;
ipf->ipf_errors = ipf->ipf_dropped = 0;
}
/*
* Fill in the updated information.
*/
+ lck_mtx_lock(rt_mtx);
ipf->ipf_ro = *ro;
- ro->ro_rt->rt_refcnt++;
+ rtref(ro->ro_rt);
+ lck_mtx_unlock(rt_mtx);
ipf->ipf_dst = ip->ip_dst;
ipf->ipf_src = ip->ip_src;
ipf->ipf_tos = ip->ip_tos;
* Insert into the approriate bucket of the flow table.
*/
hash = ipflow_hash(ip->ip_dst, ip->ip_src, ip->ip_tos);
- s = splimp();
LIST_INSERT_HEAD(&ipflows[hash], ipf, ipf_next);
- splx(s);
}