diff options
-rw-r--r-- | include/net/net_namespace.h | 2 | ||||
-rw-r--r-- | net/core/net_namespace.c | 38 |
2 files changed, 40 insertions, 0 deletions
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index e2aee2689abe..72fad1a0956b 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
@@ -185,6 +185,8 @@ extern int register_pernet_subsys(struct pernet_operations *); | |||
185 | extern void unregister_pernet_subsys(struct pernet_operations *); | 185 | extern void unregister_pernet_subsys(struct pernet_operations *); |
186 | extern int register_pernet_device(struct pernet_operations *); | 186 | extern int register_pernet_device(struct pernet_operations *); |
187 | extern void unregister_pernet_device(struct pernet_operations *); | 187 | extern void unregister_pernet_device(struct pernet_operations *); |
188 | extern int register_pernet_gen_device(int *id, struct pernet_operations *); | ||
189 | extern void unregister_pernet_gen_device(int id, struct pernet_operations *); | ||
188 | 190 | ||
189 | struct ctl_path; | 191 | struct ctl_path; |
190 | struct ctl_table; | 192 | struct ctl_table; |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 7b660834a4c2..2197d51aef3b 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
6 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/idr.h> | ||
8 | #include <net/net_namespace.h> | 9 | #include <net/net_namespace.h> |
9 | 10 | ||
10 | /* | 11 | /* |
@@ -253,6 +254,8 @@ static void unregister_pernet_operations(struct pernet_operations *ops) | |||
253 | } | 254 | } |
254 | #endif | 255 | #endif |
255 | 256 | ||
257 | static DEFINE_IDA(net_generic_ids); | ||
258 | |||
256 | /** | 259 | /** |
257 | * register_pernet_subsys - register a network namespace subsystem | 260 | * register_pernet_subsys - register a network namespace subsystem |
258 | * @ops: pernet operations structure for the subsystem | 261 | * @ops: pernet operations structure for the subsystem |
@@ -330,6 +333,30 @@ int register_pernet_device(struct pernet_operations *ops) | |||
330 | } | 333 | } |
331 | EXPORT_SYMBOL_GPL(register_pernet_device); | 334 | EXPORT_SYMBOL_GPL(register_pernet_device); |
332 | 335 | ||
336 | int register_pernet_gen_device(int *id, struct pernet_operations *ops) | ||
337 | { | ||
338 | int error; | ||
339 | mutex_lock(&net_mutex); | ||
340 | again: | ||
341 | error = ida_get_new_above(&net_generic_ids, 1, id); | ||
342 | if (error) { | ||
343 | if (error == -EAGAIN) { | ||
344 | ida_pre_get(&net_generic_ids, GFP_KERNEL); | ||
345 | goto again; | ||
346 | } | ||
347 | goto out; | ||
348 | } | ||
349 | error = register_pernet_operations(&pernet_list, ops); | ||
350 | if (error) | ||
351 | ida_remove(&net_generic_ids, *id); | ||
352 | else if (first_device == &pernet_list) | ||
353 | first_device = &ops->list; | ||
354 | out: | ||
355 | mutex_unlock(&net_mutex); | ||
356 | return error; | ||
357 | } | ||
358 | EXPORT_SYMBOL_GPL(register_pernet_gen_device); | ||
359 | |||
333 | /** | 360 | /** |
334 | * unregister_pernet_device - unregister a network namespace netdevice | 361 | * unregister_pernet_device - unregister a network namespace netdevice |
335 | * @ops: pernet operations structure to manipulate | 362 | * @ops: pernet operations structure to manipulate |
@@ -348,3 +375,14 @@ void unregister_pernet_device(struct pernet_operations *ops) | |||
348 | mutex_unlock(&net_mutex); | 375 | mutex_unlock(&net_mutex); |
349 | } | 376 | } |
350 | EXPORT_SYMBOL_GPL(unregister_pernet_device); | 377 | EXPORT_SYMBOL_GPL(unregister_pernet_device); |
378 | |||
379 | void unregister_pernet_gen_device(int id, struct pernet_operations *ops) | ||
380 | { | ||
381 | mutex_lock(&net_mutex); | ||
382 | if (&ops->list == first_device) | ||
383 | first_device = first_device->next; | ||
384 | unregister_pernet_operations(ops); | ||
385 | ida_remove(&net_generic_ids, id); | ||
386 | mutex_unlock(&net_mutex); | ||
387 | } | ||
388 | EXPORT_SYMBOL_GPL(unregister_pernet_gen_device); | ||