aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSatyam Sharma <satyam@infradead.org>2007-08-10 18:33:01 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:48:05 -0400
commit17951f34b0970b05e29fd93a5b93fa05ec71308b (patch)
treea9b03366b502d878389c09afcffe4d7feff884b2 /drivers
parentdf180e369cf54a8ef8440667ab1d13d452fc7215 (diff)
[NET] netconsole: Introduce netconsole_netdev_notifier
Based upon initial work by Keiichi Kii <k-keiichi@bx.jp.nec.com>. To update fields of underlying netpoll structure at runtime on corresponding NETDEV_CHANGEADDR or NETDEV_CHANGENAME notifications. ioctl(SIOCSIFHWADDR or SIOCSIFNAME) could be used to change the hardware/MAC address or name of the local interface that our netpoll is attached to. Whenever this happens, netdev notifier chain is called out with the NETDEV_CHANGEADDR or NETDEV_CHANGENAME event message. We respond to that and update the local_mac or dev_name field of the struct netpoll. This makes sense anyway, but is especially required for dynamic netconsole because the netpoll structure's internal members become user visible files when either sysfs or configfs are used. So this helps us to keep up with the MAC address/name changes and keep values in struct netpoll uptodate. [ Note that ioctl(SIOCSIFADDR) to change IP address of interface at runtime is not handled (to update local_ip of netpoll) on purpose -- some setups may set the local_ip to a private address, not necessary the actual IP address of the sender host, as presently allowed. ] Signed-off-by: Satyam Sharma <satyam@infradead.org> Signed-off-by: Keiichi Kii <k-keiichi@bx.jp.nec.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/netconsole.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index be15ca6205a8..55570988250b 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -80,6 +80,33 @@ static struct netconsole_target default_target = {
80 }, 80 },
81}; 81};
82 82
83/* Handle network interface device notifications */
84static int netconsole_netdev_event(struct notifier_block *this,
85 unsigned long event,
86 void *ptr)
87{
88 struct net_device *dev = ptr;
89 struct netconsole_target *nt = &default_target;
90
91 if (nt->np.dev == dev) {
92 switch (event) {
93 case NETDEV_CHANGEADDR:
94 memcpy(nt->np.local_mac, dev->dev_addr, ETH_ALEN);
95 break;
96
97 case NETDEV_CHANGENAME:
98 strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);
99 break;
100 }
101 }
102
103 return NOTIFY_DONE;
104}
105
106static struct notifier_block netconsole_netdev_notifier = {
107 .notifier_call = netconsole_netdev_event,
108};
109
83static void write_msg(struct console *con, const char *msg, unsigned int len) 110static void write_msg(struct console *con, const char *msg, unsigned int len)
84{ 111{
85 int frag, left; 112 int frag, left;
@@ -122,6 +149,10 @@ static int __init init_netconsole(void)
122 if (err) 149 if (err)
123 goto out; 150 goto out;
124 151
152 err = register_netdevice_notifier(&netconsole_netdev_notifier);
153 if (err)
154 goto out;
155
125 register_console(&netconsole); 156 register_console(&netconsole);
126 printk(KERN_INFO "netconsole: network logging started\n"); 157 printk(KERN_INFO "netconsole: network logging started\n");
127 158
@@ -134,6 +165,7 @@ static void __exit cleanup_netconsole(void)
134 struct netconsole_target *nt = &default_target; 165 struct netconsole_target *nt = &default_target;
135 166
136 unregister_console(&netconsole); 167 unregister_console(&netconsole);
168 unregister_netdevice_notifier(&netconsole_netdev_notifier);
137 netpoll_cleanup(&nt->np); 169 netpoll_cleanup(&nt->np);
138} 170}
139 171