diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 5 | ||||
-rw-r--r-- | net/core/drop_monitor.c | 124 | ||||
-rw-r--r-- | net/core/fib_rules.c | 2 | ||||
-rw-r--r-- | net/core/net-traces.c | 4 | ||||
-rw-r--r-- | net/core/net_namespace.c | 7 | ||||
-rw-r--r-- | net/core/netpoll.c | 2 | ||||
-rw-r--r-- | net/decnet/dn_rules.c | 2 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 2 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 7 | ||||
-rw-r--r-- | net/irda/irnetlink.c | 17 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 18 | ||||
-rw-r--r-- | net/netlabel/netlabel_cipso_v4.c | 16 | ||||
-rw-r--r-- | net/netlabel/netlabel_mgmt.c | 16 | ||||
-rw-r--r-- | net/netlabel/netlabel_unlabeled.c | 16 | ||||
-rw-r--r-- | net/netlink/genetlink.c | 46 | ||||
-rw-r--r-- | net/packet/af_packet.c | 10 | ||||
-rw-r--r-- | net/tipc/netlink.c | 38 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 11 |
19 files changed, 222 insertions, 123 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 92ebeca29901..3942266d1f6c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -126,6 +126,7 @@ | |||
126 | #include <linux/in.h> | 126 | #include <linux/in.h> |
127 | #include <linux/jhash.h> | 127 | #include <linux/jhash.h> |
128 | #include <linux/random.h> | 128 | #include <linux/random.h> |
129 | #include <trace/napi.h> | ||
129 | 130 | ||
130 | #include "net-sysfs.h" | 131 | #include "net-sysfs.h" |
131 | 132 | ||
@@ -2771,8 +2772,10 @@ static void net_rx_action(struct softirq_action *h) | |||
2771 | * accidently calling ->poll() when NAPI is not scheduled. | 2772 | * accidently calling ->poll() when NAPI is not scheduled. |
2772 | */ | 2773 | */ |
2773 | work = 0; | 2774 | work = 0; |
2774 | if (test_bit(NAPI_STATE_SCHED, &n->state)) | 2775 | if (test_bit(NAPI_STATE_SCHED, &n->state)) { |
2775 | work = n->poll(n, weight); | 2776 | work = n->poll(n, weight); |
2777 | trace_napi_poll(n); | ||
2778 | } | ||
2776 | 2779 | ||
2777 | WARN_ON_ONCE(work > weight); | 2780 | WARN_ON_ONCE(work > weight); |
2778 | 2781 | ||
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 2797b711a978..a6c2ac2828fb 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
@@ -22,8 +22,10 @@ | |||
22 | #include <linux/timer.h> | 22 | #include <linux/timer.h> |
23 | #include <linux/bitops.h> | 23 | #include <linux/bitops.h> |
24 | #include <net/genetlink.h> | 24 | #include <net/genetlink.h> |
25 | #include <net/netevent.h> | ||
25 | 26 | ||
26 | #include <trace/skb.h> | 27 | #include <trace/skb.h> |
28 | #include <trace/napi.h> | ||
27 | 29 | ||
28 | #include <asm/unaligned.h> | 30 | #include <asm/unaligned.h> |
29 | 31 | ||
@@ -38,7 +40,8 @@ static void send_dm_alert(struct work_struct *unused); | |||
38 | * and the work handle that will send up | 40 | * and the work handle that will send up |
39 | * netlink alerts | 41 | * netlink alerts |
40 | */ | 42 | */ |
41 | struct sock *dm_sock; | 43 | static int trace_state = TRACE_OFF; |
44 | static spinlock_t trace_state_lock = SPIN_LOCK_UNLOCKED; | ||
42 | 45 | ||
43 | struct per_cpu_dm_data { | 46 | struct per_cpu_dm_data { |
44 | struct work_struct dm_alert_work; | 47 | struct work_struct dm_alert_work; |
@@ -47,6 +50,13 @@ struct per_cpu_dm_data { | |||
47 | struct timer_list send_timer; | 50 | struct timer_list send_timer; |
48 | }; | 51 | }; |
49 | 52 | ||
53 | struct dm_hw_stat_delta { | ||
54 | struct net_device *dev; | ||
55 | struct list_head list; | ||
56 | struct rcu_head rcu; | ||
57 | unsigned long last_drop_val; | ||
58 | }; | ||
59 | |||
50 | static struct genl_family net_drop_monitor_family = { | 60 | static struct genl_family net_drop_monitor_family = { |
51 | .id = GENL_ID_GENERATE, | 61 | .id = GENL_ID_GENERATE, |
52 | .hdrsize = 0, | 62 | .hdrsize = 0, |
@@ -59,7 +69,8 @@ static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); | |||
59 | 69 | ||
60 | static int dm_hit_limit = 64; | 70 | static int dm_hit_limit = 64; |
61 | static int dm_delay = 1; | 71 | static int dm_delay = 1; |
62 | 72 | static unsigned long dm_hw_check_delta = 2*HZ; | |
73 | static LIST_HEAD(hw_stats_list); | ||
63 | 74 | ||
64 | static void reset_per_cpu_data(struct per_cpu_dm_data *data) | 75 | static void reset_per_cpu_data(struct per_cpu_dm_data *data) |
65 | { | 76 | { |
@@ -115,7 +126,7 @@ static void sched_send_work(unsigned long unused) | |||
115 | schedule_work(&data->dm_alert_work); | 126 | schedule_work(&data->dm_alert_work); |
116 | } | 127 | } |
117 | 128 | ||
118 | static void trace_kfree_skb_hit(struct sk_buff *skb, void *location) | 129 | static void trace_drop_common(struct sk_buff *skb, void *location) |
119 | { | 130 | { |
120 | struct net_dm_alert_msg *msg; | 131 | struct net_dm_alert_msg *msg; |
121 | struct nlmsghdr *nlh; | 132 | struct nlmsghdr *nlh; |
@@ -159,24 +170,80 @@ out: | |||
159 | return; | 170 | return; |
160 | } | 171 | } |
161 | 172 | ||
173 | static void trace_kfree_skb_hit(struct sk_buff *skb, void *location) | ||
174 | { | ||
175 | trace_drop_common(skb, location); | ||
176 | } | ||
177 | |||
178 | static void trace_napi_poll_hit(struct napi_struct *napi) | ||
179 | { | ||
180 | struct dm_hw_stat_delta *new_stat; | ||
181 | |||
182 | /* | ||
183 | * Ratelimit our check time to dm_hw_check_delta jiffies | ||
184 | */ | ||
185 | if (!time_after(jiffies, napi->dev->last_rx + dm_hw_check_delta)) | ||
186 | return; | ||
187 | |||
188 | rcu_read_lock(); | ||
189 | list_for_each_entry_rcu(new_stat, &hw_stats_list, list) { | ||
190 | if ((new_stat->dev == napi->dev) && | ||
191 | (napi->dev->stats.rx_dropped != new_stat->last_drop_val)) { | ||
192 | trace_drop_common(NULL, NULL); | ||
193 | new_stat->last_drop_val = napi->dev->stats.rx_dropped; | ||
194 | break; | ||
195 | } | ||
196 | } | ||
197 | rcu_read_unlock(); | ||
198 | } | ||
199 | |||
200 | |||
201 | static void free_dm_hw_stat(struct rcu_head *head) | ||
202 | { | ||
203 | struct dm_hw_stat_delta *n; | ||
204 | n = container_of(head, struct dm_hw_stat_delta, rcu); | ||
205 | kfree(n); | ||
206 | } | ||
207 | |||
162 | static int set_all_monitor_traces(int state) | 208 | static int set_all_monitor_traces(int state) |
163 | { | 209 | { |
164 | int rc = 0; | 210 | int rc = 0; |
211 | struct dm_hw_stat_delta *new_stat = NULL; | ||
212 | struct dm_hw_stat_delta *temp; | ||
213 | |||
214 | spin_lock(&trace_state_lock); | ||
165 | 215 | ||
166 | switch (state) { | 216 | switch (state) { |
167 | case TRACE_ON: | 217 | case TRACE_ON: |
168 | rc |= register_trace_kfree_skb(trace_kfree_skb_hit); | 218 | rc |= register_trace_kfree_skb(trace_kfree_skb_hit); |
219 | rc |= register_trace_napi_poll(trace_napi_poll_hit); | ||
169 | break; | 220 | break; |
170 | case TRACE_OFF: | 221 | case TRACE_OFF: |
171 | rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit); | 222 | rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit); |
223 | rc |= unregister_trace_napi_poll(trace_napi_poll_hit); | ||
172 | 224 | ||
173 | tracepoint_synchronize_unregister(); | 225 | tracepoint_synchronize_unregister(); |
226 | |||
227 | /* | ||
228 | * Clean the device list | ||
229 | */ | ||
230 | list_for_each_entry_safe(new_stat, temp, &hw_stats_list, list) { | ||
231 | if (new_stat->dev == NULL) { | ||
232 | list_del_rcu(&new_stat->list); | ||
233 | call_rcu(&new_stat->rcu, free_dm_hw_stat); | ||
234 | } | ||
235 | } | ||
174 | break; | 236 | break; |
175 | default: | 237 | default: |
176 | rc = 1; | 238 | rc = 1; |
177 | break; | 239 | break; |
178 | } | 240 | } |
179 | 241 | ||
242 | if (!rc) | ||
243 | trace_state = state; | ||
244 | |||
245 | spin_unlock(&trace_state_lock); | ||
246 | |||
180 | if (rc) | 247 | if (rc) |
181 | return -EINPROGRESS; | 248 | return -EINPROGRESS; |
182 | return rc; | 249 | return rc; |
@@ -204,6 +271,44 @@ static int net_dm_cmd_trace(struct sk_buff *skb, | |||
204 | return -ENOTSUPP; | 271 | return -ENOTSUPP; |
205 | } | 272 | } |
206 | 273 | ||
274 | static int dropmon_net_event(struct notifier_block *ev_block, | ||
275 | unsigned long event, void *ptr) | ||
276 | { | ||
277 | struct net_device *dev = ptr; | ||
278 | struct dm_hw_stat_delta *new_stat = NULL; | ||
279 | struct dm_hw_stat_delta *tmp; | ||
280 | |||
281 | switch (event) { | ||
282 | case NETDEV_REGISTER: | ||
283 | new_stat = kzalloc(sizeof(struct dm_hw_stat_delta), GFP_KERNEL); | ||
284 | |||
285 | if (!new_stat) | ||
286 | goto out; | ||
287 | |||
288 | new_stat->dev = dev; | ||
289 | INIT_RCU_HEAD(&new_stat->rcu); | ||
290 | spin_lock(&trace_state_lock); | ||
291 | list_add_rcu(&new_stat->list, &hw_stats_list); | ||
292 | spin_unlock(&trace_state_lock); | ||
293 | break; | ||
294 | case NETDEV_UNREGISTER: | ||
295 | spin_lock(&trace_state_lock); | ||
296 | list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) { | ||
297 | if (new_stat->dev == dev) { | ||
298 | new_stat->dev = NULL; | ||
299 | if (trace_state == TRACE_OFF) { | ||
300 | list_del_rcu(&new_stat->list); | ||
301 | call_rcu(&new_stat->rcu, free_dm_hw_stat); | ||
302 | break; | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | spin_unlock(&trace_state_lock); | ||
307 | break; | ||
308 | } | ||
309 | out: | ||
310 | return NOTIFY_DONE; | ||
311 | } | ||
207 | 312 | ||
208 | static struct genl_ops dropmon_ops[] = { | 313 | static struct genl_ops dropmon_ops[] = { |
209 | { | 314 | { |
@@ -220,6 +325,10 @@ static struct genl_ops dropmon_ops[] = { | |||
220 | }, | 325 | }, |
221 | }; | 326 | }; |
222 | 327 | ||
328 | static struct notifier_block dropmon_net_notifier = { | ||
329 | .notifier_call = dropmon_net_event | ||
330 | }; | ||
331 | |||
223 | static int __init init_net_drop_monitor(void) | 332 | static int __init init_net_drop_monitor(void) |
224 | { | 333 | { |
225 | int cpu; | 334 | int cpu; |
@@ -243,12 +352,18 @@ static int __init init_net_drop_monitor(void) | |||
243 | ret = genl_register_ops(&net_drop_monitor_family, | 352 | ret = genl_register_ops(&net_drop_monitor_family, |
244 | &dropmon_ops[i]); | 353 | &dropmon_ops[i]); |
245 | if (ret) { | 354 | if (ret) { |
246 | printk(KERN_CRIT "failed to register operation %d\n", | 355 | printk(KERN_CRIT "Failed to register operation %d\n", |
247 | dropmon_ops[i].cmd); | 356 | dropmon_ops[i].cmd); |
248 | goto out_unreg; | 357 | goto out_unreg; |
249 | } | 358 | } |
250 | } | 359 | } |
251 | 360 | ||
361 | rc = register_netdevice_notifier(&dropmon_net_notifier); | ||
362 | if (rc < 0) { | ||
363 | printk(KERN_CRIT "Failed to register netdevice notifier\n"); | ||
364 | goto out_unreg; | ||
365 | } | ||
366 | |||
252 | rc = 0; | 367 | rc = 0; |
253 | 368 | ||
254 | for_each_present_cpu(cpu) { | 369 | for_each_present_cpu(cpu) { |
@@ -259,6 +374,7 @@ static int __init init_net_drop_monitor(void) | |||
259 | data->send_timer.data = cpu; | 374 | data->send_timer.data = cpu; |
260 | data->send_timer.function = sched_send_work; | 375 | data->send_timer.function = sched_send_work; |
261 | } | 376 | } |
377 | |||
262 | goto out; | 378 | goto out; |
263 | 379 | ||
264 | out_unreg: | 380 | out_unreg: |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 17d9f497b797..bd309384f8b8 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -500,7 +500,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, | |||
500 | if (rule->target) | 500 | if (rule->target) |
501 | NLA_PUT_U32(skb, FRA_GOTO, rule->target); | 501 | NLA_PUT_U32(skb, FRA_GOTO, rule->target); |
502 | 502 | ||
503 | if (ops->fill(rule, skb, nlh, frh) < 0) | 503 | if (ops->fill(rule, skb, frh) < 0) |
504 | goto nla_put_failure; | 504 | goto nla_put_failure; |
505 | 505 | ||
506 | return nlmsg_end(skb, nlh); | 506 | return nlmsg_end(skb, nlh); |
diff --git a/net/core/net-traces.c b/net/core/net-traces.c index c8fb45665e4f..b07b25bd2cde 100644 --- a/net/core/net-traces.c +++ b/net/core/net-traces.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/netlink.h> | 20 | #include <linux/netlink.h> |
21 | #include <linux/net_dropmon.h> | 21 | #include <linux/net_dropmon.h> |
22 | #include <trace/skb.h> | 22 | #include <trace/skb.h> |
23 | #include <trace/napi.h> | ||
23 | 24 | ||
24 | #include <asm/unaligned.h> | 25 | #include <asm/unaligned.h> |
25 | #include <asm/bitops.h> | 26 | #include <asm/bitops.h> |
@@ -27,3 +28,6 @@ | |||
27 | 28 | ||
28 | DEFINE_TRACE(kfree_skb); | 29 | DEFINE_TRACE(kfree_skb); |
29 | EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); | 30 | EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); |
31 | |||
32 | DEFINE_TRACE(napi_poll); | ||
33 | EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 6b3edc9e6f19..b7292a2719dc 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -196,9 +196,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net) | |||
196 | static int __init net_ns_init(void) | 196 | static int __init net_ns_init(void) |
197 | { | 197 | { |
198 | struct net_generic *ng; | 198 | struct net_generic *ng; |
199 | int err; | ||
200 | 199 | ||
201 | printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net)); | ||
202 | #ifdef CONFIG_NET_NS | 200 | #ifdef CONFIG_NET_NS |
203 | net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), | 201 | net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), |
204 | SMP_CACHE_BYTES, | 202 | SMP_CACHE_BYTES, |
@@ -217,15 +215,14 @@ static int __init net_ns_init(void) | |||
217 | rcu_assign_pointer(init_net.gen, ng); | 215 | rcu_assign_pointer(init_net.gen, ng); |
218 | 216 | ||
219 | mutex_lock(&net_mutex); | 217 | mutex_lock(&net_mutex); |
220 | err = setup_net(&init_net); | 218 | if (setup_net(&init_net)) |
219 | panic("Could not setup the initial network namespace"); | ||
221 | 220 | ||
222 | rtnl_lock(); | 221 | rtnl_lock(); |
223 | list_add_tail(&init_net.list, &net_namespace_list); | 222 | list_add_tail(&init_net.list, &net_namespace_list); |
224 | rtnl_unlock(); | 223 | rtnl_unlock(); |
225 | 224 | ||
226 | mutex_unlock(&net_mutex); | 225 | mutex_unlock(&net_mutex); |
227 | if (err) | ||
228 | panic("Could not setup the initial network namespace"); | ||
229 | 226 | ||
230 | return 0; | 227 | return 0; |
231 | } | 228 | } |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 64f51eec6576..67b4f3e3d4a5 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <net/tcp.h> | 24 | #include <net/tcp.h> |
25 | #include <net/udp.h> | 25 | #include <net/udp.h> |
26 | #include <asm/unaligned.h> | 26 | #include <asm/unaligned.h> |
27 | #include <trace/napi.h> | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * We maintain a small pool of fully-sized skbs, to make sure the | 30 | * We maintain a small pool of fully-sized skbs, to make sure the |
@@ -137,6 +138,7 @@ static int poll_one_napi(struct netpoll_info *npinfo, | |||
137 | set_bit(NAPI_STATE_NPSVC, &napi->state); | 138 | set_bit(NAPI_STATE_NPSVC, &napi->state); |
138 | 139 | ||
139 | work = napi->poll(napi, budget); | 140 | work = napi->poll(napi, budget); |
141 | trace_napi_poll(napi); | ||
140 | 142 | ||
141 | clear_bit(NAPI_STATE_NPSVC, &napi->state); | 143 | clear_bit(NAPI_STATE_NPSVC, &napi->state); |
142 | atomic_dec(&trapped); | 144 | atomic_dec(&trapped); |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index a2690b12e03c..72495f25269f 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -192,7 +192,7 @@ unsigned dnet_addr_type(__le16 addr) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | 194 | static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb, |
195 | struct nlmsghdr *nlh, struct fib_rule_hdr *frh) | 195 | struct fib_rule_hdr *frh) |
196 | { | 196 | { |
197 | struct dn_fib_rule *r = (struct dn_fib_rule *)rule; | 197 | struct dn_fib_rule *r = (struct dn_fib_rule *)rule; |
198 | 198 | ||
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 38904be4102e..92d9d97ec5e3 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -209,7 +209,7 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
209 | } | 209 | } |
210 | 210 | ||
211 | static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | 211 | static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb, |
212 | struct nlmsghdr *nlh, struct fib_rule_hdr *frh) | 212 | struct fib_rule_hdr *frh) |
213 | { | 213 | { |
214 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | 214 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; |
215 | 215 | ||
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index e1a36dbb5a27..00a7a5e4ac97 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -211,7 +211,7 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
211 | } | 211 | } |
212 | 212 | ||
213 | static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | 213 | static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb, |
214 | struct nlmsghdr *nlh, struct fib_rule_hdr *frh) | 214 | struct fib_rule_hdr *frh) |
215 | { | 215 | { |
216 | struct fib6_rule *rule6 = (struct fib6_rule *) rule; | 216 | struct fib6_rule *rule6 = (struct fib6_rule *) rule; |
217 | 217 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index d9dd94b6bf66..ea37741062a9 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -941,7 +941,8 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb) | |||
941 | return 0; | 941 | return 0; |
942 | } | 942 | } |
943 | 943 | ||
944 | struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb) | 944 | static struct sk_buff **tcp6_gro_receive(struct sk_buff **head, |
945 | struct sk_buff *skb) | ||
945 | { | 946 | { |
946 | struct ipv6hdr *iph = skb_gro_network_header(skb); | 947 | struct ipv6hdr *iph = skb_gro_network_header(skb); |
947 | 948 | ||
@@ -961,9 +962,8 @@ struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
961 | 962 | ||
962 | return tcp_gro_receive(head, skb); | 963 | return tcp_gro_receive(head, skb); |
963 | } | 964 | } |
964 | EXPORT_SYMBOL(tcp6_gro_receive); | ||
965 | 965 | ||
966 | int tcp6_gro_complete(struct sk_buff *skb) | 966 | static int tcp6_gro_complete(struct sk_buff *skb) |
967 | { | 967 | { |
968 | struct ipv6hdr *iph = ipv6_hdr(skb); | 968 | struct ipv6hdr *iph = ipv6_hdr(skb); |
969 | struct tcphdr *th = tcp_hdr(skb); | 969 | struct tcphdr *th = tcp_hdr(skb); |
@@ -974,7 +974,6 @@ int tcp6_gro_complete(struct sk_buff *skb) | |||
974 | 974 | ||
975 | return tcp_gro_complete(skb); | 975 | return tcp_gro_complete(skb); |
976 | } | 976 | } |
977 | EXPORT_SYMBOL(tcp6_gro_complete); | ||
978 | 977 | ||
979 | static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | 978 | static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, |
980 | u32 ts, struct tcp_md5sig_key *key, int rst) | 979 | u32 ts, struct tcp_md5sig_key *key, int rst) |
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index 82c6118d82c6..8dd7ed7e7c1f 100644 --- a/net/irda/irnetlink.c +++ b/net/irda/irnetlink.c | |||
@@ -148,21 +148,8 @@ static struct genl_ops irda_nl_ops[] = { | |||
148 | 148 | ||
149 | int irda_nl_register(void) | 149 | int irda_nl_register(void) |
150 | { | 150 | { |
151 | int err, i; | 151 | return genl_register_family_with_ops(&irda_nl_family, |
152 | 152 | irda_nl_ops, ARRAY_SIZE(irda_nl_ops)); | |
153 | err = genl_register_family(&irda_nl_family); | ||
154 | if (err) | ||
155 | return err; | ||
156 | |||
157 | for (i = 0; i < ARRAY_SIZE(irda_nl_ops); i++) { | ||
158 | err = genl_register_ops(&irda_nl_family, &irda_nl_ops[i]); | ||
159 | if (err) | ||
160 | goto err_out; | ||
161 | } | ||
162 | return 0; | ||
163 | err_out: | ||
164 | genl_unregister_family(&irda_nl_family); | ||
165 | return err; | ||
166 | } | 153 | } |
167 | 154 | ||
168 | void irda_nl_unregister(void) | 155 | void irda_nl_unregister(void) |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index e01061f49cdc..7c1333c67ff3 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -3345,22 +3345,8 @@ static struct genl_ops ip_vs_genl_ops[] __read_mostly = { | |||
3345 | 3345 | ||
3346 | static int __init ip_vs_genl_register(void) | 3346 | static int __init ip_vs_genl_register(void) |
3347 | { | 3347 | { |
3348 | int ret, i; | 3348 | return genl_register_family_with_ops(&ip_vs_genl_family, |
3349 | 3349 | ip_vs_genl_ops, ARRAY_SIZE(ip_vs_genl_ops)); | |
3350 | ret = genl_register_family(&ip_vs_genl_family); | ||
3351 | if (ret) | ||
3352 | return ret; | ||
3353 | |||
3354 | for (i = 0; i < ARRAY_SIZE(ip_vs_genl_ops); i++) { | ||
3355 | ret = genl_register_ops(&ip_vs_genl_family, &ip_vs_genl_ops[i]); | ||
3356 | if (ret) | ||
3357 | goto err_out; | ||
3358 | } | ||
3359 | return 0; | ||
3360 | |||
3361 | err_out: | ||
3362 | genl_unregister_family(&ip_vs_genl_family); | ||
3363 | return ret; | ||
3364 | } | 3350 | } |
3365 | 3351 | ||
3366 | static void ip_vs_genl_unregister(void) | 3352 | static void ip_vs_genl_unregister(void) |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index bf1ab1a6790d..e639298bc9c8 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -785,18 +785,6 @@ static struct genl_ops netlbl_cipsov4_ops[] = { | |||
785 | */ | 785 | */ |
786 | int __init netlbl_cipsov4_genl_init(void) | 786 | int __init netlbl_cipsov4_genl_init(void) |
787 | { | 787 | { |
788 | int ret_val, i; | 788 | return genl_register_family_with_ops(&netlbl_cipsov4_gnl_family, |
789 | 789 | netlbl_cipsov4_ops, ARRAY_SIZE(netlbl_cipsov4_ops)); | |
790 | ret_val = genl_register_family(&netlbl_cipsov4_gnl_family); | ||
791 | if (ret_val != 0) | ||
792 | return ret_val; | ||
793 | |||
794 | for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) { | ||
795 | ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, | ||
796 | &netlbl_cipsov4_ops[i]); | ||
797 | if (ret_val != 0) | ||
798 | return ret_val; | ||
799 | } | ||
800 | |||
801 | return 0; | ||
802 | } | 790 | } |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 1821c5d50fb8..8203623e65ad 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -779,18 +779,6 @@ static struct genl_ops netlbl_mgmt_genl_ops[] = { | |||
779 | */ | 779 | */ |
780 | int __init netlbl_mgmt_genl_init(void) | 780 | int __init netlbl_mgmt_genl_init(void) |
781 | { | 781 | { |
782 | int ret_val, i; | 782 | return genl_register_family_with_ops(&netlbl_mgmt_gnl_family, |
783 | 783 | netlbl_mgmt_genl_ops, ARRAY_SIZE(netlbl_mgmt_genl_ops)); | |
784 | ret_val = genl_register_family(&netlbl_mgmt_gnl_family); | ||
785 | if (ret_val != 0) | ||
786 | return ret_val; | ||
787 | |||
788 | for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) { | ||
789 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | ||
790 | &netlbl_mgmt_genl_ops[i]); | ||
791 | if (ret_val != 0) | ||
792 | return ret_val; | ||
793 | } | ||
794 | |||
795 | return 0; | ||
796 | } | 784 | } |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index f3c5c68c6848..fb357f010189 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -1478,20 +1478,8 @@ static struct genl_ops netlbl_unlabel_genl_ops[] = { | |||
1478 | */ | 1478 | */ |
1479 | int __init netlbl_unlabel_genl_init(void) | 1479 | int __init netlbl_unlabel_genl_init(void) |
1480 | { | 1480 | { |
1481 | int ret_val, i; | 1481 | return genl_register_family_with_ops(&netlbl_unlabel_gnl_family, |
1482 | 1482 | netlbl_unlabel_genl_ops, ARRAY_SIZE(netlbl_unlabel_genl_ops)); | |
1483 | ret_val = genl_register_family(&netlbl_unlabel_gnl_family); | ||
1484 | if (ret_val != 0) | ||
1485 | return ret_val; | ||
1486 | |||
1487 | for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) { | ||
1488 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | ||
1489 | &netlbl_unlabel_genl_ops[i]); | ||
1490 | if (ret_val != 0) | ||
1491 | return ret_val; | ||
1492 | } | ||
1493 | |||
1494 | return 0; | ||
1495 | } | 1483 | } |
1496 | 1484 | ||
1497 | /* | 1485 | /* |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 1d3dd30099df..eed4c6a8afc0 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -384,6 +384,52 @@ errout: | |||
384 | } | 384 | } |
385 | 385 | ||
386 | /** | 386 | /** |
387 | * genl_register_family_with_ops - register a generic netlink family | ||
388 | * @family: generic netlink family | ||
389 | * @ops: operations to be registered | ||
390 | * @n_ops: number of elements to register | ||
391 | * | ||
392 | * Registers the specified family and operations from the specified table. | ||
393 | * Only one family may be registered with the same family name or identifier. | ||
394 | * | ||
395 | * The family id may equal GENL_ID_GENERATE causing an unique id to | ||
396 | * be automatically generated and assigned. | ||
397 | * | ||
398 | * Either a doit or dumpit callback must be specified for every registered | ||
399 | * operation or the function will fail. Only one operation structure per | ||
400 | * command identifier may be registered. | ||
401 | * | ||
402 | * See include/net/genetlink.h for more documenation on the operations | ||
403 | * structure. | ||
404 | * | ||
405 | * This is equivalent to calling genl_register_family() followed by | ||
406 | * genl_register_ops() for every operation entry in the table taking | ||
407 | * care to unregister the family on error path. | ||
408 | * | ||
409 | * Return 0 on success or a negative error code. | ||
410 | */ | ||
411 | int genl_register_family_with_ops(struct genl_family *family, | ||
412 | struct genl_ops *ops, size_t n_ops) | ||
413 | { | ||
414 | int err, i; | ||
415 | |||
416 | err = genl_register_family(family); | ||
417 | if (err) | ||
418 | return err; | ||
419 | |||
420 | for (i = 0; i < n_ops; ++i, ++ops) { | ||
421 | err = genl_register_ops(family, ops); | ||
422 | if (err) | ||
423 | goto err_out; | ||
424 | } | ||
425 | return 0; | ||
426 | err_out: | ||
427 | genl_unregister_family(family); | ||
428 | return err; | ||
429 | } | ||
430 | EXPORT_SYMBOL(genl_register_family_with_ops); | ||
431 | |||
432 | /** | ||
387 | * genl_unregister_family - unregister generic netlink family | 433 | * genl_unregister_family - unregister generic netlink family |
388 | * @family: generic netlink family | 434 | * @family: generic netlink family |
389 | * | 435 | * |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 766e6b41f7ca..c7c5d524967e 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1570,9 +1570,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, | |||
1570 | switch (i->type) { | 1570 | switch (i->type) { |
1571 | case PACKET_MR_MULTICAST: | 1571 | case PACKET_MR_MULTICAST: |
1572 | if (what > 0) | 1572 | if (what > 0) |
1573 | dev_mc_add(dev, i->addr, i->alen, 0); | 1573 | return dev_mc_add(dev, i->addr, i->alen, 0); |
1574 | else | 1574 | else |
1575 | dev_mc_delete(dev, i->addr, i->alen, 0); | 1575 | return dev_mc_delete(dev, i->addr, i->alen, 0); |
1576 | break; | 1576 | break; |
1577 | case PACKET_MR_PROMISC: | 1577 | case PACKET_MR_PROMISC: |
1578 | return dev_set_promiscuity(dev, what); | 1578 | return dev_set_promiscuity(dev, what); |
@@ -1580,6 +1580,12 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, | |||
1580 | case PACKET_MR_ALLMULTI: | 1580 | case PACKET_MR_ALLMULTI: |
1581 | return dev_set_allmulti(dev, what); | 1581 | return dev_set_allmulti(dev, what); |
1582 | break; | 1582 | break; |
1583 | case PACKET_MR_UNICAST: | ||
1584 | if (what > 0) | ||
1585 | return dev_unicast_add(dev, i->addr, i->alen); | ||
1586 | else | ||
1587 | return dev_unicast_delete(dev, i->addr, i->alen); | ||
1588 | break; | ||
1583 | default:; | 1589 | default:; |
1584 | } | 1590 | } |
1585 | return 0; | 1591 | return 0; |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index c387217bb230..3c57005e44d1 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -68,7 +68,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | |||
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | static struct genl_family family = { | 71 | static struct genl_family tipc_genl_family = { |
72 | .id = GENL_ID_GENERATE, | 72 | .id = GENL_ID_GENERATE, |
73 | .name = TIPC_GENL_NAME, | 73 | .name = TIPC_GENL_NAME, |
74 | .version = TIPC_GENL_VERSION, | 74 | .version = TIPC_GENL_VERSION, |
@@ -76,39 +76,33 @@ static struct genl_family family = { | |||
76 | .maxattr = 0, | 76 | .maxattr = 0, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static struct genl_ops ops = { | 79 | static struct genl_ops tipc_genl_ops = { |
80 | .cmd = TIPC_GENL_CMD, | 80 | .cmd = TIPC_GENL_CMD, |
81 | .doit = handle_cmd, | 81 | .doit = handle_cmd, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static int family_registered = 0; | 84 | static int tipc_genl_family_registered; |
85 | 85 | ||
86 | int tipc_netlink_start(void) | 86 | int tipc_netlink_start(void) |
87 | { | 87 | { |
88 | int res; | ||
88 | 89 | ||
90 | res = genl_register_family_with_ops(&tipc_genl_family, | ||
91 | &tipc_genl_ops, 1); | ||
92 | if (res) { | ||
93 | err("Failed to register netlink interface\n"); | ||
94 | return res; | ||
95 | } | ||
89 | 96 | ||
90 | if (genl_register_family(&family)) | 97 | tipc_genl_family_registered = 1; |
91 | goto err; | ||
92 | |||
93 | family_registered = 1; | ||
94 | |||
95 | if (genl_register_ops(&family, &ops)) | ||
96 | goto err_unregister; | ||
97 | |||
98 | return 0; | 98 | return 0; |
99 | |||
100 | err_unregister: | ||
101 | genl_unregister_family(&family); | ||
102 | family_registered = 0; | ||
103 | err: | ||
104 | err("Failed to register netlink interface\n"); | ||
105 | return -EFAULT; | ||
106 | } | 99 | } |
107 | 100 | ||
108 | void tipc_netlink_stop(void) | 101 | void tipc_netlink_stop(void) |
109 | { | 102 | { |
110 | if (family_registered) { | 103 | if (!tipc_genl_family_registered) |
111 | genl_unregister_family(&family); | 104 | return; |
112 | family_registered = 0; | 105 | |
113 | } | 106 | genl_unregister_family(&tipc_genl_family); |
107 | tipc_genl_family_registered = 0; | ||
114 | } | 108 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 632504060789..56d729c43b31 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3918,18 +3918,13 @@ nla_put_failure: | |||
3918 | 3918 | ||
3919 | int nl80211_init(void) | 3919 | int nl80211_init(void) |
3920 | { | 3920 | { |
3921 | int err, i; | 3921 | int err; |
3922 | 3922 | ||
3923 | err = genl_register_family(&nl80211_fam); | 3923 | err = genl_register_family_with_ops(&nl80211_fam, |
3924 | nl80211_ops, ARRAY_SIZE(nl80211_ops)); | ||
3924 | if (err) | 3925 | if (err) |
3925 | return err; | 3926 | return err; |
3926 | 3927 | ||
3927 | for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) { | ||
3928 | err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]); | ||
3929 | if (err) | ||
3930 | goto err_out; | ||
3931 | } | ||
3932 | |||
3933 | err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); | 3928 | err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); |
3934 | if (err) | 3929 | if (err) |
3935 | goto err_out; | 3930 | goto err_out; |