aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/genetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r--net/netlink/genetlink.c37
1 files changed, 13 insertions, 24 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 44ff3f3810fa..06438fa2b1e5 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/slab.h>
11#include <linux/errno.h> 12#include <linux/errno.h>
12#include <linux/types.h> 13#include <linux/types.h>
13#include <linux/socket.h> 14#include <linux/socket.h>
@@ -97,25 +98,17 @@ static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
97*/ 98*/
98static inline u16 genl_generate_id(void) 99static inline u16 genl_generate_id(void)
99{ 100{
100 static u16 id_gen_idx; 101 static u16 id_gen_idx = GENL_MIN_ID;
101 int overflowed = 0; 102 int i;
102 103
103 do { 104 for (i = 0; i <= GENL_MAX_ID - GENL_MIN_ID; i++) {
104 if (id_gen_idx == 0) 105 if (!genl_family_find_byid(id_gen_idx))
106 return id_gen_idx;
107 if (++id_gen_idx > GENL_MAX_ID)
105 id_gen_idx = GENL_MIN_ID; 108 id_gen_idx = GENL_MIN_ID;
109 }
106 110
107 if (++id_gen_idx > GENL_MAX_ID) { 111 return 0;
108 if (!overflowed) {
109 overflowed = 1;
110 id_gen_idx = 0;
111 continue;
112 } else
113 return 0;
114 }
115
116 } while (genl_family_find_byid(id_gen_idx));
117
118 return id_gen_idx;
119} 112}
120 113
121static struct genl_multicast_group notify_grp; 114static struct genl_multicast_group notify_grp;
@@ -374,11 +367,6 @@ int genl_register_family(struct genl_family *family)
374 goto errout_locked; 367 goto errout_locked;
375 } 368 }
376 369
377 if (genl_family_find_byid(family->id)) {
378 err = -EEXIST;
379 goto errout_locked;
380 }
381
382 if (family->id == GENL_ID_GENERATE) { 370 if (family->id == GENL_ID_GENERATE) {
383 u16 newid = genl_generate_id(); 371 u16 newid = genl_generate_id();
384 372
@@ -388,6 +376,9 @@ int genl_register_family(struct genl_family *family)
388 } 376 }
389 377
390 family->id = newid; 378 family->id = newid;
379 } else if (genl_family_find_byid(family->id)) {
380 err = -EEXIST;
381 goto errout_locked;
391 } 382 }
392 383
393 if (family->maxattr) { 384 if (family->maxattr) {
@@ -691,9 +682,7 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
691 int chains_to_skip = cb->args[0]; 682 int chains_to_skip = cb->args[0];
692 int fams_to_skip = cb->args[1]; 683 int fams_to_skip = cb->args[1];
693 684
694 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { 685 for (i = chains_to_skip; i < GENL_FAM_TAB_SIZE; i++) {
695 if (i < chains_to_skip)
696 continue;
697 n = 0; 686 n = 0;
698 list_for_each_entry(rt, genl_family_chain(i), family_list) { 687 list_for_each_entry(rt, genl_family_chain(i), family_list) {
699 if (!rt->netnsok && !net_eq(net, &init_net)) 688 if (!rt->netnsok && !net_eq(net, &init_net))