aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/drop_monitor.c13
-rw-r--r--net/netlink/genetlink.c13
2 files changed, 22 insertions, 4 deletions
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 0efc5028ba9d..46ee488c0015 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -106,6 +106,10 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
106 return skb; 106 return skb;
107} 107}
108 108
109static struct genl_multicast_group dm_mcgrp = {
110 .name = "events",
111};
112
109static void send_dm_alert(struct work_struct *work) 113static void send_dm_alert(struct work_struct *work)
110{ 114{
111 struct sk_buff *skb; 115 struct sk_buff *skb;
@@ -116,7 +120,7 @@ static void send_dm_alert(struct work_struct *work)
116 skb = reset_per_cpu_data(data); 120 skb = reset_per_cpu_data(data);
117 121
118 if (skb) 122 if (skb)
119 genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); 123 genlmsg_multicast(skb, 0, dm_mcgrp.id, GFP_KERNEL);
120} 124}
121 125
122/* 126/*
@@ -371,6 +375,13 @@ static int __init init_net_drop_monitor(void)
371 return rc; 375 return rc;
372 } 376 }
373 377
378 rc = genl_register_mc_group(&net_drop_monitor_family, &dm_mcgrp);
379 if (rc) {
380 pr_err("Failed to register drop monitor mcast group\n");
381 goto out_unreg;
382 }
383 WARN_ON(dm_mcgrp.id != NET_DM_GRP_ALERT);
384
374 rc = register_netdevice_notifier(&dropmon_net_notifier); 385 rc = register_netdevice_notifier(&dropmon_net_notifier);
375 if (rc < 0) { 386 if (rc < 0) {
376 pr_crit("Failed to register netdevice notifier\n"); 387 pr_crit("Failed to register netdevice notifier\n");
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index c68ce73619b5..353909d46dda 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -65,8 +65,12 @@ static struct list_head family_ht[GENL_FAM_TAB_SIZE];
65 * To avoid an allocation at boot of just one unsigned long, 65 * To avoid an allocation at boot of just one unsigned long,
66 * declare it global instead. 66 * declare it global instead.
67 * Bit 0 is marked as already used since group 0 is invalid. 67 * Bit 0 is marked as already used since group 0 is invalid.
68 * Bit 1 is marked as already used since the drop-monitor code
69 * abuses the API and thinks it can statically use group 1.
70 * That group will typically conflict with other groups that
71 * any proper users use.
68 */ 72 */
69static unsigned long mc_group_start = 0x1; 73static unsigned long mc_group_start = 0x3;
70static unsigned long *mc_groups = &mc_group_start; 74static unsigned long *mc_groups = &mc_group_start;
71static unsigned long mc_groups_longs = 1; 75static unsigned long mc_groups_longs = 1;
72 76
@@ -160,9 +164,11 @@ int genl_register_mc_group(struct genl_family *family,
160 164
161 genl_lock_all(); 165 genl_lock_all();
162 166
163 /* special-case our own group */ 167 /* special-case our own group and hacks */
164 if (grp == &notify_grp) 168 if (grp == &notify_grp)
165 id = GENL_ID_CTRL; 169 id = GENL_ID_CTRL;
170 else if (strcmp(family->name, "NET_DM") == 0)
171 id = 1;
166 else 172 else
167 id = find_first_zero_bit(mc_groups, 173 id = find_first_zero_bit(mc_groups,
168 mc_groups_longs * BITS_PER_LONG); 174 mc_groups_longs * BITS_PER_LONG);
@@ -245,7 +251,8 @@ static void __genl_unregister_mc_group(struct genl_family *family,
245 rcu_read_unlock(); 251 rcu_read_unlock();
246 netlink_table_ungrab(); 252 netlink_table_ungrab();
247 253
248 clear_bit(grp->id, mc_groups); 254 if (grp->id != 1)
255 clear_bit(grp->id, mc_groups);
249 list_del(&grp->list); 256 list_del(&grp->list);
250 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp); 257 genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp);
251 grp->id = 0; 258 grp->id = 0;