Mon Mar 11 01:56:37 2013 UTC ()
prevent the lookup function from autoloading recursively.


(christos)
diff -r1.8 -r1.9 src/sys/net/npf/npf_rproc.c

cvs diff -r1.8 -r1.9 src/sys/net/npf/npf_rproc.c (expand / switch to unified diff)

--- src/sys/net/npf/npf_rproc.c 2013/03/11 01:43:50 1.8
+++ src/sys/net/npf/npf_rproc.c 2013/03/11 01:56:37 1.9
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_rproc.c,v 1.8 2013/03/11 01:43:50 christos Exp $ */ 1/* $NetBSD: npf_rproc.c,v 1.9 2013/03/11 01:56:37 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -92,64 +92,64 @@ npf_ext_sysfini(void) @@ -92,64 +92,64 @@ npf_ext_sysfini(void)
92{ 92{
93 KASSERT(LIST_EMPTY(&ext_list)); 93 KASSERT(LIST_EMPTY(&ext_list));
94 mutex_destroy(&ext_lock); 94 mutex_destroy(&ext_lock);
95} 95}
96 96
97/* 97/*
98 * NPF extension management for the rule procedures. 98 * NPF extension management for the rule procedures.
99 */ 99 */
100 100
101static const char npf_ext_prefix[] = "npf_ext_"; 101static const char npf_ext_prefix[] = "npf_ext_";
102#define NPF_EXT_PREFLEN (sizeof(npf_ext_prefix) - 1) 102#define NPF_EXT_PREFLEN (sizeof(npf_ext_prefix) - 1)
103 103
104static npf_ext_t * 104static npf_ext_t *
105npf_ext_lookup(const char *name) 105npf_ext_lookup(const char *name, bool autoload)
106{ 106{
107 npf_ext_t *ext; 107 npf_ext_t *ext;
108 char modname[RPROC_NAME_LEN + NPF_EXT_PREFLEN]; 108 char modname[RPROC_NAME_LEN + NPF_EXT_PREFLEN];
109 int error, loaded = 0; 109 int error;
110 110
111 KASSERT(mutex_owned(&ext_lock)); 111 KASSERT(mutex_owned(&ext_lock));
112 112
113again: 113again:
114 LIST_FOREACH(ext, &ext_list, ext_entry) 114 LIST_FOREACH(ext, &ext_list, ext_entry)
115 if (strcmp(ext->ext_callname, name) == 0) 115 if (strcmp(ext->ext_callname, name) == 0)
116 break; 116 break;
117 117
118 if (ext != NULL || loaded != 0) 118 if (ext != NULL || !autoload)
119 return ext; 119 return ext;
120 120
121 mutex_exit(&ext_lock); 121 mutex_exit(&ext_lock);
122 loaded++; 122 autoload = false;
123 snprintf(modname, sizeof(modname), "%s%s", npf_ext_prefix, name); 123 snprintf(modname, sizeof(modname), "%s%s", npf_ext_prefix, name);
124 error = module_autoload(modname, MODULE_CLASS_MISC); 124 error = module_autoload(modname, MODULE_CLASS_MISC);
125 mutex_enter(&ext_lock); 125 mutex_enter(&ext_lock);
126 126
127 if (error) 127 if (error)
128 return NULL; 128 return NULL;
129 goto again; 129 goto again;
130} 130}
131 131
132void * 132void *
133npf_ext_register(const char *name, const npf_ext_ops_t *ops) 133npf_ext_register(const char *name, const npf_ext_ops_t *ops)
134{ 134{
135 npf_ext_t *ext; 135 npf_ext_t *ext;
136 136
137 ext = kmem_zalloc(sizeof(npf_ext_t), KM_SLEEP); 137 ext = kmem_zalloc(sizeof(npf_ext_t), KM_SLEEP);
138 strlcpy(ext->ext_callname, name, EXT_NAME_LEN); 138 strlcpy(ext->ext_callname, name, EXT_NAME_LEN);
139 ext->ext_ops = ops; 139 ext->ext_ops = ops;
140 140
141 mutex_enter(&ext_lock); 141 mutex_enter(&ext_lock);
142 if (npf_ext_lookup(name)) { 142 if (npf_ext_lookup(name, false)) {
143 mutex_exit(&ext_lock); 143 mutex_exit(&ext_lock);
144 kmem_free(ext, sizeof(npf_ext_t)); 144 kmem_free(ext, sizeof(npf_ext_t));
145 return NULL; 145 return NULL;
146 } 146 }
147 LIST_INSERT_HEAD(&ext_list, ext, ext_entry); 147 LIST_INSERT_HEAD(&ext_list, ext, ext_entry);
148 mutex_exit(&ext_lock); 148 mutex_exit(&ext_lock);
149 149
150 return (void *)ext; 150 return (void *)ext;
151} 151}
152 152
153int 153int
154npf_ext_unregister(void *extid) 154npf_ext_unregister(void *extid)
155{ 155{
@@ -157,48 +157,48 @@ npf_ext_unregister(void *extid) @@ -157,48 +157,48 @@ npf_ext_unregister(void *extid)
157 157
158 /* 158 /*
159 * Check if in-use first (re-check with the lock held). 159 * Check if in-use first (re-check with the lock held).
160 */ 160 */
161 if (ext->ext_refcnt) { 161 if (ext->ext_refcnt) {
162 return EBUSY; 162 return EBUSY;
163 } 163 }
164 164
165 mutex_enter(&ext_lock); 165 mutex_enter(&ext_lock);
166 if (ext->ext_refcnt) { 166 if (ext->ext_refcnt) {
167 mutex_exit(&ext_lock); 167 mutex_exit(&ext_lock);
168 return EBUSY; 168 return EBUSY;
169 } 169 }
170 KASSERT(npf_ext_lookup(ext->ext_callname)); 170 KASSERT(npf_ext_lookup(ext->ext_callname, false));
171 LIST_REMOVE(ext, ext_entry); 171 LIST_REMOVE(ext, ext_entry);
172 mutex_exit(&ext_lock); 172 mutex_exit(&ext_lock);
173 173
174 kmem_free(ext, sizeof(npf_ext_t)); 174 kmem_free(ext, sizeof(npf_ext_t));
175 return 0; 175 return 0;
176} 176}
177 177
178int 178int
179npf_ext_construct(const char *name, npf_rproc_t *rp, prop_dictionary_t params) 179npf_ext_construct(const char *name, npf_rproc_t *rp, prop_dictionary_t params)
180{ 180{
181 const npf_ext_ops_t *extops; 181 const npf_ext_ops_t *extops;
182 npf_ext_t *ext; 182 npf_ext_t *ext;
183 unsigned i; 183 unsigned i;
184 int error; 184 int error;
185 185
186 if (rp->rp_ext_count >= RPROC_EXT_COUNT) { 186 if (rp->rp_ext_count >= RPROC_EXT_COUNT) {
187 return ENOSPC; 187 return ENOSPC;
188 } 188 }
189 189
190 mutex_enter(&ext_lock); 190 mutex_enter(&ext_lock);
191 ext = npf_ext_lookup(name); 191 ext = npf_ext_lookup(name, true);
192 if (ext) { 192 if (ext) {
193 atomic_inc_uint(&ext->ext_refcnt); 193 atomic_inc_uint(&ext->ext_refcnt);
194 } 194 }
195 mutex_exit(&ext_lock); 195 mutex_exit(&ext_lock);
196 196
197 if (!ext) { 197 if (!ext) {
198 return ENOENT; 198 return ENOENT;
199 } 199 }
200 200
201 extops = ext->ext_ops; 201 extops = ext->ext_ops;
202 KASSERT(extops != NULL); 202 KASSERT(extops != NULL);
203 203
204 error = extops->ctor(rp, params); 204 error = extops->ctor(rp, params);