/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* 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. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * 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.
+ *
+ * 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
* 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.
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <libkern/OSAtomic.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/ip_flow.h>
#include <net/dlil.h>
+#if IPFLOW
+
#define IPFLOW_TIMER (5 * PR_SLOWHZ)
#define IPFLOW_HASHBITS 6 /* should not be a multiple of 8 */
#define IPFLOW_HASHSIZE (1 << IPFLOW_HASHBITS)
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, 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) {
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, &ipstat.ips_cantforward);
+ OSAddAtomic(ipf->ipf_uses, &ipstat.ips_forward);
+ OSAddAtomic(ipf->ipf_uses, &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);
ipflow_inuse--;
{
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);
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, &ipstat.ips_forward);
+ OSAddAtomic(ipf->ipf_uses, &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);
ipf->ipf_uses = ipf->ipf_last_uses = 0;
* Fill in the updated information.
*/
ipf->ipf_ro = *ro;
- rtref(ro->ro_rt);
+ RT_ADDREF(ro->ro_rt);
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);
}
+#else /* !IPFLOW */
+int
+ipflow_fastforward(struct mbuf *m)
+{
+#pragma unused(m)
+ /*
+ * Since this symbol is exported (albeit unsupported), just return
+ * false to keep things (e.g. PPP) happy, in case ipflow is not
+ * compiled in.
+ */
+ return (0);
+}
+#endif /* !IPFLOW */