/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000,2007 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <libkern/OSAtomic.h>
#include <net/if.h>
#include <net/route.h>
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);
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);
+ 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);
+ 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;
- rtref(ro->ro_rt); //### LD 5/25/04 needs rt_mtx lock
+ 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);
}