GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / net / netconsole.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  linux/drivers/net/netconsole.c
4  *
5  *  Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
6  *
7  *  This file contains the implementation of an IRQ-safe, crash-safe
8  *  kernel console implementation that outputs kernel messages to the
9  *  network.
10  *
11  * Modification history:
12  *
13  * 2001-09-17    started by Ingo Molnar.
14  * 2003-08-11    2.6 port by Matt Mackall
15  *               simplified options
16  *               generic card hooks
17  *               works non-modular
18  * 2003-09-07    rewritten with netpoll api
19  */
20
21 /****************************************************************
22  *
23  ****************************************************************/
24
25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
27 #include <linux/mm.h>
28 #include <linux/init.h>
29 #include <linux/module.h>
30 #include <linux/slab.h>
31 #include <linux/console.h>
32 #include <linux/moduleparam.h>
33 #include <linux/kernel.h>
34 #include <linux/string.h>
35 #include <linux/netpoll.h>
36 #include <linux/inet.h>
37 #include <linux/configfs.h>
38 #include <linux/etherdevice.h>
39 #include <linux/utsname.h>
40
41 MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>");
42 MODULE_DESCRIPTION("Console driver for network interfaces");
43 MODULE_LICENSE("GPL");
44
45 #define MAX_PARAM_LENGTH        256
46 #define MAX_PRINT_CHUNK         1000
47
48 static char config[MAX_PARAM_LENGTH];
49 module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0);
50 MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]");
51
52 static bool oops_only = false;
53 module_param(oops_only, bool, 0600);
54 MODULE_PARM_DESC(oops_only, "Only log oops messages");
55
56 #define NETCONSOLE_PARAM_TARGET_PREFIX "cmdline"
57
58 #ifndef MODULE
59 static int __init option_setup(char *opt)
60 {
61         strscpy(config, opt, MAX_PARAM_LENGTH);
62         return 1;
63 }
64 __setup("netconsole=", option_setup);
65 #endif  /* MODULE */
66
67 /* Linked list of all configured targets */
68 static LIST_HEAD(target_list);
69
70 /* This needs to be a spinlock because write_msg() cannot sleep */
71 static DEFINE_SPINLOCK(target_list_lock);
72
73 /*
74  * Console driver for extended netconsoles.  Registered on the first use to
75  * avoid unnecessarily enabling ext message formatting.
76  */
77 static struct console netconsole_ext;
78
79 /**
80  * struct netconsole_target - Represents a configured netconsole target.
81  * @list:       Links this target into the target_list.
82  * @item:       Links us into the configfs subsystem hierarchy.
83  * @enabled:    On / off knob to enable / disable target.
84  *              Visible from userspace (read-write).
85  *              We maintain a strict 1:1 correspondence between this and
86  *              whether the corresponding netpoll is active or inactive.
87  *              Also, other parameters of a target may be modified at
88  *              runtime only when it is disabled (enabled == 0).
89  * @extended:   Denotes whether console is extended or not.
90  * @release:    Denotes whether kernel release version should be prepended
91  *              to the message. Depends on extended console.
92  * @np:         The netpoll structure for this target.
93  *              Contains the other userspace visible parameters:
94  *              dev_name        (read-write)
95  *              local_port      (read-write)
96  *              remote_port     (read-write)
97  *              local_ip        (read-write)
98  *              remote_ip       (read-write)
99  *              local_mac       (read-only)
100  *              remote_mac      (read-write)
101  */
102 struct netconsole_target {
103         struct list_head        list;
104 #ifdef  CONFIG_NETCONSOLE_DYNAMIC
105         struct config_item      item;
106 #endif
107         bool                    enabled;
108         bool                    extended;
109         bool                    release;
110         struct netpoll          np;
111 };
112
113 #ifdef  CONFIG_NETCONSOLE_DYNAMIC
114
115 static struct configfs_subsystem netconsole_subsys;
116 static DEFINE_MUTEX(dynamic_netconsole_mutex);
117
118 static int __init dynamic_netconsole_init(void)
119 {
120         config_group_init(&netconsole_subsys.su_group);
121         mutex_init(&netconsole_subsys.su_mutex);
122         return configfs_register_subsystem(&netconsole_subsys);
123 }
124
125 static void __exit dynamic_netconsole_exit(void)
126 {
127         configfs_unregister_subsystem(&netconsole_subsys);
128 }
129
130 /*
131  * Targets that were created by parsing the boot/module option string
132  * do not exist in the configfs hierarchy (and have NULL names) and will
133  * never go away, so make these a no-op for them.
134  */
135 static void netconsole_target_get(struct netconsole_target *nt)
136 {
137         if (config_item_name(&nt->item))
138                 config_item_get(&nt->item);
139 }
140
141 static void netconsole_target_put(struct netconsole_target *nt)
142 {
143         if (config_item_name(&nt->item))
144                 config_item_put(&nt->item);
145 }
146
147 #else   /* !CONFIG_NETCONSOLE_DYNAMIC */
148
149 static int __init dynamic_netconsole_init(void)
150 {
151         return 0;
152 }
153
154 static void __exit dynamic_netconsole_exit(void)
155 {
156 }
157
158 /*
159  * No danger of targets going away from under us when dynamic
160  * reconfigurability is off.
161  */
162 static void netconsole_target_get(struct netconsole_target *nt)
163 {
164 }
165
166 static void netconsole_target_put(struct netconsole_target *nt)
167 {
168 }
169
170 static void populate_configfs_item(struct netconsole_target *nt,
171                                    int cmdline_count)
172 {
173 }
174 #endif  /* CONFIG_NETCONSOLE_DYNAMIC */
175
176 /* Allocate and initialize with defaults.
177  * Note that these targets get their config_item fields zeroed-out.
178  */
179 static struct netconsole_target *alloc_and_init(void)
180 {
181         struct netconsole_target *nt;
182
183         nt = kzalloc(sizeof(*nt), GFP_KERNEL);
184         if (!nt)
185                 return nt;
186
187         if (IS_ENABLED(CONFIG_NETCONSOLE_EXTENDED_LOG))
188                 nt->extended = true;
189         if (IS_ENABLED(CONFIG_NETCONSOLE_PREPEND_RELEASE))
190                 nt->release = true;
191
192         nt->np.name = "netconsole";
193         strscpy(nt->np.dev_name, "eth0", IFNAMSIZ);
194         nt->np.local_port = 6665;
195         nt->np.remote_port = 6666;
196         eth_broadcast_addr(nt->np.remote_mac);
197
198         return nt;
199 }
200
201 #ifdef  CONFIG_NETCONSOLE_DYNAMIC
202
203 /*
204  * Our subsystem hierarchy is:
205  *
206  * /sys/kernel/config/netconsole/
207  *                              |
208  *                              <target>/
209  *                              |       enabled
210  *                              |       release
211  *                              |       dev_name
212  *                              |       local_port
213  *                              |       remote_port
214  *                              |       local_ip
215  *                              |       remote_ip
216  *                              |       local_mac
217  *                              |       remote_mac
218  *                              |
219  *                              <target>/...
220  */
221
222 static struct netconsole_target *to_target(struct config_item *item)
223 {
224         return item ?
225                 container_of(item, struct netconsole_target, item) :
226                 NULL;
227 }
228
229 /*
230  * Attribute operations for netconsole_target.
231  */
232
233 static ssize_t enabled_show(struct config_item *item, char *buf)
234 {
235         return sysfs_emit(buf, "%d\n", to_target(item)->enabled);
236 }
237
238 static ssize_t extended_show(struct config_item *item, char *buf)
239 {
240         return sysfs_emit(buf, "%d\n", to_target(item)->extended);
241 }
242
243 static ssize_t release_show(struct config_item *item, char *buf)
244 {
245         return sysfs_emit(buf, "%d\n", to_target(item)->release);
246 }
247
248 static ssize_t dev_name_show(struct config_item *item, char *buf)
249 {
250         return sysfs_emit(buf, "%s\n", to_target(item)->np.dev_name);
251 }
252
253 static ssize_t local_port_show(struct config_item *item, char *buf)
254 {
255         return sysfs_emit(buf, "%d\n", to_target(item)->np.local_port);
256 }
257
258 static ssize_t remote_port_show(struct config_item *item, char *buf)
259 {
260         return sysfs_emit(buf, "%d\n", to_target(item)->np.remote_port);
261 }
262
263 static ssize_t local_ip_show(struct config_item *item, char *buf)
264 {
265         struct netconsole_target *nt = to_target(item);
266
267         if (nt->np.ipv6)
268                 return sysfs_emit(buf, "%pI6c\n", &nt->np.local_ip.in6);
269         else
270                 return sysfs_emit(buf, "%pI4\n", &nt->np.local_ip);
271 }
272
273 static ssize_t remote_ip_show(struct config_item *item, char *buf)
274 {
275         struct netconsole_target *nt = to_target(item);
276
277         if (nt->np.ipv6)
278                 return sysfs_emit(buf, "%pI6c\n", &nt->np.remote_ip.in6);
279         else
280                 return sysfs_emit(buf, "%pI4\n", &nt->np.remote_ip);
281 }
282
283 static ssize_t local_mac_show(struct config_item *item, char *buf)
284 {
285         struct net_device *dev = to_target(item)->np.dev;
286         static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
287
288         return sysfs_emit(buf, "%pM\n", dev ? dev->dev_addr : bcast);
289 }
290
291 static ssize_t remote_mac_show(struct config_item *item, char *buf)
292 {
293         return sysfs_emit(buf, "%pM\n", to_target(item)->np.remote_mac);
294 }
295
296 /*
297  * This one is special -- targets created through the configfs interface
298  * are not enabled (and the corresponding netpoll activated) by default.
299  * The user is expected to set the desired parameters first (which
300  * would enable him to dynamically add new netpoll targets for new
301  * network interfaces as and when they come up).
302  */
303 static ssize_t enabled_store(struct config_item *item,
304                 const char *buf, size_t count)
305 {
306         struct netconsole_target *nt = to_target(item);
307         unsigned long flags;
308         bool enabled;
309         int err;
310
311         mutex_lock(&dynamic_netconsole_mutex);
312         err = kstrtobool(buf, &enabled);
313         if (err)
314                 goto out_unlock;
315
316         err = -EINVAL;
317         if ((bool)enabled == nt->enabled) {
318                 pr_info("network logging has already %s\n",
319                         nt->enabled ? "started" : "stopped");
320                 goto out_unlock;
321         }
322
323         if (enabled) {  /* true */
324                 if (nt->release && !nt->extended) {
325                         pr_err("Not enabling netconsole. Release feature requires extended log message");
326                         goto out_unlock;
327                 }
328
329                 if (nt->extended && !console_is_registered(&netconsole_ext))
330                         register_console(&netconsole_ext);
331
332                 /*
333                  * Skip netpoll_parse_options() -- all the attributes are
334                  * already configured via configfs. Just print them out.
335                  */
336                 netpoll_print_options(&nt->np);
337
338                 err = netpoll_setup(&nt->np);
339                 if (err)
340                         goto out_unlock;
341
342                 pr_info("network logging started\n");
343         } else {        /* false */
344                 /* We need to disable the netconsole before cleaning it up
345                  * otherwise we might end up in write_msg() with
346                  * nt->np.dev == NULL and nt->enabled == true
347                  */
348                 spin_lock_irqsave(&target_list_lock, flags);
349                 nt->enabled = false;
350                 spin_unlock_irqrestore(&target_list_lock, flags);
351                 netpoll_cleanup(&nt->np);
352         }
353
354         nt->enabled = enabled;
355
356         mutex_unlock(&dynamic_netconsole_mutex);
357         return strnlen(buf, count);
358 out_unlock:
359         mutex_unlock(&dynamic_netconsole_mutex);
360         return err;
361 }
362
363 static ssize_t release_store(struct config_item *item, const char *buf,
364                              size_t count)
365 {
366         struct netconsole_target *nt = to_target(item);
367         bool release;
368         int err;
369
370         mutex_lock(&dynamic_netconsole_mutex);
371         if (nt->enabled) {
372                 pr_err("target (%s) is enabled, disable to update parameters\n",
373                        config_item_name(&nt->item));
374                 err = -EINVAL;
375                 goto out_unlock;
376         }
377
378         err = kstrtobool(buf, &release);
379         if (err)
380                 goto out_unlock;
381
382         nt->release = release;
383
384         mutex_unlock(&dynamic_netconsole_mutex);
385         return strnlen(buf, count);
386 out_unlock:
387         mutex_unlock(&dynamic_netconsole_mutex);
388         return err;
389 }
390
391 static ssize_t extended_store(struct config_item *item, const char *buf,
392                 size_t count)
393 {
394         struct netconsole_target *nt = to_target(item);
395         bool extended;
396         int err;
397
398         mutex_lock(&dynamic_netconsole_mutex);
399         if (nt->enabled) {
400                 pr_err("target (%s) is enabled, disable to update parameters\n",
401                        config_item_name(&nt->item));
402                 err = -EINVAL;
403                 goto out_unlock;
404         }
405
406         err = kstrtobool(buf, &extended);
407         if (err)
408                 goto out_unlock;
409
410         nt->extended = extended;
411
412         mutex_unlock(&dynamic_netconsole_mutex);
413         return strnlen(buf, count);
414 out_unlock:
415         mutex_unlock(&dynamic_netconsole_mutex);
416         return err;
417 }
418
419 static ssize_t dev_name_store(struct config_item *item, const char *buf,
420                 size_t count)
421 {
422         struct netconsole_target *nt = to_target(item);
423         size_t len;
424
425         mutex_lock(&dynamic_netconsole_mutex);
426         if (nt->enabled) {
427                 pr_err("target (%s) is enabled, disable to update parameters\n",
428                        config_item_name(&nt->item));
429                 mutex_unlock(&dynamic_netconsole_mutex);
430                 return -EINVAL;
431         }
432
433         strscpy(nt->np.dev_name, buf, IFNAMSIZ);
434
435         /* Get rid of possible trailing newline from echo(1) */
436         len = strnlen(nt->np.dev_name, IFNAMSIZ);
437         if (nt->np.dev_name[len - 1] == '\n')
438                 nt->np.dev_name[len - 1] = '\0';
439
440         mutex_unlock(&dynamic_netconsole_mutex);
441         return strnlen(buf, count);
442 }
443
444 static ssize_t local_port_store(struct config_item *item, const char *buf,
445                 size_t count)
446 {
447         struct netconsole_target *nt = to_target(item);
448         int rv = -EINVAL;
449
450         mutex_lock(&dynamic_netconsole_mutex);
451         if (nt->enabled) {
452                 pr_err("target (%s) is enabled, disable to update parameters\n",
453                        config_item_name(&nt->item));
454                 goto out_unlock;
455         }
456
457         rv = kstrtou16(buf, 10, &nt->np.local_port);
458         if (rv < 0)
459                 goto out_unlock;
460         mutex_unlock(&dynamic_netconsole_mutex);
461         return strnlen(buf, count);
462 out_unlock:
463         mutex_unlock(&dynamic_netconsole_mutex);
464         return rv;
465 }
466
467 static ssize_t remote_port_store(struct config_item *item,
468                 const char *buf, size_t count)
469 {
470         struct netconsole_target *nt = to_target(item);
471         int rv = -EINVAL;
472
473         mutex_lock(&dynamic_netconsole_mutex);
474         if (nt->enabled) {
475                 pr_err("target (%s) is enabled, disable to update parameters\n",
476                        config_item_name(&nt->item));
477                 goto out_unlock;
478         }
479
480         rv = kstrtou16(buf, 10, &nt->np.remote_port);
481         if (rv < 0)
482                 goto out_unlock;
483         mutex_unlock(&dynamic_netconsole_mutex);
484         return strnlen(buf, count);
485 out_unlock:
486         mutex_unlock(&dynamic_netconsole_mutex);
487         return rv;
488 }
489
490 static ssize_t local_ip_store(struct config_item *item, const char *buf,
491                 size_t count)
492 {
493         struct netconsole_target *nt = to_target(item);
494
495         mutex_lock(&dynamic_netconsole_mutex);
496         if (nt->enabled) {
497                 pr_err("target (%s) is enabled, disable to update parameters\n",
498                        config_item_name(&nt->item));
499                 goto out_unlock;
500         }
501
502         if (strnchr(buf, count, ':')) {
503                 const char *end;
504                 if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {
505                         if (*end && *end != '\n') {
506                                 pr_err("invalid IPv6 address at: <%c>\n", *end);
507                                 goto out_unlock;
508                         }
509                         nt->np.ipv6 = true;
510                 } else
511                         goto out_unlock;
512         } else {
513                 if (!nt->np.ipv6) {
514                         nt->np.local_ip.ip = in_aton(buf);
515                 } else
516                         goto out_unlock;
517         }
518
519         mutex_unlock(&dynamic_netconsole_mutex);
520         return strnlen(buf, count);
521 out_unlock:
522         mutex_unlock(&dynamic_netconsole_mutex);
523         return -EINVAL;
524 }
525
526 static ssize_t remote_ip_store(struct config_item *item, const char *buf,
527                size_t count)
528 {
529         struct netconsole_target *nt = to_target(item);
530
531         mutex_lock(&dynamic_netconsole_mutex);
532         if (nt->enabled) {
533                 pr_err("target (%s) is enabled, disable to update parameters\n",
534                        config_item_name(&nt->item));
535                 goto out_unlock;
536         }
537
538         if (strnchr(buf, count, ':')) {
539                 const char *end;
540                 if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {
541                         if (*end && *end != '\n') {
542                                 pr_err("invalid IPv6 address at: <%c>\n", *end);
543                                 goto out_unlock;
544                         }
545                         nt->np.ipv6 = true;
546                 } else
547                         goto out_unlock;
548         } else {
549                 if (!nt->np.ipv6) {
550                         nt->np.remote_ip.ip = in_aton(buf);
551                 } else
552                         goto out_unlock;
553         }
554
555         mutex_unlock(&dynamic_netconsole_mutex);
556         return strnlen(buf, count);
557 out_unlock:
558         mutex_unlock(&dynamic_netconsole_mutex);
559         return -EINVAL;
560 }
561
562 static ssize_t remote_mac_store(struct config_item *item, const char *buf,
563                 size_t count)
564 {
565         struct netconsole_target *nt = to_target(item);
566         u8 remote_mac[ETH_ALEN];
567
568         mutex_lock(&dynamic_netconsole_mutex);
569         if (nt->enabled) {
570                 pr_err("target (%s) is enabled, disable to update parameters\n",
571                        config_item_name(&nt->item));
572                 goto out_unlock;
573         }
574
575         if (!mac_pton(buf, remote_mac))
576                 goto out_unlock;
577         if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
578                 goto out_unlock;
579         memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
580
581         mutex_unlock(&dynamic_netconsole_mutex);
582         return strnlen(buf, count);
583 out_unlock:
584         mutex_unlock(&dynamic_netconsole_mutex);
585         return -EINVAL;
586 }
587
588 CONFIGFS_ATTR(, enabled);
589 CONFIGFS_ATTR(, extended);
590 CONFIGFS_ATTR(, dev_name);
591 CONFIGFS_ATTR(, local_port);
592 CONFIGFS_ATTR(, remote_port);
593 CONFIGFS_ATTR(, local_ip);
594 CONFIGFS_ATTR(, remote_ip);
595 CONFIGFS_ATTR_RO(, local_mac);
596 CONFIGFS_ATTR(, remote_mac);
597 CONFIGFS_ATTR(, release);
598
599 static struct configfs_attribute *netconsole_target_attrs[] = {
600         &attr_enabled,
601         &attr_extended,
602         &attr_release,
603         &attr_dev_name,
604         &attr_local_port,
605         &attr_remote_port,
606         &attr_local_ip,
607         &attr_remote_ip,
608         &attr_local_mac,
609         &attr_remote_mac,
610         NULL,
611 };
612
613 /*
614  * Item operations and type for netconsole_target.
615  */
616
617 static void netconsole_target_release(struct config_item *item)
618 {
619         kfree(to_target(item));
620 }
621
622 static struct configfs_item_operations netconsole_target_item_ops = {
623         .release                = netconsole_target_release,
624 };
625
626 static const struct config_item_type netconsole_target_type = {
627         .ct_attrs               = netconsole_target_attrs,
628         .ct_item_ops            = &netconsole_target_item_ops,
629         .ct_owner               = THIS_MODULE,
630 };
631
632 static struct netconsole_target *find_cmdline_target(const char *name)
633 {
634         struct netconsole_target *nt, *ret = NULL;
635         unsigned long flags;
636
637         spin_lock_irqsave(&target_list_lock, flags);
638         list_for_each_entry(nt, &target_list, list) {
639                 if (!strcmp(nt->item.ci_name, name)) {
640                         ret = nt;
641                         break;
642                 }
643         }
644         spin_unlock_irqrestore(&target_list_lock, flags);
645
646         return ret;
647 }
648
649 /*
650  * Group operations and type for netconsole_subsys.
651  */
652
653 static struct config_item *make_netconsole_target(struct config_group *group,
654                                                   const char *name)
655 {
656         struct netconsole_target *nt;
657         unsigned long flags;
658
659         /* Checking if a target by this name was created at boot time.  If so,
660          * attach a configfs entry to that target.  This enables dynamic
661          * control.
662          */
663         if (!strncmp(name, NETCONSOLE_PARAM_TARGET_PREFIX,
664                      strlen(NETCONSOLE_PARAM_TARGET_PREFIX))) {
665                 nt = find_cmdline_target(name);
666                 if (nt)
667                         return &nt->item;
668         }
669
670         nt = alloc_and_init();
671         if (!nt)
672                 return ERR_PTR(-ENOMEM);
673
674         /* Initialize the config_item member */
675         config_item_init_type_name(&nt->item, name, &netconsole_target_type);
676
677         /* Adding, but it is disabled */
678         spin_lock_irqsave(&target_list_lock, flags);
679         list_add(&nt->list, &target_list);
680         spin_unlock_irqrestore(&target_list_lock, flags);
681
682         return &nt->item;
683 }
684
685 static void drop_netconsole_target(struct config_group *group,
686                                    struct config_item *item)
687 {
688         unsigned long flags;
689         struct netconsole_target *nt = to_target(item);
690
691         spin_lock_irqsave(&target_list_lock, flags);
692         list_del(&nt->list);
693         spin_unlock_irqrestore(&target_list_lock, flags);
694
695         /*
696          * The target may have never been enabled, or was manually disabled
697          * before being removed so netpoll may have already been cleaned up.
698          */
699         if (nt->enabled)
700                 netpoll_cleanup(&nt->np);
701
702         config_item_put(&nt->item);
703 }
704
705 static struct configfs_group_operations netconsole_subsys_group_ops = {
706         .make_item      = make_netconsole_target,
707         .drop_item      = drop_netconsole_target,
708 };
709
710 static const struct config_item_type netconsole_subsys_type = {
711         .ct_group_ops   = &netconsole_subsys_group_ops,
712         .ct_owner       = THIS_MODULE,
713 };
714
715 /* The netconsole configfs subsystem */
716 static struct configfs_subsystem netconsole_subsys = {
717         .su_group       = {
718                 .cg_item        = {
719                         .ci_namebuf     = "netconsole",
720                         .ci_type        = &netconsole_subsys_type,
721                 },
722         },
723 };
724
725 static void populate_configfs_item(struct netconsole_target *nt,
726                                    int cmdline_count)
727 {
728         char target_name[16];
729
730         snprintf(target_name, sizeof(target_name), "%s%d",
731                  NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
732         config_item_init_type_name(&nt->item, target_name,
733                                    &netconsole_target_type);
734 }
735
736 #endif  /* CONFIG_NETCONSOLE_DYNAMIC */
737
738 /* Handle network interface device notifications */
739 static int netconsole_netdev_event(struct notifier_block *this,
740                                    unsigned long event, void *ptr)
741 {
742         unsigned long flags;
743         struct netconsole_target *nt;
744         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
745         bool stopped = false;
746
747         if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||
748               event == NETDEV_RELEASE || event == NETDEV_JOIN))
749                 goto done;
750
751         spin_lock_irqsave(&target_list_lock, flags);
752 restart:
753         list_for_each_entry(nt, &target_list, list) {
754                 netconsole_target_get(nt);
755                 if (nt->np.dev == dev) {
756                         switch (event) {
757                         case NETDEV_CHANGENAME:
758                                 strscpy(nt->np.dev_name, dev->name, IFNAMSIZ);
759                                 break;
760                         case NETDEV_RELEASE:
761                         case NETDEV_JOIN:
762                         case NETDEV_UNREGISTER:
763                                 /* rtnl_lock already held
764                                  * we might sleep in __netpoll_cleanup()
765                                  */
766                                 spin_unlock_irqrestore(&target_list_lock, flags);
767
768                                 __netpoll_cleanup(&nt->np);
769
770                                 spin_lock_irqsave(&target_list_lock, flags);
771                                 netdev_put(nt->np.dev, &nt->np.dev_tracker);
772                                 nt->np.dev = NULL;
773                                 nt->enabled = false;
774                                 stopped = true;
775                                 netconsole_target_put(nt);
776                                 goto restart;
777                         }
778                 }
779                 netconsole_target_put(nt);
780         }
781         spin_unlock_irqrestore(&target_list_lock, flags);
782         if (stopped) {
783                 const char *msg = "had an event";
784                 switch (event) {
785                 case NETDEV_UNREGISTER:
786                         msg = "unregistered";
787                         break;
788                 case NETDEV_RELEASE:
789                         msg = "released slaves";
790                         break;
791                 case NETDEV_JOIN:
792                         msg = "is joining a master device";
793                         break;
794                 }
795                 pr_info("network logging stopped on interface %s as it %s\n",
796                         dev->name, msg);
797         }
798
799 done:
800         return NOTIFY_DONE;
801 }
802
803 static struct notifier_block netconsole_netdev_notifier = {
804         .notifier_call  = netconsole_netdev_event,
805 };
806
807 /**
808  * send_ext_msg_udp - send extended log message to target
809  * @nt: target to send message to
810  * @msg: extended log message to send
811  * @msg_len: length of message
812  *
813  * Transfer extended log @msg to @nt.  If @msg is longer than
814  * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
815  * ncfrag header field added to identify them.
816  */
817 static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
818                              int msg_len)
819 {
820         static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
821         const char *header, *body;
822         int offset = 0;
823         int header_len, body_len;
824         const char *msg_ready = msg;
825         const char *release;
826         int release_len = 0;
827
828         if (nt->release) {
829                 release = init_utsname()->release;
830                 release_len = strlen(release) + 1;
831         }
832
833         if (msg_len + release_len <= MAX_PRINT_CHUNK) {
834                 /* No fragmentation needed */
835                 if (nt->release) {
836                         scnprintf(buf, MAX_PRINT_CHUNK, "%s,%s", release, msg);
837                         msg_len += release_len;
838                         msg_ready = buf;
839                 }
840                 netpoll_send_udp(&nt->np, msg_ready, msg_len);
841                 return;
842         }
843
844         /* need to insert extra header fields, detect header and body */
845         header = msg;
846         body = memchr(msg, ';', msg_len);
847         if (WARN_ON_ONCE(!body))
848                 return;
849
850         header_len = body - header;
851         body_len = msg_len - header_len - 1;
852         body++;
853
854         /*
855          * Transfer multiple chunks with the following extra header.
856          * "ncfrag=<byte-offset>/<total-bytes>"
857          */
858         if (nt->release)
859                 scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
860         memcpy(buf + release_len, header, header_len);
861         header_len += release_len;
862
863         while (offset < body_len) {
864                 int this_header = header_len;
865                 int this_chunk;
866
867                 this_header += scnprintf(buf + this_header,
868                                          sizeof(buf) - this_header,
869                                          ",ncfrag=%d/%d;", offset, body_len);
870
871                 this_chunk = min(body_len - offset,
872                                  MAX_PRINT_CHUNK - this_header);
873                 if (WARN_ON_ONCE(this_chunk <= 0))
874                         return;
875
876                 memcpy(buf + this_header, body + offset, this_chunk);
877
878                 netpoll_send_udp(&nt->np, buf, this_header + this_chunk);
879
880                 offset += this_chunk;
881         }
882 }
883
884 static void write_ext_msg(struct console *con, const char *msg,
885                           unsigned int len)
886 {
887         struct netconsole_target *nt;
888         unsigned long flags;
889
890         if ((oops_only && !oops_in_progress) || list_empty(&target_list))
891                 return;
892
893         spin_lock_irqsave(&target_list_lock, flags);
894         list_for_each_entry(nt, &target_list, list)
895                 if (nt->extended && nt->enabled && netif_running(nt->np.dev))
896                         send_ext_msg_udp(nt, msg, len);
897         spin_unlock_irqrestore(&target_list_lock, flags);
898 }
899
900 static void write_msg(struct console *con, const char *msg, unsigned int len)
901 {
902         int frag, left;
903         unsigned long flags;
904         struct netconsole_target *nt;
905         const char *tmp;
906
907         if (oops_only && !oops_in_progress)
908                 return;
909         /* Avoid taking lock and disabling interrupts unnecessarily */
910         if (list_empty(&target_list))
911                 return;
912
913         spin_lock_irqsave(&target_list_lock, flags);
914         list_for_each_entry(nt, &target_list, list) {
915                 if (!nt->extended && nt->enabled && netif_running(nt->np.dev)) {
916                         /*
917                          * We nest this inside the for-each-target loop above
918                          * so that we're able to get as much logging out to
919                          * at least one target if we die inside here, instead
920                          * of unnecessarily keeping all targets in lock-step.
921                          */
922                         tmp = msg;
923                         for (left = len; left;) {
924                                 frag = min(left, MAX_PRINT_CHUNK);
925                                 netpoll_send_udp(&nt->np, tmp, frag);
926                                 tmp += frag;
927                                 left -= frag;
928                         }
929                 }
930         }
931         spin_unlock_irqrestore(&target_list_lock, flags);
932 }
933
934 /* Allocate new target (from boot/module param) and setup netpoll for it */
935 static struct netconsole_target *alloc_param_target(char *target_config,
936                                                     int cmdline_count)
937 {
938         struct netconsole_target *nt;
939         int err;
940
941         nt = alloc_and_init();
942         if (!nt) {
943                 err = -ENOMEM;
944                 goto fail;
945         }
946
947         if (*target_config == '+') {
948                 nt->extended = true;
949                 target_config++;
950         }
951
952         if (*target_config == 'r') {
953                 if (!nt->extended) {
954                         pr_err("Netconsole configuration error. Release feature requires extended log message");
955                         err = -EINVAL;
956                         goto fail;
957                 }
958                 nt->release = true;
959                 target_config++;
960         }
961
962         /* Parse parameters and setup netpoll */
963         err = netpoll_parse_options(&nt->np, target_config);
964         if (err)
965                 goto fail;
966
967         err = netpoll_setup(&nt->np);
968         if (err)
969                 goto fail;
970
971         populate_configfs_item(nt, cmdline_count);
972         nt->enabled = true;
973
974         return nt;
975
976 fail:
977         kfree(nt);
978         return ERR_PTR(err);
979 }
980
981 /* Cleanup netpoll for given target (from boot/module param) and free it */
982 static void free_param_target(struct netconsole_target *nt)
983 {
984         netpoll_cleanup(&nt->np);
985         kfree(nt);
986 }
987
988 static struct console netconsole_ext = {
989         .name   = "netcon_ext",
990         .flags  = CON_ENABLED | CON_EXTENDED,
991         .write  = write_ext_msg,
992 };
993
994 static struct console netconsole = {
995         .name   = "netcon",
996         .flags  = CON_ENABLED,
997         .write  = write_msg,
998 };
999
1000 static int __init init_netconsole(void)
1001 {
1002         int err;
1003         struct netconsole_target *nt, *tmp;
1004         unsigned int count = 0;
1005         bool extended = false;
1006         unsigned long flags;
1007         char *target_config;
1008         char *input = config;
1009
1010         if (strnlen(input, MAX_PARAM_LENGTH)) {
1011                 while ((target_config = strsep(&input, ";"))) {
1012                         nt = alloc_param_target(target_config, count);
1013                         if (IS_ERR(nt)) {
1014                                 err = PTR_ERR(nt);
1015                                 goto fail;
1016                         }
1017                         /* Dump existing printks when we register */
1018                         if (nt->extended) {
1019                                 extended = true;
1020                                 netconsole_ext.flags |= CON_PRINTBUFFER;
1021                         } else {
1022                                 netconsole.flags |= CON_PRINTBUFFER;
1023                         }
1024
1025                         spin_lock_irqsave(&target_list_lock, flags);
1026                         list_add(&nt->list, &target_list);
1027                         spin_unlock_irqrestore(&target_list_lock, flags);
1028                         count++;
1029                 }
1030         }
1031
1032         err = register_netdevice_notifier(&netconsole_netdev_notifier);
1033         if (err)
1034                 goto fail;
1035
1036         err = dynamic_netconsole_init();
1037         if (err)
1038                 goto undonotifier;
1039
1040         if (extended)
1041                 register_console(&netconsole_ext);
1042         register_console(&netconsole);
1043         pr_info("network logging started\n");
1044
1045         return err;
1046
1047 undonotifier:
1048         unregister_netdevice_notifier(&netconsole_netdev_notifier);
1049
1050 fail:
1051         pr_err("cleaning up\n");
1052
1053         /*
1054          * Remove all targets and destroy them (only targets created
1055          * from the boot/module option exist here). Skipping the list
1056          * lock is safe here, and netpoll_cleanup() will sleep.
1057          */
1058         list_for_each_entry_safe(nt, tmp, &target_list, list) {
1059                 list_del(&nt->list);
1060                 free_param_target(nt);
1061         }
1062
1063         return err;
1064 }
1065
1066 static void __exit cleanup_netconsole(void)
1067 {
1068         struct netconsole_target *nt, *tmp;
1069
1070         if (console_is_registered(&netconsole_ext))
1071                 unregister_console(&netconsole_ext);
1072         unregister_console(&netconsole);
1073         dynamic_netconsole_exit();
1074         unregister_netdevice_notifier(&netconsole_netdev_notifier);
1075
1076         /*
1077          * Targets created via configfs pin references on our module
1078          * and would first be rmdir(2)'ed from userspace. We reach
1079          * here only when they are already destroyed, and only those
1080          * created from the boot/module option are left, so remove and
1081          * destroy them. Skipping the list lock is safe here, and
1082          * netpoll_cleanup() will sleep.
1083          */
1084         list_for_each_entry_safe(nt, tmp, &target_list, list) {
1085                 list_del(&nt->list);
1086                 free_param_target(nt);
1087         }
1088 }
1089
1090 /*
1091  * Use late_initcall to ensure netconsole is
1092  * initialized after network device driver if built-in.
1093  *
1094  * late_initcall() and module_init() are identical if built as module.
1095  */
1096 late_initcall(init_netconsole);
1097 module_exit(cleanup_netconsole);