aboutsummaryrefslogtreecommitdiffstats
path: root/net/phonet/pn_dev.c
diff options
context:
space:
mode:
authorRémi Denis-Courmont <remi.denis-courmont@nokia.com>2009-10-13 20:48:29 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-14 18:04:17 -0400
commitf062f41d06575744b9eaf725eef8a5d3b5f5b7ca (patch)
tree1ee1c966a2810c1f2a7274a51dba0387861efc68 /net/phonet/pn_dev.c
parent55748ac0468134a89bc55aed6a9691e320caa8a9 (diff)
Phonet: routing table Netlink interface
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/phonet/pn_dev.c')
-rw-r--r--net/phonet/pn_dev.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index 71fffa587783..6d64fda1afc9 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -240,6 +240,27 @@ static int phonet_device_autoconf(struct net_device *dev)
240 return 0; 240 return 0;
241} 241}
242 242
243static void phonet_route_autodel(struct net_device *dev)
244{
245 struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id);
246 unsigned i;
247 DECLARE_BITMAP(deleted, 64);
248
249 /* Remove left-over Phonet routes */
250 bitmap_zero(deleted, 64);
251 spin_lock_bh(&pnn->routes.lock);
252 for (i = 0; i < 64; i++)
253 if (dev == pnn->routes.table[i]) {
254 set_bit(i, deleted);
255 pnn->routes.table[i] = NULL;
256 dev_put(dev);
257 }
258 spin_unlock_bh(&pnn->routes.lock);
259 for (i = find_first_bit(deleted, 64); i < 64;
260 i = find_next_bit(deleted, 64, i + 1))
261 rtm_phonet_notify(RTM_DELROUTE, dev, i);
262}
263
243/* notify Phonet of device events */ 264/* notify Phonet of device events */
244static int phonet_device_notify(struct notifier_block *me, unsigned long what, 265static int phonet_device_notify(struct notifier_block *me, unsigned long what,
245 void *arg) 266 void *arg)
@@ -253,6 +274,7 @@ static int phonet_device_notify(struct notifier_block *me, unsigned long what,
253 break; 274 break;
254 case NETDEV_UNREGISTER: 275 case NETDEV_UNREGISTER:
255 phonet_device_destroy(dev); 276 phonet_device_destroy(dev);
277 phonet_route_autodel(dev);
256 break; 278 break;
257 } 279 }
258 return 0; 280 return 0;
@@ -287,10 +309,19 @@ static void phonet_exit_net(struct net *net)
287{ 309{
288 struct phonet_net *pnn = net_generic(net, phonet_net_id); 310 struct phonet_net *pnn = net_generic(net, phonet_net_id);
289 struct net_device *dev; 311 struct net_device *dev;
312 unsigned i;
290 313
291 rtnl_lock(); 314 rtnl_lock();
292 for_each_netdev(net, dev) 315 for_each_netdev(net, dev)
293 phonet_device_destroy(dev); 316 phonet_device_destroy(dev);
317
318 for (i = 0; i < 64; i++) {
319 dev = pnn->routes.table[i];
320 if (dev) {
321 rtm_phonet_notify(RTM_DELROUTE, dev, i);
322 dev_put(dev);
323 }
324 }
294 rtnl_unlock(); 325 rtnl_unlock();
295 326
296 proc_net_remove(net, "phonet"); 327 proc_net_remove(net, "phonet");