1 /* 2 * File: pn_dev.c 3 * 4 * Phonet network device 5 * 6 * Copyright (C) 2008 Nokia Corporation. 7 * 8 * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com> 9 * Original author: Sakari Ailus <sakari.ailus@nokia.com> 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * version 2 as published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 23 * 02110-1301 USA 24 */ 25 26 #include <linux/kernel.h> 27 #include <linux/net.h> 28 #include <linux/slab.h> 29 #include <linux/netdevice.h> 30 #include <linux/phonet.h> 31 #include <linux/proc_fs.h> 32 #include <linux/if_arp.h> 33 #include <net/sock.h> 34 #include <net/netns/generic.h> 35 #include <net/phonet/pn_dev.h> 36 37 struct phonet_routes { 38 struct mutex lock; 39 struct net_device *table[64]; 40 }; 41 42 struct phonet_net { 43 struct phonet_device_list pndevs; 44 struct phonet_routes routes; 45 }; 46 47 int phonet_net_id __read_mostly; 48 49 static struct phonet_net *phonet_pernet(struct net *net) 50 { 51 BUG_ON(!net); 52 53 return net_generic(net, phonet_net_id); 54 } 55 56 struct phonet_device_list *phonet_device_list(struct net *net) 57 { 58 struct phonet_net *pnn = phonet_pernet(net); 59 return &pnn->pndevs; 60 } 61 62 /* Allocate new Phonet device. */ 63 static struct phonet_device *__phonet_device_alloc(struct net_device *dev) 64 { 65 struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); 66 struct phonet_device *pnd = kmalloc(sizeof(*pnd), GFP_ATOMIC); 67 if (pnd == NULL) 68 return NULL; 69 pnd->netdev = dev; 70 bitmap_zero(pnd->addrs, 64); 71 72 BUG_ON(!mutex_is_locked(&pndevs->lock)); 73 list_add_rcu(&pnd->list, &pndevs->list); 74 return pnd; 75 } 76 77 static struct phonet_device *__phonet_get(struct net_device *dev) 78 { 79 struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); 80 struct phonet_device *pnd; 81 82 BUG_ON(!mutex_is_locked(&pndevs->lock)); 83 list_for_each_entry(pnd, &pndevs->list, list) { 84 if (pnd->netdev == dev) 85 return pnd; 86 } 87 return NULL; 88 } 89 90 static struct phonet_device *__phonet_get_rcu(struct net_device *dev) 91 { 92 struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); 93 struct phonet_device *pnd; 94 95 list_for_each_entry_rcu(pnd, &pndevs->list, list) { 96 if (pnd->netdev == dev) 97 return pnd; 98 } 99 return NULL; 100 } 101 102 static void phonet_device_destroy(struct net_device *dev) 103 { 104 struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); 105 struct phonet_device *pnd; 106 107 ASSERT_RTNL(); 108 109 mutex_lock(&pndevs->lock); 110 pnd = __phonet_get(dev); 111 if (pnd) 112 list_del_rcu(&pnd->list); 113 mutex_unlock(&pndevs->lock); 114 115 if (pnd) { 116 u8 addr; 117 118 for_each_set_bit(addr, pnd->addrs, 64) 119 phonet_address_notify(RTM_DELADDR, dev, addr); 120 kfree(pnd); 121 } 122 } 123 124 struct net_device *phonet_device_get(struct net *net) 125 { 126 struct phonet_device_list *pndevs = phonet_device_list(net); 127 struct phonet_device *pnd; 128 struct net_device *dev = NULL; 129 130 rcu_read_lock(); 131 list_for_each_entry_rcu(pnd, &pndevs->list, list) { 132 dev = pnd->netdev; 133 BUG_ON(!dev); 134 135 if ((dev->reg_state == NETREG_REGISTERED) && 136 ((pnd->netdev->flags & IFF_UP)) == IFF_UP) 137 break; 138 dev = NULL; 139 } 140 if (dev) 141 dev_hold(dev); 142 rcu_read_unlock(); 143 return dev; 144 } 145 146 int phonet_address_add(struct net_device *dev, u8 addr) 147 { 148 struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); 149 struct phonet_device *pnd; 150 int err = 0; 151 152 mutex_lock(&pndevs->lock); 153 /* Find or create Phonet-specific device data */ 154 pnd = __phonet_get(dev); 155 if (pnd == NULL) 156 pnd = __phonet_device_alloc(dev); 157 if (unlikely(pnd == NULL)) 158 err = -ENOMEM; 159 else if (test_and_set_bit(addr >> 2, pnd->addrs)) 160 err = -EEXIST; 161 mutex_unlock(&pndevs->lock); 162 return err; 163 } 164 165 int phonet_address_del(struct net_device *dev, u8 addr) 166 { 167 struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); 168 struct phonet_device *pnd; 169 int err = 0; 170 171 mutex_lock(&pndevs->lock); 172 pnd = __phonet_get(dev); 173 if (!pnd || !test_and_clear_bit(addr >> 2, pnd->addrs)) { 174 err = -EADDRNOTAVAIL; 175 pnd = NULL; 176 } else if (bitmap_empty(pnd->addrs, 64)) 177 list_del_rcu(&pnd->list); 178 else 179 pnd = NULL; 180 mutex_unlock(&pndevs->lock); 181 182 if (pnd) { 183 synchronize_rcu(); 184 kfree(pnd); 185 } 186 return err; 187 } 188 189 /* Gets a source address toward a destination, through a interface. */ 190 u8 phonet_address_get(struct net_device *dev, u8 daddr) 191 { 192 struct phonet_device *pnd; 193 u8 saddr; 194 195 rcu_read_lock(); 196 pnd = __phonet_get_rcu(dev); 197 if (pnd) { 198 BUG_ON(bitmap_empty(pnd->addrs, 64)); 199 200 /* Use same source address as destination, if possible */ 201 if (test_bit(daddr >> 2, pnd->addrs)) 202 saddr = daddr; 203 else 204 saddr = find_first_bit(pnd->addrs, 64) << 2; 205 } else 206 saddr = PN_NO_ADDR; 207 rcu_read_unlock(); 208 209 if (saddr == PN_NO_ADDR) { 210 /* Fallback to another device */ 211 struct net_device *def_dev; 212 213 def_dev = phonet_device_get(dev_net(dev)); 214 if (def_dev) { 215 if (def_dev != dev) 216 saddr = phonet_address_get(def_dev, daddr); 217 dev_put(def_dev); 218 } 219 } 220 return saddr; 221 } 222 223 int phonet_address_lookup(struct net *net, u8 addr) 224 { 225 struct phonet_device_list *pndevs = phonet_device_list(net); 226 struct phonet_device *pnd; 227 int err = -EADDRNOTAVAIL; 228 229 rcu_read_lock(); 230 list_for_each_entry_rcu(pnd, &pndevs->list, list) { 231 /* Don't allow unregistering devices! */ 232 if ((pnd->netdev->reg_state != NETREG_REGISTERED) || 233 ((pnd->netdev->flags & IFF_UP)) != IFF_UP) 234 continue; 235 236 if (test_bit(addr >> 2, pnd->addrs)) { 237 err = 0; 238 goto found; 239 } 240 } 241 found: 242 rcu_read_unlock(); 243 return err; 244 } 245 246 /* automatically configure a Phonet device, if supported */ 247 static int phonet_device_autoconf(struct net_device *dev) 248 { 249 struct if_phonet_req req; 250 int ret; 251 252 if (!dev->netdev_ops->ndo_do_ioctl) 253 return -EOPNOTSUPP; 254 255 ret = dev->netdev_ops->ndo_do_ioctl(dev, (struct ifreq *)&req, 256 SIOCPNGAUTOCONF); 257 if (ret < 0) 258 return ret; 259 260 ASSERT_RTNL(); 261 ret = phonet_address_add(dev, req.ifr_phonet_autoconf.device); 262 if (ret) 263 return ret; 264 phonet_address_notify(RTM_NEWADDR, dev, 265 req.ifr_phonet_autoconf.device); 266 return 0; 267 } 268 269 static void phonet_route_autodel(struct net_device *dev) 270 { 271 struct phonet_net *pnn = phonet_pernet(dev_net(dev)); 272 unsigned i; 273 DECLARE_BITMAP(deleted, 64); 274 275 /* Remove left-over Phonet routes */ 276 bitmap_zero(deleted, 64); 277 mutex_lock(&pnn->routes.lock); 278 for (i = 0; i < 64; i++) 279 if (dev == pnn->routes.table[i]) { 280 rcu_assign_pointer(pnn->routes.table[i], NULL); 281 set_bit(i, deleted); 282 } 283 mutex_unlock(&pnn->routes.lock); 284 285 if (bitmap_empty(deleted, 64)) 286 return; /* short-circuit RCU */ 287 synchronize_rcu(); 288 for (i = find_first_bit(deleted, 64); i < 64; 289 i = find_next_bit(deleted, 64, i + 1)) { 290 rtm_phonet_notify(RTM_DELROUTE, dev, i); 291 dev_put(dev); 292 } 293 } 294 295 /* notify Phonet of device events */ 296 static int phonet_device_notify(struct notifier_block *me, unsigned long what, 297 void *arg) 298 { 299 struct net_device *dev = arg; 300 301 switch (what) { 302 case NETDEV_REGISTER: 303 if (dev->type == ARPHRD_PHONET) 304 phonet_device_autoconf(dev); 305 break; 306 case NETDEV_UNREGISTER: 307 phonet_device_destroy(dev); 308 phonet_route_autodel(dev); 309 break; 310 } 311 return 0; 312 313 } 314 315 static struct notifier_block phonet_device_notifier = { 316 .notifier_call = phonet_device_notify, 317 .priority = 0, 318 }; 319 320 /* Per-namespace Phonet devices handling */ 321 static int __net_init phonet_init_net(struct net *net) 322 { 323 struct phonet_net *pnn = phonet_pernet(net); 324 325 if (!proc_net_fops_create(net, "phonet", 0, &pn_sock_seq_fops)) 326 return -ENOMEM; 327 328 INIT_LIST_HEAD(&pnn->pndevs.list); 329 mutex_init(&pnn->pndevs.lock); 330 mutex_init(&pnn->routes.lock); 331 return 0; 332 } 333 334 static void __net_exit phonet_exit_net(struct net *net) 335 { 336 struct phonet_net *pnn = phonet_pernet(net); 337 struct net_device *dev; 338 unsigned i; 339 340 rtnl_lock(); 341 for_each_netdev(net, dev) 342 phonet_device_destroy(dev); 343 344 for (i = 0; i < 64; i++) { 345 dev = pnn->routes.table[i]; 346 if (dev) { 347 rtm_phonet_notify(RTM_DELROUTE, dev, i); 348 dev_put(dev); 349 } 350 } 351 rtnl_unlock(); 352 353 proc_net_remove(net, "phonet"); 354 } 355 356 static struct pernet_operations phonet_net_ops = { 357 .init = phonet_init_net, 358 .exit = phonet_exit_net, 359 .id = &phonet_net_id, 360 .size = sizeof(struct phonet_net), 361 }; 362 363 /* Initialize Phonet devices list */ 364 int __init phonet_device_init(void) 365 { 366 int err = register_pernet_device(&phonet_net_ops); 367 if (err) 368 return err; 369 370 register_netdevice_notifier(&phonet_device_notifier); 371 err = phonet_netlink_register(); 372 if (err) 373 phonet_device_exit(); 374 return err; 375 } 376 377 void phonet_device_exit(void) 378 { 379 rtnl_unregister_all(PF_PHONET); 380 unregister_netdevice_notifier(&phonet_device_notifier); 381 unregister_pernet_device(&phonet_net_ops); 382 } 383 384 int phonet_route_add(struct net_device *dev, u8 daddr) 385 { 386 struct phonet_net *pnn = phonet_pernet(dev_net(dev)); 387 struct phonet_routes *routes = &pnn->routes; 388 int err = -EEXIST; 389 390 daddr = daddr >> 2; 391 mutex_lock(&routes->lock); 392 if (routes->table[daddr] == NULL) { 393 rcu_assign_pointer(routes->table[daddr], dev); 394 dev_hold(dev); 395 err = 0; 396 } 397 mutex_unlock(&routes->lock); 398 return err; 399 } 400 401 int phonet_route_del(struct net_device *dev, u8 daddr) 402 { 403 struct phonet_net *pnn = phonet_pernet(dev_net(dev)); 404 struct phonet_routes *routes = &pnn->routes; 405 406 daddr = daddr >> 2; 407 mutex_lock(&routes->lock); 408 if (dev == routes->table[daddr]) 409 rcu_assign_pointer(routes->table[daddr], NULL); 410 else 411 dev = NULL; 412 mutex_unlock(&routes->lock); 413 414 if (!dev) 415 return -ENOENT; 416 synchronize_rcu(); 417 dev_put(dev); 418 return 0; 419 } 420 421 struct net_device *phonet_route_get(struct net *net, u8 daddr) 422 { 423 struct phonet_net *pnn = phonet_pernet(net); 424 struct phonet_routes *routes = &pnn->routes; 425 struct net_device *dev; 426 427 ASSERT_RTNL(); /* no need to hold the device */ 428 429 daddr >>= 2; 430 rcu_read_lock(); 431 dev = rcu_dereference(routes->table[daddr]); 432 rcu_read_unlock(); 433 return dev; 434 } 435 436 struct net_device *phonet_route_output(struct net *net, u8 daddr) 437 { 438 struct phonet_net *pnn = phonet_pernet(net); 439 struct phonet_routes *routes = &pnn->routes; 440 struct net_device *dev; 441 442 daddr >>= 2; 443 rcu_read_lock(); 444 dev = rcu_dereference(routes->table[daddr]); 445 if (dev) 446 dev_hold(dev); 447 rcu_read_unlock(); 448 449 if (!dev) 450 dev = phonet_device_get(net); /* Default route */ 451 return dev; 452 } 453