Module Name: src Committed By: pooka Date: Tue Apr 1 13:11:44 UTC 2014
Modified Files: src/sys/netinet: ip_flow.c src/sys/netinet6: ip6_flow.c Log Message: Wrap ipflow_create() & ip6flow_create() in kernel lock. Prevents the interrupt side on another core from seeing the situation while the ipflow is being modified. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/netinet/ip_flow.c cvs rdiff -u -r1.21 -r1.22 src/sys/netinet6/ip6_flow.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/ip_flow.c diff -u src/sys/netinet/ip_flow.c:1.62 src/sys/netinet/ip_flow.c:1.63 --- src/sys/netinet/ip_flow.c:1.62 Wed Mar 19 10:54:20 2014 +++ src/sys/netinet/ip_flow.c Tue Apr 1 13:11:44 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_flow.c,v 1.62 2014/03/19 10:54:20 liamjfoy Exp $ */ +/* $NetBSD: ip_flow.c,v 1.63 2014/04/01 13:11:44 pooka Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.62 2014/03/19 10:54:20 liamjfoy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.63 2014/04/01 13:11:44 pooka Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -423,6 +423,9 @@ ipflow_create(const struct route *ro, st */ if (ip_maxflows == 0 || ip->ip_p == IPPROTO_ICMP) return; + + KERNEL_LOCK(1, NULL); + /* * See if an existing flow struct exists. If so remove it from it's * list and free the old route. If not, try to malloc a new one @@ -437,7 +440,7 @@ ipflow_create(const struct route *ro, st ipf = pool_get(&ipflow_pool, PR_NOWAIT); splx(s); if (ipf == NULL) - return; + goto out; ipflow_inuse++; } memset(ipf, 0, sizeof(*ipf)); @@ -467,6 +470,9 @@ ipflow_create(const struct route *ro, st s = splnet(); IPFLOW_INSERT(&ipflowtable[hash], ipf); splx(s); + + out: + KERNEL_UNLOCK_ONE(NULL); } int Index: src/sys/netinet6/ip6_flow.c diff -u src/sys/netinet6/ip6_flow.c:1.21 src/sys/netinet6/ip6_flow.c:1.22 --- src/sys/netinet6/ip6_flow.c:1.21 Thu May 23 16:49:46 2013 +++ src/sys/netinet6/ip6_flow.c Tue Apr 1 13:11:44 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_flow.c,v 1.21 2013/05/23 16:49:46 msaitoh Exp $ */ +/* $NetBSD: ip6_flow.c,v 1.22 2014/04/01 13:11:44 pooka Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip6_flow.c,v 1.21 2013/05/23 16:49:46 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_flow.c,v 1.22 2014/04/01 13:11:44 pooka Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -463,6 +463,8 @@ ip6flow_create(const struct route *ro, s if (ip6_maxflows == 0 || ip6->ip6_nxt == IPPROTO_IPV6_ICMP) return; + KERNEL_LOCK(1, NULL); + /* * See if an existing flow exists. If so: * - Remove the flow @@ -481,7 +483,7 @@ ip6flow_create(const struct route *ro, s } else { ip6f = pool_get(&ip6flow_pool, PR_NOWAIT); if (ip6f == NULL) - return; + goto out; ip6flow_inuse++; } memset(ip6f, 0, sizeof(*ip6f)); @@ -513,6 +515,9 @@ ip6flow_create(const struct route *ro, s s = splnet(); IP6FLOW_INSERT(&ip6flowtable[hash], ip6f); splx(s); + + out: + KERNEL_UNLOCK_ONE(NULL); } /*