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); | ||
